# PR #22761 proof audit, pass 2 (adversarial)

Head `0f40a81e0c82bee35ff625b7b965524c45e88e14`, before = merge-base `8acbefefc51b4d281dcd04108c82baa1ab902b0e`. All data is synthetic: it comes from the local stub (`stub.ts`) through a real OpenCode 1.18.18. No `~/.t3` data was read.

## 1. Integrity of the uploads
| file | uploaded sha256 | equals stated value | equals local `/tmp/ev-22761/driver` copy |
|---|---|---|---|
| capture.mjs | 67a26397…7047046 | yes | yes |
| stub.ts | abc10a87…f7f4a7f71 | yes | yes |
| extract.sh | 32937194…2c5ded | yes | yes |

The uploaded transcript-before.md, transcript-after.md and evidence.md are byte-identical to the local copies. In each transcript, the "Client receives" JSON section is byte-identical to the raw `transcript-<side>.json` the driver wrote. `sha-before` and `sha-after` match the stated SHAs, and so does `git rev-parse HEAD` in both worktrees.

## 2. Row by row (server events, projection row, client frames)
The stub sends this usage. Single step: prompt 12000, cached 1000, completion 32. Multi: step 1 sends 9500/500/40, step 2 sends 12000/1000/32. The head code (`adapter.ts` emitProviderTurn) computes `inputTokens = input+cache.read+cache.write`, `used = inputTokens+output`, and reads the last step only, on the completed event only. Expected for R1/R2: 12000 / 12032 / 32. Expected R2 billing: 21500 / 1500 / 72. Every value below agrees with that.

- **R1 OpenRouter single.** After: completed event seq 40, the projection row, client frame 40, and the final projection all show `{used 12032, max 128000, in 12000, cached 1000, out 32}`. Before: tokenUsage absent in all four places. Billing (12000/1000/32) is identical on both sides. Confirmed.
- **R2 multi-step.** The stub log shows 2 glm-multi requests: a glob tool call, then text. After: tokenUsage holds the last step only (12032 / max 128000), and turnTokenUsage holds the sum (21500 / 1500 / 72). Before: same billing, no tokenUsage. Confirmed.
- **R3a zero steps (400).** Both sides: run failed, tokenUsage absent, turnTokenUsage `unavailable`, no crash. Confirmed.
- **R3b step finishes without usage.** After: tokenUsage is present and all zero, with max 128000. Run completed with no crash. Before: absent. This matches the corrected expectation (all zero rather than absent), and evidence.md labels the correction. Side effect: such providers now show a 0-token meter. That is a product question, not an evidence gap.
- **R4 non-OpenRouter (`acme/stub-a`, @ai-sdk/openai-compatible).** After: 12032 / max 64000. Before: absent. Billing identical. evidence.md and matrix.md both state the behaviour change honestly: nothing is gated on OpenRouter, so every 1.x model now gets a meter.

All running events (on both sides) carry no tokenUsage, as the code intends.

## 3. Independent rerun (R2, after side)
- Fresh isolated base-dir `/tmp/ev-22761/audit2/home`, fresh fixture dir `/tmp/ev-22761/audit2/oc`, stub on port 18989, server on 13979. PIDs were recorded and killed by PID, and both ports were confirmed free afterwards.
- Client frame 50 (completed), the final projection, `orchestration_events` seq 50, and the projection row all show tokenUsage `{used 12032, max 128000, in 12000, cached 1000, out 32, reasoning 0}` and turnTokenUsage `{in 21500, cached 1500, out 72, complete}`.
- The stub log shows the same request sequence as the original (tool step 9500/500/40, then text step 12000/1000/32). **Reproduced.**

## 4. Gaps
- **maxTokens null.** Covered by the unit test `adapter.test.ts` "reports an OpenRouter turn's last step without waiting for a %s model catalog", run for each of `ready` and `pending`. With `pending`, `provider.list` never resolves before completion and the test asserts `maxTokens: null`. This also shows completion does not block on the catalog. A rejected catalog goes through the same `Effect.ignore` path, and the existing tests' stub clients have no `provider.list` and exercise that path. Acceptable.
- **OpenCode 2.x.** The PR does not touch `src/server/v2/` (empty diff), and v2 already has its own `contextWindows` handling. A gap labelled not-applicable is acceptable.
- **UI screenshot.** Not authorized. The client WS frames carry the values the meter reads. Acceptable as stated.

Minor: matrix.md suggested a 500 for R3a, but the stub used a 400. Both are zero-step failures, so this does not matter.
