telep-mainframe Master Agent — Design / Spec
An always-on Claude agent on the bare-metal host telep-mainframe, driven remotely from the phone via Claude Code Remote Control, autostarted by systemd, with homelab context (the vault) and the same recall/documentation reflexes as a normal session.
Motivation
The 2026-08-08 UPS switch triggered a reboot cycle; Frigate’s detect pipeline jammed and did not self-recover, and there was no remote way to drive the box back to health short of a manual SSH + runbook. We already run remote-controlled Claude agents inside the Incus agent containers (alpiq, facekom, crypto) as claude remote-control sessions surfaced in the phone’s Code tab. This spec brings that same capability to the host itself, plus the one piece the containers lack: systemd autostart.
See telep-mainframe-handover · SESSION-HANDOVER · 2026-08-03-telep-router-factory-reset-recovery (the autonomy blast-radius incident).
Mechanism: Claude Code Remote Control
claude remote-control --spawn same-dir runs as a long-lived process; the session appears in claude.ai/code and the Claude mobile app’s Code tab, and is driven from there (/background / /branch; a server can host concurrent sessions with --spawn worktree --capacity N). This is the exact mechanism already used on the Incus containers, where it runs inside a tmux session named control-plane-<host>. Confirmed present on the host: claude v2.1.220 at ~/.local/bin/claude, remote-control subcommand available.
Components
| # | Component | Detail |
|---|---|---|
| 1 | tmux | apt install tmux — only missing dependency on the host. |
| 2 | Vault clone | git clone wowjeeez/obsidian /home/levander/obsidian, read-write (host deploy key). Serves as both the agent’s homelab context and its WorkingDirectory. |
| 3 | control-plane.service | systemd unit, User=levander, launches claude remote-control --spawn same-dir inside a persistent tmux session control-plane-telep-mainframe. enabled (boot start), Restart=on-failure. Self-recovers after the LUKS clevis+TPM2 auto-unlocked reboots, exactly like knowledgebase.service / camwall.service. |
| 4 | obsidian-sync.timer | Every ~15 min: git pull --rebase --autostash → auto-commit local changes → git push. Bidirectional. The obsidian-documenter subagent also pushes on demand. |
| 5 | Trust pre-seed | Set remoteDialogSeen + hasTrustDialogAccepted in host Claude settings so the first remote-control launch does not block on a trust dialog. |
| 6 | Worklog | projects/homelab/telep-master-worklog.md — the agent appends timestamp · action · outcome per meaningful action; committed + pushed by component 4 / the documenter. |
| 7 | Harness parity | Host ~/.claude/CLAUDE.md (context-retrieval + proactive-documentation workflow) plus the historian and obsidian-documenter subagent defs, path-rewritten from /Users/levander/levandor_obsidian → /home/levander/obsidian. The master agent then recalls via historian and documents via documenter, same reflexes as a Mac session. |
| 8 | Skills + web | Install a curated skill set — superpowers (esp. systematic-debugging, the direct “cameras didn’t restart” case) + a sysadmin/homelab-ops skill sourced at build time — and enable WebSearch / WebFetch so the agent can look things up online mid-task. |
Safety posture (deliberate)
- Permissions stay ACTIVE —
--dangerously-skip-permissionsis NOT used, mirroring the container control-planes. The human-in-the-loop from the phone is the guardrail. - This host runs the KB, Frigate/cameras, and NUT/UPS power automation, and has passwordless sudo (
/etc/sudoers.d/levander) — any shell is instant root. A prior autonomous agent on this fleet took the site’s only DNS/gateway down and forced a factory reset with no backup (2026-08-03-telep-router-factory-reset-recovery). Trust is pre-seeded (component 5) but authority is not widened. - Standing ops guidance for the agent (carried in the host CLAUDE.md / worklog conventions): validate before bouncing critical services, apply changes atomically so a mid-run crash rolls back, never leave a critical service down.
Known gotchas / ceilings
- Docker + Incus
FORWARDpolicy — Docker setsFORWARDtoDROP, breaking the Incus bridge; fixed on the host viaDOCKER-USERrule in/usr/local/bin/agent-net-fix.sh. Relevant because the host runs both. (Not changed by this spec, but the agent should know it.) - Subagent path hardcoding — historian.md and obsidian-documenter.md hardcode the Mac vault path; must be rewritten for the host clone. Verify no other Mac-only paths leak in.
ponytail:multi-writer sync ceiling — the Mac and the host both push tomain.pull --rebase --autostashhandles the common case; the host mostly touches its own worklog + homelab docs so thrash is unlikely. Add per-path ownership / a host branch only if real conflicts appear.- No remote wake (WOL) — a full power-off still needs a physical button; the agent can reboot (auto-unlock recovers) but cannot revive a powered-off box.
- Process supervision — prefer PIDs/sentinels over
pgrep -f/pkill -f(they match the agent’s own command line). An empty task list does not mean a background job finished.
Open build-time questions (not design blockers)
- GitHub auth for the clone/push — the SSH probe to
git@github.comhung during design. Decide: reuse the containers’obsidian-deploy-agentsdeploy key, or mint a host-specific read-write deploy key. (Vault is a public repo, so read is trivial; push needs the key.) - Sysadmin skill source — identify a good ops/sysadmin skill online to install for component 8.
- TTY/supervision detail — confirm
claude remote-controlruns cleanly astmux new-session -dunder systemd (PTY provided by tmux); fall back tosetsid/pty wrapper if it misbehaves. Validate empirically.
Success criteria
- From the phone Code tab, a session named
control-plane-telep-mainframeis reachable and can run a command on the host. -
systemctl status control-plane.serviceisactive (running); after arebootit comes back automatically without intervention. - The agent can read the vault (answers a homelab question from
telep-mainframe-handover) and can write + push (a worklog entry appears in the repo). -
obsidian-sync.timerpulls and pushes on schedule; a change made on the Mac shows up on the host within one interval and vice-versa. -
historianandobsidian-documentersubagents run on the host against the host clone. - Permissions remain active (a destructive op prompts in the app rather than executing silently).
Related
- telep-mainframe-handover · telep-mainframe · SESSION-HANDOVER
- babylon-deploy-notes (closest systemd-managed always-on-agent template)
- 2026-08-03-telep-router-factory-reset-recovery (autonomy blast-radius lesson)