# Capture protocol and limits

Synthetic data only. Before: eff45664fae739f0efadaee13acc145ddf0d0b66; after: 404a277da1197925e37ecb7546750e3a5a8be1c2. No commits, pushes, PR edits, or live-database seeding.

## Rebuild

Start isolated `T3CODE_DEV_SEED=0 vp run dev --host 0.0.0.0` in each checkout. Read its actual ports and adjust `rpc-driver.mjs`. Put the supplied MCP server and wrapper in your scratch path, update their absolute paths, and set `CAPTURE_MODEL` to your configured least-cost Codex model. Run the driver's `seed`, `retry`, `single`, and `visibility` actions on each side. `seed` configures only that isolated server's provider binary and creates the synthetic project. Initial seed attempts sometimes produced narration without calls; the final captures use `capture2-error`, `capture2-mixed`, `capture2-disclosure`, `capture-single-empty`, and `capture-visibility`.

The RPC driver issues a temporary credential against its isolated server. Never publish its config, pairing output, or raw provider logs. The unused `results` action is retained as an attempted minimal fixture, not a captured state.

## Web driver

The actual browser was T3 Code's preview tools, not the downloaded earlier-round CDP driver. Set viewport 1440x1000 and dark appearance. Use the preview tab navigation to each environment/thread URL. Hide the main sidebar through `[data-sidebar-control] button` and close the details panel if its aria-pressed is true. Click `button:has-text('Worked for')`, then `button[aria-label^='Used repro integration']` if present, then `[data-v2-item-type='dynamic_tool'][role='button']`. Failed rows carry an accessible failure suffix. Scroll `.messages-timeline-scroll` to 0 for comparisons. Single empty results have a direct tool row, with no nested integration group.

Before each published still, blur the focused element, await `document.fonts.ready`, wait 600ms, take two preview snapshots with 500ms between calls, and compare PNG bytes. Retry until identical. The public originals preserve the full surface and mask the bottom 64 CSS pixels to hide the private composer model label. Diff0 marks any changed RGB channel; DiffT marks a channel difference greater than 3/255. All changed pixels are amplified to magenta on black.

P16: navigate to Settings > Chat > Tool calls in chat; click its real combobox and select Show all, Hide successful, Hide all, Zen, Show all. Return to the populated visibility thread after each selection and expand the fold/group when present. Two app iframes remained mounted through every mode. The completed row disappeared in Hide successful; its failed sibling remained. Both rows disappeared in Hide all and Zen. Restoring Show all restored both rows. The before clip records the default thread once, not the full mode cycle.

P15: reload the persisted single-empty thread, expand its fold/row, and count one dynamic-tool row and one iframe after. Before has no tool row and one iframe. The clips include tool delays and unedited idle intervals.

## Native

Leases used agent-device 0.21.32 through Simlock. Matching clients came only from `vp run mobile:install`. Native fingerprints were identical between the assigned SHAs; Metro supplied each checkout's JavaScript. Android: Pixel 9 1080x2424, about 411x923dp, DPR2.625. iOS: iPhone 17 Pro 402x874pt, DPR3 (video1206x2622; screenshots logical1x). OS text-size category was Large/default; app font scale was not overridden. No rotation or font-size changes were used in the accepted captures. Stills normalize the status bar where supported; recordings retain live OS time.

`record-native.py` and the action JSON files are the actual native driver. Edge pans at x8 move the outer feed; central pans move the bounded output. P09's TSV reopen failed because two rows shared an accessible label. Do not count it as a successful reversal. P09's JSON supplement opens the second row and shows its closing braces and retained app table. P10's second clip supplies the final TSV rows and row collapse/reopen. A complete matching native before sequence was not captured.

P15 iOS: the relaunch command returned a proxy error, so cold relaunch is unverified. The recording starts at the thread list; opening the persisted single-empty thread and expanding it shows one row and its retained blank app. It is after-only and is not the matrix's requested Android comparison. The Android relaunch retry produced a foldable-sized surface after a failed explicit lease; that recording was excluded.

## Inspector harness

`harness-server.mjs` plus `harness/index.html` and `harness/main.tsx` mount the actual V2ItemInspector with a controlled detail source. Loading uses Effect.never, error uses Effect.fail, success returns a synthetic app-bearing item. The published loading/error stills are after-only, clearly labelled, and make no app-card lifecycle, network, provider or guest-route claim. Recording stop timed out and the successful-resolution frame was not accepted. No P13 completion claim follows from these stills.

## Capture conditions not fully met

The preview API did not expose reduced-motion or frozen-clock emulation. No frozen-clock claim is made. Persisted timestamps were stable; native status bars were normalized for stills where supported. Still pixel equality verifies stable rendering, not network-idle instrumentation. Provider elapsed labels and brief narration vary between independently seeded sides. Native before attempts failed through pool/proxy errors and lease expiry. P17 was not attempted because it requires a running T3 Connect guest share, absent from these isolated servers. No tunnel or live user environment was changed.

AI-assisted; verified with the tests and tools listed above.
