Files
6krrt/deploy/llm-router-offsite.timer
adlee-was-taken 4a32b0180f feat(deploy): 6-hourly off-site backup to a private git repo
Closes the last gap from docs/incidents.md #5. The hourly local snapshots
survive `git clean -fdx` because they live outside the repo, but they do not
survive the disk. This pushes the irreplaceable-and-small state to a private
Gitea repo: .omo plans and evidence ledger, tuned systemd units, opencode
plugins, this project's Claude memory, config/config.local.yaml, and a DAILY
gzipped router.db.

The database is committed daily rather than hourly on purpose: it is binary and
~5MB gzipped, so git cannot delta it. Hourly would grow the repo ~120MB/day
instead of ~5MB. SYNC_DB=0 turns it off entirely.

.env is deliberately NOT synced. There is no usable secret key on this host to
encrypt it to (public keys only), so it would sit in git history in plaintext,
and history is forever even in a private repo. An API key is replaceable by
regenerating it from the provider; 22,821 energy observations are not. It stays
in the local backups only, and the user confirmed that trade.

Verified by fresh clone: 35 plan artifacts, 127 evidence files, 9 systemd
units, 2 opencode plugins, 11 memory files, the tariff, and a 5.1MB db
snapshot. Checked the actual 67-character key VALUE appears in zero off-site
files -- an earlier check grepped for the variable NAME and for 'sk-', which
matches 'task-', and produced 50 false positives. Grep for the secret, not for
its label.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
2026-09-04 18:43:23 -04:00

14 lines
375 B
SYSTEMD

# Every 6h. Less frequent than the hourly local snapshot on purpose: this one
# needs the network and pushes a ~5MB binary daily, so the local timer stays
# the fine-grained safety net and this is the off-site floor.
[Unit]
Description=Periodic off-site backup of LLM router state
[Timer]
OnBootSec=15min
OnUnitActiveSec=6h
Persistent=true
[Install]
WantedBy=timers.target