Files
timmy-home/docs/BACKUP_PIPELINE.md
2026-04-14 23:57:41 -04:00

2.7 KiB

Encrypted Hermes Backup Pipeline

Issue: timmy-home#693

This pipeline creates a nightly encrypted archive of ~/.hermes, stores a local encrypted copy, uploads it to remote storage, and supports restore verification.

What gets backed up

By default the pipeline archives:

  • ~/.hermes/config.yaml
  • ~/.hermes/state.db
  • ~/.hermes/sessions/
  • ~/.hermes/cron/
  • any other files under ~/.hermes

Override the source with BACKUP_SOURCE_DIR=/path/to/.hermes.

Backup command

BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups \
bash scripts/backup_pipeline.sh

The script writes:

  • local encrypted copy: ~/.timmy-backups/hermes/<timestamp>/hermes-backup-<timestamp>.tar.gz.enc
  • local manifest: ~/.timmy-backups/hermes/<timestamp>/hermes-backup-<timestamp>.json
  • log file: ~/.timmy-backups/hermes/logs/backup_pipeline.log

Nightly schedule

Run every night at 03:00:

0 3 * * * cd /Users/apayne/.timmy/timmy-home && BACKUP_PASSPHRASE_FILE=/Users/apayne/.config/timmy/backup.passphrase BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups bash scripts/backup_pipeline.sh >> /Users/apayne/.timmy-backups/hermes/logs/cron.log 2>&1

Remote targets

At least one remote target must be configured.

Local NAS

Use a mounted path:

BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups

The pipeline copies the encrypted archive and manifest into <BACKUP_NAS_TARGET>/<timestamp>/.

S3-compatible storage

BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
BACKUP_S3_URI=s3://timmy-backups/hermes \
AWS_ENDPOINT_URL=https://minio.example.com \
bash scripts/backup_pipeline.sh

Notes:

  • aws CLI must be installed if BACKUP_S3_URI is set.
  • AWS_ENDPOINT_URL is optional and is used for MinIO, R2, and other S3-compatible endpoints.

Restore playbook

Restore an encrypted archive into a clean target root:

BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
bash scripts/restore_backup.sh \
  /Volumes/timmy-nas/hermes-backups/20260415-030000/hermes-backup-20260415-030000.tar.gz.enc \
  /tmp/hermes-restore

Result:

  • restored tree lands at /tmp/hermes-restore/.hermes
  • if a sibling manifest exists, the restore script verifies the archive SHA256 before decrypting

End-to-end verification

Run the regression suite:

python3 -m unittest discover -s tests -p 'test_backup_pipeline.py' -v

This proves:

  1. the backup output is encrypted
  2. plaintext archives do not leak into the backup destinations
  3. the restore script recreates the original .hermes tree end-to-end
  4. the pipeline refuses to run without a remote target