# Server evidence index

For draft [#22833](https://git.cafe/pingdotgg/t3code/pull/22833), mirrored as [#22834](https://github.com/pingdotgg/t3code/pull/22834), branch `fix/issue-15357`. This packages existing primary-agent captures and the accepted pass-1 proof matrix for a second audit. The packaging agent inspected the supplied artifacts and committed fixtures; it did not witness or replay the browser sessions, launch a server, rerun tests, or change implementation. Pass 1 returned SUFFICIENT; pass 2 is pending.

## Revision binding

- **B (before):** [1688f96568](https://git.cafe/pingdotgg/t3code/commit/1688f965682d331da16a8c39f049592361f69c8d), full SHA `1688f965682d331da16a8c39f049592361f69c8d`, the pinned merge-base against main. The baseline transcript records its ten-character abbreviation. This is not a claim about the current main tip.
- **H (after):** [bc74467048](https://git.cafe/pingdotgg/t3code/commit/bc7446704898fbdd19e25542f0924e0472e9f655), full SHA `bc7446704898fbdd19e25542f0924e0472e9f655`. Both after transcripts record the full SHA. Local checkout was independently checked at H with a clean status during packaging.

## Public artifacts

- [Accepted fixture matrix and pass-1 proof audit](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f172d571e3c50874/proof-matrix.md): seven rows, detailed seeds, assertions and exclusions.
- [Baseline setup narrative](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7dc988f8c7ec9126/baseline.md): primary's environment, launch commands, crash/restart procedure and cleanup account.
- **E0:** [Before PID transcript, B](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c0b087d22e41cd37/runtime.txt): systemd and no-systemd baseline.
- **E1:** [After no-systemd PID transcript, H](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7395aef4b9aa4d6d/after-runtime.txt).
- **E2:** [After systemd PID transcript, H](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/734ccf5c6ce91a0c/systemd-runtime.txt): includes meaningful active-tool Codex comparison and redacted restart excerpt.

Raw `after.log` and `systemd-after.log` contain pairing credentials and are not uploaded. No new supplemental log is needed: E0–E2 plus the scoped fixtures meet the accepted matrix. The truncated E1 restart excerpt is not evidence of precise CLI-death timing.

## Before | After by matrix row

Runtime captures cover **3/7 rows (R1–R3)**. Accepted scoped evidence covers R4–R6 and supplements R1–R3. Thus **6/7 rows have accepted evidence**, with R7 explicitly unverified; this does not mean six integrated runtime captures.

| Row | Before (B) | After (H) | Evidence type and limit |
| --- | --- | --- | --- |
| R1: no-systemd Claude crash/restart | [E0](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c0b087d22e41cd37/runtime.txt): backend 20934; Claude 22811/23324 survive crash and restart; original runs cancelled and continuations running. | [E1](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7395aef4b9aa4d6d/after-runtime.txt): backend 51528; Claude 53331/53871 survive crash then are absent after restart; original runs cancelled and continuations running. | Real app runtime plus scoped startup-barrier test and production layer wiring. E1 samples 11:42:15 and 11:42:28 bracket recovery at 11:42:22.329; they do not timestamp CLI death before recovery. Bash/sleep 54343/54344 and 54627/54628 remain at the after sample. |
| R2: systemd cleanup order | [E0](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c0b087d22e41cd37/runtime.txt) and [baseline narrative](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7dc988f8c7ec9126/baseline.md): backend 13717; Claude 15367/16413 survive crash; recovery 11:14:29.335 precedes lazy cleanup 11:14:29.813; sampled PIDs absent by 11:14:33. | [E2](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/734ccf5c6ce91a0c/systemd-runtime.txt): backend 59868; Claude 64721/65109 and recorded scope members survive crash then are absent after restart. Cleanup call logged 11:46:22.587, recovery 11:46:23.986. | Runtime plus fake-systemd acquisition-order fixture. Awaited systemctl stop and fixture bridge the gap between cleanup-call timestamp and later PID absence; no individual exit timestamp is claimed. |
| R3: Codex comparison | [E0](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c0b087d22e41cd37/runtime.txt): wrapper 17036/CLI 17063 disappear after crash. No tool startup was captured. | [E2](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/734ccf5c6ce91a0c/systemd-runtime.txt): wrapper 65489/CLI 65536, codex-code-mode 66709 and sleep 66717 are present before crash and absent before restart. Continuation completes. | Real app systemd comparison plus shared-scope policy fixture. Baseline is CLI-only; meaningful active-tool evidence exists only at H. No no-systemd Codex active-tool capture. No Codex adapter change or new Codex ledgering. |
| R4: ownership and PID identity | No dedicated runtime capture at B; [matrix R4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f172d571e3c50874/proof-matrix.md) defines deterministic scoped seeds. | [Committed ownership fixtures at H](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/process/agentScope.test.ts): matching dead-owner orphans removed; live-owner providers, unrecorded sibling and mismatched provider identity preserved; mismatched owner identity does not protect orphan. | Scoped real Node subprocesses, not real-provider runtime. PID reuse simulated by start-time mismatch, not forced OS reuse. Fake-systemd fixture preserves a slice with another live owner. |
| R5: record before CLI execution | No dedicated runtime boundary capture at B; [matrix R5](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f172d571e3c50874/proof-matrix.md) defines the seed. | [Committed production-SDK/fake-CLI fixture at H](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/process/agentScope.test.ts) observes its own PID in the ledger at executable entry and removal after SDK close. [E1](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7395aef4b9aa4d6d/after-runtime.txt) separately shows successful real-Claude launch/recovery. | Scoped production SDK and default spawn callback with credential-free fake CLI. E1 does not itself capture record-before-exec. No injected gate/write-failure runtime fixture. |
| R6: normal completion/cancel/exit | No dedicated real-Claude normal-exit/cancel capture; see [matrix R6](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f172d571e3c50874/proof-matrix.md). | [Adapter fixtures at H](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts) cover completion and Stop/interrupt; [SDK fake-CLI fixture](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/process/agentScope.test.ts) covers close and ledger removal. | Accepted scoped compatibility evidence only. Real-Claude normal completion/cancel remains unverified. Crash continuations do not establish normal-exit coverage. Completion may correctly retain an idle session/CLI. |
| R7: other OS / packaged desktop / other providers | No runtime capture; [matrix R7](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f172d571e3c50874/proof-matrix.md). | No runtime capture; [platform guards at H](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/process/providerProcesses.ts) and representative Codex/terminal scope tests are code/scoped evidence only. | Explicitly unverified macOS, Windows, desktop-bundled Linux and every-provider launch compatibility. Linux source-dev captures cannot establish packaged or cross-platform behavior. |

## Scoped proof, separate from app runtime

Existing committed fixtures fulfill the scoped rows; no new seeding data or PR-only repository assets are needed. The app scenario was set up through the UI procedure below, not checked-in artificial app data.

From `/home/ubuntu/wt/issue-15357` at H, the pass-1 command was:

```sh
node_modules/.bin/vp test run apps/server/src/process/agentScope.test.ts apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
```

Pass 1 independently ran **213 passing tests across 2 files**, exit 0, at 2026-10-21 11:51 UTC. The code reviewer independently reported **229 passing tests across 5 files**. The initial implementation reported **226 scoped passes**. These are distinct runs/scopes; do not add them together or call them runtime reproductions. This packaging step did not rerun them. Both round-1 code reviewers returned MERGE with no confirmed findings; that is separate from the proof assessment.

For the planned pass-2 single-fixture rerun at H (not executed here):

```sh
node_modules/.bin/vp test run apps/server/src/process/agentScope.test.ts -t 'stops both recorded survivors before startup completes and leaves an unrecorded process alone'
```

Relevant exact fixture names in `agentScope.test.ts`:

- `stops both recorded survivors before startup completes and leaves an unrecorded process alone`
- `preserves a live server's provider and a reused provider PID while reaping a matching orphan`
- `does not mistake a reused owner PID for a live owning server`
- `stops agents a killed server left during acquisition before the first launch`
- `does not stop the owned slice while another recorded server is alive`
- `records the production SDK child before it executes and forgets it after exit`
- `keeps shared Codex scopes running without attributing their OOM to the launch thread`

Adapter compatibility fixtures include `stops background work after the turn settled` and parameterized `settles a plain background subagent and its open call on %s after the root turn completes` (exit/Stop). The production startup barrier is [AgentScope acquisition](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/process/agentScope.ts), provided into [server runtime services](https://git.cafe/pingdotgg/t3code/blob/bc7446704898fbdd19e25542f0924e0472e9f655/apps/server/src/server.ts). This wiring and the subprocess fixture establish R1 ordering, rather than E1's coarse samples.

## Environment and repeat procedure

Captured environment: Linux x86_64 VM, primary-reported canonical machine `freestyle`, display `fs-27`; source dev server with real provider CLIs and a real browser at `http://localhost:6475`, backend `http://localhost:14515`. No UI render path changed, so browser DPR, theme, viewport and pixel diffs are irrelevant under the explicit SERVER-ONLY override. Web/mobile/remote clients use this host-side startup path; their individual connection flows were not separately tested.

The following reconstructs the supplied capture procedure for an authorized primary agent; the packaging agent did not execute it. Run B then H serially in the existing worktree, with all owned dev processes stopped before changing revision. Keep one isolated home per comparison, reuse that home's state across crash/restart, never use the live `~/.t3/userdata`, and do not set `VITE_HTTP_URL` or `VITE_WS_URL`.

Baseline systemd launch (user manager available):

```sh
env -u T3CODE_HOME node_modules/.bin/vp run dev --home-dir /home/ubuntu/wt/issue-15357/.t3
```

Baseline no-systemd launch:

```sh
env -u T3CODE_HOME -u XDG_RUNTIME_DIR T3CODE_DEV_SEED=0 node_modules/.bin/vp run dev --home-dir /home/ubuntu/wt/issue-15357/.t3
```

Corresponding H isolated homes were `/home/ubuntu/wt/issue-15357/.t3-after` (no-systemd) and `/home/ubuntu/wt/issue-15357/.t3/systemd-after` (systemd). Substitute those explicit `--home-dir` values in the respective commands. The local dev-runner headers confirm those homes and ports. The matrix identifies the environment branches; this index is not a new shell-environment capture.

1. Record the full checkout SHA, retained dev-runner PID and actual ports from the dev-runner line. Pair locally using the private startup link, without publishing it.
2. In the browser, select the isolated environment/project, create two distinct Claude threads, and send each: “Run Bash `sleep 120` in foreground, timeout 180000; no other tools/files/agents.” Wait for both foreground tools. For systemd comparison add a Codex thread doing foreground `sleep 120` and wait for tool startup.
3. Retain backend/provider/tool PIDs from the owned launch/scope records. Capture timestamped `ps` columns PID, PPID, PGID, STAT, COMMAND for those exact PIDs before crash. Confirm `/proc/<backend-pid>/cwd` is this worktree's `apps/server`, then SIGKILL only that captured backend PID. Never select processes by argv/path pattern.
4. Sample the same exact PID set after crash and before restart. The first immediate E0 systemd sample still contains the old backend; use the later before-restart sample to establish orphan survival.
5. Restart the watched backend by `touch apps/server/src/bin.ts` (mtime only, no source content edit), retaining the same isolated home and launch environment. Sample old PIDs again after restart; read run states through a read-only snapshot of the isolated SQLite state. Capture cleanup/recovery lines with credentials omitted. Record original ordinal-1 cancellation and ordinal-2 continuation status.
6. Stop only the processes owned and retained by that run and the retained dev-runner. The primary already performed its capture cleanup. No new server or browser was started here, and no new server cleanup is needed.

## What else changed and remaining limits

- Linux Claude launch now uses a gate and per-launch identity ledger so the CLI is recorded before execution; SDK exit removes its record.
- Startup reconciles recorded orphan CLIs and eagerly awaits systemd cleanup before recovery. Live owners and unmatched identities are preserved by the tested guards.
- Visible cancellation and continuation behavior is unchanged in the crash captures: original runs cancel and recovery starts continuations. Normal completion/Stop compatibility is scoped-test evidence, with the runtime limit in R6.
- No-systemd Bash descendants remain at the post-restart sample. Their eventual exit was not observed; arbitrary-grandchild cleanup is excluded.
- Codex has no adapter diff and is not newly ledgered. Shared AgentScope initialization changes; representative Codex/terminal policies are tested, not every provider configuration.
- No UI, client contract, navigation, transport-origin or rendering changes. No screenshots/pixel comparisons are claimed.
- Pre-upgrade survivors without records are excluded. Boot/identity checks do not eliminate the remaining identity-read-to-signal race without pidfds. Several defensive guards are code-inspected rather than separately fixture-tested, as disclosed in the matrix.

Friction categories: **tool** — singular GitCafe `/pull/` URL rejected by native thread linking; explicit host/repository/number succeeded. **brief** — pass-1 caveats must remain attached to runtime and scoped evidence, especially R1/R6. **policy** — server-only override and primary-owned capture workflow prohibit new subagent servers/browsers; raw pairing logs cannot be published. No new runbook, infra, forge-read, model or other blocker. No `gh`, forge reads, public forge writes/comments/merge, implementation edits, commits or new runtime captures were used in packaging. Evidence uploads use ghdrop. Root filesystem had 9.2 GB free at packaging checks, above the 2 GB stop threshold; work completed within the 120-minute budget.
