# SD Qualifier B recovery and supervisor mitigation

Status: verified; software recovery gap closed and paused-run supervisor incident reconciled
Type: evidence
Updated: 2026-08-13
Next Action: physically qualify the deployed Controller B recovery path under explicit authorization; separately decide migration versus INCONCLUSIVE closeout for the paused Aug. 10 campaign
Campaign Reason: Historical record from campaign 009-complete-clean-contract-bound-a-b-qualification; retained independently after campaign closure and requires no separate owner-queue execution.
Campaign: standalone
Parent: work/wp/active/wp-controller-neutral-sd-qualification-and-independent-a-b-execution.md
Canonical Truth: `jong@srv-rpi00.local:~/dev/sdq-independent-ab-20260813`, the deployed SD Qualifier runtime, and its PostgreSQL state

## Outcome

The supposed missing Controller B power infrastructure was a narrower SD
Qualifier integration defect. The local HPT service already supported group B;
the qualifier retained an A-only recovery matrix, power client, evidence
binder, and power-interruption adjudicator.

Pi commit `8cdfa3bdc591ce29ac00a5411432239586b776e4` makes those surfaces
role-neutral and configures both recovery environment variables to the same
installed executable. Role selects only the permitted infrastructure binding:
A uses port `19120` and J-Link `69664082`; B uses port `19121` and J-Link
`69660123`.

## Verification

- Focused recovery and packaging tests: `75/75` passed.
- Full application suite: `428/428` passed.
- Non-hardware B dispatch fixture: passed with exact B role, endpoint, probe,
  campaign, CID, and authorization-envelope variables.
- Deployed image:
  `srv-rpi00-sd-qualifier:independent-ab-8cdfa3b`.
- Image ID:
  `sha256:3f2e2086da480eafaaacbb964e5e90bb0ac1af5ffe73d11a30464f3e9bd8c304`.
- Installed source/runtime hashes matched for the runner, power client, and
  evidence binder.
- Playwright returned the production health JSON as `application/json` with
  `status=ok`, `required_now_ready=true`, and `workers=true`.
- Backup archive:
  `/home/jong/.local/share/sd-qualifier/backups/sd-qualifier-20260813T200000Z-b-recovery-mitigation.dump`,
  SHA-256
  `29d39f1a2425e1e9c1a1892f6eed1968afb6f17d6b04ef82982d23bbe3303bb3`;
  archive-list verification passed.

No power operation, controller command, firmware programming, media write, or
campaign resume was performed. Physical B recovery qualification remains an
explicitly authorized later gate, so `recovery_supported=false` remains the
correct fail-closed health value.

## Paused campaign reconciliation

Before and after deployment, campaign
`8c7a2b1a-7e67-48ac-8895-7999d76c4c2a` remained coordinator `PAUSED`, desired
state `PAUSED`, version `64`, with zero claimed task and command count `361`.
Latest command `f1492992-f957-4baa-a676-471b8c2f995f` remained the one already
acknowledged Stop.

The open B run `efdeaec7-f0e7-4458-8012-7580dab9f18f` already had two stable
`STOPPED_CLEAN` observations, `19267` and `19268`, with exact CID
`05000C61736466672200001C8201A379`, terminal proof `31`, zero mismatch/loss,
and acknowledged Stop sequence `1`. The supported non-promoting finalizer
created result evidence `19269`, SHA-256
`115d18cab443b6ec542e1053021b84c9e1d30b1066e4705ea9dbd46477ab6c99`,
classification `BOUNDED_STOP_PASS_CASE_TRIGGER_NOT_MET`, and
`case_accepted=false`. No adjudication evidence was created, so the run grants
no S2 matrix credit.

The run is `COMPLETED`; both Controller A and B supervisor states are
`QUALIFICATION_SUPERVISOR_HEALTHY`. The persistent A observer is active and
the run-scoped B observer is stopped. The campaign remains paused for an
explicit migration-versus-INCONCLUSIVE decision.
