# Proof audit pass 1 — issue 16000

Scope: `/home/ubuntu/wt/issue-16000`, branch `fix/issue-16000`, base `7f7daad985`, audited HEAD `c36d0a1f322695bacbb8f0ae670514c339e40b7e`. Read-only source/evidence audit; no tests rerun, servers, browsers, captures, edits to the checkout, pushes, PRs, or comments. Artifact written outside checkout. Worktree AGENTS.md read.

## Verdict

**An empty UI/interaction matrix is not honest for this cumulative diff.** Server guards are the core fix, but web removes a preemptive Stop from the branch/worktree picker and mobile changes queued-message retry identity. Those are observable behavioral surfaces even though JSX, styles, and layout do not change. A generic primary web smoke plus server tests and the supplied pre-fix transcript is insufficient. A primary smoke can satisfy the web rows below if it actually exercises and records their interactions and outcomes; it need not be a separate extra session.

Do not turn this into a visual redesign matrix. No before/after layout gallery is needed. Short real-app recordings are appropriate because survival, queued delivery, refusal, eventual retry, and deliberate Stop are temporal claims. Pair recordings with session/process IDs, persisted events, and background progress/DONE markers: a spinner or still screenshot cannot establish process survival.

## Existing evidence and its limits

- [Pre-fix runtime transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fbfb84514a66a475/t3-issue-16000-runtime.txt): genuine Claude runtime-mode reproduction at base; background Agent stopped at 2/24 and shell at 8/48, neither DONE. It records session detachment. Provider-instance trial explicitly excluded because watcher restart interrupted it. This is before evidence only.
- [Existing pre-fix screenshot](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2028fce175d2bade/browser-screenshot-localhost-mvmeecqg-8016699d.png): supplied artifact, not visually inspected in this audit; transcript says 1280x800. Cannot substitute for required 1440/390 configurations or a recording.
- Five busy cases red on previous commit and final 17 passing: **reported by requester, not independently rerun or log-verified here**. Source confirms ten new busy/clear cases over five operations, plus seven pre-existing cases. New cases use a fake exclusive adapter with session probe true/false and per-thread probe always false. They prove guard routing and no close in the busy case; they do not execute real Claude tasks.
- No post-fix real-app recording or post-fix process-survival transcript was supplied for audit.

## Affected fixture matrix derived from the diff

“Test” means focused behavior proof, not a request for a recording of every backend permutation. Rows can share fixtures and recordings.

| Row | Caller / branch | Fixture and expected outcome | Existing proof | Minimum additional proof |
|---|---|---|---|---|
| S1 | Explicit runtime-mode mutation | Exclusive Claude; completed parent turn, native background Agent only; incompatible runtime change refused before mutation/detach; original process progresses | New fake busy/clear case models precisely the session-true/thread-false distinction | Real Claude after transcript + R1; test busy→finished→fresh-command success |
| S2 | Explicit provider-instance/model-selection mutation | Session-release plan nonempty; refuse with background work; no release plan / same selection does not falsely block | New provider-instance case; older selection-command compatibility case | R1; test modern `thread.model-selection.set` routing as well as legacy `provider.switch` if not already covered elsewhere |
| S3 | Worktree metadata mutation | Existing web thread, different worktree; pending shell only; no eager Stop; refusal preserves original worktree/session; retry after completion succeeds | New server workspace case; no new web test | R2, including actual branch/worktree picker, displayed selection after refusal and successful retry |
| S4 | Immediate send to another compatible account | Same continuation home, `restart_and_resume`; background work prevents old-session detach and send; no lost draft or false success | New immediate-send busy/clear case | R3 + runtime event correlation |
| S5 | Server queued send to another compatible account | Queue behind active parent, recheck when parent ends while background work remains; queued run fails with exact actionable reason; queue does not remain stuck | New queued busy/clear case, error text asserted | R3; verify subsequent normal message still delivers |
| S6 | Mobile local outbox settings sync | Existing thread, queued runtime change refused while background work remains; automatic retries use distinct settings command IDs; after natural completion delivery succeeds once | Source only; no mobile test added in diff | R4 + focused mobile retry behavior test or equivalent RPC transcript proving IDs and one final delivery |
| S7 | Mobile interaction-mode settings sync | Transient failure then retry uses new setting command ID; normal interaction-only settings change still delivers | ID helper changed for both settings; interaction mode is not a new background detach guard | Focused mobile observable retry test; can combine with S6, no separate video required |
| S8 | Ordinary same-account send / no-op changes | Busy background work but operation does not detach; still allowed under existing active-turn dispatch policy | Not established by new busy cases | Focused negative-control test; include ordinary send in R1/R3 |
| S9 | Natural finish / no work | Separate native-Agent-only, shell-only, both, and completed rosters; refuse any live work, allow when all probes clear | Fake busy=false is absence, not a busy→finished transition; real before trial had both | Adapter tests establish the two task sources; one real Agent-only episode and one shell-only episode across R1/R2; both can be backend fixture, no third video solely for combination |
| S10 | Active vs completed parent | Explicit mutations with active parent versus completed parent/background-only; queued send transitions active→completed | New explicit cases are completed parent; queued case starts active | Focused active-parent guard case; real completed-parent background-only episode is mandatory so parent activity cannot mask bug |
| S11 | Pooled/shared provider session | Own thread busy => refuse detach; only unrelated thread busy => permit this thread's change without killing other thread; inspect all this thread's provider-thread records | Older pooled compatibility case has no new busy ownership proof | Focused pooled ownership tests; no extra UI recording |
| S12 | Probe edge branches | Session-wide fallback when thread probe absent; exclusive session probe preferred; thread-only probe; failed probe conservatively refuses; missing runtime/no probes behavior explicit | Only exclusive session-preference branch added to tests | Focused branch tests, particularly pooled unrelated work and probe failure; runtime transcript cannot replace deterministic error fixture |
| S13 | Deliberate Stop / archive / settle | Stop still ends work; retry after Stop allowed; archive/settle remain deliberate ends, settle still rejects active/blocked runs | Intentionally exempted guards; not asserted by new cases | Record Stop once in R2; focused existing/new lifecycle assertions for archive/settle, no separate visual rows |
| S14 | Workspace no-op / branch-only / drafts / empty automatic | Same worktree branch change and draft selection do not gain false refusal; automatic `expectedEmpty` remains guarded by existing semantics | Removed eager Stop was conditional on existing session + different worktree; other branches untouched | Source trace plus focused smoke/test for different vs same worktree; no recording of every draft/empty branch |
| S15 | Non-compatible provider/home change | Explicit release plans still checked; send paths that do not resume old native thread must preserve background process according to existing ownership semantics | Older separate-home compatibility case, no new busy case | Targeted test for busy separate-home/cross-driver selection; do not assume same-home test proves it |

## Minimum real-app recording plan

Four web viewport/theme cells are retained because the requester explicitly requires 1440/390 × light/dark when the UI matrix applies. Heights should be reported, not invented. They are allocated across scenarios rather than multiplying every fixture by four. The native mobile outbox cannot be proved by a narrow web browser; it needs its own native-client run. One mobile theme suffices because no native render/style changed, unless the original requirement explicitly meant both themes on every client too (then add that native theme, not every provider/state combination).

| Recording | Real client / configuration | Interaction sequence and observable result |
|---|---|---|
| R1 | Web, width 1440, light | Real Claude native Agent only after parent completes. Attempt runtime-mode and provider-instance change, observe actionable refusal and continued progress on original process. Ordinary same-account send remains usable. Let Agent finish, retry succeeds. Capture session/events alongside video. |
| R2 | Web, width 390, dark | Real Claude shell only. Use changed branch/worktree picker, show refusal with no eager Stop and truthful displayed workspace. Let shell finish and retry successfully; start short work again, explicitly Stop, show termination and permitted subsequent change. |
| R3 | Web, width 1440, dark | Compatible second account: immediate send refused while busy; queue send behind active parent, end parent without stopping background work, show queued run fails with readable reason rather than hangs; ordinary retry/delivery works after completion. |
| R2b | Web, width 390, light | Short representative repeat of changed worktree-picker refusal/recovery. Covers remaining expressly required viewport/theme cell; no need to repeat runtime/account/task permutations. |
| R4 | Native mobile, width ~390 (report actual logical width), dark | Existing-thread local outbox with runtime-mode mismatch. Show refused attempt keeps message, work continues, natural completion permits retry and exactly one delivery; correlate distinct settings command IDs in sanitized transcript. Include normal retry control. Native simulator dimensions may differ: disclose actual dimensions rather than call web emulation mobile proof. |

These are five configuration executions, not five separately hosted artifacts: concatenate labeled clips if convenient. A single video may contain several rows. No separate static screenshots are necessary for this behavioral fix. Do not fabricate a pre-fix video: existing transcript is usable before proof with its limits disclosed. All videos above remain **required/not executed by this audit**.

## Caller, client, provider, connection coverage decisions

- Web ChatView persists runtime/interaction settings before send through shared client commands. Metadata/model selection goes through `updateMetadata`, which maps to `thread.model-selection.set` on capable servers or legacy selection/provider-switch commands. The branch picker calls metadata update directly; its previous fire-and-forget Stop could defeat a server guard, hence R2 is indispensable.
- Mobile settings are applied in `use-thread-outbox-drain` before `startTurn`; failure returns false and schedules retry. Runtime and interaction settings IDs now include an in-memory attempt counter. Test delivery behavior, not just string construction. Remount resets counter: include persisted-outbox/remount recovery in focused proof if retries can reuse refused receipts; not proven fixed merely by the new suffix.
- WS/UI, MCP ThreadMetadata/Worktree services, Orchestrator MCP message dispatch, provider continuation, scheduler/service dispatch and queued effect-worker start converge on server guards. RPC/service tests cover these callers; do not require separate agent/scheduler recordings or invent nonexistent settings/keybinding entry points. Settings/command-palette/keybindings sharing a command get route tracing; independently bypassing paths need their own test.
- Desktop wraps the changed web component; no Electron IPC or shell change. Reuse web behavior proof, no duplicate desktop video. Native mobile has separate retry logic and cannot reuse that proof.
- Claude is the mandatory real provider: exclusive session, runtime switch requires restart, session probe sees Agents and shells while thread probe sees shell roster only.
- Codex is the pooled negative-control provider: runtime switches in session, scoped probe distinguishes this thread from others. Test ownership; no requirement to record all Codex interactions.
- OpenCode legacy exclusive versus v2 pooled and in-session runtime support, ACP-backed Cursor/Grok, and Antigravity capability overrides need capability/probe-route tracing. Shared guard applicability follows actual runtime capabilities and available probes, not provider name. Their adapters are unchanged: focused representative capability tests suffice; do not claim every provider was run or every provider supports native Claude Agents. No-probe adapters cannot magically establish pending work; record limitation explicitly if applicable.
- Local/remote/relay/tunnel all execute destination server orchestration, with no wire-schema/origin change. One environment connection is sufficient for recordings plus destination/event correlation; do not multiply by transport, theme, provider and lifecycle. A remote mobile connection naturally adds useful path coverage. Multi-environment ownership is a targeted command-routing check, not a new layout matrix.

## Minimum proof package before calling this ready

1. Preserve the five reason-specific red failures and matching final 17-pass logs with exact revisions/commands (reported results must not be presented as independently verified by this auditor).
2. Close decisive focused gaps: pooled own/unrelated work, probe failure, busy→finished retry and non-detaching negative control, active-parent explicit mutation, and observable mobile settings retry including recovery identity. Reuse existing tests where they genuinely assert these facts; no requirement to add duplicative tests.
3. Post-fix real Claude runtime transcript: original process/session, work progress before/after refused changes, no detach/close on refusal, DONE on natural completion, successful fresh retry, deliberate Stop ends work. Cover Agent-only and shell-only independently across recordings.
4. Labeled R1/R2/R3/R2b/R4 real-client interaction recordings in requested configurations. The primary integrated smoke can produce them. No generated mockup, static render, synthetic browser markup, or screenshot of a spinner substitutes.

## FRICTION

- No captures performed: requester explicitly prohibited server/browser/capture activity for this audit. Matrix is an evidence requirement, not a claim these rows passed.
- Supplied transcript is pre-fix, 1280x800, and excludes provider-instance trial; final test output and primary web-smoke artifacts were not supplied. Cannot certify those unseen results.
- The cumulative change is not server-only. Calling its matrix empty would hide web eager-Stop removal and native mobile retry behavior.
- No checkout edits, tests, pushes, comments, merges, servers, browser sessions or captures. Only this external Markdown artifact is uploaded. No implementation scripts/evidence committed.
