# Reproduction — evidence round 1

Real app revisions: before 85bd3f2a2a0ad4a8ddf2950e01db80765e9a1bf4; after 0277fd6975bcf7b79b12833bee93ed714844b319. No application source was changed. Only synthetic fixture data was used. No live database was read or copied.

Download the scripts into /tmp/lead-28065-r1/capture. The scripts deliberately use that fixed scratch root. Start fixture.mjs with Node; it prints its PID and creates a timestamped fixture directory. It copies the checkout's ProviderInstanceRegistryLive.fixture.mjs, then changes its email, plan and usage response. The hub speaks the real CLIProxyAPI management protocol. Reset timestamp is fixed at 2026-11-03T03:00:00Z + 2h/session or +4d/weekly; remaining usage is 60%/75%.

Create two new home directories under scratch. Start each checkout with T3CODE_DEV_SEED=0 vp run dev --home-dir <new-home>; read its actual backend/web ports from the dev-runner line. Pair the browser with that server's own startup pairing URL. Never upload the pairing URL. Run seed.mjs <checkout> <new-home> <backend-port> disable, then plan, then thread, then codex. The seed driver issues its own local auth session and makes real typed RPC calls. Each invocation writes to a new timestamped output directory. No provider turn is started.

MIX is the fixture's default mode: default Claude/a@example.com, Work/beta@work.test with a purple accent, hub-only c@example.net. A01/A03/A06/A09 use MIX. Create the literal scratch file hub-full to enable the full popup fixture, then call seed.mjs ... refresh on both servers. Full mode adds claude-b@example.com.json, team-seat.json, UPPER.JSON, and two Codex auth files with the same synthetic email and distinct ChatGPT workspace ids wa/wb. Remove only that literal hub-full file and refresh both servers to return to MIX.

Web: T3 preview browser, no device emulation. Resize CSS viewport to 1440×1000 or 390×844. Set light/dark with preview_set_appearance. Freeze Date before opening Usage or the slash command, using a Date subclass whose no-argument constructor and Date.now both return 1793674800000. Await document.fonts.ready and network idle. Hover off the popup, wait for scrollbar/tooltip fade, then capture twice 500 ms apart and compare RGB pixels. Retake unless identical.

A01/A03: click Usage in the sidebar, then Limits. The measured pool width is 742 px at 1440 and 316 px at 390; the latter uses a numbered compact legend. A06: record; open the default merged account's Session segment; reveal its email; dismiss; open Work; reveal its email; dismiss; stop. See the uploaded precise timeline JSON. Equal resets intentionally make the changed name affect alphabetical ordering.

For B02/B01/B07 use the real Synthetic usage evidence thread; collapse the main sidebar and details panel. web-driver.mjs exports popupCapture(tools, tabId, outputDirectory, side, options), to run with the T3 tool object. It opens /usage-limits through the composer, reveals email labels through actual button clicks, captures the top, scrolls the real popup container to the bottom, captures, closes, and saves the recording. Use width=390,height=844 for phone. For B06 navigate to Synthetic workspace evidence, use title='Synthetic workspace evidence', stem='B06-W-dark'. The popup filters to the selected provider, so Claude and Codex are captured in separate real threads. Both Codex rows are retained, as the seed gives them different workspace ids.

Native: prepare/install only with vp run mobile:install. install-pinned-package.json is the small vp wrapper used to run the pinned checkout's installer while retaining the root workspace that owned the agent-device lease. Connect each session through SIMLOCK_AGENT_DEVICE_URL, lease the named device, and pass that same session to every command. Start each checkout's Metro with vp run dev:client --port <port> in apps/mobile. clock-proxy.mjs <public-port> <metro-port> prepends only the fixed Date constructor/Date.now instrumentation to bundle responses; it forwards unchanged app code, and forwards Metro websocket traffic. Use a fresh public port on both sides to avoid cached bundles from earlier instrumentation. mobile-proxy.mjs forwards the after backend from its loopback listener to the device-facing port. Pair with test-t3-mobile/scripts/pair-client.sh, using the server's own credential and the VM's Tailscale IP. No native UI fixture mode was used.

A09 native: select Usage → Limits with MIX, standard OS text size large, dark. a09-final.mjs records the phone switching procedure; failed earlier attempts are uploaded for transparency and are not accepted captures. The final evidence index states any remaining comparison limitation. Android captures use normalize-status-bar; iOS raw frames avoid the tool's animated charged-battery override.

Native B02: iPad 13-inch, maximize the thread content, use the same synthetic thread and full fixture. native-popup-driver.mjs records command entry, hides the keyboard, reveals labels, scrolls to the email row, scrolls to the final row, returns and closes. Its timeline JSON gives actual step offsets. An image called middle is a recording keyframe companion; consult its pixel-stability qualification in the index.

Diffs: diffs.py computes absolute RGB differences without alignment, crops or masks. Diff0 multiplies each channel by 255 and clips; any nonzero level is visible. DiffT8 is white where the maximum RGB channel delta exceeds 8/255. Comparison sheets scale whole surfaces only; raw PNGs retain the capture tool's output size.

Cleanup: stop only tracked PIDs; close device sessions; remove the detached before checkout. Leave uploaded scratch scripts for the lead/auditor. Logs containing pairing credentials are deliberately not uploaded.
