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
+2
View File
@@ -417,6 +417,7 @@ type pbsDRView struct {
TokenID string
WGPeer bool // cascade stage 2: the host has registered its tunnel peer
EscrowPresent bool // cascade stage 4: the ceremony ran (blob in custody)
EscrowStale bool // v0.57.0 (2.3): the blob is stale (offsite password re-issued since) — re-run the ceremony
}
// pbsDRViewFor loads the section state for the form. Read-only; every error degrades to a
@@ -439,6 +440,7 @@ func (s *Server) pbsDRViewFor(customerID string, drTier bool) pbsDRView {
}
if escrow, err := s.store.GetHostEscrow(host.HostID); err == nil && escrow != nil {
v.EscrowPresent = true
v.EscrowStale = escrow.StaleAt != ""
}
if d := readPBSDR(host.DesiredJSON); d != nil {
v.Enabled = d.Enabled