Evidence gap fill for [#32921](https://git.cafe/pingdotgg/t3code/pull/32921) ([#32921](https://github.com/pingdotgg/t3code/pull/32921) on GitHub). Only R2, R3 and R4 are updated here. BEFORE is [bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9); AFTER is [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9).

Both frozen checkouts used their own fresh database and `T3CODE_DEV_SEED=0 vp run dev`. Synthetic files and RPC-created data only; every deferred message was stopped before provider start. Client Chrome under Xvfb: **1440×1000, light, DPR 1**, desktop mouse, 100% zoom/font scaling. Integrated browser: 960×640, maximized client panel asserted through **Restore panel size** and canvas width >1300. Only client Chrome maps `repro-box.tailnet-repro.ts.net` to loopback; server DNS returns `ENOTFOUND`. Each server launch sets `T3CODE_DEV_ALLOWED_ORIGINS` to the exact active client origin. Web ports are **6983 BEFORE / 6984 AFTER**, server ports **15023 / 15024**.

Every still waited for network idle and fonts and required two byte-identical screenshots 500 ms apart. **Diff0 = 0% fuzz; DiffT = 5% fuzz**, red changed pixels on white, with no masking or image edits. Every accepted capture and diff was opened individually. Each recording was decoded using ffmpeg and its frame sample inspected. Recorded loading transitions are retained; final stills are settled. The workspace card visible in chat is the ordinary thread-details panel. Signed tokens in the [transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f85a918eb00b409c/transcript.txt) are `<token>`; no private runtime model identifiers are published.

**R2 — localhost control**

`report.html` opens through `http://localhost:<web port>` on both sides and renders successfully.

| Before | After | Diff0 | DiffT |
|---|---|---|---|
| ![R2 localhost report — BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/aca042718119a40b/R2-before.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | ![R2 localhost report — AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7ed576e5c3dd37d1/R2-after.png)<br>[dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R2 localhost report — all changed pixels](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3c44109fee149836/R2-Diff0.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R2 localhost report — changed pixels at 5% tolerance](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b861759ce734e1c8/R2-DiffT.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |

Exactly what differs: the address-bar port (**6983 → 6984**) and the signed asset token. All changed pixels are inside **x=228, y=60, width=1108, height=14**. The report, title, panel controls, viewport and every other pixel match. Diff0: **8,989** changed pixels; DiffT: **8,535**.

**R3 — dependencies recording pair**

Same scripted interaction on both revisions: start from the prepared synthetic chat, right-click `dependencies.html`, choose **Open in integrated browser**, await terminal navigation, maximize and await pixel-identical stills. Timestamps below are seconds from each trimmed recording's start (encoder frame boundaries may differ by one frame).

| Step | BEFORE | AFTER |
|---|---:|---:|
| Prepared chat | 0.00 | 0.00 |
| Right-click dependencies.html | 1.00 | 1.00 |
| Choose Open in integrated browser | 1.84 | 1.92 |
| Navigation completes | 4.43 | 2.80 |
| Maximized layout asserted | 5.00 | 4.33 |
| Settled still captured | 7.00 | 6.30 |
| End | 8.53 | 7.82 |

| BEFORE [bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | AFTER [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |
|---|---|
| [R3 BEFORE recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5125535471cf4f87/R3-before.webm) | [R3 AFTER recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a045ec385ef206f0/R3-after.webm) |

BEFORE shows `ERR_NAME_NOT_RESOLVED`. AFTER renders the green CSS panel, JS-written text, blue/gold image and purple same-process iframe. Fresh matching stills and diffs replace the earlier R3 still pair:

| Before | After | Diff0 | DiffT |
|---|---|---|---|
| ![R3 workspace dependencies — BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/aa12fcc462a6023a/R3-before.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | ![R3 workspace dependencies — AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8ca73be209ff7250/R3-after.png)<br>[dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R3 workspace dependencies — all changed pixels](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8158d510063aa868/R3-Diff0.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R3 workspace dependencies — changed pixels at 5% tolerance](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/61d4b97a57cccac2/R3-DiffT.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |

**R4 — three-page PDF recording pair**

The same synthetic **three-page `guide.pdf`** is used on both sides. The script right-clicks `guide.pdf`, chooses **Open in integrated browser**, awaits the client PDF embed or a terminal navigation failure, maximizes, captures the settled initial state, then sends the same downward wheel input (**deltaY 1050 at client x=1050, y=700**) and captures the settled result. BEFORE fails DNS and never creates a PDF viewer or page counter; its scroll input leaves the error unchanged. AFTER shows the native client PDF viewer at **1 / 3**, then **2 / 3**, with readable matching page labels and the second thumbnail selected. These recordings establish client PDF rendering/scrolling.

| Step | BEFORE | AFTER |
|---|---:|---:|
| Prepared chat | 0.00 | 0.00 |
| Right-click guide.pdf | 1.00 | 1.01 |
| Choose Open in integrated browser | 1.82 | 2.09 |
| Navigation completes | 2.38 | 10.48 |
| Maximized layout asserted | 2.88 | 13.71 |
| Viewer outcome observed | 3.14: failed, no viewer | 15.29: PDF embed visible |
| Initial settled still | 4.15 | 29.41: 1 / 3 |
| Same downward wheel input | 5.68 | 30.94 |
| Scrolled settled still | 8.56: same error | 35.72: 2 / 3 |
| End | 10.06 | 37.23 |

| BEFORE [bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | AFTER [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |
|---|---|
| [R4 BEFORE recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a83a3841e946789f/R4-before.webm) | [R4 AFTER recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a019b2048517785e/R4-after.webm) |

R4 initial stills were re-taken with the three-page fixture:

| Before | After | Diff0 | DiffT |
|---|---|---|---|
| ![R4 three-page PDF — initial state — BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/27027d02fd712b0a/R4-before.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | ![R4 three-page PDF — initial state — AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2f352aaae5211ff9/R4-after.png)<br>[dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R4 three-page PDF — initial state — all changed pixels](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/17b532f5e9862e2e/R4-Diff0.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R4 three-page PDF — initial state — changed pixels at 5% tolerance](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d43adfcfb9c94853/R4-DiffT.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |

R4 after the same scroll input:

| Before | After | Diff0 | DiffT |
|---|---|---|---|
| ![R4 three-page PDF — scrolled state — BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4918e0d1ce743de5/R4-scrolled-before.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) | ![R4 three-page PDF — scrolled state — AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f92e8e3698bbc221/R4-scrolled-after.png)<br>[dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R4 three-page PDF — scrolled state — all changed pixels](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d01ffcc8c0166bce/R4-scrolled-Diff0.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) | ![R4 three-page PDF — scrolled state — changed pixels at 5% tolerance](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6e8dbb0e31ed3482/R4-scrolled-DiffT.png)<br>[bcee0f5d28](https://git.cafe/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9) → [dc301a4a44](https://git.cafe/pingdotgg/t3code/commit/dc301a4a44469871eb307d55b1b2d89af31f4dc9) |

**What else changed in these rows**

- **R2:** only address-bar port and signed token. No document or panel changes.
- **R3:** DNS error content, error buttons and generic hostname title become the dependency document, its title, colors, borders, text, image and iframe. Successful navigation enables the back button and dimensions controls; title width and the adjacent new-tab control move accordingly. URL ports/tokens differ. The chat pre-roll has the normal wall-clock message times from the separate runs.
- **R4:** DNS error content, error buttons and generic title become `guide.pdf` and the client PDF toolbar, thumbnails, page count and document. The successful page exposes dimensions/back controls and changes tab width/new-tab placement. Scroll changes the selected thumbnail, scrollbar position, page counter and visible page text on AFTER. BEFORE remains unchanged. URL ports/tokens and chat pre-roll message times differ.
- **Fixture update:** only `guide.pdf` changed from the earlier capture setup: three pages with explicit page labels replace the one-page fixture. HTML dependencies and their markers are unchanged. No application source was edited. HTTP/local desktop evidence only; no HTTPS, OOPIF, mobile or native-server PDF rendering claim is added.

**Reproduction and audit files**

[Parameterized capture driver](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bb0c387e5e2ba6f0/run-capture.mjs) · [Synthetic fixture generator](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c0d6c1387278f8c6/seed.py) · [Exact synthetic workspace](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8acc43493233a045/synthetic-workspace.tar.gz) · [Same-port loopback relay](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/052150954681715d/client-loopback-relay.mjs) · [Tracked process launcher/cleanup](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4a571352c81de39f/processes.py) · [Diff generator](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/935a1724dea1c525/make-diffs.mjs) · [Evidence packager](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/03382cca39c86db2/package-evidence.py).

[Accepted timestamped run directories](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f26711f0a2bf8c2e/accepted-runs.json) · [Diff input pairs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d2d486447308ed71/diff-pairs.json) · [Diff commands and counts](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/05c8ec1ae81a6107/diff-metrics.json) · [SHAs, conditions, navigation outcomes, step times and settled-frame hashes](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4e23db7bbd6fd376/capture-provenance.json) · [Rendering/reproduction notes](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5dc2a1c5139f7772/rendering-notes.txt) · [Cleanup verification](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9b28c845041d76b1/cleanup-verified.json).

Recording frame samples: [R3 BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/790eaf50ce0b4490/R3-before-contact.png) · [R3 AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bd93e3b702144dbe/R3-after-contact.png) · [R4 BEFORE](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1190f5c337df4199/R4-before-contact.png) · [R4 AFTER](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/006a3be8b384fb08/R4-after-contact.png). Empty black grid cells are contact-sheet padding.

[write-gaps.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/59f7537395b5b954/write-gaps.py) generates this markdown fragment.

Useful diagnostic scripts are also uploaded: [inspect.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4c82f140dbee1b86/inspect.mjs) · [diagnose.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/80e479bc3bdeebbc/diagnose.mjs) · [reload-diagnostics.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/61ee657466bf975c/reload-diagnostics.mjs) · [raw-inspect.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f6fc7e1e8cb94d6b/raw-inspect.mjs).

For a fresh rebuild, install each frozen checkout, generate the workspace, launch each side with seeding disabled and its exact origin, wait for the dev-runner ports, then attach the IPv4 relay. Pass side, row, actual web port, client host and checkout to `run-capture.mjs`. `CAPTURE_PAIR_FROM_LOG=1` uses a fresh unused startup pairing credential; otherwise the driver mints a fresh one. Disposable local session files may be reused within that synthetic server only and are excluded from upload. The existing client router is used only to prepare the synthetic thread; all recorded document opening uses the real right-click menu. Each invocation writes a fresh timestamped directory. Build `accepted-runs.json` from accepted results, then run the packager and diff generator. Set `PLAYWRIGHT_MODULE` if its installed module location differs. Both capture worktrees and all captured servers/browser/Xvfb/relay processes have been removed or stopped; all capture ports are closed. Nothing was committed or posted to the PR.

FRICTION:
- runbook | Retry state collided with synthetic project IDs, and relay startup before port selection shifted the public launch. | Reuse the known synthetic project, generate unique thread IDs, and attach relays only after reading the actual dev-runner ports.
- infra | Heavy VM load and filesystem waits made startup slow; one client-readiness attempt timed out. | Reuse the disposable test session and use the existing client router for thread setup; keep preparation outside the recording window.
- other | The normal thread-details card was initially misidentified as a popover, causing an unnecessary dependency retake. | Check its DOM/source role before classifying it as stale UI.

All three requested evidence gaps are filled; no broader audit coverage is claimed.
