fix(AGENT-001): anti-retarget re-resolution for inline customer-confirmed wipe

handleDiskFormat's customer-confirmed branch formatted the mutable req.Device
path; the durable id only bound the confirmation, never the mkfs target. A /dev
reassignment between inspect and mkfs could wipe the wrong physical disk.

Now mirrors signedjobs.WipeExecutor: resolve confirmed durable id -> current
device, re-derive + require exact match, re-inspect (still data-bearing), then
format THAT device. Any refusal -> 409, no mkfs. New antiRetargetResolve helper
(injected deps, unit-tested: mismatch/gone/blank/empty all refuse). Injectable
reresolveWipe seam on Server (defaults to real storage funcs).

BRANCH ONLY — pending supervised review/deploy (see AGENT-001-FIX-NOTES.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-13 19:26:27 +02:00
parent d17b5ab45d
commit d96e5bddd0
6 changed files with 266 additions and 7 deletions
+10 -2
View File
@@ -148,6 +148,12 @@ type Server struct {
hostMetrics HostMetricsProvider // slice 9 (optional)
hostID string // slice 10B: for the data-bearing-format pending-op hint
// reresolveWipe performs the [AGENT-001] anti-retarget re-resolution before an
// inline customer-confirmed wipe (durable id → current device, re-derive+match,
// re-inspect). Defaults to s.reresolveDurableForWipe (real storage funcs); tests
// override it to avoid touching real /dev.
reresolveWipe func(ctx context.Context, durableID string) (string, error)
jobsMu sync.Mutex
jobs map[int]*backupJob // per-guest backup job state (slice 8B)
@@ -169,7 +175,7 @@ func NewServer(o Options) (*Server, error) {
if cadence <= 0 {
cadence = defaultBackupCadence
}
return &Server{
s := &Server{
addr: o.ListenAddr,
cert: o.Cert,
guests: o.Guests,
@@ -189,7 +195,9 @@ func NewServer(o Options) (*Server, error) {
hostMetrics: o.HostMetrics,
hostID: o.HostID,
jobs: map[int]*backupJob{},
}, nil
}
s.reresolveWipe = s.reresolveDurableForWipe
return s, nil
}
// Handler builds the routed mux (exposed for tests via httptest).