Files
felhom-agent/REPORT.md
T

2.2 KiB

REPORT — leaf lifecycle: signal + loud-log a regenerated leaf, v0.46.0

Task: Part B.1 of the F2 + prevention slice — make an accidental local-API leaf regeneration (the 2026-06-28 root→non-root migration class: a state-dir move silently minted a new leaf → every controller's pin invalidated for days, R1) visible immediately instead of silent.

Baseline: agent main @ 1958204 (live 0.45.0) → v0.46.0 @ 9b0d6c2, sha 03966da3….

Change

  • internal/localapi/cert.goEnsureLeaf now returns generated bool: false = an existing pair was LOADED (stable fingerprint); true = a fresh leaf was GENERATED.
  • cmd/felhom-agent/main.go — loud call-site: a load logs INFO local-api leaf LOADED; a regeneration logs WARN local-api leaf REGENERATED — any previously issued bootstrap pins are now INVALID; controllers will fail the pin check until re-bootstrapped (or restore the prior leaf) (with the new fingerprint). The --selftest=provision caller updated to the new signature.
  • No new sudo/capability surface — pure return + log change. The companion install-script preservation (--preserve-state-from + populated-host guard) is in felhom.eu/scripts/felhom-host-install.sh.

Tests (green: go build/vet/test ./...)

TestEnsureLeaf_StableFingerprintAcrossReload: first call generated==true, second generated==false AND same fingerprint — persistence keeps the pin stable (a regression that regenerated would flip gen2 true and change the fp, failing both asserts).

Live validation (felhom-pve) — both paths PASS

  • Quiet load (the normal case): deployed 0.46.0; the agent restart logged INFO local-api leaf LOADED fp 60b5974d… (the leaf existed → loaded, not regenerated).
  • Loud regenerate: during the F2 born-down test, moving the leaf aside + restart produced WARN local-api leaf REGENERATED — any previously issued bootstrap pins are now INVALID … fp 751367a2… — the loud signal fires exactly when a new leaf is minted. Restored cleanly (leaf LOADED 60b5974d… again). capabilities 45/45 ok throughout.

NOT changed

The pin/transport, the token store, the sudoers/capability surface, the drive gate. Cert lifecycle signalling + logging only.