# Proof audit, pass 2: [#22830](https://github.com/pingdotgg/t3code/pull/22830) (GitCafe #22829), issue [#15250](https://github.com/pingdotgg/t3code/issues/15250)

**Verdict: SUFFICIENT**

Codex is a **STUBBED Codex app-server**, so this is not real-Codex evidence.

## 1. SHAs and diffs

- The PR worktree HEAD is `89d72c1ff2110106722bf258610d15d5240e2051`.
- `git diff --stat aa57d7d3ba 89d72c1ff2` touches only `apps/server/scripts/evidence/issue-15250/{README.md,run.mjs,stub-codex-app-server.mjs}`. That is 524 insertions, with no server code.
- `git diff --stat 8d3b061121 89d72c1ff2` is those 3 files plus `CodexAdapterV2.ts` (+109/-38 lines touched) and `CodexAdapterV2.test.ts` (+127). That matches the "what else changed" claim.
- The pass-1 raw logs record checkout *paths* (`/tmp/ev-22830/before` and `/home/ubuntu/wt/pr-22830`), not SHAs. That before worktree was already removed. So the SHA labels on the pass-1 captures can't be proven from the artifacts alone. My rebuild below closes this gap: I re-ran on a fresh detached worktree verified at `8d3b061121fe…` and on the PR worktree at `89d72c1ff2` (identical implementation to `aa57d7d3ba`). The rows I re-ran reproduced.

## 2. Driver and stub honesty

- `run.mjs` spawns a real `node apps/server/src/bin.ts start --base-dir <out>/home --host 127.0.0.1 --port N`. It refuses to run against `~/.t3`.
- It drives rows through the real CLI (`bin.ts thread start … --provider codex`). Codex is replaced only through `providerInstances.codex.config.binaryPath`, which points at a launcher script.
- It reads `statev2.sqlite` with `readOnly`, and SIGTERMs only the PID it spawned. There is no in-process mock of the server or adapter.
- The stub is clearly labelled `STUBBED Codex app-server` in its header comment, in its `initialize` userAgent, in the model description, and in the README.

## 3. Pass-1 raw results vs. the claimed matrix

I re-derived every row from `raw/{before,after}/results.json`.

| Row | Before (raw) | After (raw) | Client value (raw) | Matches claim |
|---|---|---|---|---|
| R1 | 1R 0S (R@0.04) | 1R 0S (R@0.04) | gpt-6-luna → gpt-6-luna | ✅ |
| R2a | 1R 1S (0.01, 0.02) | 2R 1S (0.00, 0.04, **R@1.04**) | **null → gpt-6-luna** | ✅ |
| R3 | 1R 1S | 6R 6S at 0.01/0.04, 1.04, 3.04, 7.04/7.05, 15.05, 31.05 | null → null, 1 update event | ✅ |
| R4a | 1R 1S, interrupted | 1R 1S, interrupted, no +1 s retry | null, interrupted, at both SHAs | ✅ |
| R5 | 1R 1S | 1R 1S | gpt-5.6-sol at both SHAs, 2 update events | ✅ |
| R6 | 1R 1S | 1R 1S | gpt-6-luna at both SHAs | ✅ |
| R3b | 1R 0S | 6R 0S at 0.00, 6.01, 13.01, 22.01, 35.01, 56.02 | null at both SHAs | ✅ |

- The recheck log (`raw/after-recheck.driver.log`) shows R2a 2R/1S and R3 6R/6S (last request at +31.11 s). ✅
- The R3 "quiet afterwards" claim holds: the last request is at +31.05 s and the projection was read about 99 s after R3's spawn.

## 4. Rebuild (this audit)

The commands use the committed `run.mjs` per its README, with `--rows R2a,R3 --window-ms 45000`. Output went to the isolated `--out /tmp/ev-22830/audit2/{after,before}`.

| Row | BEFORE `8d3b061121` (detached worktree, port 43837) | AFTER `89d72c1ff2` (PR worktree, port 43836) |
|---|---|---|
| R2a | 1R 1S (R@0.02 S@0.03), model **null**, 1 update event | 2R 1S (R@0.03 S@0.05 **R@1.05**), model **gpt-6-luna**, `{"instanceId":"codex","model":"gpt-6-luna","options":[{"id":"reasoningEffort","value":"high"}]}`, update at +1.02 s |
| R3 | 1R 1S, null | 6R 6S at 0.00/0.04, 1.05, 3.05/3.06, 7.06, 15.06/15.07, 31.07; null; 1 update event |

- Both runs **reproduce** the pass-1 claims to within about 20 ms.
- Both servers exited (pids 1665963 and 1667034). Ports 43836–43839 were free afterwards.
- The before worktree was removed with `git worktree remove --force`. `~/.t3` was never touched.

## Gaps (non-blocking)

- R2b, R2c, R4b–R4e, R5b, R6b, R7 and R4f were not captured. R5b is covered by a unit test.
- There is no client screenshot. The client value is the projection row the clients render.

## Note: open design question R4f (not a blocker)

R4f is a child that reaches a terminal state before any lookup succeeds. The retry loop stops on terminal or interrupted status (R4a shows this), so such a child **never shows a model**.

That is the same user-visible result as before the fix. Whether a late or one-shot lookup should still backfill the model for a finished child is a product decision to settle in review. It does not affect whether the evidence for the fix is sufficient.
