# SD Qualifier independent A/B work2 evidence

Date: 2026-08-13
Scope: controller-neutral planning, independent A/B execution lanes, work2 deployment and browser verification

## Source and deployment identity

- Pi worktree: `/home/jong/dev/sdq-independent-ab-20260813`
- Branch: `codex/independent-ab-execution-20260813`
- Work1 checkpoint: `dad5277c9bb57fe3bf669049b245784bb259ae13`
- Post-deployment checkpoint: `c6b53dc27e9481f0dc38e77dce397f88754ac980`
- Deployed image: `srv-rpi00-sd-qualifier:independent-ab-c6b53dc`
- Image ID: `sha256:25aa4332f032c1a5538d082cff187b8f8b6f543251536dc86a239ce11ffcd0d8`
- Database backup: `/backups/sd-qualifier-20260813T192528Z.dump`
- Restore check: passed; restored campaign count `11`
- Rollback runtime/config copy: `/home/jong/.local/share/sd-qualifier/deploy-backups/independent-ab-pre-dad5277-20260813T1925Z`

## Verification

- Full Django suite: 373 tests passed in 117.028 seconds.
- Host runtime and packaging: 20 tests passed.
- Focused paused-lane backfill: 13 tests passed.
- Migration `qualification.0023_campaign_coordinator_lanes`: applied.
- Migration drift: `makemigrations --check --dry-run` reported no changes.
- Evidence storage preflight: passed with atomic rename and readback hash.
- Web, database, command worker, coordinator, watchdog, and notification services: running; web healthy.
- Campaign task runner: active with one parent and independent A/B child loops; zero restarts.
- Event poll after deployment: HTTP 200 JSON.
- Playwright authenticated check showed:
  - Controller A `PAUSED` at `matrix.s4.1440.before.a` with `Resume A`;
  - Controller B `PAUSED` at `matrix.s2.b` with `Resume B`;
  - no endpoint, J-Link script, memory address, or raw-command browser control.
- Browser screenshot (generated, intentionally unversioned):
  `work/evidence/generated/sdq-independent-ab-lanes-20260813.png`.

## Protected campaign invariant

Campaign `8c7a2b1a-7e67-48ac-8895-7999d76c4c2a` remained:

- campaign state `RUNNING`;
- coordinator state `PAUSED`, desired state `PAUSED`;
- coordinator version `64`;
- legacy active node `matrix.s2.b`;
- command count `361`;
- latest command timestamp `2026-08-13T16:18:08.758490+00:00`.

Deployment initialized only the new lane projection fields. No campaign task
was claimed, no controller command was added, and no controller/media action
was performed. A pre-existing fixture coordinator also received lane status
projection when the backfill was first exercised; it created no controller
task or command.

## Remaining gate

Controller B's role-neutral recovery dispatch is present and fails closed only
in B's lane, but `SDQ_CONTROLLER_B_RECOVERY_RUNNER` and the external B
coordinated-cycle capability are not configured. Health continues to report
`recovery_supported: false`. This must be qualified before the workpackage and
project can close.

## 2026-08-13 Controller B recovery mitigation

The earlier remaining-gate diagnosis was corrected and mitigated. The HPT
power-control service already provided a locally reachable, positively drilled
Controller B coordinated-cycle endpoint; the missing surface was the SD
Qualifier adapter and evidence path.

- Pi source commit: `8cdfa3bdc591ce29ac00a5411432239586b776e4`.
- Deployed image: `srv-rpi00-sd-qualifier:independent-ab-8cdfa3b`.
- Image ID: `sha256:3f2e2086da480eafaaacbb964e5e90bb0ac1af5ffe73d11a30464f3e9bd8c304`.
- Both A and B recovery environment variables select the same installed
  role-neutral runner.
- B dispatch binds endpoint `19121`, J-Link `69660123`, HPT group B, and B
  evidence attribution.
- Focused recovery/packaging tests passed `75/75`; the full application suite
  passed `428/428`.
- A non-hardware B dispatch fixture passed. No power or controller command was
  issued by deployment verification.
- Backup
  `/home/jong/.local/share/sd-qualifier/backups/sd-qualifier-20260813T200000Z-b-recovery-mitigation.dump`
  passed archive-list verification; SHA-256
  `29d39f1a2425e1e9c1a1892f6eed1968afb6f17d6b04ef82982d23bbe3303bb3`.

The paused campaign remained at coordinator version `64`, command count `361`,
and last command `f1492992-f957-4baa-a676-471b8c2f995f`. Its pre-existing B S2
run was then reconciled separately through the supported non-promoting
finalizer using terminal observations `19267` and `19268`. Result evidence
`19269` classifies it as `BOUNDED_STOP_PASS_CASE_TRIGGER_NOT_MET`,
`case_accepted=false`; both A and B supervisor states are healthy. No Start or
Stop was replayed, and the campaign remains paused pending the explicit
migration-versus-INCONCLUSIVE decision.

The remaining recovery gate is physical end-to-end Controller B qualification
through the deployed runner under explicit authorization. Health therefore
continues to report `recovery_supported=false`.
