# Evidence reproduction

Pinned app checkouts: before [a9b513b50c](https://github.com/pingdotgg/t3code/commit/a9b513b50cc967cc715228b38cb922d1aaaa3a8b) in `/home/ubuntu/wt/pr-25709-base`; after [ee9754767f](https://github.com/pingdotgg/t3code/commit/ee9754767f02d68551b716e5c7eb9f4257b74030) in `/home/ubuntu/wt/pr-25709`. No tracked edits, no harness, no real database or provider run.

1. Install each checkout with `vp install`. Start with `python3 start-server.py base` and `python3 start-server.py after-off`. These use `T3CODE_DEV_SEED=0`, unset the Secrets flag, retain process-group IDs, and log real dev-runner ports. The driver defaults here are 8440/16480 for base web/server and 6696/14736 for after web/server. Update `ORIGIN` and bootstrap web ports if different on another machine.
2. Pair each editable context with its startup URL. `bootstrap.cjs` can mint a replacement default-scoped token if the startup token was consumed; `pair-startup.cjs` uses the flag-on startup admin token. Auth state files and server logs stay private and must never be uploaded.
3. `node capture.cjs base baseline`; `node capture.cjs base baseline-extra`; `node capture.cjs after-off baseline`. Run directories are timestamped and append-only. The default server-created empty project/thread is the same synthetic starting state on both sides. Each side creates its own fresh SQLite schema. No DB is copied.
4. Stop the off server with `python3 stop-server.py after-off`, then `python3 start-server.py after-on`. Pair via `node pair-startup.cjs`. `node capture.cjs after-on feature-all` creates every page/dialog state through the UI: no direct settings or DB edits. `feature` resumes at the palette after navigation/empty-state captures. `clean-interactions` first removes synthetic providers, then repeats these flows while keeping every recording at 1440×900 light. Separate original stills cover dark and narrow layouts. `long-repeat` repeats the 64/253 boundary fixtures and records DOM overflow measurements.
5. After long-data captures, `node capture.cjs after-on cleanup-long` removes the two long fixtures through the UI. `node capture.cjs after-on restricted` mints exactly `--scope orchestration:read` with explicit `.t3` base dir, pairs a context with no admin storage, and records a separate context carrying only that restricted session. Pairing itself is excluded from recordings.
6. `bash seed-project.sh`; `node capture.cjs after-on scope`. This initializes an empty synthetic git directory, adds it through Command palette → Add project → Local folder, selects it in the Settings project-scope picker, and verifies the environment-wide notice and absence of mutation controls.
7. `python3 diffs.py <feature-run-directory>` generates saturated magenta masks at max RGB channel delta >0 and >16/255. No pixel tolerance is used for settling or equality. `prepare-videos.py` trims startup-only lead-in from recordings and emits per-action timestamps; the raw `.webm` remains available. Video timestamps are wall-clock aligned to video duration, approximately ±0.5 seconds.
8. `sheets.py` groups every selected still/diff without cropping. `build-evidence.py` makes the HTML index, compact Markdown section and overview from uploaded asset mappings. Open and inspect all sheets, raw captures and video storyboards before upload.

The date is frozen to 2026-10-27T12:00:00Z; browser timers continue so authentication and UI work. Reduced motion, network idle, `document.fonts.ready`, parked pointer, and two pixel-identical screenshots 500 ms apart are required for each still. Font size/zoom 100%; DPR 1; no device or touch emulation; Chromium 148.0.7778.96 / Playwright 1.60.0 headless on Linux fs-25. Viewports: 1440×900 and 390×844. Native fonts from the app, default system light/dark theme. Modal backdrop blur and hidden-account blur are product UI, not capture artifacts.

Before has no Secrets page: B0 is the shared baseline for new-page rows. New-page form actions cannot be performed there; its navigation recording demonstrates the missing route. An extra before palette recording uses the same Ctrl+K/type interaction. Only R0 and R1 sidebar/search frames receive diffs. The flag-off direct-route outcome is deliberately reported separately because main has no matching route.

Cleanup: stop both tracked server groups with `stop-server.py`; close every launched browser; after uploading evidence, remove `/home/ubuntu/wt/pr-25709/.t3` and remove the detached base worktree with `git -C /home/ubuntu/t3code worktree remove --force /home/ubuntu/wt/pr-25709-base`. Keep uploaded raw evidence and logs under the scratch directory. Never upload auth JSON or server/pairing logs.
