# Mobile loading evidence driver

Both sides ran on the same pooled Pixel 9, Android API 36, dark appearance, with a cleared app installation and each commit's own Metro bundle and fresh server databases. The cached native client was installed separately for each side. The two commits have the same native fingerprint.

Copy the three TypeScript helpers into scripts/scenarios of the checkout being captured. Install dependencies with vp i. Start manual-start.ts with arguments `mobile <disposable-home> 14990 8290 <device-reachable-host>`, and manual-proxy.ts in another terminal. Set T3CODE_DEV_SEED=0. Both backend servers bind loopback, preventing learned direct routes from bypassing the proxy; Metro remains device-accessible. No live database is copied.

Run seed.sh with the disposable home, a synthetic project directory, the device-reachable host, and a private pairing-output filename. Install with `vp run mobile:install android --prepare`, then `vp run mobile:install android --session <leased-session>`. Clear the app state, launch the development client against Metro on port 8290 with development chrome disabled, and wait for Add environment.

Run manual-driver.py with --checkout, --home, --out, --pair, --session, --host, and --project. Every output directory must be new. The driver holds real HTTP shell responses, cuts only environment reachability while the device remains online, restarts the app, restores reachability before releasing the snapshot, verifies restored rows, restarts while unreachable with cached rows, removes the first project, and pairs a second seeded environment while the first is known empty. Both remain enabled. No UI state is mocked or substituted.

Device-tool failures interrupted the recordings. Base resumed after restoration (`--resume`) and then from cached rows with manual-continue.py. Head resumed from the uncached retry step (`--from-stage 2`) after one failed relaunch. The default device wait was extended to 120 seconds after cached startup exceeded its default. These were tool recovery steps; the synthetic state and reproduction stages stayed the same.

Published stills have the Android status bar cropped identically. The two-environment settings images show both enable switches, with private address lines redacted. Video clips exclude pairing setup and have a two-second final-frame hold. The head single-environment recording is split into initial-shell and restart/retry/restoration clips because of the interrupted relaunch. Static cached-row captures are identical across a 500 ms interval; loading spinners are intentionally animated and are also shown in the recordings.

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