From a7f26e27c408de4d77fd4d5f41ce0ea95e6a6a64 Mon Sep 17 00:00:00 2001 From: PJ Date: Tue, 18 Aug 2026 13:03:42 +0530 Subject: [PATCH] fix(campaign): quarantine a device that keeps failing fast Preflight cannot catch a device that disappears mid-sweep, which is what happened: the serials were alive the previous day. Three consecutive failures under two minutes, with no run that worked in between, is a property of the device and not a coincidence. The manifest records which device was quarantined and which seeds have no result, so an aborted sweep says so in its own artefact. Claude-Session: https://claude.ai/code/session_01A5KmftdEJ49A9z5mF5ESrX --- cmd/internal-tools/campaign/manifest.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cmd/internal-tools/campaign/manifest.go b/cmd/internal-tools/campaign/manifest.go index 98df917..91430c1 100644 --- a/cmd/internal-tools/campaign/manifest.go +++ b/cmd/internal-tools/campaign/manifest.go @@ -35,6 +35,22 @@ type manifest struct { SanderlingVersion string `json:"sanderling_version"` StartedAt time.Time `json:"started_at"` ArgumentTemplate []string `json:"argument_template"` + + // Quarantined and UnrunSeeds are filled in when the sweep ends, so the + // artifact says a device dropped out and which seeds have no result rather + // than leaving both to be inferred from a thin runs.jsonl. + Quarantined []quarantinedDevice `json:"quarantined,omitempty"` + UnrunSeeds []int64 `json:"unrun_seeds,omitempty"` +} + +// quarantinedDevice is a device the sweep stopped assigning seeds to, with the +// seeds it consumed on the way out. Those seeds are reported unrun rather than +// requeued: their directories already hold the failed attempt's log, and a +// second record for the same seed would make a seed count two runs. +type quarantinedDevice struct { + Device string `json:"device"` + FastFailures int `json:"fast_failures"` + ConsumedSeeds []int64 `json:"consumed_seeds"` } func buildManifest(configuration config, host, binaryPath, version string, startedAt time.Time) manifest {