feat(escrow): v0.138.0 — "awaiting hub confirmation" waiting state

After a completed escrow ceremony the Távoli mentés page showed the yellow
"Helyreállítási kód szükséges" card for ~15 min until the next hub-report ACK
flipped pending→escrowed. Phase-0 diagnosis (read-only) = verdict A (report-cycle
lag), already resolved on the demo box (escrow_state:"escrowed"); hub Hypothesis B
verified false (SaveHostEscrow ON CONFLICT already clears stale_at on upload) → no
hub change.

- settings.OffboxTarget.CeremonyCompletedAt: stamped on the recovery-code claim,
  zeroed on the auto-confirmer Flip + the deprecated manual confirm; persisted.
- web/handlers.go: offboxCeremonyWaitState + escrowCeremonyGraceWindow (35m).
- backups_remote.html: info "megerősítésre vár, legfeljebb 15 perc" card → warn
  "a megerősítés nem érkezett meg" past the window. Existing branches untouched.
- backups_escrow.html: "Mi történik ezután?" note on the wizard's final step.
- Test web/escrow_wait_state_test.go (truth table + red-proof recorded in REPORT).

No scheduler/agent/hub/endpoint changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017qDiBqKKQ5vPB5fXBqu7Kp
This commit is contained in:
2026-07-16 18:44:13 +02:00
parent e99c675fe4
commit 120332103a
13 changed files with 283 additions and 61 deletions
+6
View File
@@ -162,6 +162,12 @@ type OffboxTarget struct {
// proceeds until an operator confirms the escrow ceremony ("escrowed") — so no un-recoverable
// offsite ciphertext can exist. It is NOT a secret (a state label); the password never lives here.
EscrowState string `json:"escrow_state,omitempty"`
// CeremonyCompletedAt (v0.138.0) is the RFC3339 stamp of the last successful escrow ceremony
// (recovery-code claim) taken while EscrowState is still "pending". It drives the "awaiting hub
// confirmation" card on /backups/remote during the report-cycle gap between the ceremony and the
// hub-verified pending→escrowed flip (report.EscrowAutoConfirmer). Zeroed by that flip (and the
// deprecated manual confirm). Persisted, so it survives a controller restart mid-wait. Not a secret.
CeremonyCompletedAt string `json:"ceremony_completed_at,omitempty"`
}
// CrossDriveBackup configures per-app backup to a secondary drive.