# PR polling runtime reproduction

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

This is a manual server comparison, not a unit test or a browser scenario. Each unchanged app commit runs against its own fresh database and a local HTTPS GitHub Enterprise API fixture. The fixture controls not-found, successful recovery, and stack failures. All waits use the real clock. No production account or external forge is changed, and no model is run.

The live output recording is `before-recording.cast` / `after-recording.cast` (asciicast v2). The MP4 files are 30x transcript playbacks generated from the same timestamped events; the PNGs are transcript frames, not browser screenshots. Raw captured events, filtered server spans retaining original span IDs/parentage, and read-only projection snapshots are included. Span attributes and exception stacks were omitted to remove local paths.

## Re-run

Create and install two fresh checkouts at the commits stated in the evidence. Put these scripts together in an otherwise empty scratch directory. The app checkouts must have no `.t3` state. Run `python3 prepare.py BASE_CHECKOUT HEAD_CHECKOUT`. Generate `key.pem` and `cert.pem` beside `fixture.cjs` with `openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 1 -subj /CN=github.127.0.0.1.nip.io -addext 'subjectAltName=DNS:github.127.0.0.1.nip.io'`. Create `run-0748` beside the scripts. Start `node fixture.cjs`.

From each app checkout, start `T3CODE_DEV_SEED=0 NODE_EXTRA_CA_CERTS=CERTIFICATE_PATH node apps/server/src/bin.ts --no-browser --host 127.0.0.1 --port PORT --base-dir .t3`, using ports 19221 for base and 19222 for head. Keep server stdout private because startup prints pairing tokens. Wait for Listening. In each checkout run `node apps/server/src/bin.ts auth session issue --base-dir .t3 --token-only` and redirect its output to `run-0748/before-token` or `run-0748/after-token`. Never upload these files.

Run `node driver.cjs before BASE_CHECKOUT` and `node driver.cjs after HEAD_CHECKOUT` concurrently. Each takes about 23 minutes. Stop only the fixture and server processes you started afterwards.

The synthetic PR roles are: 1 missing then recovered on the active thread, 2 found sibling on that thread, 4 missing on a settled thread with found sibling 5, and 7 a successful snapshot followed by a failed periodic stack read and settlement. The driver changes PR 1 visibility after observing the fifteen-minute retry, explicitly refreshes it, then waits another 140 seconds for automatic polling. PR 4 also becomes visible at the fixture, but remains settled and is not explicitly refreshed.

No application source, timer, read cache, cadence constant or persistence code is patched. A scenario was not used because the repository scenario guidance excludes timing evidence.

## Captured-run infrastructure interruption

The fixture process terminated unexpectedly with exit code 143 after the head fifteen-minute retry had been captured and before the first recovery refresh. Both app servers continued running with their original state. Each first recovery refresh reached its server but failed to reach the fixture, so the driver recorded `No summary for 1`. No successful recovery is claimed for those attempts.

The fixture was restarted with its state and recordings preserved. `recovery-driver.cjs` was run on both sides to repeat the explicit refresh and record a successful found response for the same existing PR key. `normal-observer.cjs` extended observation to 210 seconds from that response, with no more refreshes. The final recordings retain the interruption and both scripts. There are four explicit refreshes per side: two not-found responses, one unreachable fixture attempt, and one successful recovery response.
