# Read-only proof audit — PASS 1 revised

PR [#14496](https://git.cafe/pingdotgg/t3code/pulls/14496) ([GitHub mirror #14496](https://github.com/pingdotgg/t3code/pull/14496)). No captures executed or examined in this pass. This is an evidence prescription, not a claim that the change passes.

Inspected only `/home/ubuntu/wt/pr-14496`. Complete `git diff origin/main...HEAD`: five paths, 266 insertions, three deletions. Verified clean worktree; HEAD `a7c675caa1f2ea52842c77ebc6fe6cc874d6ec01`, merge-base `5a969c17e76301e45e53e1fd9aad2f5b4599d865`. Before [5a969c17e7](https://git.cafe/pingdotgg/t3code/commit/5a969c17e76301e45e53e1fd9aad2f5b4599d865); after [a7c675caa1](https://git.cafe/pingdotgg/t3code/commit/a7c675caa1f2ea52842c77ebc6fe6cc874d6ec01) is local/unpushed, so that link may not resolve yet. Original provenance supplied by lead: `saphid/t3code`, `fix/v2-claude-lost-runtime-request`, [66d551e59c](https://github.com/saphid/t3code/commit/66d551e59cbb1910d3bc105374793b899161f730); original branch was not fetched or audited.

## Scope and complete changed-component inventory

Surfaces by changed paths: **SERVER and CONTRACTS only**. No web, desktop, mobile, provider adapter, RPC handler, projection schema, or database migration changed. A browser view of the thread is optional supporting evidence, not another affected surface.

| Changed component path | Caller / data / changed conditional | Proof obligation |
|---|---|---|
| `apps/server/src/orchestration-v2/EffectWorker.ts` | Worker executes `runtime-request.respond` through `RuntimeRequestServiceV2.respond`; wraps failures with `tapCause`. Suppresses reporting when `willRetry` or `Cause.hasInterruptsOnly`; otherwise dispatches internal failure. Dispatch failure is caught/logged; original delivery failure still propagates. | Retry silence, terminal error, interruption silence, reporting-failure containment. Default maximum five attempts; backoff `min(30000,100*2^(attemptCount-1))` ms. Do not substitute the test's 30-second clock jumps for real timing. |
| `apps/server/src/orchestration-v2/Orchestrator.ts` | Adds command-thread routing and internal dispatch handler. Reads thread and `getRuntimeResponseContext(...).node`; deleted thread or absent node returns without event. Existing node yields one `turn-item.updated` with stable request-derived ID; optional event `runId`, nullable payload `runId`, node/provider correlation and fresh ordinal/timestamps. | Error reaches subscribing client and persists; request/answer/node/run unchanged by failure command. Empty/deleted cases silent; null run accepted. |
| `packages/contracts/src/orchestrationV2.ts` | Adds internal `{type:"runtime-request.delivery.fail",commandId,threadId,requestId}`. Server command union includes it; public `OrchestrationV2Command` and `orchestration.dispatchCommand` input exclude it. | Internal command decodes in server path; client cannot forge it. Existing response and error event shapes remain interoperable. |
| `apps/server/src/orchestration-v2/EffectWorker.test.ts` | Adds optional injected `respond` to executor test layer and last-attempt `Effect.interrupt` case; asserts no failure-command dispatch and interrupted exit. | Supporting source only. Not a real server/client recording and not executed in this pass. |
| `apps/server/src/orchestration-v2/runtimeLayer.test.ts` | Adds synthetic attached-but-not-live session, null-run request, answer, five delivery attempts via TestClock/drain, one failed error item and resolved saved answer. | Supporting source only. It does not establish real WebSocket delivery, active-run invariance, reconnect behavior, or approval invariance. |

## Shared runtime driver and acceptance rules

Capture agent must run the actual dev server, never only `runtimeLayer.test.ts` or a standalone orchestrator. Use fresh homes under `/tmp/ev-14496`, e.g. `/tmp/ev-14496/before/home` and `/tmp/ev-14496/after/home`, with `vp run dev --no-seed --home-dir <fresh-home>`. Record exact argv, full checked-out SHA, resolved home, real ports and injection source/hash. Use disposable before/after source copies derived from the named local commits, not a checkout/reset of this worktree. No fetching is needed. Never use the live T3 home or seed real user data. This pass does not authorize starting any of that work.

Drive the real authenticated `/ws` using the repository's typed Effect RPC protocol (`WsRpcGroup`, `RpcClient.make`, `Socket.layerWebSocket`, `RpcSerialization.layerJson`; see `packages/client-runtime/src/rpc/protocol.ts` and `session.ts`). Use ordinary project/thread launch and message RPCs to produce the request, `orchestration.subscribeThread` before answering, `orchestration.dispatchCommand` to answer, and `orchestration.getThreadProjection` for checkpoints. Do not handwave a bare JSON socket message as a valid RPC frame. Discover the isolated dev credential using the documented local dev auth flow; redact credentials from artifacts.

Use an actual provider process through the unchanged actual adapter to produce one explicit live `request_user_input` question, held until the RPC driver answers. A disclosed deterministic protocol-faithful provider process qualifies as real-app evidence; an external paid live LLM or OAuth session is not required. For deterministic fault injection, a temporary Node source-loader overlay outside the repository can wrap the existing `ProviderSessionManager.ts` `runtime.respondToRuntimeRequest(input)` call. Load the real server entrypoint with that overlay (including spawned server process, not just Vite), preserve its real layers, worker, persistence, RPC transport and real Claude adapter. Gate only the chosen request ID. Modes: fail-before-call on attempts 1–5; fail first two then delegate normally; wait on an externally released gate; delegate then fail to model ambiguous delivery. Log monotonic attempt/time, input, mode, call-forwarding and outcome. Fail injection must be an Effect failure, not a successful no-op. Returning success while silently dropping an answer does not exercise this diff. A controlled defect may share the terminal row; pure interruption is separate. There is no inspected built-in fault-injection switch: the overlay and its process propagation need implementation/verification by capture agent. Do not present an unverified overlay as already available.

Real-app means the actual isolated dev server driven through normal typed WebSocket RPC, with externally scoped provider delivery fault injection and the unchanged actual adapter. A deterministic protocol-faithful provider process is permitted and must be disclosed, including protocol/adapter and fixture provenance. It does not require paid live LLM access or OAuth. A fully mocked adapter/service layer, service-only execution, standalone orchestrator or direct EventSink-only fixture remains **harness evidence** and cannot replace either mandatory real-app paired reel. Do not mutate the database to force the primary fixtures.

All interaction/time rows below require a continuous screen/terminal recording (MP4/WebM or replayable terminal recording) showing labeled request, attempt, event and client-receipt streams. Stills alone fail. Every mandatory real row runs before AND after with the same fault program and semantic fixture; normalize generated IDs/timestamps only for comparison. Timestamped JSONL alone supplements, but does not replace, the recording. Record no credentials or private prompts.

For each case retain: sanitized RPC requests/responses and subscription frames; injection log; isolated server log; read-only SQLite snapshot/export of `orchestration_events`, effect outbox, runtime request, node, turn item and run projections; SHA/home manifest; recording time ranges. Snapshot before response, after committed response, before terminal attempt and after settlement. Attribute mutations to command/event IDs rather than assuming a concurrently running provider never changes a run. The new failure command itself must not emit request/node/run updates, reopen a question, overwrite an answer, interrupt/restart a run or alter approval semantics.

Expected after error: one logical item ID `turn-item:runtime-request-delivery-failure:<requestId>`, `type:error`, `status:failed`, `title:"Answer delivery not confirmed"`; failure `{class:"transport_error",message:"T3 Code could not confirm that your answer reached the agent. If the run stays stuck, stop it and try again.",code:null,retryable:null}`. Correlate node, nullable run and provider thread/turn IDs; `nativeItemRef`/`parentItemId` null; timestamps complete and ordinal usable. This is an ordinary committed timeline event, not an RPC answer rejection or a new pending approval.

## Revised branch-proportional fixture matrix

**A** = affected behavior, mandatory recording; **G** = unchanged boundary, source-reviewed with no mandatory capture; **H** = affected internal branch, supporting harness recording. R1 and R2 are each paired before/after real-app recordings. H1 is one supporting reel with labeled segments. Replayable terminal recordings are sufficient for server/contracts; stills prove only static state. No cross-product is required. These are required future captures, not evidence already collected.

| ID / classification | Branch and fixture | Required driver and observable acceptance | Capture |
|---|---|---|---|
| F1 **A** | Live question terminal delivery failure; retry suppression; attached non-null run; saved answer; online delivery and reconnect. | Actual isolated server + unchanged adapter + provider process; answer once using typed RPC; fail delivery attempts 1–5 for that request. Subscribe A before answering; disconnect B after commit and reconnect after terminal settlement. Both revisions preserve resolved request, saved answer and completed request node; delivery eventually fails. Attempts 1–4 have no delivery warning. Before: no new warning. After: one logical persisted error item received by A and present in B's reconnect projection. Correlate event/command IDs to prove failure reporting itself leaves run/request/answer unchanged; do not require absence of unrelated provider events. | **R1 before + after**, mandatory real app. |
| F2 **G / optional control** | First-attempt success; transient recovery; ambiguous delivery (adapter forwards then reports failure). | No separate mandatory real-provider reels: success and recovery take existing paths; ambiguity reaches the same new terminal reporting branch as F1. Short success/recovery control may be appended if practical. Source-review conservative wording and preservation of saved answer; do not claim the warning proves non-delivery. If captured, label optional controls and actual injection semantics. | No additional mandatory capture. |
| F3 **A/H** | Pure interruption on last attempt; non-pure causes. | H1 executes final-attempt pure `Effect.interrupt`: no failure command/item, original interruption propagates. Terminal typed failure is covered by R1; include short defect/mixed-cause segments in H1 to show non-pure causes report, without new real-provider reels. A UI stop alone does not prove the delivery fiber was interrupted. | **H1**, recorded; before/after executor comparison where applicable. |
| F4 **A** | One representative real live approval terminal delivery failure. | Actual isolated server + unchanged adapter + provider process; produce a native approval request and send one supported decision through typed RPC, then exhaust delivery attempts. Record the chosen decision (and feedback if present) before delivery and after settlement; it stays exactly as committed. Before: no new warning. After: terminal warning, no reopened approval, policy/session-grant change or run action attributable to failure reporting. Other approval decision families share this branch and need no separate recordings. | **R2 before + after**, mandatory real app; one representative decision only. |
| F5 **A/H** | Detached/null-run context; deleted thread; missing request/node no-op; missing-thread lookup error. | H1 uses isolated real services and labeled synthetic context/direct internal dispatch. Null-run node emits error with event `runId` omitted, payload `runId:null`, correct node/provider refs. Deleted thread and missing-node contexts emit no item. Distinguish nonexistent request yielding absent node from lookup failure; missing thread retains lookup-error behavior, not a fabricated warning. No deleted-thread race capture required. Direct new-command cases are **after-only**, no fictional before support; a baseline terminal-response comparison may supplement if practical. | **H1**, every affected segment recorded. Missing-thread lookup is retained source-reviewed boundary; optional recorded control. |
| F6 **A/H** | Reporting dispatch failure containment; deterministic command/item identity; replay. | H1 scopes a dispatch wrapper to fail only the new reporting command. Show warning log and original delivery failure still propagating rather than success or unbounded retry. Show request-derived item ID and effect-command-derived reporting command ID. Replay identical internal command ID and inspect receipt/event/item count for no duplicate. Record baseline executor failure propagation where applicable; direct new-command replay is **after-only**. | **H1**, recorded. |
| F7 **G** | Existing response validation: invalid feedback, empty answers, duplicate/missing request; `message`/`not_resumable`; approval decision families and successful semantics. | Retain prior source trace. None adds a new conditional in this diff; no mandatory captures for these boundaries. `message` uses message dispatch; `not_resumable` rejects before this effect; accepted live empty answers share F1. Rejected input alone cannot trigger the new effect. Do not claim runtime verification. | **Source-reviewed / no mandatory capture.** |
| F8 **A/H + G** | Internal command schema/routing and replay; public wire exclusion; existing error item transport. | H1 records internal decoding of complete new shape and rejection of missing required fields, plus actual internal routing. These new command cases are **after-only**. Public client union/exclusion is unchanged and source-reviewed, no separate paired public-invalid-input reel. R1 proves typed RPC client receives and decodes existing error-event shape; F5 covers null-run correlation. | **H1** internal/schema; **R1** emitted event; public exclusion **source-reviewed / no mandatory capture**. |

## Provider / kind / interaction collapse

Unchanged call chain: public RPC → `ThreadMessageIntake` / orchestrator → response projection commit and outbox → effect worker → `RuntimeRequestService` → session manager → adapter. New reporting chain: worker terminal cause → internal failure command → orchestrator context lookup → existing event sink/projections → existing WebSocket thread stream. Transports remain thin.

All live request kinds share the changed worker branch: approval kinds `command`, `file-read`, `file-change`, `mcp-elicitation`, `permission`, plus `user_input`, `dynamic_tool_call`, `auth_refresh` where an adapter exposes them. Contracts enumerate them; this does not imply each provider emits every kind. `message` responses instead use message dispatch, and `not_resumable` rejects before any delivery effect. Default/plan and runtime access modes only matter to obtaining a real question/approval; no new branch inspects them. Answer normalization, attachments/question-answer projection and decline feedback are existing response behavior, not new delivery payload fields.

The unchanged Claude adapter is the natural primary capture because of the reported origin; a disclosed deterministic protocol-faithful process through it is sufficient. Codex, Cursor, Grok, OpenCode and Antigravity need no additional adapter matrix: no adapter changed and worker reporting does not branch on driver. One real-app live question plus one representative live approval is the minimum provider coverage; external paid Claude/OAuth is not required; mark other providers “shared path, not separately captured,” not “verified.” No new desktop/mobile/browser, tunnel, relay or scheduled-task capture is required. Reconnect is a second RPC client on the same server, not a new surface. Do not label this a comprehensive adapter audit.

## Minimum capture set for the lead

1. **R1 before + after:** actual isolated dev server, provider-created live question, scoped delivery failure to exhaustion, retry silence, online subscription, reconnect projection, persisted answer/request/node/run invariance.
2. **R2 before + after:** same real-app standard, one native approval with one supported saved decision, terminal delivery failure and saved decision invariance.
3. **H1 supporting reel:** pure interruption; non-pure defect/mixed-cause check; detached/null-run context; deleted/missing-node no-op; reporting-dispatch failure; replay and internal schema/routing. Each affected segment needs recording. Pair existing executor behavior where comparable; explicitly label direct new internal command cases **after-only**.

Minimum: **two paired real-app reels (four recordings) plus one supporting harness reel**. Success/recovered may be short optional controls. No R3/R4, all-decision-family matrix, unrelated validation captures, or success/transient/ambiguous live-provider reel quota. No browser required. Terminal recordings may carry all required server/contracts evidence; stills only support static claims. Capture exact SHA/home/argv, normal typed RPC and injection provenance as above. A deterministic provider process through the unchanged actual adapter qualifies as real-app; service-only execution does not.

## Source scrutiny and revision status

Re-read the three production-file diffs against the supplied base. No objection to the lead correction: no distinct newly added branch is dropped by this collapse. New worker retry/interrupt/reporting-failure branches, handler deleted/missing-node/null-run branches, internal schema/routing and deterministic IDs remain assigned to recorded evidence. Detached context is a fixture for the node/null-run path, not a new provider-family axis. Defect/mixed causes share the non-pure terminal reporting path and fit H1. Existing response validation, all approval decision variants and public exclusion remain source-reviewed inventory, not newly introduced capture obligations.

No capture was executed or examined in this revision. PASS 2 must inspect the actual recordings and reconcile events/client/state rather than treating prescribed outcomes as observed proof. Scope is the supplied local replacement, not refreshed remote PR state; no merge-readiness verdict is claimed.

## FRICTION

- **brief:** Prior prescription over-scoped existing validation and approval families and implied external live Claude access. Corrected to changed-branch coverage and the user's actual-server/typed-RPC standard; disclosed deterministic adapter-backed provider process is permitted.
- **runbook:** External scoped delivery overlay and propagation to the actual spawned server still need implementation and verification by the capture agent. There is no inspected built-in fault switch. This is planned capture work, not an observed blocker.
- **tool | infra | forge | policy | model | other:** none observed. No tests, server, browser, delegation, watch, repository edits, fetch, push or comment. Only the outside-worktree matrix was revised/uploaded; required app PR-link metadata registered.
