# Rebuilding the citation evidence

All fixtures are synthetic. Use the three exact revisions linked in the evidence index in detached checkouts named `/home/ubuntu/wt/pr-33440-before`, `/home/ubuntu/wt/pr-33440-after`, and `/home/ubuntu/wt/pr-33440-v1`. Install dependencies with `vp i` in each checkout. Keep every server isolated: `T3CODE_DEV_SEED=0` is mandatory. Never seed from the host's live T3 home.

Put the uploaded scripts together in `/tmp/lead-33440-r1/evidence-capture-3/` (or set `CAPTURE_ROOT` for the Node drivers). Install Playwright **1.58.2** there. Chromium's executable is parameterized with `CHROMIUM_PATH`; the delivered run used the installed headless shell at the default path in the driver. Required tools: Node, Python3 with Pillow, Git, vp, ffmpeg/ffprobe, and ImageMagick.

1. Run `bash fixture-seed.sh` and `python3 start-capture-servers.py`. The latter records the PIDs it spawned in a private file. Read each dev runner's actual ports and wait for its pairing URL. Do not publish server logs, startup pairing URLs, auth storage files, or anchor URLs.
2. Run `node seed-bootstrap.mjs before after v1`. It pairs through each checkout's CLI, creates the tiny fixture project through the app, selects Replay (dev), sends the first Multi turn prompt, disables rich text, chooses Queue follow-up behavior, closes panels, and saves private auth/anchor files. No database rows are copied or modified directly. Pairing uses real time to avoid authentication skew.
3. Run `CAPTURE_FIXED_TIME=2026-11-10T04:12:00.000Z node capture-driver.mjs`. It executes R1-D, R1-N, R2b simple/advanced, R5, R2 simple/advanced, R3, R4 in that order, on both main and current head, plus the superseded intermediate head on R2b only. Each invocation writes a new timestamped run directory. Arguments restrict rows; `CAPTURE_SIDES=after` restricts sides for the rebuild check.
4. Run `python3 prepare-diffs.py <run>/capture-results.json`, `python3 video-review.py <run>/capture-results.json`, and `python3 verify-artifacts.py <run>/capture-results.json`. Inspect every delivered still and diff plus the recording frames. Diff0 multiplies exact RGB differences by 255; DiffT is ImageMagick `compare -fuzz 2%`, magenta differences on black, with AE counts. Black means no changed pixels under that comparison.

The real UI is driven with mouse selection, native clipboard paste, keyboard shortcuts, and pointer clicks. `window.t3dev.replay` creates each fresh synthetic Replay thread. R3 uses one documented caret placement to seed trailing text; the interaction being verified uses the real comment editor and keyboard. R5 uses Showcase: cite its first assistant paragraph, save the empty comment, approve the first fixture write, reopen the comment while the turn runs, press Ctrl+Enter, verify the real queue count, approve remaining Replay writes, wait for the queued turn to finish, then type `fresh draft` without clicking the composer.

R2 and R2b obtain a serialized citation from a real chip, then paste it into Appearance's typography preview. Advanced enables Separate fonts; each case has its own isolated browser context. R2 reopens the comment and uses plain Enter before typing; R2b types immediately after Ctrl+Enter as soon as the editor receives the real return-focus event, with no artificial delay, reopen, or click. The superseded intermediate head appears only as a labelled regression reference on R2b.

Capture instrumentation: frozen browser clock, reduced motion, a visible user-message-count HUD, and an identical injected CSS mask on all revisions. The mask hides message `.tabular-nums` metadata and innermost `Working for …` / `Worked for …` duration labels using `visibility:hidden`; layout remains intact. The HUD names the mask. Its rectangular edges sit on whole pixels to prevent rounded-corner antialiasing from contaminating exact diffs. The browser clock does not freeze server-authored timestamps, which is why the CSS mask is required.

Before each final still, the driver waits for network idle and fonts, parks the pointer, hides the caret for screenshots, and accepts only two byte-identical PNGs 500 ms apart. The whole viewport is recorded and captured. MP4 recordings trim only setup before the first narrated interaction; the interaction remains continuous. Index times come from driver events and are approximate video positions. Advanced final frames scroll the Typography heading to the start of the settings scroller so the complete font previews fit. Contact sheets sample each recording across the interaction and final state; they supplement the MP4s.

For a fresh-database rebuild: after the matrix driver exits, run `python3 stop-capture-servers.py after`. Confirm that captured process group has exited. Move that checkout's entire `.t3` directory to a private backup under this scratch directory, restart only `after` with `python3 start-capture-servers.py after`, and bootstrap it again with `node seed-bootstrap.mjs after`. The fresh server creates its own database at its own migration level. Run `CAPTURE_FIXED_TIME=2026-11-10T04:12:00.000Z CAPTURE_SIDES=after node capture-driver.mjs R1-N`, then `python3 rebuild-check.py <delivered-run>/capture-results.json <rebuild-run>/capture-results.json`. Compare the rebuilt still to the delivered after still at zero threshold and at 2%.

Stop every captured server with `stop-capture-servers.py` and remove the three capture worktrees. Do not touch the lead checkout. The failed exploratory recordings and all private auth/log/state files stay outside the uploaded evidence.

AI-assisted; verified with the tests and tools listed above.
