Backups

Three backup paths, each with its own GitHub deploy key (deploy keys are
repo-scoped, not account-wide). Coverage completed 2026-11-01 — all 14 modules'
code and all module databases are now backed up.

1. In-run DB archive

2. Code snapshots

3. Hub DB snapshots (daily)

Deliberately not backed up: racing's data/ (daily-regenerated scrape JSON,
covered by the staging "observed-only" policy) and the 0-byte app.db/rsssports.db.

Deploy keys

Key Repo
/root/.ssh/id_ed25519_vps_backup sportstlm-db-backups (DB archives)
/root/.ssh/id_ed25519_vps_code sportstlm-code-backups (code snapshots)

code_backup.py and the supervisor probe both use the _code key for the code repo.
Probing the code repo with the _backup key returns ERROR: Repository not found —
that means wrong key, not a missing repo.

GitHub PAT alternative

/etc/inrun-backup/github.token (0700 dir / 0600 file), installed via
/opt/backups/accept_credential.py --from-file|--from-url.

Retention / deletion policy

Automated deletion only:
- docker image prune -af --filter until=24h (daily 04:22) — images only
- docker builder prune -f (Wed 04:54) — build cache only
- logrotate — docker/caddy/apt logs only
- systemd-tmpfiles — /tmp 10 d, /var/tmp 30 d
- inrun DB archive rotation — keeps 12 archives

Staging datasets (/opt/sportstlm/data, /opt/racing/data, /opt/lottery/data) are
observed only — no timer/heal may purge them (fallback datasets).