# Proof audit PASS 1 — fixture MATRIX

PR [#14419](https://github.com/pingdotgg/t3code/pull/14419), requested source kiiwee/t3code branch `fix/v2-acp-mcp-abort-20260928`.
Read-only inspected worktree `/home/ubuntu/wt/pr-14419`.
Head [66eddc7](https://github.com/pingdotgg/t3code/commit/66eddc7146296220b71ce85c3ba1644d6285a6ee); origin/main and merge-base both [a68e6e9](https://github.com/pingdotgg/t3code/commit/a68e6e97c501d265e1edccb47b96f8365c8e38f4).
Local refs verified; no fetch/ref refresh or remote metadata proof claimed. Product working tree clean before inspection.

## Full diff inventory and request coverage

- [AcpMcpStdioBridge.ts](https://github.com/pingdotgg/t3code/blob/66eddc7146296220b71ce85c3ba1644d6285a6ee/apps/server/src/mcp/AcpMcpStdioBridge.ts): only two POST fetch sites change, passing Effect.tryPromise's signal to fetch. No response parser, protocol, contract, permission, CLI interrupt source, or body-lifetime change.
- [AcpMcpStdioBridge.test.ts](https://github.com/pingdotgg/t3code/blob/66eddc7146296220b71ce85c3ba1644d6285a6ee/apps/server/src/mcp/AcpMcpStdioBridge.test.ts): six existing tests plus two pending-fetch signal assertions. Fake fetch never settles or reacts to abort; final follow-up removes the inaccurate comment. Assertions prove signal forwarding, not socket closure.

| Issuing path / collapsed request class | Affected? | How staged / required observation |
| --- | --- | --- |
| mcpToolSession.send: initialize | Yes, POST pending before headers | Existing new test reaches only this request. Runtime may separately hold initialize to establish handshake cancellation, but this cannot substitute for tools/call. |
| mcpToolSession.send: notifications/initialized | Yes, same POST site; no id | Respond to initialize with session id and protocol version; allow notification 202/204 to finish before the target call. Same transport lifetime; no separate Cartesian suite needed. |
| mcpToolSession.send: tools/call | Yes, same POST site | Import exported mcpToolSession, establish handshake, call a harmless fixture tool; endpoint holds this specific request's headers; interrupt owning scoped fiber. Correlate request id/method/socket. |
| stdio.forward: requests, including tools/list and tools/call | Yes, POST | Import exported runAcpMcpStdioBridge, PassThrough input, write tools/list JSON-RPC line; hold its headers; interrupt bridge fiber. Existing signal test targets tools/list. |
| stdio.forward: initialize and initialized notification | Yes, same POST; handshake barrier | Ordered handshake is unchanged; normal fixture checks session/protocol replay. Collapse with shared transport cases, rather than multiplying identical cancellation tests. |
| stdio.forward: other notifications (including notifications/cancelled), client result/error replies to server requests | Yes, same POST; replies bypass handshake barrier | Existing tests exercise concurrent SSE client reply and protocol cancellation forwarding. Normal control checks no changed routing/error behavior; transport interruption is not MCP notifications/cancelled. |
| mcpToolSession terminate: DELETE | No, separate unchanged tryPromise | Respond immediately with 204 during scoped teardown. Log separately; never attribute its socket close to target POST. Do not hold DELETE and confuse finalizer hang with target abort. |
| malformed/blank/non-envelope stdio input | No fetch | Existing parse test; no runtime expansion needed. |

## Collapsed timing MATRIX

Apply each row to BOTH exported entry paths above. This is five timing classes, not every method multiplied by every timing. Only pre-header interruption is the changed behavior; other rows are controls. Fresh final-head captures cover all 20 runtime cases; see capture-report.md and the uploaded exact transcripts.

| Row | Timing / affected status | Deterministic staging | Required bounded evidence at main vs head |
| --- | --- | --- | --- |
| T1 | Interrupt before headers — affected, core proof | Real loopback HTTP endpoint consumes target request and signals receipt, withholds all response headers. Await receipt, assert headersSent=false, then Fiber.interrupt owner. | Head: target fetch signal abort event and native fetch rejection, target response/socket closes BEFORE releasing headers or cleanup. Main: target remains open through a declared short observation window (e.g. 150ms), then release response for cleanup. Fiber completion alone is insufficient. |
| T2 | Interrupt during body — unchanged lifetime control | Send JSON headers and partial body; await native fetch resolution and a body-read-start marker before interrupt. Release remaining body afterward. SSE may be recorded separately if claimed; JSON control does not prove SSE lifetime. | Record outcome at both revisions with deadline; do not require socket abort or turn pre-existing body lifetime into a blocker. Any difference needs explanation before asserting a regression. Bound interrupt wait as well as server observation. |
| T3 | Interrupt after completion — unchanged control | Fully consume response and observe tool result / stdio output before interruption. For session, close scope normally before interrupting completed fiber; for bridge, end input and join. | Completed result/output retained, no new abort/error or duplicate output. A normal HTTP keep-alive socket may stay open; no false claim that every completed socket must close. |
| T4 | Double interrupt while pending — affected idempotence control | Same T1 gate; issue two interruption requests against same fiber with deadlines; record both outcomes and abort events. | Head closes target once without duplicate output/unhandled rejection; main stays open until explicit release. One abort event is NOT proof of exactly one abort() invocation. Effect source trace can substantiate controller/finalizer semantics. |
| T5 | Normal completion — unchanged control | No interrupt; handshake, call/result, initialized acknowledgement, stdio output and EOF; normal session DELETE. | Both revisions complete with expected result/output, session/protocol replay, no abort event or unhandled rejection; cleanup recorded separately. |

## Capture acceptance criteria (satisfied by final-head artifacts)

1. Pin full revisions, merge-base, source/test hashes, driver hash, dependency/runtime versions, exact commands, exits, timestamps and clean product status before/after. Current hashes: head implementation a119e2c3e74c2e6b4af5273ad395cb70c5f69f7ea1ed0d62f506bf2ea8289386; main implementation 9ee5f005fa278268015b3ec619f71a2f524b181a64f3f4b79b44fd67db5cd136; head test 9f0f42b2f87db068f619281fa190aae53e4395e095c5229031a95cf27c897477.
2. Fresh eight-test capture: same HEAD tests/dependencies against main implementation => exactly 2 fail / 6 pass, failures specifically missing aborted signal. HEAD => 8 pass. Main's unchanged test suite alone cannot produce this red comparison. Stage source outside product worktree or another explicitly authorized capture location; do not mutate product during this pass.
3. Fresh native-fetch runtime at both pinned implementations covering T1 on both exports is mandatory. Fake fetch, copied old logs, process death, or a standalone AbortController demo do not qualify. Log request identity, headers state, interrupt and close ordering. Instrument native fetch transparently, rethrow identical rejection, record unhandledRejection throughout captured lifecycle.
4. Stage T2–T5 controls as above, or label them explicitly uncaptured and constrain claims. Bound each request gate, fiber interrupt/join, socket observation, listener start/stop (e.g. 5 seconds); no infinite wait and no polling-based repository tests. Timed main observation is external diagnostic evidence, not a new product test.
5. Runtime fixture listener is a local HTTP endpoint only, not a T3 server. Current pass forbids servers, so none was started. Capture phase needs authorization consistent with that fixture requirement. Record spawned PID, port and owner; self-close fixture and tracked connections in finally; log target close before cleanup separately. No DB, live T3 state, browser, real tool side effects, or credential use. Use synthetic authorization and harmless fixture results.
6. Source boundary: CLI uses runPromise without an in-process interruption hook, and outer Effect.promise does not establish a fresh cancellation source. Direct-export fiber proof does not prove OS signal/CLI cancellation, remote tool rollback, MCP protocol cancellation, JSON/SSE body cancellation, or every provider behavior. These are limits, not additional feature demands.
7. Prior `/tmp/ev-14419/prior` files are reference-only at different revisions. Their old 10-test totals and old API/conflict conclusions are NOT applicable proof for this eight-test, rebased head. Separate auditor PASS 2 must inspect fresh artifacts and current hashes; not performed here.

## Final-head evidence refresh

All six commands were rerun at the exact identities above, 2026-10-23 06:27:06–06:27:12 UTC. Base focused: 2 failed / 6 skipped; base full: 2 failed / 6 passed. Head focused: 2 passed / 6 skipped; head full: 8 passed. All 20 native HTTP runtime cases passed; all listeners and processes stopped. Implementation and test hashes match the previous capture, but these are fresh transcripts with updated revision pins. See capture-report.md for boundaries and downloads. Parent final-*.txt logs are separate and were not modified or included in this capture. This refresh establishes capture acceptance, not an independent merge verdict.

## FRICTION

- Origin is GitCafe, despite the supplied GitHub PR URL. No forge CLI was used to read PR state; no PR writes occurred. T3 thread registration only linked the supplied PR.
- A guessed sibling path `apps/server/src/mcp/mcpOverAcpBridge.ts` was absent; no sibling behavior is relied on as current proof.
- Final comment-only revision verified against the previous head; product implementation hash unchanged. Maintainer reports both reviewers MERGE round 1 and comment-only round 2 underway; those reviews do not replace fresh captures. Main already integrated per maintainer; no outstanding integration-conflict claim.
- Existing unit test name says tool call but pendingFetch blocks initialize first. Runtime must target post-handshake tools/call explicitly.
- User explicitly authorized synthetic local HTTP fixtures for this refresh; all 20 were started and stopped with PID/port/cwd evidence. No T3 server was launched.
- No product/test changes, commits, pushes, PR mutations, watches, DB access or browsers. Local synthetic HTTP fixtures only. Old uploads preserved; previous local staging retained under prior/pre-final-refresh.

CAPTURE VERDICT: COMPLETE at exact final head/base; no independent merge-readiness verdict.
