v0.246.0: an interrupted restore is told; the recovery-code reminder waits until the box can take it
gates / gates (push) Successful in 15s
gates / gates (push) Successful in 15s
MinAgent: 0.131.0 (unchanged). Requires hub v0.117.0 for restore_interrupted. R-550 (operator ruling: fix). A design reversed and recorded: the restore op-status was in memory by choice. Now restore-status.json in DataDir, written atomically at both ends of an op. At startup a record still marked running becomes a failed, interrupted result kept per app until that app's next restore, shown on /backups/restore and the off-site wizard, and raised once as restore_interrupted. Cooldowns stay in memory. R-546. The R-543 reminder bar consults the agent's own preflight ok (every blocking item, not a copy of pbs_storage_id), cached 60 s, probed only while paused. /backup/escrow shows a waiting card that polls and reloads instead of red crosses and English diagnostics. POST /api/escrow/start refuses 409 before staging or starting - the direct path chaos night used. Unknown readiness keeps the bar. Red-proofs (each seen failing): restore record across restart; main() calls both startup functions; startup helper with loading skipped; restore page card; bar held back; waiting card; start refusal. go build/vet/test ./... green, 28 packages; controller_gates --fast all OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -87,6 +87,9 @@ func newEscrowWizardHarness(t *testing.T) *escrowWizardHarness {
|
||||
version: "0.88.0",
|
||||
startResp: agentapi.EscrowCeremonyStartResponse{JobID: "escrow-1", Phase: "running"},
|
||||
startStatus: http.StatusAccepted,
|
||||
// R-546 (v0.246.0): the start API now asks the agent's preflight first; this harness is a
|
||||
// READY box. A not-ready box is r546_escrow_readiness_test.go.
|
||||
pf: agentapi.EscrowPreflightResponse{OK: true},
|
||||
}
|
||||
h.s = &Server{cfg: cfg, backupMgr: h.m, settings: sett, logger: lg}
|
||||
h.s.escrowAgentFn = func() (escrowAgent, error) { return h.agent, nil }
|
||||
@@ -131,8 +134,8 @@ func TestEscrowStart_StagesBeforeTrigger(t *testing.T) {
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("start: got %d (%s)", w.Code, w.Body.String())
|
||||
}
|
||||
if got := strings.Join(h.order, ","); got != "stage,start" {
|
||||
t.Fatalf("call order = %q, want stage BEFORE start (a ceremony without the staged secret mints a hash-less blob)", got)
|
||||
if got := strings.Join(h.order, ","); got != "preflight,stage,start" { // R-546: readiness first
|
||||
t.Fatalf("call order = %q, want preflight, then stage BEFORE start (a ceremony without the staged secret mints a hash-less blob)", got)
|
||||
}
|
||||
if !strings.Contains(w.Body.String(), "escrow-1") {
|
||||
t.Fatalf("response lacks the job id: %s", w.Body.String())
|
||||
@@ -147,8 +150,8 @@ func TestEscrowStart_ReceremonyStagesToo(t *testing.T) {
|
||||
if w := postStart(t, h.s, wizardPassword); w.Code != http.StatusOK {
|
||||
t.Fatalf("re-ceremony start: got %d", w.Code)
|
||||
}
|
||||
if got := strings.Join(h.order, ","); got != "stage,start" {
|
||||
t.Fatalf("re-ceremony call order = %q, want stage,start", got)
|
||||
if got := strings.Join(h.order, ","); got != "preflight,stage,start" { // R-546: readiness first
|
||||
t.Fatalf("re-ceremony call order = %q, want preflight,stage,start", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +162,8 @@ func TestEscrowStart_NoOffboxSkipsStaging(t *testing.T) {
|
||||
if w := postStart(t, h.s, wizardPassword); w.Code != http.StatusOK {
|
||||
t.Fatalf("start: got %d", w.Code)
|
||||
}
|
||||
if got := strings.Join(h.order, ","); got != "start" {
|
||||
t.Fatalf("call order = %q, want start only (no staging without offbox)", got)
|
||||
if got := strings.Join(h.order, ","); got != "preflight,start" { // R-546: readiness first
|
||||
t.Fatalf("call order = %q, want preflight then start only (no staging without offbox)", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user