feat(hub): v0.57.0 reinstall-of-existing-customer arc — claim/offsite/escrow continuity

F2 claim re-issue on clean-slate re-enroll (ReissueForReenroll, host-enroll mint path,
single-bump, reset code; hub never stores the password so fork B). F3 offsite re-issue on
re-enroll (ReissueOffsiteForCustomer, same machinery as the manual button). 2.3 escrow honesty
(red-proofed): re-issuing offsite marks the escrow stale (MarkEscrowStale), withholds the
mismatched restic hash from auto-confirm, DR checklist shows stale not done. Events:
claim_reissued_reenroll / offsite_reissued / escrow_stale.

Controller + scripts unchanged (source contradicted both premises): the controller reads escrow
prereqs live from the agent; the installer can't know the descriptor-provisioned storage id. F4
root fix is agent-side -> ROADMAP R-22; demo unblocked live (Part 0 ACL grant). VALIDATION doc
F2 erratum + F3/F4 dispositions. Green gate + Scenario-C red-proof pass.
This commit is contained in:
2026-07-16 18:00:13 +02:00
parent dd961a66bb
commit 7747a16ff1
15 changed files with 395 additions and 37 deletions
+35
View File
@@ -1,5 +1,40 @@
# Felhom Hub — Changelog
## v0.57.0 — reinstall-of-existing-customer arc: claim continuity, offsite re-issue, escrow honesty (2026-07-16)
Closes the N100 physical-run findings F2/F3 and the correctness edge behind F4→2.3
(`documentation/tests/VALIDATION-n100-baremetal-2026-07-16.md`). When an existing customer's box is
clean-slate reinstalled, hub and box previously disagreed about claim, offsite, and escrow state.
This makes the reinstall path first-class — the Peti (R-1) convergence prerequisite.
- **F2 — claim continuity.** `claim.Engine.ReissueForReenroll` rides the existing rotation semantics:
for a CLAIMED customer whose box re-enrolls (fresh, passwordless), it bumps the generation ONCE and
emails a RESET code (delivery via the existing report ACK) — the customer no longer has to hunt for
the manual "request a new code" button. No-op for an unclaimed customer (first-provision path owns
the code). Hooked at the host-enroll **mint path** (`handleHostEnroll`), which fires exactly once per
fresh host record — the single-bump-per-re-enroll guarantee. Emits `claim_reissued_reenroll`.
*(Fork verdict, source-verified: the hub stores only the claim code + a claimed boolean — never the
password hash, which is controller-owned by the arc's design. So fork B, not A.)*
- **F3 — offsite continuity.** The re-enroll mint path also calls the same machinery as the manual
"Re-issue offsite credentials" button (`web.Server.ReissueOffsiteForCustomer`, wired to the api
handler via `SetOffsiteReissuer`) — the one-time offsite password only ever reached the OLD
controller, so the fresh box gets a fresh one and a `ConfigVersion` bump. Emits `offsite_reissued`.
- **2.3 — escrow honesty (correctness; red-proofed).** Re-issuing offsite credentials changes the
restic repo password, so any existing key-escrow blob is now STALE (a recovery code minted against
it would decrypt a password that no longer opens the repo). `offsite.ReissueCredentials` now marks
the escrow stale (`store.MarkEscrowStale`, cleared by the next ceremony via `SaveHostEscrow`); the
ACK **withholds** the now-mismatched `restic_pw_sha256` so the controller cannot auto-confirm against
a dead key, and the DR-tier checklist shows **stale** instead of "ceremony done." Emits `escrow_stale`.
Red-proof: with `MarkEscrowStale` gutted, the hub keeps advertising ceremony-done after a re-issue →
`TestReissue_InvalidatesEscrow` FAILS; restored → passes.
- **Out of scope (reported):** F4's general installer fix is NOT feasible — the DR storage id lives in
the agent-domain pbs_dr descriptor (provisioned post-WG), not the installer-fetched config, and the
underlying block is the agent's token-auth pre-check 403ing before its own root-run `felhom-pbs-apply
grant`. Root fix is agent-side (ROADMAP agent-train item); the demo was unblocked live with a
one-shot ACL grant. Controller (Part 3) unchanged: its escrow prereqs are already fetched live from
the agent, so F4/Part-0 alone restore them (3.1 spec premise contradicted by source). scripts
unchanged (v1.16.0).
## v0.56.0 — PBS-DR self-heal reconciler (re-stage a consumable secret) (2026-07-15)
Implements `SPIKE-pbsdr-selfheal-2026-07-15` (`e8f8c44`). **⚠️ ARCHITECTURE IMPACT:** before this,