# PR watch runtime reproduction

Surface: built T3 Code server on Linux, loopback WebSocket RPC, fresh isolated SQLite state. No browser or mobile viewport applies. Terminal recording uses 116 columns x 34 rows, dark theme, rendered at 1600 x 900. Videos compress waits 10x and hold each output frame for at least one second for readability; the `.cast` files retain original event times.

The fixture serves synthetic GitHub API responses over the production GitHub client's supported `gh` Unix socket transport. No GitHub workflow was actually rerun. The server, GitHub adapter, check aggregation, watch reactor, persisted notification and free replay agent are real. Watch sweeps keep their production two-minute interval. No production module was patched and no test runner is involved.

Build each worktree with `vp i` then `vp run --filter t3 build:bundle`.

Place the fixture and driver together in a scratch folder. Start `node fixture.mjs <scratch-folder>`. In a private GH_CONFIG_DIR, write config.yml with `http_unix_socket: <scratch-folder>/api.sock`. Start each worktree's built server with T3CODE_DEV_SEED=0, GH_TOKEN set to a synthetic placeholder and GH_CONFIG_DIR pointing to that private config. Use ports 18320 (base) and 18319 (head), an empty --base-dir under each worktree's gitignored .t3, --host 127.0.0.1 and --no-browser. Redirect startup output to server-base-final.log or server-head-final.log in the scratch folder. Copy the corresponding startup log to pair-base-final.log or pair-head-final.log; the driver reads its one-time pairing credential locally and never includes it in the recording. Set EVIDENCE_DB to the corresponding fresh server database, then run `node drive.mjs base` in the base worktree, then `node drive.mjs head` in the head worktree. Each driver creates a timestamped output directory. Run each side sequentially because the external fixture stage is shared.

The driver selects the server's automatically bootstrapped project, configures the free replay agent, creates a thread and watches a synthetic GitHub pull request. Run 100 fails, the first normal watch sweep delivers a failure notification, and the replay turn ends. The fixture then returns failed run 200 on the same head with the same job name. Its start and finish occur between watch reads. The driver waits 150 seconds, reads the persisted thread projection and reads the synthetic database read-only using sqlite3 to print persisted notifications mentioning run 200. The full-thread projection omits delivered internal user notifications after completion, so it is not used to count those notifications. The driver also prints the actual agent turn count and terminal statuses.

The driver then unwatches the PR and requests two fresh details: a failed push lint run beside a running pull_request lint run, then the same failed push run beside a successful pull_request run. It prints each aggregated check's status, URL and required flag.

Only terminal.txt, terminal.cast, checks.json, videos and these scripts are public evidence. Startup logs, cookies, ticket material and full projections remain private and must never be uploaded. Replay assistant prose is not proof of a code change or test run; only the server's recorded watch notifications and check responses are inspected.

AI-assisted; verified with the tools listed above.

The rerun fixture advances its status fingerprint so the normal sweep rereads details. An unchanged GitHub aggregate fingerprint was not exercised. Mixed-event evidence is from the server detail RPC; a separate mixed-event watch wake was not recorded. The exploratory archive contains failed setup attempts and superseded observer output; the before/after files are the final proof.
