# Rebuild current-head evidence

Synthetic fixtures for [#25675](https://git.cafe/pingdotgg/t3code/pull/25675). Before [96fc7b9551](https://git.cafe/pingdotgg/t3code/commit/96fc7b955196637605cbf3b415152ce4dd0e2294), after [802efb97da](https://git.cafe/pingdotgg/t3code/commit/802efb97da70e935d2c55ff2be6caf1093ffdb32). No historical capture is counted.

Use only the authorized scratch checkouts and `/tmp/lead-25675-r2/evidence-capture-1`. Never touch `/home/ubuntu/wt/pr-25675`, another lead's worktree or live userdata. Every run uses a new UTC-stamped output directory; no prior capture is deleted. Every database is freshly migrated by that side's actual app server, with `T3CODE_DEV_SEED=0`. The evidence archive contains synthetic data only, with no credential/config copies.

```sh
git -C /home/ubuntu/t3code worktree add --detach /home/ubuntu/wt/pr-25675-before 96fc7b955196637605cbf3b415152ce4dd0e2294
git -C /home/ubuntu/t3code worktree add --detach /home/ubuntu/wt/pr-25675-after 802efb97da70e935d2c55ff2be6caf1093ffdb32
```

Run global `vp install` inside each checkout. Keep the installed scripts at the scratch directory, then:

```sh
python3 /tmp/lead-25675-r2/evidence-capture-1/run-captures.py R1 R2 R3 R4 R5 R7 R8
python3 /tmp/lead-25675-r2/evidence-capture-1/capture-inventory.py
python3 /tmp/lead-25675-r2/evidence-capture-1/assemble-evidence.py
python3 /tmp/lead-25675-r2/evidence-capture-1/analyze-captures.py
```

The runner executes the same recorder on each side in parallel, and rows sequentially. It resets the worker from the side's immutable HEAD before applying each row's exact executor-only injection. R3/R7/R8 production source is byte-identical to HEAD. The app recorder supplies an in-memory bootstrap token over fd 3, authenticates through HTTP/RPC, creates an empty synthetic Git project and thread, disables automatic restart continuations, and stops its own recorded server before seed instrumentation. No browser is needed. The real service assembly is `apps/server/src/bin.ts start`, executed with the checkout's Node 26 native TypeScript runtime, equivalent to running the server alone.

`seed-outbox.py` instruments the fresh disposable database with append-only INSERT/UPDATE audit triggers. Only R1/R2/R4/R5 seed one pending stop. It never writes projections. The recorder opens SQLite read-only and preserves every outbox transition plus all persisted events. Rapid pending retry states cannot be lost to 50ms observer sampling because the audit trigger persists each write. Outbox `updated_at`, `available_at` and audit sequence establish timing/order; observer `at` is when the record was read. Logger times use this VM's UTC clock. Host observer deadlines cap recordings; they do not alter server behavior.

Production timeout/retry/backoff policy is unchanged: after-only stop deadline 30s, default maxAttempts 5, lease 30s, retry delays 100/200/400/800ms. R4's 25s wait and R5's 5s fault delay alter executor outcomes only. R1/R2 use interruptible Effect.never; the actual production incident's hang cause is unknown. The bound does not guarantee settlement for uninterruptible regions, synchronously blocked JS, or hanging finalizers. Direct recursive-service calls bypass this worker timeout.

R2 performs actual SIGKILL of the recorded server, followed by restart of the same DB with no rewriting. Startup requeues the replay-safe stop with zero delay and preserves attempt accounting; pending process-bound starts are cancelled. The post-restart message is distinct from the cancelled pre-crash message.

R3 uses a genuine parent, app-owned delegated child, provider running milestone and normal thread.stop. HTTP gates keep provider terminal work active. One child is sufficient for the matrix; no synthetic stop is seeded. The subsequent message is a real Codex reply. The HTTP gate's dynamic port is fixture input on both sides.

R7/R8 are explicitly labelled harness captures: the app creates/migrates the DB and then stops; the production worker and real file-backed SQLite outbox run with a synthetic executor layer. Harness daemon concurrency is 2; worker timeout/maxAttempts/backoff defaults are untouched. R7 cancels through real cancelUnsettled/signalCancellations and records interruption/registration cleanup, then stays alive 35s. R8 holds checkpoint.capture for 35s, records the expired first lease without reclaim, then releases it. Successor provider starts are executor stubs and claim no provider reply.

`assemble-evidence.py` verifies the captured source SHA, reconstructs the worker from its immutable blob plus the retained exact injection diff, and checks the SHA256 against the captured manifest. It merges all original logs and observations into chronological transcripts. IDs and absolute timestamps are normalized only for companion diffs; status/attempt/error/payload/event ordering remains. Derived timing tables retain actual durations and persisted backoffs. Raw diffs preserve all differences. Normalized transcript inputs, manifests, full raw logs and each invocation's script copies are in the archive. `analyze-captures.py` checks the recordings, never substitutes a test for a capture. `selected-runs.json` identifies accepted directories.

The inherited R1 manifest used a static hostname label from the old recorder. Measured `hostname` and `~/.agents/MACHINE` are both fs-37; environment.txt and transcript headers correct it, and later rows measure hostname. This does not change source or fixture behavior. The original R1 manifest and exact original driver copy remain retained.

All server PIDs are captured at spawn, stopped by exact PID, and recorded with shutdown/crash boundaries. SIGTERM cleanup requeues in baseline logs are explicitly labelled as cleanup, never successful live recovery. No kill-by-pattern is used. Final cleanup removes only the two scratch checkouts:

```sh
git -C /home/ubuntu/t3code worktree remove --force /home/ubuntu/wt/pr-25675-before
git -C /home/ubuntu/t3code worktree remove --force /home/ubuntu/wt/pr-25675-after
```

No source, evidence or fixtures are committed, pushed, or added to the PR body. Upload with `ghdrop upload -m`; its exact stdout is retained and returned to the lead.
