---
name: hermes-config-backup
description: Version-control Hermes Agent configuration (config.yaml, skills, memories, logs) with Git and push to GitHub — one repo with multiple branches per environment (cloud, WSL, etc.). Includes .gitignore design, cron-based auto-commit, and full recovery scripts for system rebuild.
version: 1.0.0
author: Hermes Agent
tags: [hermes, backup, git, github, version-control, recovery, cron]
---

# Hermes Config Backup with Git

Set up version control for Hermes Agent's core data — configuration, learned skills, user memories, and diagnostic logs — so that system crashes or rebuilds don't lose accumulated knowledge.

## When to Use

- User configures Hermes extensively and wants crash recovery
- User has multiple Hermes instances (cloud + local WSL) and wants unified backup
- User asks "how to prevent losing skills/configuration if the server crashes"
- User expresses concern about Hermes crashing during network/debug work
- User wants to "track changes" to their Hermes setup over time

## Architecture: One Repository, Multiple Branches

```
GitHub: <user>/hermes-dotfiles (private repo)
│
├── main           ← Cloud/server Hermes instance
│   ├── config.yaml
│   ├── skills/
│   ├── memories/
│   ├── logs/
│   ├── .gitignore
│   └── scripts/recover.sh
│
└── local          ← WSL/local Hermes instance
    ├── config.yaml
    ├── skills/
    ├── memories/
    ├── logs/
    ├── .gitignore
    └── scripts/recover.sh
```

Skills are synced between branches via merge (not copy-paste):
```bash
# On cloud: pull local's new skills
git merge origin/local

# On local: pull cloud's new skills
git merge origin/main
```

## What to Track vs. Exclude

### ✅ Track

| Item | Path | Typical Size | Notes |
|------|------|-------------|-------|
| Config | `config.yaml` | ~10 KB | Core settings |
| Skills | `skills/` | ~10 MB | 551 files, 84 skills — **most valuable** |
| Memories | `memories/` | ~12 KB | User profile data |
| Logs | `logs/` | ~100 KB | Crash debugging — daily growth ~50 KB |

### ❌ Exclude (.gitignore)

| Item | Reason |
|------|--------|
| `.env` | Contains API keys — store separately |
| `sessions/` | Chat transcripts, large and unnecessary |
| `state.db` / `state.db-shm` / `state.db-wal` | Binary DB files |
| `*.lock` | Temporary lock files |
| `cache/`, `image_cache/`, `audio_cache/` | Cached data, regenerated |
| `logs/curator/` | Curator logs, noisy |

**Sample .gitignore:**
```
.env
*.lock
sessions/
state.db
state.db-shm
state.db-wal
gateway.lock
gateway.pid
cache/
image_cache/
audio_cache/
logs/curator/
```

## Setup Steps

### Prerequisites

- Git installed (`git --version`)
- GitHub account and `gh` CLI installed (`gh --version`)
- GitHub reachable (`ping github.com`)

### Step 1: Create GitHub Token

1. Go to https://github.com/settings/tokens → Generate new token (classic)
2. Scope: `repo` (full private repo access) — minimum needed
3. **SAVE the token to a secure, offline location** (password manager, user's local PC `~/secure/`). The token is the key to recovery.

### Step 2: Cloud Environment Init

```bash
cd ~/.hermes

# Create .gitignore
cat > .gitignore << 'EOF'
.env
*.lock
sessions/
state.db
state.db-shm
state.db-wal
gateway.lock
gateway.pid
cache/
image_cache/
audio_cache/
logs/curator/
EOF

# Init repo
git init
git add -A
git status   # VERIFY no .env or sensitive files are staged
git commit -m "chore: init hermes dotfiles backup [cloud]"

# Create local branch for WSL
git checkout -b local
git commit --allow-empty -m "chore: init local branch for WSL"
git checkout main

# Create GitHub repo and push
gh auth login   # use the token from step 1
gh repo create hermes-dotfiles --private --push --remote origin
git push --all origin
```

### Step 3: Local (WSL) Environment Init

Inside the user's WSL terminal:

```bash
cd ~/.hermes

# Same .gitignore as cloud
cat > .gitignore << 'EOF'
...  # same content as above
EOF

git init
git add -A
git commit -m "chore: init hermes dotfiles backup [local]"
git remote add origin https://github.com/<username>/hermes-dotfiles.git
git fetch origin
git rebase origin/local
git push --set-upstream origin local
```

### Step 4: Create Recovery Script

Save as `scripts/recover.sh` in the repo:

```bash
#!/bin/bash
set -e

echo "=== Hermes Dotfiles Recovery ==="

# Dependencies
command -v git >/dev/null 2>&1 || { echo "❌ Git not installed"; exit 1; }
command -v gh >/dev/null 2>&1 || {
  echo "Installing gh CLI..."
  sudo apt install gh -y
}

# Auth
gh auth status >/dev/null 2>&1 || {
  echo "⚠️  Please login first: echo \$TOKEN | gh auth login --with-token"
  exit 1
}

# Backup existing (if any)
[ -d ~/.hermes ] && mv ~/.hermes ~/.hermes.bak.$(date +%Y%m%d_%H%M%S)

# Clone
gh repo clone <user>/hermes-dotfiles ~/.hermes
cd ~/.hermes

# Checkout correct branch for this environment
# Cloud: git checkout main
# WSL:   git checkout local
git checkout main

echo "✅ Recovery complete. Restore .env manually, then: hermes gateway start"
```

Also create a `recover-local.sh` variant that checks out `local` instead of `main`.

### Step 5: Automated Daily Backup (Cron)

**Cloud (cronjob):**  
```yaml
schedule: "0 3 * * *"    # 3 AM daily
command: |
  cd ~/.hermes
  git add -A
  git diff --cached --quiet || git commit -m "chore: auto backup $(date +%Y-%m-%d)"
  git push origin main
```

**WSL (crontab):**  
```bash
0 4 * * * cd ~/.hermes && git add -A && git diff --cached --quiet || git commit -m "chore: auto backup $(date +\%Y-\%m-\%d)" && git push origin local
```

### Step 6: Secure .env Storage

The `.env` file (containing API keys) must NEVER go into the repo. Instead:

```bash
# On the user's local PC (WSL):
mkdir -p ~/secure
cp ~/.hermes/.env ~/secure/hermes-env-cloud    # Cloud's .env backup
cp ~/.hermes/.env ~/secure/hermes-env-local    # WSL's .env backup
```

After a cloud system rebuild, manually copy the .env back.

## Recovery Flow (System Rebuild)

```
1. Install Hermes      → curl -fsSL https://...install.sh | bash
2. Install gh CLI      → sudo apt install gh -y
3. Retrieve token      → from local PC ~/secure/ or password manager
4. Authenticate        → echo $TOKEN | gh auth login --with-token
5. Run recovery script → bash repo/scripts/recover.sh
6. Restore .env        → copy from local PC backup
7. Start gateway       → hermes gateway start
```

**Estimated time: 5–10 minutes**

## Verification Checklist

- [ ] GitHub repo exists with `main` + `local` branches
- [ ] Config pushed without API keys (check git diff)
- [ ] All 84 skills are committed
- [ ] WSL config pushed to `local` branch
- [ ] Recovery script syntax-checked
- [ ] Cron auto-commit works
- [ ] `.env` securely stored off-repo

## Pitfalls

- **Token on the server is dangerous.** Don't store the token in `.env` or anywhere on the server. Keep it on the user's local PC. If the server is compromised, the token is safe.
- **.env must never be committed.** Double-check `git status` and `.gitignore` before the first commit. If committed by accident, remove from git history with `git filter-branch` or `bfg`.
- **Two branches, two configs.** Cloud and WSL have different models and settings (cloud: deepseek-v4-flash; WSL: deepseek-chat, kawaii personality). Never force-push one branch over the other.
- **Log growth.** Logs grow daily (~50 KB/day). The repo stays small for years but monitor `du -sh .git` periodically.
- **Cron must use correct shell.** In crontab, `%` must be escaped with backslash for date formatting.
- **Recovery script needs the branch right.** The recover script must know which branch to checkout. Use different scripts or parameterize by hostname.

## Reference Files

- `references/session-20260515-plan-design.md` — Real session log of designing this Git backup plan with user 小天, including decision rationale, user values, and recovery flow.
