# πŸ’Ύ Backup The Crew: Schedules, Folders & Configuration

**Date:** July 16, 2026  
**Tags:** Backups, AI Agents, GitHub, NAS, SMB, cron, Self-Hosted, Ops

---

## 🎯 Overview

This guide documents **how the agent crew is backed up** β€” every folder, every schedule, every destination. The strategy has two legs:

1. **GitHub** β€” config + code for each agent pushed to a dedicated private repo (offsite, versioned).
2. **Local NAS (SMB2)** β€” full config snapshots copied to a network share (`/mnt/VM/...`) for fast local restore.

A shared **status tracker** records each run so you can see at a glance what backed up and what failed.

> ⚠️ **Secrets rule:** Every credential (Telegram tokens, GitHub PATs, NAS passwords, Supabase URLs) is a `` here. The real scripts load them from `~/.hermes/.env` or a secure token file β€” never committed.

---

## πŸ—ΊοΈ Backup Topology

```
   Each agent's config dirs
        β”‚  (per-schedule scripts)
        β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                          β–Ό
   GitHub  (offsite, versioned)   Local NAS  /mnt/VM  (SMB2)
     β”œ HermesBot.git                β”œ OpenClaw/
     β”œ OpenClaw.git                 β”œ Codex/
     β”œ Codex β†’ OpenAI.git          β”œ OpenCode/
     β”œ PiAgent.git                 β”œ PiAgent/
     β”œ OpenCode.git                β”” Dashboards/
     β”” gbrain-brain / gbrain-workspace
        β”‚
        β–Ό
   backup_status.json  (central run ledger)
```

---

## 🧩 Requirements

- **GitHub** account with one private repo per agent (or grouped repo).
- **Local NAS** exporting an SMB2 share mounted at `/mnt/VM` (credentials in `~/.hermes/.env`).
- **`git`** configured with a token helper / PAT (`` or token file).
- **`rsync`** + **`cp`** available on the VM.
- **Telegram bot token + home channel chat id** (``, ``) for notifications.
- **cron** (user crontab) and/or **Hermes no_agent cron jobs** to fire the scripts.
- **Bun** for GBrain CLI (`gbrain-brain` / `gbrain-workspace` pushes).

---

## πŸ“… Scheduling

| Job | Schedule | Mechanism |
|-----|----------|-----------|
| Hermes config daily backup | `0 0 * * *` (midnight) | system crontab β†’ `daily-backup.sh` |
| Hermes config update | `0 8,16 * * *` (8am, 4pm) | system crontab β†’ `update-config.sh` |
| Claude β†’ Obsidian notes sync | `0 * * * *` (hourly) | system crontab β†’ `claude_to_obsidian.py` |
| GitHub backups (Hermes/OpenClaw/Codex/Pi/OpenCode) | daily (date-stamped folders) | cron / Hermes no_agent jobs calling each `*-github-backup.sh` |
| NAS/SMB backups (OpenClaw/Codex/Pi/OpenCode/Dashboards) | daily (date-stamped folders) | cron / Hermes no_agent jobs calling each `*-smb-backup.sh` |
| NAS monitor | periodic | `nas-monitor.sh` / `nas-monitor.py` |
| GBrain GitHub mirror | periodic (offsite) | `gbrain-brain` + `gbrain-workspace` push |

> πŸ’‘ Date-stamped folders (`Backups/YYYYMMDD/`) mean each day is an immutable snapshot β€” you can roll back to any date.

---

## πŸ“ What Gets Backed Up (per agent)

### πŸ€– Hermes β†’ GitHub `ryanthemanr0x/HermesBot`
- Source: `~/.hermes` (config, skills, plugins, cron, scripts)
- **Excluded:** heavy runtime/cache (`node/`, `venvs/`, `cache/`, `sessions/`) β€” regenerable.
- `.env` is **sanitized** to `.env.template` (placeholders) before push.
- Also: `hermes-backup/Backups/YYYYMMDD/` working repo.

### πŸ¦… OpenClaw β†’ GitHub `OpenClaw.git` + NAS `/mnt/VM/OpenClaw`
- Source: `~/.openclaw`
- Copied: `openclaw.json`, `credentials/`, `logs/`, `skills/`, `canvas/`
- Mirror script: `openclaw-github-backup.sh` (GitHub) and `openclaw-smb-backup.sh` (NAS).

### πŸŒ€ Codex β†’ GitHub `OpenAI.git` (Codex/Backups/NAS/YYYYMMDD) + NAS `/mnt/VM/Codex`
- Source: `~/.codex`, `~/telegram-codex`, `~/codex-workspace`
- Telegram bot: `codex-telegram-bot.service`

### πŸ₯§ Pi β†’ GitHub `PiAgent.git` + NAS `/mnt/VM/PiAgent/YYYYMMDD`
- Source: `~/.pi`, `~/telegram-pi`
- Notifications: **success AND failure** (Pi script is the verbose one).

### 🧠 OpenCode β†’ GitHub `OpenCode.git` + NAS `/mnt/VM/OpenCode`
- Source: `~/.opencode`, `~/.config/opencode`, `~/.local/share/opencode`, `~/.local/state/opencode`, `~/.local/cache/opencode`
- **Excluded:** `node_modules/`, `*.db`, `locks/` (regenerable).

### πŸ“Š Dashboards β†’ NAS `/mnt/VM/Dashboards`
- Source: `~/ramlabs-ai-dashboard`, `~/local-agent-search`, `~/.hermes/hermes-agent/hermes_cli`, `~/.hermes/node/lib/node_modules/9router`
- Subfolders per dashboard: `RamLabs/`, `Hermes/`, `9Router/`, `LocalAgentSearch/`
- **Excluded:** `__pycache__/`, `venv/`, `node_modules/`

### 🧠 GBrain β†’ GitHub `gbrain-brain` + `gbrain-workspace`
- `gbrain-brain`: the brain content (pages, sources, structured memory)
- `gbrain-workspace`: working notes, drafts
- Pushed via git (Bun CLI available at `~/.bun/bin/gbrain`).

---

## πŸ”” Notification Policy

| Destination | Success | Failure |
|-------------|---------|----------|
| GitHub (Hermes, OpenClaw, Codex, OpenCode) | silent | Telegram alert |
| NAS/SMB (OpenClaw, Codex, OpenCode, Dashboards) | silent | Telegram alert |
| Pi GitHub | **Telegram (both)** | **Telegram (both)** |

> πŸ’‘ Most jobs are **silent on success** (watchdog pattern) β€” you only hear about failures. Pi is the exception and confirms success too.

---

## πŸ“Š Approximate Sizes (source dirs)

| Agent / dir | Approx size |
|-------------|-------------|
| `~/.hermes` | ~6.7 GB (GitHub copy excludes caches β†’ much smaller) |
| `~/.openclaw` | ~190 MB |
| `~/.codex` | ~200 MB |
| `~/.pi` | ~7 MB |
| `~/.opencode` | ~138 MB |
| `~/.claude` | ~13 MB |
| `~/telegram-codex` | ~26 MB |
| `~/telegram-pi` | ~40 MB |
| `gbrain-brain` | ~7.4 MB |
| `gbrain-workspace` | ~330 KB |
| `ramlabs-ai-dashboard` | ~4.6 MB |

> πŸ“ Excluded dirs (node_modules, caches, session DBs) are **not** backed up β€” they regenerate. This keeps GitHub repos lean and under size limits.

---

## βš™οΈ Configuration (sanitized)

### Example: GitHub backup script shape

```bash
#!/usr/bin/env bash
set -e
# Load secrets from env (NEVER commit):
if [ -f "$HOME/.hermes/.env" ]; then
  set -a; . "$HOME/.hermes/.env"; set +a
fi

GITHUB_REPO="https://github.com/ryanthemanr0x/.git"
WORK_DIR="$HOME/-github-backup"
DATE=$(date +%Y%m%d)
BACKUP_PATH="$WORK_DIR/Backups/$DATE"

# Token: from a secure token file or .env (placeholder here):
GITHUB_TOKEN=""
TELEGRAM_BOT_TOKEN=""
TELEGRAM_CHAT_ID=""

# Copy config, sanitize secrets, commit + push
rsync -av "$HOME/.hermes/" "$BACKUP_PATH/" --exclude=node_modules --exclude=cache
git -C "$WORK_DIR" add -A
git -C "$WORK_DIR" commit -m "Backup $DATE"
git -C "$WORK_DIR" push "https://${GITHUB_TOKEN}@github.com/ryanthemanr0x/.git" main
```

### Example: NAS (SMB2) backup shape

```bash
#!/usr/bin/env bash
set -e
BACKUP_DEST="/mnt/VM/"
DATE=$(date +%Y%m%d)
BACKUP_PATH="$BACKUP_DEST/$DATE"
mkdir -p "$BACKUP_PATH"
# NAS credentials mounted via /etc/fstab or .env (placeholder):
#   //192.168.50.100/VM  /mnt/VM  cifs  username=,password=,_netdev  0 0
rsync -av --copy-links "$HOME/.opencode/" "$BACKUP_PATH/"
# silent on success; Telegram alert only on failure
```

### Central status ledger

Every script calls `backup-status.sh    [message]`, which appends a JSON entry to:

```
~/ramlabs-ai-dashboard/data/backup_status.json
```

Entry shape:

```json
{
  "agent": "",
  "destination": "github|local",
  "status": "success|failure",
  "ts_utc": "",
  "ts_local": "",
  "message": ""
}
```

---

## 🩺 Troubleshooting

| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| GitHub push 401 | expired PAT | refresh `` / token file |
| NAS backup fails | share unmounted | `mount /mnt/VM` or check `_netdev` + credentials |
| Silent success, no restore tested | no dry-run | periodically test-restore a dated folder |
| `backup_status.json` missing entry | script aborted early | check the script's exit / Telegram failure alert |

---

## πŸ” Security Checklist

- [ ] All tokens in `~/.hermes/.env` / secure token files β€” never in repos.
- [ ] `.env` sanitized to `.env.template` before any GitHub push.
- [ ] NAS credentials in fstab with `password=` (or autofs secret), not in scripts.
- [ ] GitHub repos are **private**.
- [ ] Excluded dirs (caches, node_modules, session DBs) reduce leak surface + repo size.

---

## βœ… Summary

The crew is protected on **two fronts**: versioned **GitHub** repos (offsite, immutable date-stamped snapshots) and fast **local NAS** copies over **SMB2**. Schedules run daily (midnight Hermes config, 8am/4pm updates, hourly Claudeβ†’Obsidian), notifications are silent-on-success (Pi confirms both), and a central `backup_status.json` ledger tracks every run. Restore = clone the dated folder or copy from `/mnt/VM`. πŸš€

---

*No API keys, tokens, passwords, or secrets are included β€” every value is a `` you supply locally. Built with Astro, GitHub, and Cloudflare Pages.*