118 lines
5.4 KiB
Markdown
118 lines
5.4 KiB
Markdown
---
|
|
name: server-recovery-bundle
|
|
description: "Build self-contained recovery bundles containing all config, scripts, credentials, cron jobs, and conversation history needed to restore a Hermes instance onto a brand-new server."
|
|
version: 1.1.0
|
|
author: Hermes Agent
|
|
license: MIT
|
|
platforms: [linux]
|
|
metadata:
|
|
hermes:
|
|
tags: [disaster-recovery, backup, migration, bootstrap, hermetic]
|
|
related_skills: [email-workflows, hermes-agent, hermes-backup]
|
|
---
|
|
|
|
# Server Recovery Bundle
|
|
|
|
Build a single self-contained markdown file that can be pasted into a fresh Hermes agent to fully restore the instance. Think of it as a **disaster recovery envelope** — all the config, scripts, and secrets someone would need if this server died tomorrow.
|
|
|
|
## When to use
|
|
|
|
- User asks for a "recovery bundle", "restore kit", "bootstrap file", or "everything I need to rebuild you"
|
|
- After a server migration (document the new state)
|
|
- Before a destructive upgrade or decommission
|
|
- As a periodic safety net alongside regular backups
|
|
|
|
## What to include
|
|
|
|
### 1. Header section
|
|
- Title, date, one-line purpose
|
|
- "Paste this into a new Hermes to restore me" instruction
|
|
|
|
### 2. Bootstrap instructions
|
|
- Step-by-step: install Hermes, create each file, start gateway, recreate cron jobs, verify
|
|
|
|
### 3. Credentials summary (one place, easy to find)
|
|
- SMTP/IMAP password
|
|
- S3 (Wasabi/AWS) keys
|
|
- Cloud API tokens (Hetzner, netcup, etc.)
|
|
- VPN keys or passwords
|
|
- A clear note of what each credential is for
|
|
- **WARNING: The recovery bundle contains cleartext secrets.** It must be treated as a credential file and stored securely (password manager, encrypted vault). If emailed, use encrypted email or delete after transfer.
|
|
|
|
### 4. Config files — verbatim
|
|
- `~/.hermes/config.yaml`
|
|
- `~/.hermes/.env`
|
|
- `~/.aws/credentials`
|
|
- `~/.hermes/SOUL.md`
|
|
- `/etc/systemd/system/hermes.service`
|
|
- Any other env/config files the instance depends on
|
|
|
|
### 5. SSH keys (public + private)
|
|
- WISP keys, deploy keys, any SSH keys used by scripts
|
|
|
|
### 6. Cron jobs — full definition
|
|
Include for each job: name, schedule, script path, skills, mode (no_agent/agent), deliver target
|
|
Use `hermes cron list --json` (and fallback to text if JSON fails)
|
|
|
|
### 7. Scripts — verbatim
|
|
Every file in `~/.hermes/scripts/` that isn't in `__pycache__` or starts with `.`
|
|
Also include subdirectory scripts (wisp-backup/, etc.)
|
|
|
|
### 8. Today's conversation history
|
|
- Get today's user sessions (not cron sessions) from the state DB
|
|
- Filter by `started_at >= today_midnight AND id LIKE '20%'` (excludes cron sessions which start with `cron_`)
|
|
- Include full message text from both sessions
|
|
- Truncate extremely long messages (>5000 chars) with a note
|
|
|
|
## Key patterns and pitfalls
|
|
|
|
### Session filtering
|
|
Cron sessions have IDs like `cron_<hash>_<timestamp>` — filter them out by requiring `id LIKE '20%'` (user session IDs start with a date). The SQL filter:
|
|
|
|
```sql
|
|
SELECT id, title, started_at, ended_at, end_reason, message_count
|
|
FROM sessions
|
|
WHERE started_at >= <today_unix_ts> AND id LIKE '20%'
|
|
ORDER BY started_at
|
|
```
|
|
|
|
### Handling SMTP delivery failure
|
|
The recovery bundle file can be large (200-500 KB). Common email pitfalls:
|
|
|
|
- **Your mail server and agent server are different machines** — always verify port reachability before assuming SMTP works
|
|
- Test each port separately: SMTP (587), IMAP (993). One can be open while the other is firewalled.
|
|
- A CNAME or MX record can point to a totally different provider than your other infrastructure. DNS lookup: `host mail.example.com` or `python3 -c "import socket; print(socket.gethostbyname('mail.example.com'))"`
|
|
- Test with: `python3 -c "import socket; s=socket.socket(); s.settimeout(5); s.connect(('<host>', 587)); print('OK')"`
|
|
- A port that **times out** (not refuses) points to a firewall drop, not a server-side block — your ISP or cloud provider may be filtering outbound SMTP
|
|
- If SMTP fails: try Wasabi S3 upload as fallback (`aws s3 cp` with `--endpoint-url`)
|
|
- Or deliver directly in the current chat (Telegram/WhatsApp can take large files)
|
|
|
|
### Don't fabricate
|
|
Do not include password/API-key values you "reconstruct" from memory. Only include credentials you actually read from files on this machine. If a credential file doesn't exist, say so rather than leaving a placeholder.
|
|
|
|
### Message truncation
|
|
Very long messages (compacted context, large JSON tool outputs) should be truncated at ~5000 chars with a note: `[truncated, was N chars]`. This keeps the bundle readable and under email size limits.
|
|
|
|
### Cron job retention from state.db
|
|
After a server migration, cron jobs survive in `state.db` but the scheduler needs ~30-60s to discover them after startup. If `hermes cron list` returns empty immediately after migration, wait and retry before assuming they were lost.
|
|
|
|
### Build script pattern
|
|
Rather than assembling the bundle inline in the agent's tool loop, write a Python build script (`scripts/build-recovery.py`) that:
|
|
1. Queries state.db for sessions/messages
|
|
2. Reads all config/script/credential files
|
|
3. Assembles the markdown document
|
|
4. Writes the output file
|
|
|
|
This avoids context-window overflow on large state DBs and makes the bundle reproducible.
|
|
|
|
## Verification
|
|
|
|
After building the recovery bundle:
|
|
|
|
1. Verify the file was written: `wc -c <path>`
|
|
2. Try to upload/send it (failures here are worth reporting to the user)
|
|
3. List what's in it: session count, script count, cron count
|
|
4. Report result to the user with the file location and any delivery issues
|
|
|
|
---
|