# Rebuild this evidence

Synthetic data only. Run both revisions as their real dev apps, each on its own fresh `.t3` database with `T3CODE_DEV_SEED=0`; never seed from the VM's live T3 home. Before is 60aec28a9c6fdb7417a7382ec094ccc4984d0738 (web 6581, server 14621); after is 7c0cf8340c03829333d4f12eb59d021529283e7f (web 6673, server 14713). Ports can shift on a later run. Install with global `vp install`; launch with global `vp run dev` and read its actual ports.

`browser-driver.mjs` starts Chromium on the loopback controller at 18961. Authenticate its `after` and `before` pages with each dev server's startup pairing URL. `control.py` sends controller operations. Keep startup URLs and Playwright storage-state files private; the scripts contain no credentials. Save each authenticated context using the controller's `save` operation, which writes `<side>-private-state.json`. The capture driver reads these local state files. Use a separate controller port if 18961 is occupied.

Create `/tmp/lead-28684-r1/evidence-capture/fixture-workspace`, run `git init -b main`, and make an empty synthetic commit (no remote). `rpc-driver.mjs <side> seed` creates the project and two persisted threads through HTTP/RPC, opens their real terminals, and launches `seed-servers.py` through `terminal.write`. A has ports 43100–43109; B has 43200–43204. This is real process discovery, not mocked ports. To avoid conflicts between the two apps, finish after captures and run `rpc-driver.mjs after quit` before starting before's listeners. Before may first use `seed 0`, then `count 10` and `countb 5`. `count 4` and `count 5` change A for rows 03 and 04. `ports` records the actual discovery subscription, including terminal ownership.

`capture-driver.mjs <side> <scenario> <count>` starts a fresh authenticated Playwright context. Scenarios: `collapsed-dark`, `collapsed-light`, `expanded-light`, `mobile-dark`, `paging-dark`, `short-dark`, `floating-dark`, `switch-dark` (after only). Use count 4 or 5 with `collapsed-dark`; otherwise 10. `run-captures.py` runs named scenarios in sequence. Each run creates a timestamped directory. Metadata records frozen wall clock, viewport, resolved theme, DOM row count, full/compact density, scroll position, and event times. Every still requires two identical PNG buffers 500ms apart after network idle and font readiness; reduced motion is set before mount. Full viewport captures use DPR 1 and 100% font scaling. Mobile width uses touch/mobile emulation, coarse pointer and no hover; other contexts use no device emulation.

`assemble-evidence.py` chooses the manifest's successful runs, creates zero-threshold amplified diffs and threshold-16 diffs, full-resolution labeled sheets, and trims real Playwright recordings to their recorded start/end events. `inspect-videos.py` makes contact sheets so the recording frames can be visually checked. Upload only selected synthetic captures, metadata, scripts, and trimmed videos; never upload private auth state, pairing credentials, or dev logs containing credentials. `build-report.py` writes the compact Evidence section after upload URLs exist.

Stop listeners with `rpc-driver.mjs <side> quit`, close terminals with `close`, stop browsers through the controller or captured execution session, and stop both retained dev sessions. Remove only `.t3` state created for this evidence and the before checkout created for it. Do not modify after's tracked files.
