# SD Qualifier card-page performance correction — 2026-08-10

Status: PASS; dashboard and active-card page latency is reduced without changing qualification execution
Type: evidence
Updated: 2026-08-10
Next Action: preserve both active S4 runners and continue the ordinary A/B matrix under independent supervision
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
Parent: work/checklists/checklist-hpt2-bounded-stop-recovery-and-regression-measurement.md
Project Map: work/maps/map-smi-firmware-stabilization-and-qualification.md

## Report and diagnosis

The operator reported that the dashboard and `Active SD card qualifications`
pages were extremely slow. Authenticated Playwright measurement reproduced the
problem:

- dashboard: `11.666 s`, including `11.632 s` to first response byte;
- F1-A1 qualification page: `5.881 s`, including `5.874 s` to first byte.

Browser rendering took only milliseconds. Production Django query capture
located the delay in campaign/assignment aggregation. The query joined every
run to every event for the same campaign before applying distinct run counts
and latest-event selection. Qualification progress continuously adds events,
so the join cost grew with the campaign and would have continued worsening.
Observed individual aggregations took `0.8728–2.8552 s` and sometimes exceeded
`10 s` under concurrent load.

## Correction and regression gate

Source commit `e2bc362e487e9e5f170198bef5a31ca39087f967` replaces the event join
with a correlated latest-event subquery while retaining the existing run
counts, activity timestamps, ordering, and rendered status. The proposed
aggregations measured `0.0088–0.0113 s`, approximately 100–300 times faster
than the isolated old query. A regression test asserts that dashboard and card
qualification run aggregates do not reintroduce an event join.

Focused UI/query-shape tests pass `3/3`. The complete exact ARM64 application
suite passes `307/307` with no system-check errors.

## Release and live verification

Release `qualification-page-performance-e2bc362` is deployed from the exact
source commit above. The ARM64 image is
`sha256:d7c5a8557ce52bc936a095505da35869a561fca830d9cfe231d1a223afcc3552`.
The offline package is retained at
`/home/jong/releases/qualification-page-performance-e2bc362`; all packaged
checksums pass and `manifest.json` has SHA-256
`53abe580ce1b4d36a7bce48fdda17718851d56c351433724b9c1e67701abc8e0`.
The prior override is retained at
`/home/jong/.local/share/sd-qualifier/rollback-page-performance-e2bc362-20260810T1355Z`.
This release has no migration; the previously restore-verified production
backup remains compatible.

Post-deployment authenticated Playwright timings are:

- dashboard: `1.080 s` total, `1.074 s` to first byte;
- F1-A1: `1.745 s` total, `1.735 s` to first byte;
- F1-B1: `1.644 s` total, `1.636 s` to first byte.

Production Django render measurements agree: the warm dashboard is `1.055 s`,
F1-A1 is `1.672 s`, and F1-B1 is `1.469 s`; database time is only
`0.195–0.270 s`. Web health is `healthy`, all four application services use
the exact release image, active supervisor alerts and current interventions
are both zero, and the temporary Playwright users were removed.

Controller A and B parent invocation IDs remain respectively
`496dbd96a55e45aaa6333b7fbd8f5a67` and
`fa196d1f1db54a6c8a4fd9c806f48c00`. Both parent services and both observers
remain active. Current runs continued to heartbeat after deployment: A
`a2dbfca4-805b-4fca-bf69-b01717e0f083` and B
`58502e45-4a72-4433-bb43-6490de9adcb2`. No controller command, replay, card
operation, database migration, or runner restart occurred.
