# Watchdog Stage 5 Controller B parallelization-policy evidence — 2026-08-09

Status: PASS; independent B preflight is enabled by reviewed evidence while B Start remains fail-closed
Type: evidence
Updated: 2026-08-09
Next Action: execute Stage 6 complete Controller B preflight; do not create a B Start intent
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/completed/wp-watchdog-gated-controller-a-recovery-and-controller-b-start.md
Project Map: work/maps/map-smi-firmware-stabilization-and-qualification.md
Decision: work/adr/adr-controller-b-parallel-qualification-entry-policy.md

## Reviewed policy and implementation

Pi source commit `dc492e4482626631e8b33588ce3a27ce707ea38f` removes the
matrix-derived B execution key and implements the accepted two-decision policy.
Protected policy
`controller-b-parallel-entry-2026-08-09` has SHA-256
`5fd91dc2f0038fca76655c6dfc48422e3e01d2b02aa395535f57099f7367aba9`.
It binds Stage 2 evidence SHA-256
`27d53819995e536554cd250e862e08b5c0798fcdd6567b8ae21d540da4eed67d`,
Stage 4 evidence SHA-256
`64bbca18cf1be5aaae072f4da85084e8cf3967d1c07263f7eb046d29d37b183a`,
the 3-snapshot/60-second A proving window, A probe `69664082` at port
`19120`, B probe `69660123` at port `19121`, and distinct role lock
namespaces.

B HPT2 admission now checks `preflight_allowed` before read-only target
observation. UI Start preparation, direct command preparation, and final
publication each enforce the complete Start decision. Baseline scrub and HPT
initialization preparation enforce the preflight decision. The card page shows
the policy ID, review reference, reason, and separate B Preflight/Start state.
Management command `evaluate_controller_b_parallelization` records an
append-only event only when the effective decision changes.

## Fail-closed qualification

Focused tests passed `11/11`. They prove:

- the old A-local matrix result no longer emits or decides
  `controller_b_execution_allowed`;
- absent/mismatched policy blocks B before controller observation;
- A/B endpoint or lock collision invalidates the policy;
- stable supervised A can open only preflight while missing B evidence keeps
  Start blocked;
- repeating an unchanged evaluation does not duplicate the audit event.

The complete application suite passed `299/299` in the exact ARM64 image on
both disposable SQLite and PostgreSQL 17 databases. Django system checks were
clean apart from the expected, explicitly accepted trusted-LAN HTTP warning in
production mode.

## Backup, release, and deployment

Predeployment backup
`/backups/sd-qualifier-20260809T213907Z.dump` is `553190` bytes with SHA-256
`eb9c7b34ff285dc22ccaa37df97683cfe42e73f7cbae2c8b6282ea1657a359e1`.
It restored successfully into disposable database
`sdq_stage5_restore_20260809`, where eight campaign rows were verified, then
the disposable database was removed. No migration was required.

Production release `/home/jong/dev/sd_qualification-release-dc492e4` runs
exact image
`sha256:6543e1ea2f1515e571d12e8329fb447663262883d8817c379ec8268441003db7`.
Deployment manifest SHA-256 is
`b1d3e06a9a2cfee6920bc6f1f7f443eb9e7753742c25000b69e2888d8979094f`;
it binds the image, source, scripts, updated observer unit, unchanged database
schema, HPT2 profile, A supervisor profile, new parallelization policy, and
restore-verified backup.

The first apply failed before replacement because the release-local default
bundle path did not exist; the shared runtime paths were then explicitly
loaded from the supervisor environment. The corrected apply encountered the
known Docker Compose stale `Created`-container naming race. The three exact
non-running new-image shells were verified and removed, after which all four
application services recreated successfully. The old services stayed live
through both failed attempts. The observer restarted under the new release
with `NRestarts=0`.

## Live gate and controller state

Campaign `648ba10c-0bc0-4319-8089-78a0cce287ce` event `251` records:

- `preflight_allowed=true`;
- `controller_b_execution_allowed=false`;
- code `CONTROLLER_B_PREFLIGHT_ALLOWED_START_BLOCKED`;
- no base parallelization blocker;
- exact Start blockers for B stage, CID, baseline scrub, initialization,
  admitted run, runtime HPT2 endpoint, and role enablement.

Three qualifying same-deployment A snapshot hashes accompanied the event. A
subsequent unchanged evaluation used newer proving snapshots and correctly
reported `audit_event_appended=false`, leaving sequence 251 unique.

After deployment, Controller A remained `HEALTHY` on run
`de340af2-d505-495e-a14f-5159e55b1633`, CID
`05000C61736466672200001C8901A34F`, boot witness `26B10B1280443248`, and
the exact firmware bundle. At `2026-08-09T21:45:31Z` its counters were
`5562 / 5562 / 5561`; a later exact-identity snapshot at
`2026-08-09T21:47:23Z` advanced them to `5720 / 5720 / 5719`, with no
identity divergence or latched failure.

Controller B remains `INTAKE`, with zero active runs and zero HPT2 command
operations. No B endpoint, observation, command intent, or controller command
was used in Stage 5. No SD card was removed, inserted, or replaced.

Stage 5 is complete. Stage 6 may now perform only the full governed Controller
B preflight. B Start remains outside this stage and blocked by application
policy until every preflight item passes.
