# Rebuild F2 and F4 evidence

Before [6d450a4284](https://git.cafe/pingdotgg/t3code/commit/6d450a4284); after [5c1c8b0004](https://git.cafe/pingdotgg/t3code/commit/5c1c8b0004ee52542418bfc9f22c3a6f07f57b56). These scripts revise the first capture round. F1, F3, F5 and F6 retain their original evidence and original scripts; the new scripts and normalization apply to F2/F4 only.

All scratch material belongs under `/tmp/issue-lead-26950-r1/evidence-capture-2`. No real T3 userdata is read or copied. No real repository write action is performed. The synthetic fixture has a public origin solely to configure the GitHub provider; the harness supplies the list/detail RPC responses, and rejects forge mutations.

1. Create dedicated checkouts with `git -C /home/ubuntu/t3code worktree add /home/ubuntu/wt/issue-26950-before2 6d450a4284` and `git -C /home/ubuntu/t3code worktree add /home/ubuntu/wt/issue-26950-after2 5c1c8b0004`. Run global `vp install` in each. Do not use the lead's checkout.
2. Run `bash seed.sh`. Run `python3 start-servers.py --tag <unique-run-name>`. It creates new homes and logs in a new `servers-<tag>` directory, starts both exact revisions with `T3CODE_DEV_SEED=0`, and records PID/process-group leaders in `servers-private.json`. The original capture used `before-home` and `after-home` directly; the revised starter always creates a new directory. Read actual ports and pairing URLs from the logs after startup completes. Logs and pairing URLs stay private.
3. Use the T3 preview tools: `preview_status`, `preview_open` at each server's pairing URL in a separate owned tab, `preview_resize` to freeform 1440×900, and `preview_set_appearance` to dark. The API has no reduced-motion emulation; do not pretend that a JavaScript `matchMedia` override emulates CSS media queries.
4. Load `bootstrap-page.js` as a function expression in a Codex functions.exec cell and call `await bootstrap(tools,{tabId,home})`. It adds the synthetic directory through Add project → Local folder → Add, then reads only this sandbox's project ID from its own database in read-only mode. It returns `{projectId}`. A freshly created database may also contain the server's automatic empty project/thread; it is hidden by the main sidebar collapse.
5. Load `setup-page.js` as a function and call `await setup(tools,{tabId,side,fixture:'F2',projectId,port})`. It reloads the clean All/open/GitHub route, applies `instrument.js` and `harness.js`, refreshes, and awaits the All-involvement text-free synthetic baseline. Expected baseline counts are F2=4, F4=6. The initial authored/reviewing partition replies must not be mistaken for this baseline. Reload the page and repeat setup for every fixture.
6. Load `driver.js` as a function and call `await driver(tools,{tabId,side,fixture:'F2',outputDir:'<new timestamped directory under the scratch root>'})`. Repeat for both sides and F4. Each recording contains the same scripted typing, refresh and selection attempt. On before, F2 cannot select absent B3; after opens B3 and closes it. F4 switches All → Authored, then types the full qualifier string. Exact action and successful RPC timestamps are in the manifests.
7. Before recording, the driver collapses the main sidebar through the real toggle on both sides. Before every still, it blurs focus, physically parks the pointer at CSS (1400,850), verifies no hovered control and collapsed sidebar, awaits fonts and at least 500ms of observed fetch/resource inactivity, and waits for relevant successful RPC completion. It accepts a still only after two full-surface PNG screenshots at least 500ms apart have exactly identical pixels. It records pointer, focus, sidebar state, active animations, toolbar geometry and rendering styles.
8. **Toolbar compositor normalization:** before recording and each still, the driver applies `transform: translateZ(0)` to the entire search/sort/filter toolbar on both revisions. This identity transform changes its compositor paint context, without changing layout, content, paths, colors or order. Without isolation, the F4 result-vs-empty paint contexts produce four Sort-arrow antialias pixels despite identical DOM, geometry and computed styles, no hover/focus and no active animations. Resize, menu open/close and temporary repaint did not remove them. Isolating the whole toolbar removes every unrelated toolbar pixel from Diff0. This is a disclosed capture-harness rendering normalization, not a production fix, pixel mask, crop or postprocessing repair. The original unisolated and diagnostic captures are uploaded separately. The same normalization is applied to F2.
9. Run `package-evidence.py`; its RUNS map pins the delivered capture directory and can be changed to a new run for reproduction. It copies the accepted captures, creates full-surface Diff0 (any RGB channel >0, magenta) and DiffT (>16/255), comparison sheets and recording inspection filmstrips. Context is quarter brightness. No crop or pixel alignment is applied.
10. For an independent rebuild, stop the after process group from the private PID record, close its tab, then `python3 start-servers.py --sides after --tag rebuild` (use another unique tag for subsequent rebuilds). This creates an entirely new database at the after revision's migration level. Pair a new tab, bootstrap a new project, run setup and driver again in a new run directory. `compare-rebuild.py` pins the original and rebuilt run paths and creates both full-surface diffs plus `reproducibility-manifest.json`. This run compared F2-after-mixed from the original capture to the entirely rebuilt still: **0 changed pixels**, maximum channel delta 0, RGB pixel SHA-256 `aafccd91ac359b69c4ab059ee61cf7fb67e1feb029fc04c1f1ac9249701fc0d9` on both. Mixed versus returned is also 0 pixels. Both F2/F4 have 0 changed pixels outside the expected result/count/empty-state rectangles.
11. Open all final stills, diffs and recording filmstrips before upload. `upload-evidence.py` uploads the explicitly collected synthetic deliverables and scripts with `ghdrop upload -m` and saves its output unchanged in `uploads.md`. `build-index.py` replaces only the F2/F4 sections of the original Evidence section and updates the shared preamble and what-else-changed list; it asserts F1/F3/F5/F6 are unchanged. Upload the evidence and report after generation.
12. Stop only captured PID/process groups, close every owned tab, and remove both dedicated checkouts. Keep this scratch evidence and the lead's original evidence directory. Never upload server homes, authentication, raw server logs, or pairing URLs.

Every accepted capture: Linux x86_64, T3 preview headless Chrome 156.0.0.0, no device emulation, 1440×900 CSS viewport, DPR 2, default 16px/100% font scaling, dark theme, scroll top, merge-readiness sort, browser Date frozen at 2026-10-29T13:30:00Z. Full-surface PNGs are downsampled by the preview tool to 1280×800; original MP4 recordings are 2880×1800. The tool does not expose a global network-idle primitive; the driver observes fetch/resource quiet and relevant RPC completion. Reduced motion is unsupported and remains false. Recording timing is original, with action offsets approximate to about one second because of tool/screencast latency.
