Operating in production
Supervisor back-ends
The default TmuxSupervisor works on any host with tmux installed. The agent wrapper loops on the runtime binary, so crashes restart within 5 s. What you don’t get is reboot-survivability.
For 24/7 home-lab use, switch to a system supervisor:
supervisor: type: systemd # Linux (user-scope units) # or: type: launchd # macOS (per-user LaunchAgents)The Supervisor trait abstracts the back-end; agent lifecycle, teamctl status, and teamctl reload work the same regardless.
State on disk
Everything runtime-ish lives under state/:
state/├── mailbox.db # SQLite, WAL mode├── envs/<project>-<agent>.env # rendered per-agent env├── mcp/<project>-<agent>.json # MCP stdio config└── applied.json # last-reloaded compose hashBack it up the way you back up any SQLite DB (VACUUM INTO, litestream, or copy while the agents are quiesced with teamctl down).
Garbage collection
teamctl gc drops acked messages older than budget.message_ttl_hours (default 24) and marks expired pending approvals. Run it on a cron:
*/30 * * * * /usr/local/bin/teamctl -C /srv/teamctl gcObservability
teamctl status— agent state + inbox depth per agent.teamctl budget— 24 h message / approval / USD counts per project.teamctl bridge list— open and recently expired inter-project links.tmux attach -t a-<project>-<agent>— raw runtime TTY (read-only recommended).TEAMCTL_LOG=debug teamctl up— verbose tracing from the control plane.
Security posture
- Give each interface adapter the minimum token scope it needs — Telegram bots can be restricted by
authorized_chat_ids. - The HITL gate denies sensitive actions by default. Don’t remove items from
hitl.globally_sensitive_actions— addauto_approve_windowswith tightuntil:when you need time-limited automation. - Runtimes (
claude,codex,gemini) can do whatever you permit them to do. Usepermission_mode: planto make an agent read-only.
When something goes wrong
- Agent keeps restarting →
teamctl logs <project>:<agent>shows the wrapper and runtime output. - Mailbox grows unbounded →
teamctl gc; checkmessage_ttl_hours. - Agents idle with full inbox →
teamctl statusinbox depth > 0 but no activity usually means the prompt doesn’t instruct them to callinbox_watch. Review role markdown.