Auto-heal drill with the agent STOPPED healed /run/sshd in 30.0s (measured); mgmt_plane stanza + hub mgmt_plane_healed warning proven end-to-end. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
4.9 KiB
REPORT — TASK G1: management-plane break-glass (felhom-agent half) — v0.71.0
Baseline: felhom-agent main @ 1c75a45 (v0.70.0) → v0.71.0 (commit fd4e177). felhom.eu @
2f97ce3. Trunk-based, direct to main.
What shipped (this repo)
The prevent + auto-heal + observe thirds of the break-glass system (the hub vault + surfacing are
the felhom.eu half, hub v0.34.1). Closes the lockout from
felhom.eu/documentation/audits/SPIKE-felhom-sshd-2026-07-05.md §8: a second sshd's
RuntimeDirectory=sshd removed the SHARED /run/sshd privsep dir → the stock sshd on :22 reset every
session after SSH2_MSG_KEXINIT.
- Host artifacts (
configs/, installed by felhom-host-install):felhom-privsep.tmpfiles—d /run/sshd 0755 root root -(layer 1: boot-persistent, owned by no unit's lifecycle).felhom-mgmt-watchdog.sh— the heal action: stat-first recreate/run/sshd,reset-failedthe stock sshd ONLY whenfailed, write an RFC3339 heal-marker; never restarts the stock sshd, never touches a healthy dir. shellcheck-clean.felhom-mgmt-watchdog.service(oneshot) +.timer(OnUnitActiveSec=60s, Persistent). No unit declaresRuntimeDirectory=(the incident cause).
- Go (
internal/mgmtplane/): a read-onlyReporter(os.Stat/run/sshd, read the heal-marker, TCP-dial sshd:22) → the additiveomitemptymgmt_planeheartbeat stanza (privsep_dir_ok, sshd_reachable, healed_recently, privsep_healed_at). Wired always-on viaCollector.SetMgmtPlaneReporter(report.go additive fields, the SelfUpdatePending precedent — no hub-schema change; the golden contract test uses a nil reporter so the golden stays byte-identical).
Tests + red-proofs
go build ./... && go vet ./... && go test ./... on the build server — all green.
internal/mgmtplane: healthy (dir ok, no marker → healed_recently=false); missing dir detected while sshd_reachable stays true (the "TCP up, sessions broken" trap); marker present → healed_recently- timestamp; empty/whitespace marker treated as absent (red-proof for a hub warning with no timestamp); sshd-unreachable reported.
internal/hubcollector: nil reporter →mgmt_planeomitted; wired → carried through.
Live validation (felhom-pve) — the acceptance
Deployed manually (agent self-update needs an operator-signed op + a pinned signer; the box has
no signer pinned, so D1's self-update path was not usable — stated honestly). Build on 180
(-X main.version=0.71.0, sha b3b616fe…) → scp via local → install -m0755 (backup .bak-0.70.0)
→ restart. Host artifacts installed + timer enabled; systemd-analyze verify + systemd-tmpfiles --create + shellcheck all clean; RuntimeDirectory guard verified (no directive, only the warning
comment).
Auto-heal drill (agent STOPPED — the load-bearing proof): systemctl stop felhom-agent →
rm -rf /run/sshd → a new :22 session reproduced the incident (Connection reset right after the
banner) → the agent-independent watchdog recreated /run/sshd and a new :22 session succeeded
again in 30.0 s (measured), with the agent still inactive. Marker written. This proves the heal is
login-free AND agent-independent.
End-to-end visibility chain (hub v0.34.1): the v0.71.0 report carried
mgmt_plane:{privsep_dir_ok:true, sshd_reachable:true, healed_recently:true, privsep_healed_at:"2026-07-05T17:15:32Z"}; the prior healthy report had healed_recently:false; the
old v0.70.0 report had no stanza (correctly absent). The hub monitor raised the
mgmt_plane_healed warning at 17:16:21 ("privsep dir … was missing and was AUTO-HEALED …").
KEXINIT-reset reproduction: confirmed live in the drill (Connection reset by 127.0.0.1 port 22
immediately after the banner exchange, /run/sshd absent).
Cross-repo state
- Agent v0.71.0 live on felhom-pve; three break-glass layers active + enabled (they STAY — this
is the shipped feature). Rollback:
.bak-0.70.0. - Hub v0.34.1 live; break-glass vault +
mgmt_plane_healedmonitor. felhom.eu commits05d8181(hub+installer),28ac5f5(runbook),012e5f3(monitor fix + v0.34.1). - H1 (felhom-sshd) can now assume
/run/sshdis guaranteed present (tmpfiles + watchdog) and must never declareRuntimeDirectory=— the installer refuses any unit that does.
Notes / observations
- Secret discipline verified: the root@pam recovery password appears in NO log/commit (the vault handler logs username + length only; red-proofed hub-side).
- Least-privilege console user (vs root@pam): not probed live (PVE gates the node Shell to root@pam historically); G1 ships the proven root@pam path — a non-blocking future item.
- Auto-rotation of the recovery credential is a noted future item;
--rotate-recoveryre-vaults on demand. - Heal cadence: OnUnitActiveSec=60s (measured 30 s this run, mid-cycle); worst case ~60 s.