21 KiB
CV-UX verification execution plan
Prepared 25 October 2026 from the existing Phase 9 reproduction instructions and runners. This document is a prospective execution plan, not passing evidence. The parent owns the final source freeze, serial execution, reconciliation and publication. Do not execute while workers are changing backend/frontend sources. Preserve every failed or superseded attempt.
Fresh identity and lifecycle
Use a new absolute evidence root, for example E:/Storage/Projects/Active/Job tracker/.artifacts/cv-ux-01/final-01; reject it if it already exists. Use final-02 after an implementation/fixture correction. Do not invoke .artifacts/p9-sec-02/final-run.py, p9-sec-02/reconcile.py, p9-sec-02/linux-run.py, or the historical MariaDB lane wrapper unchanged: they hardcode historical evidence roots, image identities, counts or source lineage and can overwrite/reuse historical evidence.
Before the first build, record branch/HEAD/status and SHA256 for all application, migration, frontend, fixture, config, lock, Dockerfile and helper inputs, including new untracked source. Build once, then freeze the API Release binaries/deps/font resources and frontend out file hashes plus tool/runtime/browser identities. Repeat source and runtime hashes after all producers finish. A Git SHA alone does not identify uncommitted worker changes. Record UTC start/end, actual argv, cwd, selected nonsecret environment, exit code and native report hashes for every lane. Never print connection/session credentials. App health's fixture token is not source provenance.
Prerequisites: pinned .NET SDK from global.json (currently 9.0.317), C:/Users/Connor/.dotnet/dotnet.exe; installed locked UI dependencies and Node; installed Playwright Chromium; Python with pdfplumber, pypdfium2, Pillow; Docker Linux engine; local pinned MariaDB 12.2.2 image. Do not run npm install, change locks, download models, or mutate developer databases as a substitute for these prerequisites. Obtain the bundled PDF Python path with the app dependency tool if the retained path below is absent.
All commands below are run serially. Root cwd unless explicitly UI cwd. The execution controller must retain stdout/stderr to per-lane logs and check each exit code before proceeding; pipelines must not turn failures into passing exit codes. UI/API servers must be stopped before rebuilding binaries/static assets. Ports 3300/5302 (plus the diagnostic/volume-specific ports) must be free or positively identified as this attempt's owned processes; PLAYWRIGHT_REUSE_SERVERS=false prevents accidental reuse.
$cvUxRoot = 'E:/Storage/Projects/Active/Job tracker/.artifacts/cv-ux-01/final-01'
if (Test-Path -LiteralPath $cvUxRoot) { throw 'Select a fresh evidence root' }
New-Item -ItemType Directory -Path $cvUxRoot | Out-Null
$env:DOTNET_ROOT = 'C:/Users/Connor/.dotnet'
$env:DOTNET_HOST_PATH = 'C:/Users/Connor/.dotnet/dotnet.exe'
$env:NEXT_PUBLIC_API_BASE_URL = 'http://localhost:5302/api'
$env:PLAYWRIGHT_STATIC_EXPORT = 'true'
$env:PLAYWRIGHT_PREBUILT_EXPORT = 'true'
$env:PLAYWRIGHT_REUSE_SERVERS = 'false'
$env:CV_FIDELITY_OUTPUT = "$cvUxRoot/windows/fidelity"
$env:CV_SETTINGS_FIDELITY_OUTPUT = "$cvUxRoot/windows/settings-fidelity"
$env:LETTER_FIDELITY_OUTPUT = "$cvUxRoot/windows/letter-fidelity"
$env:SKIP_MODEL_LOAD = '1'
$env:AI_SERVICE_SKIP_MODEL_LOAD = '1'
$env:PYTHONIOENCODING = 'utf-8'
The model-disable variables retain the established local application regression conditions. Unchanged Python/model security qualification is inherited from the Phase 9 baseline and explicitly labelled historical; this feature does not rerun or establish GPU/model/hosted/provider/production acceptance.
Builds and complete local suites
Root cwd:
rtk C:/Users/Connor/.dotnet/dotnet.exe test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --configuration Release --no-restore --logger 'trx;LogFileName=backend.trx' --results-directory "$cvUxRoot/backend"
rtk C:/Users/Connor/.dotnet/dotnet.exe build JobTrackerApi/JobTrackerApi.csproj --configuration Release --no-restore
The backend test build also creates the Release PDF process stub required by the separate admission config. If locked restore is actually required, record that separate command/outcome; never treat a restore-only exit as a test result.
UI cwd E:/Storage/Projects/Active/Job tracker/job-tracker-ui:
rtk node node_modules/jest/bin/jest.js --runInBand --json "--outputFile=$cvUxRoot/frontend.json"
rtk node node_modules/typescript/bin/tsc --noEmit --incremental false
rtk node node_modules/eslint/bin/eslint.js . --max-warnings=0
rtk node --max-old-space-size=4096 node_modules/next/dist/bin/next build
Record fresh native totals rather than fixing expected counts to the historical backend 1130/frontend 935. Compare discovery/membership with baseline; every added/removed/renamed case needs an explicit source-backed explanation. Do not add earlier focused worker checks to the full-suite totals.
Ordinary browsers and independent contracts
Keep UI cwd and the environment above. First retain ordinary discovery:
$env:PLAYWRIGHT_JSON_OUTPUT_NAME = "$cvUxRoot/discovery.json"
rtk node node_modules/@playwright/test/cli.js test --list --retries=0 --reporter=list,json
Execute four complete shards one at a time, with process metadata/logs and a separate native JSON for each:
foreach ($cvUxShard in 1..4) {
$env:PLAYWRIGHT_JSON_OUTPUT_NAME = "$cvUxRoot/ordinary-$cvUxShard.json"
rtk node node_modules/@playwright/test/cli.js test --retries=0 --reporter=list,json "--output=$cvUxRoot/ordinary-$cvUxShard-results" "--shard=$cvUxShard/4"
if ($LASTEXITCODE -ne 0) { throw "Ordinary shard $cvUxShard failed; preserve this attempt" }
}
Historical ordinary discovery was 362. The new cover-letter-document-fidelity.spec.ts currently adds one browser test containing four physical letter fixtures; new CV workflow cases may increase discovery further. Reconcile exact test ID/project membership across the four native reports with current discovery; require each discovered case exactly once, no retries, failures, unexpected skips or missing errors. Four physical letter documents are not four browser cases. Capture LETTER_FIDELITY_OUTPUT only once per attempt: its producer refuses an existing started.json.
Execute each configuration below separately using this exact command pattern, setting $cvUxLane and $cvUxConfig to the corresponding row. Do not combine or sum these with ordinary cases.
$env:PLAYWRIGHT_JSON_OUTPUT_NAME = "$cvUxRoot/$cvUxLane.json"
rtk node node_modules/@playwright/test/cli.js test --retries=0 --reporter=list,json "--output=$cvUxRoot/$cvUxLane-results" "--config=$cvUxConfig"
| Lane | Configuration relative to UI cwd | Historical expected membership (verify fresh) |
|---|---|---|
| ai | playwright.cv-ai.config.ts |
2 |
| auth | playwright.auth-recovery.config.ts |
2 |
| rate | playwright.rate-limits.config.ts |
9 |
| ingress | playwright.ingress.config.ts |
6 |
| pdf-admission | playwright.pdf.config.ts |
1 |
| preferences | ../docs/redesign/phase-5/p5-15/p5-15-01/diagnostics/playwright.config.ts |
3 |
| rd21 | ../docs/redesign/phase-9/rd21-remediation/diagnostics/playwright.config.ts |
6 |
| diagnostics | ../docs/redesign/phase-9/p9-05/diagnostics/playwright.config.ts |
18 |
| volume | ../docs/redesign/phase-9/p9-05/volume/playwright.config.ts |
3 |
| rd21-volume | ../docs/redesign/phase-9/rd21-remediation/volume/playwright.config.ts |
3 |
The six contract lanes historically total 23; RD21/diagnostics/volume lanes remain separate. Run both volume lanes alone without builds, renders, provider pacing or other browser suites. Admission uses inert child stubs and must never be described as real physical PDF fidelity.
Actual MariaDB
The letter-persistence worker owns provider qualification. Its earlier 47-case all-writer gate predates document design/migration; it is not the final additive-schema gate. Its later checkpoint at .artifacts/cv-ux-01/letter-design-mariadb reported 56/56 passing with the additive migration and provider downgrade/reupgrade preservation, and positive generated-project cleanup. That is separately reported worker evidence, not a fresh parent frozen-source full regression. The guarded runner already supports fresh output and generated projects/schemas:
rtk python scripts/mariadb-integration.py --output "$cvUxRoot/mariadb"
Run only after final source freeze and record actual new TRX membership/count, exact pinned image/server 12.2.2, schema ownership and positive cleanup. The runner's default mode creates a generated jobtracker-it-<uuid> project, loopback random port and tmpfs test data, then removes only its owned test service. Do not substitute SQLite or developer mariadb-dev; do not use broad prune/down -v. An earlier worker checkpoint may support development sequencing but cannot be added to this fresh full provider total.
Existing MariaDB browser/HTTP-observation/15-minute workload helpers have fixed roots/project assumptions. If those are in the final parent-required matrix, adapt only fresh-root/project parameters and retain their native independent counts and exact paced-duration evidence. Run the pacing workload alone. The parent must identify which helper executes that lane before marking it complete; ordinary browsers and backend MariaDB tests do not supply workload proof.
Windows original 24-document CV oracle
Ordinary shards produce the existing 16-fixture fidelity corpus and four settings-browser cases containing eight settings states in the fresh Windows roots above. Stop all producers before proof. Root cwd, use the bundled Python (verify available; retained installation path shown):
rtk C:/Users/Connor/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe -B docs/redesign/phase-9/p9-requal-01/pdf-proof.py --platform windows --fidelity-root "$cvUxRoot/windows/fidelity" --settings-root "$cvUxRoot/windows/settings-fidelity" --output "$cvUxRoot/windows/proof" --record "$cvUxRoot/windows/native-pdf.json"
pdf-proof.py accepts fresh roots unchanged and checks exact 16/36-page plus 8/24-page membership using scripts/verify-cv-fidelity.py. Retain original oracle SHA256 64f82e622cc11483c33307d987e969f6cf27f82ab6bdbd72c2aeb1bfbceade87; never edit tolerances or fixture expectations to make this feature pass. A real regression stays FAIL with artifacts.
Current-source Linux API and original 24-document oracle
Do not run the historical image as if it contains current letter schema/rendering. Prefer the current JobTrackerApi/Dockerfile rebuilt from the frozen current source into a new local-only feature tag. Record Dockerfile/context hashes, build log, local base IDs, resulting immutable image ID, runtime/Chromium/font/package identity and API Release DLL hash. --pull=false preserves installed inputs but does not make floating local tags immutable. Record resolved inputs; if unavailable, leave the lane blocked rather than silently downloading/reusing a different qualified runtime.
rtk proxy docker build --pull=false -f JobTrackerApi/Dockerfile -t jobtracker-cv-ux-api:final-01 .
rtk proxy docker image inspect jobtracker-cv-ux-api:final-01
A narrower alternative when existing SDK/apt inputs cannot rebuild offline is a fresh image over the verified historical Linux runtime ID with every current portable API publish output copied over /app, built from a fresh hashed publish directory with /p:UseAppHost=false. That reuses native runtime/fonts, not historical application-source evidence; record current DLL/deps/migration/resource hashes and a new immutable image ID. Do not claim hermetic OS rebuilding. The old source image ID alone is insufficient.
The reusable lifecycle is p9-requal-01/linux-run.py: generated guarded jt_it_<32 hex> schema, isolated network, tmpfs API /data, loopback API port 5302, actual ready/migration checks, logs and positive API/network/schema cleanup. It needs a small new feature adapter before execution because its DB project/port checks are hardcoded to jobtracker-it-p9-requal/33308 and its config includes only historical CV tests. Required parameters: fresh output, immutable newly built image ID, frozen source identity, validated dedicated tmpfs DB container/project/port and a current Linux Playwright config. Guard DB image pin, tmpfs/no persistent mounts, loopback-only port, nonprivileged/nonhost networking and exact server 12.2.2 before any SQL. Verify /health version and source commit against recorded identity; do not infer source freshness from the unchanged legacy fixture-ready token.
The feature Linux Playwright config must retain the original base frontend server only (Linux runner owns API), workers 1/retries 0, and select:
cv-readiness.spec.ts/native preview/PDF fidelity corpus(1 browser case, 16 documents).cv-settings-presentation.spec.ts/document controls preserve settings(4 browser cases, 8 states).cover-letter-document-fidelity.spec.ts/cover letter native preview/PDF fidelity(1 browser case, 4 documents).
Set fresh CV_FIDELITY_OUTPUT, CV_SETTINGS_FIDELITY_OUTPUT, LETTER_FIDELITY_OUTPUT under $cvUxRoot/linux, PLAYWRIGHT_JSON_OUTPUT_NAME=$cvUxRoot/linux-renderer.json, the immutable image and full current source identity. The adapter should retain the existing guarded cleanup and add offline assert checks for wrong image/project/port/schema, reused output, API startup failure and cleanup failures. No adapter was implemented in this documentation-only ownership; the parent must implement/review it or supply an equivalent owned lifecycle before running Linux.
After successful Linux producers and positive cleanup, root cwd:
rtk C:/Users/Connor/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe -B docs/redesign/phase-9/p9-requal-01/pdf-proof.py --platform linux --fidelity-root "$cvUxRoot/linux/fidelity" --settings-root "$cvUxRoot/linux/settings-fidelity" --output "$cvUxRoot/linux/proof" --record "$cvUxRoot/linux/linux-pdf.json"
Separate letter physical fidelity
The new e2e/cover-letter-document-fidelity.spec.ts is a real authenticated producer, with one browser case/four independent multipage A4/Letter × EN/NB × light/dark documents. It creates a synthetic owned job per fixture, saves text+design with the shared expectedVersion, previews through the real server and application iframe, waits for font/image pagination readiness, walks every next-page control, proves final marker reachability, checks sender/recipient and inline formatting, downloads the saved-revision PDF and records bytes/HTML hashes, settings, all unique text-marker geometry/style, actual browser version and per-page screenshots. It asserts preview/export do not mutate saved letter or canonical source. It refuses reusing the attempt and writes root measurements.json only after all four succeed. No browser execution has occurred at preparation time.
Its measurements use the existing oracle's schema. The unchanged lower-level oracle supports arbitrary corpus size, so no new PDF oracle or widened tolerances are needed. Run separately after each platform's producers stop:
rtk C:/Users/Connor/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe -B scripts/verify-cv-fidelity.py "$cvUxRoot/windows/letter-fidelity"
rtk C:/Users/Connor/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe -B scripts/verify-cv-fidelity.py "$cvUxRoot/linux/letter-fidelity"
Require exactly the four fixture names light-en-a4, dark-nb-a4, light-nb-letter, dark-en-letter, each native result passing without failures, no duplicate/missing marker, matching physical page count/geometry/fonts/colors/safe areas. Retain fidelity-results.json, actual PDF page images/comparison images and producer inputs/hashes. Do not add these four documents to either original CV24 count. Review extracted PDF text for full sender email/phone/location, multiline recipient, subject, bold/italic content and final diacritics; marker checks alone do not establish every unmarked string. No physical printer/human fidelity claim follows from this oracle.
Reconciliation and stop rules
The historical collector is not parameterized for this feature and hardcodes old totals/roots. A minimal new parent-owned collector must read only this fresh attempt, reconcile current discovery exactly against four ordinary reports, enumerate frontend assertion names and backend/provider TRX test IDs, validate all independent lane reports and process exits, verify no retries/unexpected skips, check CV24 and letter4 oracle membership, bind inputs/runtime/image hashes, and require positive cleanup. Its offline self-check must reject a historical-root report, absent/duplicate cases, bad process exit, source/runtime drift, wrong image and missing cleanup. --collect-only must not mean acceptance. Historical Phase 9 evidence stays immutable.
Stop/re-freeze on source or runtime drift, stale apphost/static output, migration/schema failure, failed oracle, frozen history loss or unqualified revision behavior. Keep failed attempts separate; never replace a full failed shard with an overlapping focused test total. Report focused/full/backend/frontend/browser/provider/PDF/human outcomes independently. Human screen-reader/touch/device/zoom/print, hosted isolation/MariaDB, provider, deployment and production remain NOT TESTED/BLOCKED as applicable. Production and Phase 10 remain NO-GO.
26 October: blank letter accessibility checkpoint
Frozen aggregate final-06 completed its first ordinary shard with 96 passing and four failing cases; source/runtime hashes remained unchanged. Three application-form failures exposed empty optional letter headings and an unnamed document landmark. The fourth fixture incorrectly counted the new read-only preview POST as a durable mutation. This attempt remains failed and retained.
The shared renderer now omits blank optional headings, supplies an escaped localized fallback document title, and names the document body landmark. Nonempty headings and document layout retain their existing rendering. The mutation fixture excludes only the exact numeric-job preview POST; all save/restore/other commands and durable readbacks remain checked.
Two new EN/NB regression cases failed before the renderer fix. Fresh full Release backend validation passed 1,229/1,229 with zero skips (.artifacts/cv-ux-01/letter-empty-backend-successor.trx); all 11 original application-form browser cases passed (letter-legacy-forms-01.json). Guarded actual MariaDB 12.2.2 passed 59/59 with zero skips, matching before/after source hashes, runner exit 0 and positive owned-service cleanup (provider-final-04). Independent review found no material issue. These totals overlap earlier focused/full runs and must not be added together.
The frozen aggregate and current-source Linux image/PDF checks must be rerun after this checkpoint. Earlier aggregate failures and pre-fix images do not establish final acceptance. Full frontend frontend-final-03 remains current at 981 passing assertions across 107 suites because this checkpoint changes no frontend product or unit-test source. Final acceptance remains pending.
26 October: generic writer flag preservation
Frozen final-07 passed the full backend (1,229 cases) and ordinary shard 2 (87/87), then failed shard 3 (86/88). Both source and runtime hashes were stable. Native JSON identifies two failures: the Documents editor-save request counter included its read-only letter preview POST, and the JSON job-import round trip found an unexpected HasCoverLetter flag promotion. This aggregate remains failed; its passing subset does not replace a complete successor.
The flag failure was a product regression introduced by moving dedicated letter-save history into the shared writer. The accepted baseline promotes the flag only for a changed nonempty dedicated letter Save, while create, generic update and application-draft writers preserve existing attachment flags. Restore that side effect to the dedicated Save after its no-op branch; retain atomic text/design/history persistence, clear semantics and the original import expectation. No backfill is performed. SQLite and MariaDB writer tests cover both existing flag values, clear, dedicated no-op, promotion and restore.
Regression evidence: three failing flag cases before the fix, then 67/67 focused cases and 1,234/1,234 full Release backend cases passed with zero skips (letter-flag-red-01, letter-flag-green-01, letter-flag-backend-full-01). Actual guarded MariaDB 12.2.2 passed 64/64 with source hashes unchanged, no audit override, process exit 0 and positive owned-service cleanup (provider-final-05). Independent diff review found no material issue.
The Documents fixture correction excludes only the current job's exact preview POST from the final editor-write count. Listing checks continue to forbid implicit rendering, preview and writes; exact Save body, expected revision, history and durable metadata readbacks remain asserted. Its entire original browser suite passed 10/10 (documents-preview-fixture-01). The unchanged JSON job-import suite passed all four cases (import-flag-browser-01), including the actual PascalCase export/native chooser round trip, graph/owner boundaries and uncertain-write recovery. Final aggregate, current-source Linux and native PDF acceptance remain pending.