# Pi HPT2 operator UI fixture-only deployment evidence

Status: accepted fixture-only deployment
Type: evidence
Updated: 2026-08-02
Next Action: none for this deployment; the owner separately authorized one Controller B read-only identity observation, recorded in `work/evidence/controller-b-exact-candidate-readonly-identity-20260802.md`, while live execution remains blocked
Campaign Reason: Historical record from campaign 014-complete-standalone-sd-qualifier-acceptance; retained independently after campaign closure and requires no separate owner-queue execution.
Campaign: standalone

## Authorization and scope

The owner explicitly authorized
`work/checklists/checklist-pi-hpt2-operator-ui-release-deployment.md` in the
active Codex thread. The authorization was limited to backup/restore,
migration 0013, and fixture-only recreation and verification of `web`,
`command-worker`, and `notification-worker`.

It did not authorize an HPT2 tools-service invocation, a controller role or
endpoint, live admission, controller access, programming, power, physical
media, or T00 work. Controller B remained frozen.

## Pre-mutation gate

- Pi source was clean at
  `351182d1930969c7d58cb8a262dd923d70e62b3c`.
- Candidate image and labels matched
  `sha256:d837e727357f4f7bf5896621e7f06cb9024a831bd52bbd14a168d27fa4b40049`
  and release `hpt2-operator-ui-351182d`.
- Every offline release member passed `SHA256SUMS` readback verification.
- The prior deployment was healthy at image
  `sha256:924ff94619db643db59efb50b5877a0c69310df7488a40fbc0b7986b237907d5`.
- HPT2 roles and Controller A/B endpoints were empty or unset.
- There were zero pending or running fixture commands.
- Database migration state ended at 0012 and source contained exactly one new
  migration, `0013_hpt2commandoperation_hpt2commandphase`.
- Preserved configuration identities included `.env` SHA-256
  `b7629490a2a44e19f80ae3abe6b52b1e740d074c4e73872a7d035a870bc1b858`,
  protected registry SHA-256
  `39c021d68c0344258fab641acbfb5c2f2ae1bfdd9985dd5a337058e078a49af7`,
  and fixture-image SHA-256
  `0a6fc612c75d067ebd0888f640ab48f07dd1c921c329ca1c693af0e08c8687b7`.

## Backup and rollback

The command and notification workers were stopped before the backup window.
Web and PostgreSQL remained healthy.

- Backup: `/backups/sd-qualifier-20260803T012114Z.dump`;
- backup SHA-256:
  `395a726db38325f2891474790b0ed06e98c65eecdd4e9d8e9d7eb8d697c3a2ee`;
- disposable restore check: passed;
- restored campaign count query: `1`;
- prior image retained as
  `srv-rpi00-sd-qualifier:rollback-hpt2-firmware-contract-1b7fa39`.

Because migration 0013 changes the schema, rollback requires this verified
database backup with the prior image/configuration; image-only rollback is not
claimed.

## Migration and deployment

Django's migration plan listed only migration 0013 and its operation/phase
tables and constraints. Migration 0013 applied once and reported `OK`.
PostgreSQL and Front Door were not recreated. Only `web`, `command-worker`, and
`notification-worker` were recreated from the candidate image.

Initial post-recreation verification caught that the protected runtime
identity variables still named the prior release even though the container
image was exact. No target capability was involved. The two non-secret `.env`
identity lines were corrected to the candidate release/source, producing new
`.env` SHA-256
`1703b1a79495bd5d3c2ac48db61e070a2564d99a2a914b44c2084295ea3e30dc`,
and the same three services were recreated again. This verification finding
prevented a false runtime identity claim.

## Accepted runtime verification

- All three application services run image
  `sha256:d837e727357f4f7bf5896621e7f06cb9024a831bd52bbd14a168d27fa4b40049`.
- Runtime release/source identity is `hpt2-operator-ui-351182d` /
  `351182d1930969c7d58cb8a262dd923d70e62b3c`.
- Web, PostgreSQL, clock, storage, and both workers are healthy.
- Local and Front Door health routes report `status=ok`, `fixture_only=true`,
  `live_admitted=false`, and every state-changing/stop/recovery capability
  false.
- Storage preflight passes atomic rename and hash readback.
- Migration 0013 is applied.
- Active fixture commands, HPT2 operations, and HPT2 phases are all zero.
- The deployed URL set contains only `hpt2-operation-prepare`; the UI template
  contains no publish or reconcile action.
- HPT2 roles and both endpoints remain empty or unset; no HPT2 adapter
  container exists.
- Front Door login returns HTTP 200.
- SMTP password is blank in web and command worker, present only in
  notification worker, and only notification worker joins notification egress.
- Django system check passes and recent application logs contain no error,
  traceback, or exception.

The exact image's automated authorization/UI tests had already proved CSRF and
reviewer/administrator restrictions. No connected browser was available for a
visual smoke test in this Codex session, so that optional visual observation is
not represented as performed. This does not weaken the functional and HTTP
deployment gates above.
