3.4 KiB
3.4 KiB
semprini-maintainer — Claude Instructions
What this is
A standalone, always-on autonomous maintenance agent for the semprini.me
container stack, deployed as a systemd service (semprini-maintainer). It keeps
the stack healthy and current and talks to the operator over Matrix
(chat.semprini.me).
It is the unattended driver for the canonical stack-support agent, which lives in the separate semprini-core repo. This project does not reimplement that logic — it gathers state and invokes the stack-support agent headless via Claude Code, then relays/acts on the agent's JSON result.
Relationship to other projects
- semprini-core (
../semprini-core) — the Enterprise Landing Zone this agent maintains. At runtime the daemon reads, from the path inconfig.jsonrepo_dir:agents/stack-support.agent.md(injected as system prompt)docs/stack-support-runbook.mdcore_stack/compose*.ymlKeep the stack-support agent definition canonical in semprini-core — do not fork a copy here.
- Other projects (e.g.
../semprini-blog) that register Uptime Kuma monitors are also maintained; their repos are exposed to the agent viaextra_dirs.
How it works (one screen)
- Scope = whatever Uptime Kuma tracks at check time, re-read every cycle
(never hard-coded). Kuma's heartbeat is the health signal — the daemon does not
re-probe. Kuma's root-owned
kuma.dbis read via a throwawaykeinos/sqlite3container mounting theuptime-kuma-datavolume read-only. - Health loop (5 min): down services confirmed over
down_confirmationscycles → invoke stack-support agent to remediate → report to Matrix. Also reads Kuma'simportant=1heartbeat transitions since the last cycle (tracked by heartbeat id) to catch services that blipped DOWN→UP on their own, and hands those self-recovered windows to the agent for a log post-mortem. - Upgrade loop (7 days): resolve containers behind tracked services → agent researches + applies safe upgrades (test, pin, rollback); escalates major/breaking ones to Matrix.
- Matrix: bot
@maintainer-bot:semprini.meDMs@paul:semprini.me. Escalations are numbered questions; the reply is fed back to the agent to carry out. - Autonomy (
config.json→autonomy):full(default) |fix-only|notify.
Conventions / guardrails
- Runs as host user
paul(indockergroup), not root — Claude Code refuses--permission-mode bypassPermissionsunder root. maintainer.pyis stdlib-only — keep it dependency-free so it deploys without a venv.- Secrets live in
config.jsonand.bot-secrets— never commit (gitignored). - Prefer editing existing files over adding new ones.
Files
| File | Purpose |
|---|---|
maintainer.py |
The daemon (stdlib only). |
config.example.json |
Template — copy to config.json. |
register-matrix-bot.sh |
Creates @maintainer-bot account + DM room; writes token to config. |
install.sh |
Syntax-check, install unit, enable + start. |
semprini-maintainer.service |
systemd unit (runs as paul). |
docs/architecture.md |
Architecture decision record. |
Test without the service
python3 maintainer.py --config config.json --once health
python3 maintainer.py --config config.json --once upgrade
python3 maintainer.py --config config.json --once replies