# Second capture driver

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

Before checkout: ca796d52119592de771d8ccfa955d70dba84d11e; after checkout: eb39186ba693087529323f5e4da65018d8377ad5. Native fingerprint 5fa891c99bf29870cc7d56112e3458d95a948393.

1. Start each server with `T3CODE_DEV_SEED=0 vp run dev --host 0.0.0.0 --no-auto-bootstrap-project-from-cwd --home-dir <fresh-home>`. Before server port 15228, after 14456. Start each `vp run dev:client --port 18081` / `18082` in apps/mobile, with `REACT_NATIVE_PACKAGER_HOSTNAME=fs-86.tail131df4.ts.net` and `CI=1`.
2. Issue a bearer session with the server CLI `auth session issue --base-dir <home> --token-only --ttl 2h`, saving it locally only as before-token.private / after-token.private.
3. Create a project through `projects.mutate`: `{type:"project.create",commandId:<unique>,projectId:"capture2-project",title:"Capture Fixture",workspaceRoot:"/tmp/lead-32936-r1/capture2"}`. The captured seed-rpc.mjs leaves this precondition separate because the project already existed when its successful resumed run started. Run `node seed-rpc.mjs before` and `after`; all content is generated through the public RPC and free Replay (dev). No database writes outside the server and no live userdata.
4. Run `node sidebar-rpc.mjs before` / `after`. This exposes 20 completed Done threads (unsettled for visibility, no active replay), archives the two auxiliary roots, and keeps the list controlled for S1. Launch both devices fresh, at list top.
5. Lease matching iPad (7th generation), iOS 18, landscape-right/light, and iPhone Xs, iOS 18 portrait/light via device-pool. Install with `vp run mobile:install ios --session <session>`. Launch the matching Metro with Expo disableOnboarding, disableAutoLaunch, disableFab, and pair using test-t3-mobile/scripts/pair-client.sh. Proxy ports 17057/17058 forward each backend with single origin.
6. Capture S1 with capture.py. For inspector F2, unarchive/unsettle parent, navigate to `t3code-dev://threads/<environment-id>/capture2-parent`, scroll parent to its first Worked block, expand the block, and tap the actual child card from the AX snapshot. Open in right inspector, scroll child to top of its loaded page (row04). Never focus composer. Capture stable F2 frames, then record history control interaction.
7. For I3, navigate phone to capture2-short. Run `node send-rpc.mjs <side>`; it awaits the persisted terminal run update/snapshot through subscribeThread. Never focus composer. Capture resting completed turn with keyboard absent.
8. Search: iPad landscape/dark; restart at root; focus Search, `fill 140 90 "Capture thread"`, then `keyboard enter`. Capture S5. Fill entire field with `no-match-capture-omega`, then `keyboard enter`, capture S6b. Enter removes both keyboard and iPad input accessory while retaining active Search/Cancel state.
9. capture.py requires two whole-screen captures at least 500ms apart, pixel-identical after masking only the clock. verify-stills.py verifies the chosen pairs. make-diffs.py compares complete final frames with binary magenta changed pixels at fuzz0% and5%; no crop or clock exclusion. F2 model label lines are grey redacted on both sides before diff; video-process.py applies grey boxes throughout each video.

Agent sessions: capture2-ipad18, capture2-after-ipad18, capture2-phone18, capture2-after-phone18. Every device command uses its explicit session. `action.py` saves UTC action timestamps. The cached-health shim handles the CLI three-second gateway health limit; all actual device RPCs remain live. Credentials and raw diagnostics are never public uploads.
