diff --git a/internal/backup/inflight.go b/internal/backup/inflight.go index af543f0..fb6c2fa 100644 --- a/internal/backup/inflight.go +++ b/internal/backup/inflight.go @@ -18,6 +18,18 @@ import "sync" // The gate is ADVISORY in one direction only — it never cancels anything already running. A caller // that cannot acquire DEFERS to its next cadence. Deferring a restore-test costs a few hours of // coverage; cancelling a running backup costs the backup. +// +// CORRECTED 2026-07-28 (F-A1). That "DEFERS" was true of the restore-test caller and NOT of the +// backup caller, and the comment did not say so. The controller's start path had no 409 branch, so +// a refusal here was recorded as a tier FAILURE: the R-88 breaker armed and the operator was +// emailed "Whole-guest backup FAILED" about a backup that was merely waiting its turn. Campaign 8 +// observed it on both demo boxes in the same minute. +// +// Fixed on the CONTROLLER side (v0.179.0), which is where the misreading lived — this gate's +// behaviour was correct throughout and is unchanged. The controller now maps HTTP 409 to a +// contention path: it defers the tier, keeps it DUE, and alarms only if contention outlives the +// agent's own restore-test ceiling. Nothing here needs to change; the claim above is simply now +// true of both callers. type InFlight struct { mu sync.Mutex what string // "" = idle