Files
felhom-agent/REPORT.md
T
admin 8675bff3da docs(G1): REPORT.md — break-glass agent half (v0.71.0) live-validated
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
2026-07-05 19:23:05 +02:00

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.tmpfilesd /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-failed the stock sshd ONLY when failed, 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 declares RuntimeDirectory= (the incident cause).
  • Go (internal/mgmtplane/): a read-only Reporter (os.Stat /run/sshd, read the heal-marker, TCP-dial sshd:22) → the additive omitempty mgmt_plane heartbeat stanza (privsep_dir_ok, sshd_reachable, healed_recently, privsep_healed_at). Wired always-on via Collector.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/hub collector: nil reporter → mgmt_plane omitted; 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-agentrm -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_healed monitor. felhom.eu commits 05d8181 (hub+installer), 28ac5f5 (runbook), 012e5f3 (monitor fix + v0.34.1).
  • H1 (felhom-sshd) can now assume /run/sshd is guaranteed present (tmpfiles + watchdog) and must never declare RuntimeDirectory= — 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-recovery re-vaults on demand.
  • Heal cadence: OnUnitActiveSec=60s (measured 30 s this run, mid-cycle); worst case ~60 s.