STAGE 05 / HARDENED
Runner P6
Homelab P4–5
~30 credits
Polish.
Backups run on a schedule and are restorable. Agents do useful work without you. Infra changes go through CI. The system is reproducible from zero — and you have a tested path home if it isn't.
Goal
Operating system, not a project.
Cron-driven backups, scheduled agents, CI-gated deploys. The end of build, the start of use.
Exit criteria
- Restic fast (daily) + slow (weekly) running on cron, with forget + prune
- Restore tested against a clean Dev-Learning VM — non-optional
- Uptime Kuma alerts if a backup cron fails
- Daily briefing agent posts to vault + Discord
- Scheduled research pipeline produces a vault note
terraform planon every MR,applyon merge to main
Files & commands
roles/restic· fast tier daily cron · 7d / 4w / 3m- Slow tier weekly cron · 4w / 12m · Glacier IR
- Restic forget + prune scheduled
- PostgreSQL dump script · runs before fast backup · cleaned after
restore.yml· tagged playbook (vault · gitea · dbs · photos)- ★ Restore test on clean Dev-Learning VM
docs/restore.md· exact commands- Uptime Kuma alert if backup cron fails
.gitlab-ci.yml·terraform planon MR · output as MR commentterraform applyon merge to main- Ansible lint on every push
- Secrets in GitLab CI variables only
- Pipeline must pass before merge
agents/briefing.py· daily cron · vault + Discordagents/research.py· scheduled topic → search → synth → vaultagents/memory.py· extract user facts → memory collection- Per-provider usage tracker · surfaced in
/health+ UI - Runner
.gitlab-ci.yml· test → build → deploy on main
## Homelab — Phase 4 (Backup + Restore) Cron the Restic fast + slow backups per spec. Write restore.yml with tags. Most importantly: a tested restore on a clean Dev-Learning VM. The phase is not done until that test passes. ## Homelab — Phase 5 (CI) .gitlab-ci.yml with plan-on-MR and apply-on-main. Variables only, no secrets in repo. Lint Ansible on every push. ## Runner — Phase 6 (Agents) Three agents: briefing, research, memory. All schedule-driven. Usage tracker surfaces in /health. Add the runner's own .gitlab-ci.yml.
Final pitfalls
CRITICAL
Restore test
Run it. A backup with an untested restore is not a backup. Phase 4 fails without this.
WATCH
Cron drift
Set Uptime Kuma push monitors so silent cron failure becomes a Discord ping.
WATCH
CI secrets
Project-scope CI variables only. Never echo a secret in a job; use masking.
END OF BUILD
Reproducible from zero.
From here it's operation, not construction. Phase 6 of the runner can become its own project tracker — build the tool, then use the tool.