# Rebuild the replacement recordings

Only the seven rejected recordings are replaced. All accepted still/diff links are preserved verbatim in the compact evidence section. No tracked app files were changed.

Before: [60aec28a9c](https://github.com/pingdotgg/t3code/commit/60aec28a9c6fdb7417a7382ec094ccc4984d0738), detached checkout `/home/ubuntu/wt/pr-28684-before`, web 6581/server 14621. After: [7c0cf8340c](https://github.com/pingdotgg/t3code/commit/7c0cf8340c03829333d4f12eb59d021529283e7f), `/home/ubuntu/wt/pr-28684`, web 6673/server 14713. These were the actual dev-runner ports for this run. Linux fs-29; Playwright 1.60.0; Chromium 148.0.7778.96; the same dark theme, reduced motion, DPR 1, 100% zoom/font scaling, 16px root, no device emulation, and fixed browser wall clock as the accepted evidence.

Use global `vp install` in the before checkout. Start each real app with `T3CODE_DEV_SEED=0 vp run dev`, its own newly created `.t3`, and retain its process/session. Never use the live T3 database or migrate-dev-db. Capture logs privately: they contain startup pairing tokens. Read actual ports before driving either app; if they differ, update the driver port bindings. Driver roots point to `/tmp/lead-28684-r1/evidence-capture-2/2026-11-02T22-50-00Z`; use a fresh timestamped run root when rebuilding, remapping that one binding in each script.

Start `node browser-driver.mjs`, then run `python3 bootstrap.py`; the controller uses loopback port 18981. Bootstrap reads each local startup pairing URL, waits for an authenticated main sidebar, and saves private browser storage state. Do not upload these state files or startup logs.

Create `fixture-workspace` beneath the run root, initialize a synthetic Git repository on `main`, and create an empty commit with fixture-only author details. `rpc-driver.mjs after seed` creates the project, A/B threads, and real terminal-owned Python HTTP listeners through HTTP/RPC. A owns 43100–43109; B owns 43200–43204. `rpc-driver.mjs before seed 0` creates the same fresh app data with zero listeners until after's listeners are released. Preserve terminal ancestry; do not run the seed launcher directly from shell tooling.

Run `python3 run-redo.py after paging-dark short-dark floating-dark switch-dark`. After those captures finish, run `rpc-driver.mjs after quit` and `after close`; confirm the recorded listener PIDs exited. Run `rpc-driver.mjs before count 10` and `before countb 5`, await the discovery subscription with `before ports 10`, and run `python3 run-redo.py before paging-dark short-dark floating-dark`. RPC commands run with the owning checkout's dependencies. Each scenario gets its own timestamped directory and logs.

The capture driver retains the original actual-app interactions and stability waits. It never configures Playwright recordVideo. Its recording loop captures lossless PNGs through CDP `Page.captureScreenshot`, with `format: png`, `fromSurface: true`, `captureBeyondViewport: false`, and `optimizeForSpeed: true`. This changes PNG compression speed, not pixels. It records monotonic start/end/midpoint timestamps and targets 20 fps. `frames.json` retains every source frame's timing; every selected capture averages at least 10 fps. `metadata.json` records the DOM row counts, footer labels, scroll positions, viewport, theme, and narration milestones.

`encode-verify.py` maps each 10 fps presentation timestamp to the nearest captured PNG, hard-links the exact source into encode-input, and encodes with ffmpeg `libx264 -crf 0 -preset slow -tune stillimage -pix_fmt yuv444p -movflags +faststart`. CRF 0 eliminates lossy temporal encoding; 4:4:4 avoids chroma subsampling. RGB/YUV conversion yields a measured maximum RGB channel difference of 2/255. Every decoded RGB frame is compared against its mapped source PNG, retained under verified-decoded, and listed in verification.json; any delta above 4/255 or source capture rate below 10 fps fails. There is no frame interpolation or blending. Contact sheets use actual decoded frames around every narrated milestone, with native-resolution card crops. The metadata preserves the exact sample frames and timing map.

`package-evidence.py` verifies the observable row/footer/scroll transitions, selects the latest passing run for all seven scenarios, assembles full verification-summary.json and recordings.json, and uploads videos, sheets, and scripts with `ghdrop upload -m`. `build-evidence.py` preserves every accepted still/diff image link byte-for-byte and asserts the replacement evidence section is at most 60 lines, then the package driver uploads it. No app code, PR comments, or PR state are mutated.

Finally quit/close before's terminals, close the browser controller using its close operation, stop each retained dev session, confirm owned ports/listener PIDs have exited, and remove the before checkout with `git -C /home/ubuntu/t3code worktree remove --force /home/ubuntu/wt/pr-28684-before`. Preserve the after checkout's clean tracked state and retain all local raw evidence/logs.
