# Proof audit, pass 1 — runtime fixture matrix

PR [#28108](https://git.cafe/pingdotgg/t3code/pull/28108), `fix/issue-28098`, reviewed head [5732ee6018](https://git.cafe/pingdotgg/t3code/commit/5732ee6018fee30328bb7394c8be7e5cd638286d), against merge-base [79f1fadfc6](https://git.cafe/pingdotgg/t3code/commit/79f1fadfc6020b820d541ca4691d2feebb15dd1b). Source audit only: no captures or tests were run in this pass. No server was started and no worktree file was changed. PR metadata agrees with the requested head. GitCafe reports 41 successful checks, but this is not runtime proof.

## Findings first

1. **Current-head runtime proof is missing.** The PR description's after transcript is from [b0843f7b51](https://git.cafe/pingdotgg/t3code/commit/b0843f7b51); it cannot prove the rollback guard, the subsequent main merge, or the final replay-harness change at the reviewed head. Keep the raw before/after records and recapture after at the exact reviewed SHA. The description is an outline of observations, not a complete timestamped recording with raw commands, results and process snapshots.
2. **The previous driver does not independently prove the new-thread-first path, unchanged-settings reuse, pending-background-work retention, compaction or rollback.** Its new thread follows an existing-thread turn that has already replaced the process. Run a separate settings transition where a new thread is the first opener. A completed root run with a genuinely retained background task is distinct from a busy root turn. The added settings race test makes the pending-work probe return `false`; there is no settings-change test for `true` or a failed probe.
3. **Several claims require finer evidence.** Conversation retention needs a stable native thread reference and recall of a marker sent only before the change. New settings must be visible on the persistent serving process, not just a short-lived status probe. The PR explicitly did not run a real home switch: binary-path evidence cannot prove `homePath`/`CODEX_HOME` or instance environment. The runtime should log only selected, nonsecret environment values. A different home may legitimately lack the old native transcript; do not claim arbitrary cross-home conversation migration.
4. **The two rollback race orders have deterministic tests.** A real server can execute rollback through RPC, but CLI timing cannot reliably place it after removal from the live-session map and before scope close. The existing Deferred-controlled test is the proof for that order. Likewise, the sibling-start-during-probe order requires its existing deterministic test. Compaction has a test for keeping its process, but that test does not emit a terminal event and prove later retirement. Test gaps below are coverage limits, not established runtime defects.
5. **Scope caveat:** [#28098](https://git.cafe/pingdotgg/t3code/issues/28098) includes external credential changes. This code detects instance rebuilds, not an auth-file fingerprint. Auth-file-only switching is explicitly excluded in the PR in favor of [#23720](https://git.cafe/pingdotgg/t3code/issues/23720); no evidence should claim that case fixed. This pass does not adjudicate issue-closing scope.

## Entry points and branch inventory

The production callers of manager `open` are [ProviderTurnStartService.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/ProviderTurnStartService.ts#L772) and [CheckpointRollbackService.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/CheckpointRollbackService.ts#L244). The former handles new and existing threads, queued turns, retries, scheduled/agent-originated turns and manual/idle compaction; the latter opens/resumes before native rollback, skips native rollback when there are zero runs to rewind, and records the result afterward. Existing native session projection, native thread ID and item identity version are forwarded on reopen. The runtime decorators are installed for every newly opened provider session, not only sessions that later become stale.

[ProviderSessionManager.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/ProviderSessionManager.ts#L1116): workspace validation precedes stale detection; no existing session opens normally; same adapter or failed registry lookup keeps an existing session; different adapter plus pending work (or a failing pending-work probe) keeps it; absent/false pending-work probe proceeds to atomic busy-aware removal; busy turns keep it; successful removal continues through normal adapter lookup/open and existing error cleanup. Existing-thread attachment versus new-thread attachment, shared versus exclusive sessions, terminal events versus failed/interrupted starts, and release failure/timeout are separate observable branches. Successful `startTurn`/`compactThread` calls stay busy until a terminal event; failed/interrupted starts clear only their own turn key. Rollback marks a distinct key, rejects a released/replaced runtime, and clears its key on every exit.

[ProviderAdapterRegistry.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/ProviderAdapterRegistry.ts#L69): absent instance is a lookup error; an instance without auth returns the original adapter; one with auth receives one memoized wrapper per instance object; a rebuild receives a different wrapper. Each `openSession` still evaluates related credential bindings, changing-credential state and access guards. Registry users beyond the manager are `Orchestrator` (capability/continuation/turn decisions), `ProviderSwitchService` (target capability and adapter lookup), and `OrchestratorMcpService` (instance listing). None directly starts sessions through a bypass added by this diff. The changed merge-back replay harness must also keep wrapper identity stable.

There are no width, theme, layout, loading, browser or client-platform branches in these changes. Web, desktop, mobile, agent tools, scheduled tasks and remote/tunnel clients converge on the server paths above. Codex is the shared-session live fixture; per-thread providers use the same manager and need the exclusive-session control, not a claim that Codex proves their native resume behavior. No browser verification is needed.

## Capture contract and driver recipes

**For this server-only change, a timestamped runtime transcript with process-list snapshots plays the role of a recording.** Every interaction/time-dependent row is marked `recording`, including deterministic test recordings where a real-server interleaving cannot be guaranteed. A test recording is explicitly a test substitute, never represented as a real Codex run.

Use a fresh timestamped directory under `/tmp/lead-28108-r1/proof-audit-1/` for each new run, with its own home and synthetic git project. Run from `apps/server` at the reviewed head. Record `git rev-parse HEAD`, CLI version, exact server command, captured server PID, command timestamps, exit statuses, wrapper launch records, selected settings changes, raw RPC/CLI results and process snapshots. Set `T3CODE_DEV_SEED=0`; use `node src/bin.ts serve --base-dir <run>/home --port <free-port> --host 127.0.0.1 <run>/project`. Keep auth material out of uploaded logs. Stop only the server/processes whose PIDs the driver captured; do not kill by pattern.

Wrappers `codex-a`/`codex-b` should log UTC timestamp, wrapper name, PID/PPID, argv, and only the chosen safe values (`CODEX_HOME`, a synthetic `T3_PROOF_MARKER`). They then exec the same real Codex CLI. Capture process ancestry/PID/start time/argv at the initial idle point, after settings reconciliation, during retained work, after replacement, and after shutdown. Do not assume every actual executable is a direct child of the server. Distinguish status probes (they exit) from the serving process (persists across the actual recorded turn). Do not dump all environment variables or raw credentials.

**D1 — ordinary CLI:** `node src/bin.ts project add --base-dir <home> <project>`; `node src/bin.ts thread start --base-dir <home> --provider codex --model <available-model> --wait --json <project> <prompt>`; retain `threadId`/`runId`; `thread send --base-dir <home> --wait --json <threadId> <prompt>`; `thread show --base-dir <home> --json <threadId>`. A busy starter omits `--wait`; follow the specific run with the server's `t3_thread_wait`/subscription or a concurrently captured wait result. `thread show` is a point-in-time snapshot, not proof an operation was in flight at a different timestamp.

**D2 — settings:** edit only this run's `<home>/userdata/settings.json`, preserving other fields, or use `server.updateSettings`. Change `providerInstances.codex.config.binaryPath`, `.launchArgs`, or `.homePath`; instance environment is on the provider instance entry, not inside `config`. For the no-change control, rewrite an equal instance config and then change an unrelated global setting. Observe reconciliation/status before the next turn; avoid treating a fixed sleep as evidence settings were applied. Save only nonsecret selected settings in the public transcript.

**D3 — compaction:** establish a real conversation first, then CLI `thread send ... '/compact'` without waiting, subscribe to its run/turn events, change settings after compaction is observed in flight, and open a sibling thread. Manual and idle compaction share `compactThread`; manual is the minimum live case. If Codex finishes before overlap is established, record that attempt as inconclusive; a replayed or delayed provider is a test fixture, not a real-Codex capture.

**D4 — rollback RPC:** obtain checkpoints, scope IDs, native thread references and provider-turn state through `orchestration.getThreadProjection`/`subscribeThread`. The payload schema for `orchestration.dispatchCommand` is the command itself: `{type:'checkpoint.rollback',commandId:<unique>,threadId,scopeId,checkpointId,restoreFiles:false}`. Use a valid earlier checkpoint with at least one actual provider turn to rewind. Observe the persisted rollback result, then ask a question that distinguishes kept from removed context. `restoreFiles:false` avoids the unrelated shared-workspace restore guard. There is no dedicated rollback CLI command in `thread.ts`. A no-op rollback with zero provider runs does not exercise the new runtime wrapper.

**D5 — retained background work:** ask Codex to launch a tracked long-lived background command/subagent and let the root turn finish. Use projected background-work events to prove work is still pending; an untracked shell `sleep &` is insufficient. Change settings, start a sibling, show old serving PID survives; await actual background completion, then open again and show replacement. Root still running only proves the busy-turn row. If CLI 0.163.0 cannot create a retained task observable by this adapter, report that limitation and use a deterministic settings-plus-pending-work test; none currently covers the `true` branch.

**D6 — deterministic tests:** run focused named tests at the exact reviewed SHA and preserve command, SHA, test name, outcome and timestamp in the recording. Existing Deferred barriers prove ordering without sleeps. This read-only pass did not execute or modify tests. Missing tests are identified below rather than invented.

## Fixture matrix

`Δ` = changed behavior; `R` = regression/control branch traversing changed code; `—` = outside claim. `LIVE` = minimum real-server recording; `TEST` = minimum focused deterministic recording; `SUPP` = supplemental branch/limit, not an extra live-run requirement. Rows may share one recording, but independent first-opener cases require separate settings transitions. All statuses are for this pass, before captures exist.

| ID / named fixture | Inputs and distinct expected observation | Diff | Minimum / proof form | Drive / exact test fallback | Pass-1 status |
|---|---|---|---|---|---|
| F01 Cold open | No live session, valid project/config; one serving process, successful first turn; baseline PID/native thread reference recorded. | R | LIVE, recording; combine F04 | D1. Baseline for every transition. | Missing capture |
| F02 Unchanged reuse | Same instance build, repeat existing-thread turn and create sibling with unchanged settings; same serving PID. Auth wrapper must not create false staleness. | Δ/R | LIVE, recording | D1 repeatedly; T-identity below establishes object identity directly. | Missing capture |
| F03 Equal settings / unrelated setting | Rewrite the same effective instance config; separately change a global setting outside providerInstances; next turn must keep serving PID. | R | LIVE, recording; combine F02 | D2 then D1. The instance reconciler uses structural equality; a different actual instance entry can rebuild. | Missing capture |
| F04 Idle existing thread, binary change | Finished turn on A; change binary to B; existing thread is first opener. A serving process ends, B serving process runs next turn without T3 restart. | Δ | LIVE, recording | D1+D2; T-idle is focused unit support. | Missing current-head capture |
| F05 Idle new thread, binary change | Existing A session idle; another change A→B (or reverse); brand-new thread is the first opener. It must retire old process and succeed on new binary. | Δ | LIVE, recording | Independent D2→`thread start` transition. Creating it after F04 does not prove this branch. | Missing independent capture |
| F06 Launch args / instance environment | Idle serving session; change launchArgs to a safe accepted option and a synthetic instance env marker; show actual new serving argv/env, completed existing-thread and new-thread turns. Exercise a new-thread-first transition here if desired. | Δ | LIVE, recording | D2+D1; use `-c model_reasoning_summary=none` only if supported by the installed CLI. Wrapper logs safe marker only. | Missing current-head capture |
| F07 CODEX_HOME config | Known valid scratch home A and B; change `config.homePath`, then create a new thread first. New serving process receives expected CODEX_HOME and completes. | Δ | LIVE, recording | D2+D1. Preprovision usable credentials privately. No claim that arbitrary homes share native transcripts; no credential upload. | Missing capture; PR explicitly untested |
| F08 Native conversation resume | On a binary/args-only transition with the same home, pre-change turn contains a unique secret-free marker; post-change asks for it without resending it. Stable native thread ID, correct recall, new serving PID. Revisit an older sibling too. | Δ/R | LIVE, recording; combine F04/F06 | D1 plus native references from D4 projection reads. Normal resume paths get existing session and native ID. | Missing current-head capture |
| F09 Busy stale session | Root X observably running; change settings; sibling Y first opens while X still running. Old PID handles both, X finishes uncut; after all work ends the next open replaces it. | Δ | LIVE, recording | D1 without wait, D2, sibling D1; wait actual X result; next D1. Long command needs observed running event. | Missing current-head capture |
| F10 Sibling starts during stale check | Pending-work probe paused, sibling becomes busy before atomic release, probe returns false. No close/replacement despite entry activity updates. | Δ | TEST, recording (unit substitute) | D6 T-race. Cannot force this internal order reliably through CLI/settings timing. | Test exists; no recording reviewed |
| F11 Compaction pins then releases | Nonempty thread `/compact` observed in flight; settings change plus sibling open keeps old PID; terminal compaction then next open allows retirement. Manual/idle share this path. | Δ | LIVE if overlap attainable; otherwise TEST substitute with stated limit; recording | D3. T-compact proves pinning only; it does not prove terminal cleanup/retirement. Need live completion or focused deterministic extension to cover that end. | Missing capture; partial test coverage |
| F12 Rollback wins race | Actual rollback started, then settings change plus sibling open. Rollback completes on old runtime, sibling keeps it; later open uses replacement. Success must not leave rollback key busy. | Δ | TEST, recording (unit substitute); ordinary real D4 rollback recommended alongside | D6 T-rollback. CLI can execute D4 but cannot reliably hold native rollback in flight; use exact existing Deferred barrier for overlap. | Test exists; no recording reviewed |
| F13 Release wins rollback race | Old runtime removed from map and scope close held; a caller retains old runtime and tries rollback. It fails; adapter rollback is never invoked; replacement opens. | Δ | TEST, recording (unit substitute) | D6 T-released. No reliable external CLI/RPC barrier exposes map removal before scope close. | Test exists; no recording reviewed |
| F14 Pending background work | Root terminal/idle but tracked work still pending; changed adapter must not retire process. Once pending work becomes false, next open replaces it. | Δ | LIVE, recording; test substitute only with explicit provider limitation | D5. T-race probes false and is not coverage for true. | Missing capture; no direct settings+true test |
| F15 Pending probe unavailable/failed | Undefined probe and false permit idle retirement (covered by T-idle/T-race). A typed failure or defect during probe conservatively keeps old session. | Δ | SUPP, recording (unit substitute for failure) | Cannot inject native probe failure through CLI reliably. No focused settings+failed-probe test exists. | Undefined/false tests exist; error branch gap |
| F16 Registry unavailable during check | Existing session, registry.get fails/instance absent; `Effect.option` yields None, so no retirement from this check. Later no-live-session open still reports ordinary lookup failure. | Δ | SUPP, recording (unit substitute) | Registry injection required to pin transient failure; removing/disabling a real provider may be rejected earlier. No focused stale-check lookup-error test exists. | Source branch only; test gap |
| F17 Start/compact failure or interruption | Failed/stopped start removes its own busy key, never sibling's; normal successful starts remain busy until terminal event. Released runtime must not start on dying process. | R/Δ for compact | TEST for existing start controls; SUPP compact error, recording | D6 T-stopped and T-stopped-terminal. No focused settings+failed-compaction test; T-compact only succeeds without terminal event. | Start tests exist; compact error gap |
| F18 Rollback failure/interruption | Adapter rollback fails or is interrupted; acquireUseRelease clears rollback key; idle stale session can later retire. Stale/replaced runtime still rejected. | Δ | SUPP, recording (unit substitute) | Inject failing/interrupted rollback with Deferred; T-rollback covers successful cleanup only. No focused failure/interruption test exists. | Source finalizer only; test gap |
| F19 Release cleanup failures / timeout | Session removed despite bounded scope-close failure or persistence retry; replacement stays live and its MCP credentials/records are preserved. | R newly exercised by stale open | SUPP, recording (unit substitute) | D6 T-released covers hanging close; T-release-records/T-replacement/T-credentials cover reusable release invariants, not every settings integration. No real process wedging required. | Related tests exist; integration limit stated |
| F20 Adapter identity per build | Auth instance: same object per repeated registry.get; new instance object gives different adapter. No-auth: original adapter unchanged. Instances remain independent. | Δ | TEST, recording (unit transcript) | D6 T-identity and T-routes. Identity itself is not exposed by CLI/RPC; F02 checks its observable consequence. | Exact tests exist; no recording reviewed |
| F21 Auth guard remains live | Memoized wrapper evaluates current auth/related peers on open, refuses changing credentials; withAccess interrupts admitted startup on peer sign-out. | R | TEST, recording (unit substitute) | D6 T-auth-block/T-auth-interrupt. Existing tests cover guard and shared peers; neither repeats open after mutating guard state on the same cached wrapper. | Tests exist; repeated-open variant is supplemental gap |
| F22 Shared/exclusive and per-instance | Shared Codex permits sibling attachment; exclusive provider rejects attaching another thread to same session. Rebuild one instance leaves other instance's adapter/session unchanged. | R | TEST, recording; live two-instance isolation supplemental | D6 T-shared/T-exclusive/T-routes. Live can configure two separate Codex instances; do not infer native Claude/Grok resume from Codex. | Tests exist; cross-provider live behavior untested |
| F23 Reopen failure/recovery | Stale process released; replacement open fails (invalid launch argument or unusable executable), turn reports failure, then correcting config permits another turn. No stale success/no half-open session. | R newly reachable after edit | SUPP, recording | D2 unsafe-to-start scratch wrapper/option, D1, repair, D1; T-interrupted-open only covers interrupted handshake, not this complete sequence. | No capture; partial unit support |
| F24 Workspace and capability preconditions | Missing/file workspace rejected before stale session mutation; unsupported compaction stays absent; empty-history /compact rejected before native compact. Zero-turn rollback skips runtime rollback. | R | SUPP, recording | Existing workspace tests T-workspace and ProviderTurnStartService test `rejects compaction without conversation context after 0 prior compactions`; capability/zero-turn paths source inspected. No UI capture. | Existing controls; no recording reviewed |
| F25 Merge-back replay identity | Changed test harness wraps registry adapter once; sibling fork delta injection/merge-back preserves original native thread and stored history. | Δ test harness | TEST, recording (replay, not live) | D6 T-merge-back, Codex and Claude variants. No product capture can directly prove test-harness object identity. | Replay exists; no output reviewed |
| F26 External account switch | Auth file changes without provider instance rebuild; identity remains same, so this fix does not retire old process. | — | Excluded, recording only if making this claim | Do not log/replace real auth files for this audit. Scope remains with linked account-switch issue. | Explicitly outside PR's implemented claim |
| F27 Concurrent opens / successive rebuilds | Two opens target one stale shared-session ID; only one replacement is installed. Settings change again before the next open; replacement uses the registry's current build, not an intermediate one. | R/Δ | SUPP, recording | Two parallel D1 sibling starts after D2, or deterministic barriers. Existing test `ProviderSessionManagerV2 opens a duplicate session only once` proves cold-open serialization, not settings-race integration. | Related test exists; stale/rapid-rebuild variant unrecorded |

## Exact focused test names

All `T-*` names below are real tests at the reviewed head, not new test proposals. Preserve output at that SHA if using them as substitutes. The manager prefix is part of the full test name.

In [ProviderSessionManager.test.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/ProviderSessionManager.test.ts):

- **T-idle:** `ProviderSessionManagerV2 reopens an idle session on the adapter rebuilt from changed settings`
- **T-race:** `ProviderSessionManagerV2 keeps a session rebuilt settings made stale when a sibling turn starts while it is checked`
- **T-compact:** `ProviderSessionManagerV2 keeps a session rebuilt settings made stale while a compaction runs on it`
- **T-rollback:** `ProviderSessionManagerV2 retires a session settings made stale only after a rollback on it ends`
- **T-released:** `ProviderSessionManagerV2 does not send a rollback to a stale session already being released`
- **T-stopped:** `ProviderSessionManagerV2 keeps a shared session busy when another thread's start is stopped early`
- **T-stopped-terminal:** `ProviderSessionManagerV2 keeps a shared session busy when a stopped start still ends its turn`
- **T-release-records:** `ProviderSessionManagerV2 retries release records that failed to persist`
- **T-replacement:** `ProviderSessionManagerV2 release retries leave a replacement session alone`
- **T-credentials:** `ProviderSessionManagerV2 protects a reused credential from a predecessor release during open`
- **T-shared:** `ProviderSessionManagerV2 opens one shared runtime, broadcasts events, and detaches threads independently`
- **T-exclusive:** `ProviderSessionManagerV2 rejects a second thread when the provider runtime is exclusive`
- **T-interrupted-open:** `ProviderSessionManagerV2 cleans up an open interrupted mid-handshake`
- **T-workspace:** `rejects a deleted workspace before reusing a live session without changing its state`, plus `rejects a missing workspace before opening a provider session` and its `file` parameter variant.

In [ProviderAdapterRegistry.test.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/ProviderAdapterRegistry.test.ts):

- **T-identity:** `returns one adapter per instance build so sessions can detect a rebuild`
- **T-routes:** `routes two configured instances of the same driver independently`
- **T-auth-block:** `blocks a new session while another instance changes their shared provider credentials`
- **T-auth-interrupt:** `interrupts admitted session startup when a shared peer signs out`

In [ThreadMergeBack.integration.test.ts](https://git.cafe/pingdotgg/t3code/blob/5732ee6018fee30328bb7394c8be7e5cd638286d/apps/server/src/orchestration-v2/testkit/ThreadMergeBack.integration.test.ts):

- **T-merge-back:** suite `orchestration V2 merge-back provider replay`, parameterized test `merges two sibling fork deltas into the original $driver thread` (Codex and Claude variants).

## Minimum handoff

One current-head main recording can combine F01–F08, provided it has independent existing-thread-first and new-thread-first settings transitions and an actual home/env capture. A second phase records F09. Record F14 separately with root already terminal. F11 needs established compaction overlap and subsequent retirement; otherwise label the real run inconclusive, use the existing test for pinning, and supply deterministic completion coverage instead of claiming it observed completion. F10/F12/F13 are deterministic-test recordings; include the focused controls F17/F20/F21/F22/F25 in the same test output. Supplemental gaps do not justify inventing a live race or demanding unrelated provider/platform builds.

Coverage: complete five-file diff, changed runtime decorators and direct production callers, instance equality/rebuild boundary, Codex background/compaction paths, exact tests, PR description, issue scope and current status. No runtime validation or full correctness verdict was attempted. All scratch files remain under the specified directory; no processes were started. Free disk at start: 19 GB.

FRICTION: none

VERDICT: INSUFFICIENT F01–F09, F11 and F14 runtime recordings; F10, F12–F13, F17, F20–F22 and F25 focused test recordings
