# Proof audit, pass 1

Read-only evidence audit of [#32921](https://git.cafe/pingdotgg/t3code/pull/32921) ([GitHub mirror #32921](https://github.com/pingdotgg/t3code/pull/32921)). Requested revision: [2a94fbea6c](https://github.com/pingdotgg/t3code/commit/2a94fbea6cb67eec572e8f1e9642b982d7e3db63), branch `fix/issue-32898`, against supplied merge-base [bcee0f5d28](https://github.com/pingdotgg/t3code/commit/bcee0f5d2872ba193c66ed9ba979bbe424f89ff9). The supplied diff exactly matches the checkout's base-to-head diff (SHA-256 `c5cbeab76c96df037927d6dbfae99cb0db08a0cf267d7e5e4225d2603cf8cd9e`).

## Findings

1. **Navigation proof exists; rendered-file proof is missing.** The PR body supplies inline before/after `navStatus` transcripts for HTTP workspace HTML and a localhost control. It supplies no linked screenshot, video, raw driver, or raw runtime log. `Success` plus a title proves navigation committed, not that HTML dependencies or the streamed client canvas rendered. Record the actual client showing the file and retained public address. The before transcript demonstrates `ERR_NAME_NOT_RESOLVED`, not the originally reported `ERR_CONNECTION_REFUSED`; this is a reasonable unreachable-origin stand-in, but label it accurately.
2. **PDF success is specifically weaker than rendered-PDF proof.** Without a native server PDF viewer, the handler fulfills a small HTML placeholder with the PDF filename as its title. The web client separately overlays `<embed type="application/pdf">` after `Success`. The body’s `guide.pdf` success therefore proves neither PDF bytes nor visible PDF pages in that embed. R4 needs a real client recording showing recognizable PDF content. A server screenshot of the placeholder is insufficient.
3. **The viewer limitation is not an unconditional localhost restriction.** The stream calls the normal media WebSocket authentication. Browser cookie auth accepts a trusted dev origin, same-origin Fetch metadata, or matching `Host`/`X-Forwarded-Host`. Vite preserves the host on `/ws` but changes it on `/api`, which includes `/api/preview-stream/ws`. On an insecure custom hostname the browser may omit Fetch metadata, leaving the original `Origin` mismatched with Vite’s rewritten backend host. Configure `T3CODE_DEV_ALLOWED_ORIGINS` with the exact client origin (scheme and port), or use `--dev-url` for that origin. No product-code change is required to permit that dev capture. This diagnosis/workaround is source-derived; it was not executed in this pass, and the PR supplies no raw refusal diagnostic to identify which check actually failed.
4. **Important branches have no supplied evidence.** HTTPS through the actual app; rendered HTML dependencies and PDF pages; successful interception with a native server PDF viewer; IPv6/non-IP listeners; desktop exclusion; expiry boundaries; PDF failure/pass-through states; and navigation/reload/history all lack complete row evidence. Mocked CDP continuation assertions are appropriate proof for routing and guard rows, but cannot substitute for rendered-file evidence.
5. **Provenance is historical.** GitCafe currently reports head [ae4904d43c](https://github.com/pingdotgg/t3code/commit/ae4904d43c7ea0d75e8c68ebfd3e1132e208e155), which is also the body’s after-transcript revision; the requested local head is the later merge revision above. `AssetAccess.ts`, its test, `PdfDocumentNavigation.ts`, and its test are identical between those revisions. `ServerBrowser.ts` has upstream desktop-related changes, and its test file also changed. Credit historical coverage explicitly; do not claim a runtime run at the requested head. The body reports 99/99 tests and `check:changed`; this audit inspected the cases, but did not rerun them or infer new current-head test results.

## Changed paths and fixture reduction

There are **no changed React components, styles, props, or wire schemas**. Counts, long text, empty lists, app theme, mobile width, and OS-specific UI layout add no new branch in this diff. One desktop web viewport and one theme suffice for visual proof; no light/dark or responsive screenshot Cartesian product is warranted.

- [AssetAccess.ts](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/assets/AssetAccess.ts#L878): `verifyAssetToken` is shared by `resolveAsset` (the GET asset HTTP route) and new `rebaseSignedAssetUrl` (only production caller: `ServerBrowser`’s redirect callback). Branches: parseable absolute HTTP(S); exact `/api/assets/` prefix; token/file separator; payload/signature present; signer verification success/failure; decodable claim; expiry strictly greater than now; preserve path/query/hash; identical URL becomes no CDP override. Valid claim kinds are workspace directory, exact workspace/media file, attachment, project/external favicon, native app icon, tool-output image, and source-control media. Verification treats them uniformly; representative directory HTML, exact PDF, and image-token fixtures cover transport shapes. Existing resource-resolution cases need no new per-kind screenshots.
- [ServerBrowser.ts](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/preview/ServerBrowser.ts#L489): choose null for non-IP/no-port listener, loopback for wildcard, formatted literal for specific address; install redirect only for non-desktop pages. `createTab` handles new context, pooled/profile context, adopted popup, and Electron-attached page. Its direct caller is `ensureTab`, reached through `openTab`, `findTab`, manager opened events, and desktop attachment recovery. User `preview.open`, agent broker operations, lazy viewer attachment/restoration converge here. An installed handler persists for navigate/reload/back/forward. A popup’s first request precedes installation; PDF initial navigation is explicitly retried, ordinary adopted HTML is not. Do not claim this fixes every initial popup navigation.
- [PdfDocumentNavigation.ts](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/preview/PdfDocumentNavigation.ts#L16): the sole production installer call is `createTab`; direct calls elsewhere are tests. Four installer combinations: native PDF on/off × redirect present/null. Native+null returns without Fetch; native+redirect installs Request only; shell+null installs Document Response only; shell+redirect installs both in one `Fetch.enable`. Request stage redirects all matching methods/resource types, not just main-document GET. Response stage requires GET, main frame, PDF pathname; missing status/response error or 3xx continues; non-2xx or wrong/missing MIME fails; 2xx `application/pdf` fulfills escaped-filename placeholder; rejection attempts to continue and suppresses final failure if the session closed.
- Relevant unchanged render consumers: [PreviewView](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/web/src/components/preview/PreviewView.tsx#L1003) chooses stream versus error/download overlay and passes a PDF URL only on Success; [ServerBrowserSurface](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/web/src/browser/ServerBrowserSurface.tsx#L772) overlays client PDF embed; [previewPdfAssetUrl](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/packages/shared/src/preview.ts#L9) selects client/environment asset origin. The panel and mini-player reuse that surface. A native desktop page bypasses the streamed surface. No provider adapter changed; no paid provider run is needed. Mobile has no changed render code and does not require a separate UI matrix for this server-only change.

## Fixture matrix

Status means evidence already in the PR body, not a new run by this auditor. **Covered** credits a specifically described transcript or test. **Missing** means the body does not supply the required proof; partial coverage is named. Every behavioral sequence is labelled **recording**: an ordered runtime/CDP transcript is sufficient where no pixels are required; a video is required for the listed rendered or interactive client claims. Harness rows must be labelled as harness evidence, never app captures.

Capture presets: **V** = real web client 1440×1000 CSS px, light theme, server tab fixed to approximately 960×640 with address toolbar visible; same settings before/after. **T** = runtime/harness transcript, viewport/theme N/A. V is a chosen reproducible preset, not a claimed responsive requirement.

| Row | Named fixture and data / affected branch | Seed or driver path | Minimum evidence; visual needed? | PR-body status |
|---|---|---|---|---|
| R1 | Client-only HTTP origin; signed workspace `report.html`, unique visible heading; before unreachable, after renders with original public URL | S1 + S2; actual file context menu → Open in integrated browser; server runtime | **recording**, V × light × before/after plus ordered `preview.open`/navStatus. **Yes**, file pixels and URL, not only title | **Missing rendered proof**. Historical before LoadFailed (-105), after Loading→Success and title covered |
| R2 | Localhost control and already-on-listen URL; same HTML | S2 from localhost; additionally open exact backend-listen signed URL | **recording**, T; unchanged continuation and successful content/nav transcript. No separate visual needed; may appear in R1 video | **Covered historically**: localhost success before/after; mocked already-listening no override |
| R3 | Client-only HTTPS origin; workspace HTML with sibling CSS, JS, image, and same-process iframe; query and anchor | S3 + S2; files with unmistakable style/image/script/iframe markers | **recording**, V × light × after, network trace and visible markers; before may share R1 unreachable result. **Yes** | **Missing app proof**. Only a described standalone HTTPS→HTTP shell probe; no linked probe log or actual-app recording |
| R4 | Shell PDF document succeeds while redirect active; `guide.pdf` with recognizable two-page content; client embed loads bytes | S2 with PDF, normal headless-shell server and headed Chromium client; change page/scroll | **recording**, V × light × after, retained public URL + readable PDF page and page/scroll interaction. **Yes**, client view; server placeholder cannot prove it | **Missing rendered PDF proof**. Historical Success/title and mocked placeholder fulfillment covered |
| R5 | Native PDF server viewer available + redirect present; valid signed remote HTML/PDF succeeds, Request pattern only | Native-viewer browser supplied through supported browser setup, or labelled CDP harness (`pdfViewerEnabled=true`) | **recording**, T for installation/continuation and bytes/network result; native PDF visual only if claiming it renders there | **Missing successful native-viewer proof**. Existing native=true case exercises redirect rejection only |
| R6 | Shell response matrix: main GET PDF 2xx correct MIME; 3xx; status absent/responseErrorReason; non-2xx; wrong/missing MIME; non-GET, subframe, non-PDF bypass; encoded/long filename | Labelled S4 CDP harness with redirect present and null; feed each response variant; use `A%20%3Cscript%3E.PDF` for escaping | **recording**, T; fulfill vs continue vs fail and requestId counts. No screenshot needed; pixels represented by R4 | **Missing complete branch proof**. Body covers successful fulfillment and escaping; does not cover bypass/error/status/MIME variants |
| R7 | IPv4 wildcard `0.0.0.0`→127.0.0.1 and specific `100.64.0.5`→itself | Existing `ServerBrowser.test.ts` table (mock HTTP address/CDP); real wildcard HTML may share R1 | **recording**, T, original snapshot URL and continued request target. No separate visual needed | **Covered by reported harness tests** for both addresses, own token and forged/listening controls |
| R8 | IPv6 wildcard `::`, specific `::1`/non-loopback v6, non-IP/no-port address | S4 injected HttpServer address harness; actual IPv6-only listener for reachability if available | **recording**, T; wildcard currently selects 127.0.0.1; specific v6 bracketed; no-IP redirect null. No screenshot needed | **Missing**. Neither body transcript nor named tests cover these branches; dual-stack reachability must not be assumed for IPv6-only binds |
| R9 | Desktop attached vs headless server; native PDF on/off × redirect null/present; desktop attach fallback | S4 installer and desktop-channel harness; optional real Electron flow, with same signed URL | **recording**, T; disabled redirect and one correct Fetch pattern set for all four combinations. No separate desktop screenshot needed | **Missing complete exclusion proof**. Body explicitly says desktop unchecked; shell+null/shell+redirect and native+redirect-error appear in tests, native+null early-return does not |
| R10 | Own valid token with query/hash; representative image token and workspace HTML token | Existing AssetAccess case + S2; `?v=1#page=2` | **recording**, T; preserved path/search/hash and original page URL. No screenshot needed | **Covered by reported tests** (image token rebase, HTML routing); historical runtime keeps public URL |
| R11 | No redirect for forged/unsigned/foreign-key/malformed token; bad URL/protocol/prefix; missing token/file slash | Existing AssetAccess/ServerBrowser cases plus S4 URL table; two isolated signers for foreign-server token | **recording**, T; unchanged URL/no override for each equivalence class. No screenshot needed | **Missing remaining guards**. Forged, unsigned, FTP are covered; foreign key, malformed URL/payload/claim/empty segments and non-asset prefix are not specifically evidenced |
| R12 | Own token before expiry, exactly at expiry, after expiry; signer verification/key failure | S4 real signer + injected TestClock and scoped signer failure; advance clock without wall-clock sleeps | **recording**, T; valid→unchanged boundary and existing HTTP resolution rejection. No screenshot needed | **Missing expiry/key-failure proof**. Body claims unexpired-only; no described rebase expiry case. Generic throwing redirect is not this verification branch |
| R13 | Redirect callback rejects; placeholder fulfillment rejects/closed session | Existing PdfDocumentNavigation tests; S4 terminal-CDP-call counts if asserting exactly once | **recording**, T; continues original request/no hang, with counts. No screenshot needed | **Covered for fallback selection by reported tests**. “Exactly once” is not fully established: tests resolve the first terminal command, with no count assertion |
| R14 | Navigate existing tab, ordinary reload/hard reload, Back/Forward HTML↔PDF; loading settles and address remains public | S2 + viewer toolbar or broker navigate; use R1 report, second report, R4 PDF | **recording**, V × light × after; include URL changes and rendered destinations. **Yes** for interaction claim | **Missing**. Body claims preserved history/client loading but supplies initial-open transcripts only |
| R15 | Fresh/default profile and existing profile/pooled context; manager open, agent open/navigate, lazy reattachment | S2 `preview.open` with omitted vs selected profileId; S4 manager/broker/findTab driver | **recording**, T; installer before first tracked navigation on each creation path, successful load after attach. No duplicate pixels needed | **Missing caller-path proof** beyond normal user open. These are transport-equivalent, so one labelled event trace can cover all |
| R16 | Adopted popup: initial HTML request vs later navigation; initial PDF reload after adoption | S2 HTML button `window.open(publicSignedUrl)` and subsequent navigation; repeat PDF | **recording**, V × light × after or labelled S4 trace for installation order. Visual only for a claimed rendered-popup result | **Missing**. First ordinary popup request precedes Fetch installation; no evidence in body. Record limitation instead of assuming initial popup is fixed |
| R17 | External Open in browser and tab move retain public URL; ordinary external non-asset page remains unchanged | S2 browser toolbar action; move tab using app; S4 routing trace can prove unchanged outgoing URL without launching external browser | **recording**, T (V if demonstrating UI interaction); no new destination screenshot required | **Missing explicit regression evidence**. Body states unchanged; no action transcript/capture supplied |
| R18 | Missing/deleted signed HTML/PDF; downloadable asset; signed subresource in out-of-process iframe | S2 delete file after issuing token; exact download grant; external iframe harness containing signed child request | **recording**, T for request/response/error/download and child-target routing; V only if claiming an overlay or child rendering. No extra theme/width | **Missing**. Main-title success does not prove these. Fetch is installed on page CDP; separate frame CDP sessions shown in code install copy recording only, so do not infer OOPIF interception |

The minimum **visual** set is four segments, which can be combined into two videos: (1) R1 before; (2) R1 after including R2 control and R14 history/reload; (3) R3 HTTPS with dependencies; (4) R4 recognizable PDF with page/scroll interaction. All use V × light. R16 needs added video only if claiming initial popup rendering; otherwise a labelled order trace records its scope. Remaining rows use focused ordered runtime/harness transcripts. No repeated dark/mobile screenshots are requested. The full branch table includes regression guards, not a requirement to repeat the same proof at every caller or render wrapper.

## Concrete seeding and capture routes

**S1 — isolated app on Linux.** Create each run under `/tmp/lead-32921-r1/proof-audit-1/<UTC timestamp>/`; keep profiles, workspaces, server home, driver, raw logs and videos there. Reuse a healthy isolated server only if it has the intended revision and home; otherwise start `T3CODE_DEV_SEED=0 vp run dev --home-dir <run>/home` from the requested checkout. Capture its spawned PID and stdout; read actual backend/web ports from `[dev-runner]`, not guessed constants. Do not use the live T3 home. Create a project rooted in `<run>/workspace` and a thread through the real app. No paid agent turn is needed; create a markdown file link through an app/RPC fixture if needed, or use S2 directly. If injecting a chat link is impractical, label RPC-driven seeding in the capture, rather than claiming a context-menu interaction happened.

**S2 — real asset/preview RPC path.** Write `report.html`, its dependency files, `second.html`, and a real `guide.pdf` in that workspace. In the authenticated client use the normal file explorer/file-preview browser action or the chat link context menu. Equivalent typed RPC inputs are `assets.createUrl({resource:{_tag:"workspace-file",threadId,path:"report.html"}})` then `preview.open({threadId,runtime:"server",url:new URL(relativeUrl,clientOrigin).href,viewport:{_tag:"freeform",width:960,height:640}})`. For exact outside-workspace file grants use the existing `media-file` resource; for attachments use existing upload then `attachment` asset resource. Subscribe to preview events and preserve Loading/Success/LoadFailed snapshots. Use the app’s typed RPC client/framing, not an invented JSON transport. Navigate to the app’s actual thread route after UI-created project/thread selection; do not invent a route ID. Existing tab actions and stream messages (`navigate`, `reload`, `history`) seed R14. Signatures and pairing tokens remain private; redact them in public logs and address bars without hiding hostname, file name or outcome.

**Client-only hostname, without changing server DNS.** Launch a separate **headed full Chromium** under Xvfb (`DISPLAY=:<unused display>`, screen 1440×1000×24), with a fresh profile under the timestamped run directory. In Playwright use the full installed Chromium executable with `headless:false`, viewport 1440×1000, `colorScheme:"light"`, video output under that run, and launch args `--host-resolver-rules=MAP repro-box.tailnet-repro.ts.net 127.0.0.1, EXCLUDE localhost` and `--no-proxy-server`. The client opens `http://repro-box.tailnet-repro.ts.net:<actual-web-port>`. This is a non-loopback **origin hostname**, mapped to a loopback socket only inside that client browser; do not edit global `/etc/hosts` and do not pass that flag to the server’s headless-shell process. Confirm the server process cannot resolve the chosen name (Node `dns.lookup` or `getent`), and log the client’s successful HTTP response. Use an unregistered throwaway hostname and `T3CODE_DEV_ALLOWED_HOSTS=<hostname>` if the selected `.ts.net` name unexpectedly resolves publicly. T3’s Vite config already allows `.ts.net` hostnames. Xvfb is available on this VM; a full Chromium executable must be located/provisioned by the capture run (the bare `chromium` command was not on PATH in this audit). Playwright is a capture recipe here, not an automation run performed in this pass.

**Permit the preview stream.** After reading the actual port, start/restart the isolated dev runner with `T3CODE_DEV_ALLOWED_ORIGINS=http://repro-box.tailnet-repro.ts.net:<actual-web-port>` (comma-separated values supported). Alternatively set `--dev-url http://repro-box.tailnet-repro.ts.net:<actual-web-port>`; that feeds `config.devUrl`, also a trusted origin. Retain any discovery-run logs and stop only the PID captured at spawn. Pair on that origin with a fresh credential; localhost cookies do not authenticate a distinct hostname. Keep `VITE_HTTP_URL` and `VITE_WS_URL` unset: the app/stream must stay single-origin. Verify the stream WebSocket opens and emits image frames before recording. The explicit allowed origin affects auth/CORS, not OS DNS, so the server browser still cannot resolve the hostname and the reproduction remains valid.

Source basis: [Vite allowed hosts and proxy](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/web/vite.config.ts#L248), [proxy prefix preservation](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/packages/shared/src/devProxy.ts#L5), [origin policy](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/auth/EnvironmentAuth.ts#L693), [dev origins config](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/cli/config.ts#L141), [media auth](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/auth/http.ts#L160), [stream handler](https://github.com/pingdotgg/t3code/blob/2a94fbea6cb67eec572e8f1e9642b982d7e3db63/apps/server/src/preview/ServerBrowserStream.ts#L77). There is no localhost-only check in that handler. A media-audience `wsTicket` is another existing auth path; a fresh cookie with configured dev origin is simpler for app captures.

**S3 — HTTPS through the actual app.** Put a timestamped loopback TLS reverse proxy in front of the same Vite origin, forwarding ordinary HTTP and both `/ws` and `/api/preview-stream/ws` upgrades. Keep the original host/forwarded host, register the exact HTTPS origin in `T3CODE_DEV_ALLOWED_ORIGINS`, map its hostname only in the capture browser, and trust the local test certificate in that browser (or use a clearly labelled test-only browser certificate bypass). Configure the proxy for that hostname; do not point Chromium’s HTTPS URL at a plain HTTP listener. Keep key, certificate, proxy logs and PID under the run directory and out of uploads. This exercises HTTPS public URL→HTTP backend-listen rebase inside T3, unlike a standalone shell probe. No actual Tailscale Serve setup is required to prove this routing condition; the body honestly labels that hop untested.

**S4 — labelled harness, not screenshots of the app.** Unsupported/no-port HttpServer addresses, exact expiry boundaries, signer exceptions, native-viewer capability combinations, and synthetic CDP response statuses should be driven at the lowest relevant layer using the existing AssetAccess/PdfDocumentNavigation/ServerBrowser fixtures. Store any new audit driver outside the worktree and set all fixture temp roots to the timestamped scratch directory. Capture event order and terminal request commands. Use controlled clock advancement for expiry; do not wait an hour. A driver can mock `Runtime.evaluate` and inject `Fetch.requestPaused`, but must label those outputs “CDP harness”; it cannot prove real browser rendering. An actual native-viewer browser run is needed only for a claim about native PDF pixels. An actual IPv6-only listener is needed to establish that listener’s reachability, beyond URL formatting.

## Scope and handback

This pass wrote only audit scratch files and uploaded this matrix. No repository edits, comments, pushes, browser tabs, servers, proxies or Xvfb processes were started. No evidence/raw logs were deleted. Runtime captures and new tests are requests for the subsequent proof pass, not work claimed here.

FRICTION:
brief | PR metadata and inline runtime proof identify the older source revision while the requested checkout is a later merge revision | include current-head runtime proof or explicitly mark prior proof as historical
runbook | PR body treats the dev stream-origin refusal as preventing rendered evidence; source exposes an explicit dev-origin allowlist | include exact-origin auth/proxy setup in the capture recipe and preserve the refusal diagnostic

VERDICT: INSUFFICIENT R1 rendered HTML, R3 HTTPS/dependencies, R4 rendered PDF, R5-R6 native/PDF branches, R8-R9 listener/exclusion branches, R11-R12 remaining guards/expiry, R14-R18 interactions/caller/error paths
