# Proof audit, pass 1 — fixture matrix

## Findings first

1. **Evidence gap, not a demonstrated implementation defect:** no fresh captures were supplied for this round. The prior evidence uses different commits and does not satisfy this matrix. All mandatory rows below remain **MISSING** until captured at the pinned pair. The new regression alone reaches only changed clauses C4/C5/C6: no explicit `threadIds`, no fork sources, and no active runs means C1/C2/C3/C7 are omitted or skipped.
2. **Additional production entry points:** `getThreadShell` reaches the changed count/provider/pending queries, and fork readers; `getSettlementCandidates` reaches the changed provider/pending queries. Cover them in the same harness rather than treating this as just `getShellSnapshot`.
3. **Combined parameter boundary:** in the old pending-item UNION, the thread-ID and active-run-ID bindings share one statement. 16,384 selected threads with one qualifying running run each already bind 32,768 IDs; its 16,383-thread/run control binds 32,766. Testing only more than 32,766 threads misses this distinct trigger. Likewise an explicit active-location filter adds one binding: 32,766 explicit IDs plus `location: "active"` exceeds the old initial thread query limit, whereas 32,765 does not.
4. **Visual Before/After is NOT required.** No JSX, layout, client state implementation, contracts, provider adapter, theme, width, platform UI branch, or rendering interaction changes. Successful shell delivery restores existing sidebar data and synchronization. Runtime startup logs, authenticated HTTP/RPC payloads, ordered WebSocket transcripts, and focused test transcripts are the appropriate proof. This does not assert that 32,767 rows render smoothly or that native clients were exercised.

## Identity and audit limits

- PR [#25696](https://git.cafe/pingdotgg/t3code/pull/25696), issue [#25621](https://git.cafe/pingdotgg/t3code/issues/25621), repository [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code), branch `fix/issue-25621`, target `main`.
- Before: [d73fd1279a](https://git.cafe/pingdotgg/t3code/commit/d73fd1279a9cbf3ef4677b88b4ad82f0a55583c7). After: [20d22421d5](https://git.cafe/pingdotgg/t3code/commit/20d22421d54cce014bfacdeb9d86de83a00a1e4b). Local HEAD and forge head agree. `git merge-base HEAD d73fd1279a...` returns the pinned base. The local moving `main` ref is older, so do not substitute `git merge-base HEAD main` for the supplied base.
- Entire fixed-base diff inspected: two files, 71 additions and 7 deletions. Only seven membership expressions and one regression test change.
- Read-only source/forge audit only. No tests, captures, browsers, servers, edits to the worktree, pushes, reviews, or comments performed. Current-head CI reports 39 successful checks; this is background, not fresh runtime proof.
- Historical reference only: [earlier evidence index](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/858696b7a26a8cd1/evidence-index.md). No old output counts as a captured row here.

## Changed clauses and immediate reader graph

The changed source is [ProjectionStore.ts](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ProjectionStore.ts#L5787); regression is [ProjectionStore.test.ts](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ProjectionStore.test.ts#L1322). All clauses use the existing schema-based string-array JSON encoder at `ProjectionStore.ts:1173`. SQL membership, exclusions, joins, ordering, and decoding are otherwise unchanged. `json_each` binds one JSON string per list; the pending UNION binds two list strings when present.

| Clause | Changed reader / line | Direct callers and execution condition | Minimum rows |
| --- | --- | --- | --- |
| C1 | `selectShellThreadRows`, 5991: explicit thread IDs | `readShellSnapshotRows` initial target read; reached only with `options.threadIds !== undefined`. Source-ancestor reads and `getThreadShell` call it with a single scalar thread ID and no explicit list, so C1 is absent there. `[]` still executes the initial query and matches nothing. | E2, P7, H2 |
| C2 | `selectShellRunRows`, 6004: fork source IDs | `readShellSnapshotRows:6515`, `getThreadShell:6719`. Only when `forkSourceIds.length > 0`; no-fork snapshots skip the query. | P0, K1 |
| C3 | `selectShellRunItemCounts`, 6011: fork source IDs | `readShellSnapshotRows:6516`, `getThreadShell:6722`; same nonempty fork-source guard. Counts only non-null run IDs. | P0, K1 |
| C4 | `selectShellItemCounts`, 6026: count subquery joined to runs | `readShellSnapshotRows:6517`, `getThreadShell:6723`; snapshot skips when the expanded thread list is empty, single-thread lookup returns early if target absent. Runless items included; rolled-back run items excluded from total. | R1–R3, P0, K1 |
| C5 | `selectShellProviderThreadRows`, 6043 | `readShellSnapshotRows:6524`, `getThreadShell:6724`, `getSettlementCandidates:6205`; nonempty selected/expanded/candidate IDs only. | R1–R3, P0, S1 |
| C6 | `selectShellPendingTurnItemRows`, 6059: pending thread IDs | `readShellSnapshotRows:6526`, `getThreadShell:6725`, `getSettlementCandidates:6206`. First arm selects command_execution/dynamic_tool/subagent, excludes completed/interrupted/failed/cancelled, excludes rolled-back owning runs. Runless items allowed; provider owner joined. | R1–R3, P0, S1 |
| C7 | Same reader, 6068: active-run UNION | Snapshot and single-thread readers supply active IDs only when SQL-selected active run has stored status `running`; preparing/starting runs do not contribute, and waiting is not an `active`-join status. Empty IDs omit UNION. Settlement caller passes default `[]`, so never UNION. Second arm selects file_change/file_search/web_search/compaction in running/waiting state, only on those active runs. | P0, H1 |

`getShellSnapshot` wraps row reads in its own transaction and decodes afterward. `readShellSnapshot` returns the deferred decode for caller-owned transactions. Both use `readShellSnapshotRows`. That function expands run-fork source ancestry (including archived or differently scoped sources), deduplicates already-seen sources, skips missing/deleted sources, then emits only original target IDs. `getThreadShell` has its own equivalent ancestry/read/decode path and returns null for missing/deleted targets. Empty target sets skip C2–C7; empty fork-source sets skip C2/C3. SQL readers' `threadIds === undefined` alternatives in run/provider/pending readers have no current production caller: every call supplies an array. Do not invent a production fixture for these dormant alternatives.

## Caller and surface inventory

- Full snapshots: `ProjectionStore.getShellSnapshot` → `Orchestrator.getShellSnapshot` → `ThreadManagementService.getShellSnapshot` (forwarding). Unscoped callers: server startup heartbeat and optional cwd bootstrap; storage cleanup; project deletion's child listing; checkpoint restore safety's shared-worktree scan; thread launch's shared-worktree branch rename; relay awareness startup snapshot. Scoped callers: `ThreadManagementService.listProjectThreads` (`projectId` + active, then include/exclude subagents and sort), `ThreadPullRequestService.readThreadSnapshot` (active + optional unsettled-only).
- Deferred snapshots: `ProjectionStore.readShellSnapshot` → `Orchestrator.readShellSnapshot` → `ThreadManagementService.readShellSnapshot`. HTTP shell handler and WebSocket initial/fallback shell subscription use active location through `loadShellSnapshotParts`. Archive snapshot/subscription use archive location. Family and worktree RPCs use active + `familyOf` or `worktreePath`. Search's older-settled hydration and older-settled paging use active + explicit `threadIds` (empty pages can skip the reader before it is called).
- Single shells: `getThreadShell` forwarding wrappers and direct consumers are exhaustively indexed below. They include WebSocket snapshot/live/replay and provider-history import paths, dispatch mode checks, startup recovery, run finalization, MCP tools/access, workspace and git/PR operations, cleanup, relay and delegated-task analytics. Their unchanged business interactions collapse onto K1/P0; no need to enact destructive project deletion or real git/forge operations to re-prove SQL membership.
- Settlement: `ThreadSettlementService.sweep` calls `getSettlementCandidates(threadId?)`, once for all candidates or one thread. Candidate eligibility adds active/nondeleted, unpinned, no auto-settle-disable, no settlement override, no active runs (preparing/starting/running/waiting), and no pending runtime requests. Empty candidates return before C5/C6. This read is separate from time-dependent service sweep decisions; S1 tests the read without allowing the sweep to change data.
- Real client path: authenticated `GET /api/orchestration/shell` and `orchestration.subscribeShell` feed shared `packages/client-runtime/src/state/shell.ts` (new sessions fetch authoritative HTTP state, then resume WS; foreground resubscription can resume the current session). Web `Sidebar` / `LegacySidebar` and sidebar row components consume environment thread shells; command palette, thread links/status surfaces and settings also consume these shells. Electron uses the web client; mobile uses the shared shell runtime and its native home/thread list and connection status. These clients all consume the same fixed server result. Local, direct remote, relay and tunnel transports converge on these server readers; no additional origin/transport branch is introduced.
- WebSocket branch map: no `afterSequence` → full snapshot; valid persisted cursor → metadata + event replay via single-shell reads; absent/unreplayable cursor → full-snapshot fallback; completion marker requested/omitted; then live per-thread changes. Subscriber flags (`omitIdleSubagents`, `omitOlderSettled`) filter **after** reading the full active shell, so they cannot prevent the old SQL overflow. Time-based settled/snoozed decisions remain downstream and unchanged.

### Exact current production call sites

The following source index includes wrappers as well as terminal consumers; only non-test server source is included. All links are pinned to the audited head.

| Invoked reader | Source |
| --- | --- |
| `getThreadShell` | [apps/server/src/git/GitManager.ts:680](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/git/GitManager.ts#L680) |
| `getThreadShell` | [apps/server/src/git/linkCreatedPullRequest.ts:64](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/git/linkCreatedPullRequest.ts#L64) |
| `getThreadShell` | [apps/server/src/git/refreshPushedPullRequests.ts:17](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/git/refreshPushedPullRequests.ts#L17) |
| `getThreadShell` | [apps/server/src/mcp/McpHttpServer.ts:809](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/McpHttpServer.ts#L809) |
| `getThreadShell` | [apps/server/src/mcp/McpToolAccess.ts:127](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/McpToolAccess.ts#L127) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:245](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L245) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:1201](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L1201) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:1251](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L1251) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:1273](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L1273) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:1717](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L1717) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:2326](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L2326) |
| `getThreadShell` | [apps/server/src/mcp/OrchestratorMcpService.ts:2545](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/OrchestratorMcpService.ts#L2545) |
| `getThreadShell` | [apps/server/src/mcp/ThreadMetadataMcpService.ts:161](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/ThreadMetadataMcpService.ts#L161) |
| `getThreadShell` | [apps/server/src/mcp/ThreadMetadataMcpService.ts:211](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/ThreadMetadataMcpService.ts#L211) |
| `getThreadShell` | [apps/server/src/mcp/threadAccess.ts:78](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/threadAccess.ts#L78) |
| `getThreadShell` | [apps/server/src/mcp/threadAccess.ts:152](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/threadAccess.ts#L152) |
| `getThreadShell` | [apps/server/src/mcp/toolkits/pullRequests/handlers.ts:223](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/toolkits/pullRequests/handlers.ts#L223) |
| `getThreadShell` | [apps/server/src/mcp/toolkits/pullRequests/handlers.ts:310](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/mcp/toolkits/pullRequests/handlers.ts#L310) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/CheckpointRestoreSafety.ts:47](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/CheckpointRestoreSafety.ts#L47) |
| `getThreadShell` | [apps/server/src/orchestration-v2/Orchestrator.ts:12172](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/Orchestrator.ts#L12172) |
| `getThreadShell` | [apps/server/src/orchestration-v2/Orchestrator.ts:12456](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/Orchestrator.ts#L12456) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/Orchestrator.ts:12698](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/Orchestrator.ts#L12698) |
| `readShellSnapshot` | [apps/server/src/orchestration-v2/Orchestrator.ts:12714](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/Orchestrator.ts#L12714) |
| `getThreadShell` | [apps/server/src/orchestration-v2/Orchestrator.ts:12722](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/Orchestrator.ts#L12722) |
| `getThreadShell` | [apps/server/src/orchestration-v2/RunFinalizationService.ts:108](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/RunFinalizationService.ts#L108) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/ThreadLaunchService.ts:509](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadLaunchService.ts#L509) |
| `getThreadShell` | [apps/server/src/orchestration-v2/ThreadLaunchService.ts:855](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadLaunchService.ts#L855) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/ThreadManagementService.ts:748](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadManagementService.ts#L748) |
| `getThreadShell` | [apps/server/src/orchestration-v2/ThreadManagementService.ts:965](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadManagementService.ts#L965) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/ThreadPullRequestService.ts:123](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadPullRequestService.ts#L123) |
| `getThreadShell` | [apps/server/src/orchestration-v2/ThreadPullRequestService.ts:131](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadPullRequestService.ts#L131) |
| `getSettlementCandidates` | [apps/server/src/orchestration-v2/ThreadSettlementService.ts:317](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/ThreadSettlementService.ts#L317) |
| `readShellSnapshot` | [apps/server/src/orchestration-v2/http.ts:90](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/http.ts#L90) |
| `getThreadShell` | [apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts:365](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts#L365) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts:672](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts#L672) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts:679](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts#L679) |
| `getShellSnapshot` | [apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts:703](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/orchestration-v2/testkit/OrchestratorScenario.ts#L703) |
| `getShellSnapshot` | [apps/server/src/project/ProjectService.ts:449](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/project/ProjectService.ts#L449) |
| `getThreadShell` | [apps/server/src/project/threadWorkspaceRoot.ts:13](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/project/threadWorkspaceRoot.ts#L13) |
| `getThreadShell` | [apps/server/src/relay/AgentAwarenessRelay.ts:516](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/relay/AgentAwarenessRelay.ts#L516) |
| `getShellSnapshot` | [apps/server/src/relay/AgentAwarenessRelay.ts:734](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/relay/AgentAwarenessRelay.ts#L734) |
| `getShellSnapshot` | [apps/server/src/serverRuntimeStartup.ts:156](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/serverRuntimeStartup.ts#L156) |
| `getShellSnapshot` | [apps/server/src/serverRuntimeStartup.ts:282](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/serverRuntimeStartup.ts#L282) |
| `getShellSnapshot` | [apps/server/src/storageCleanup.ts:332](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/storageCleanup.ts#L332) |
| `getThreadShell` | [apps/server/src/storageCleanup.ts:942](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/storageCleanup.ts#L942) |
| `getThreadShell` | [apps/server/src/telemetry/DelegatedTaskAnalytics.ts:46](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/telemetry/DelegatedTaskAnalytics.ts#L46) |
| `getThreadShell` | [apps/server/src/ws.ts:956](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L956) |
| `readShellSnapshot` | [apps/server/src/ws.ts:1028](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1028) |
| `getThreadShell` | [apps/server/src/ws.ts:1083](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1083) |
| `getThreadShell` | [apps/server/src/ws.ts:1464](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1464) |
| `getThreadShell` | [apps/server/src/ws.ts:1506](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1506) |
| `getThreadShell` | [apps/server/src/ws.ts:1555](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1555) |
| `getThreadShell` | [apps/server/src/ws.ts:1596](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1596) |
| `readShellSnapshot` | [apps/server/src/ws.ts:1816](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1816) |
| `readShellSnapshot` | [apps/server/src/ws.ts:1849](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1849) |
| `getThreadShell` | [apps/server/src/ws.ts:1874](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L1874) |
| `readShellSnapshot` | [apps/server/src/ws.ts:2004](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L2004) |
| `readShellSnapshot` | [apps/server/src/ws.ts:2024](https://git.cafe/pingdotgg/t3code/blob/20d22421d54cce014bfacdeb9d86de83a00a1e4b/apps/server/src/ws.ts#L2024) |

## Seed recipes and capture rules

**A — isolated real app, idle data:** capturer initializes an isolated checkout's own `.t3/userdata/statev2.sqlite` with `T3CODE_DEV_SEED=0`, then stops its tracked server before bulk seeding. A seed script adds a real project plus valid idle thread projections, with unique IDs, consistent indexed columns and payload JSON (`id`, lineage root, project, deleted/archived fields). Use schema/migrations from the same pinned revision. Never write to the live home, never copy credentials/customer data into public artifacts, never seed a database while a server owns it. A production RPC driver may create the small valid seed; bulk cloning like the new test is appropriate for scale. Direct projection seeding must be labelled synthetic projection fixture; persist it **after** migrations/rebuilds and record row counts after server startup so any startup replay/rebuild is detected. Select isolated home/ports explicitly, do not set VITE origin variables. Each run gets a new timestamped scratch subdirectory and a fresh database copy from the same seed.

**B — labelled production-service harness:** use the actual pinned `ProjectionStore.layer` with the project's SQLite persistence layer (the existing tests use `SqlitePersistence.layerMemory`). Apply valid events or seed this harness's isolated migrated SQL database. This is a harness capture, not an app/HTTP capture. It is the preferred route for rich provider/pending/active-run rows because startup recovery can cancel or normalize synthetic running state before a real-server probe. These states are reachable in the app via actual provider runs and tools, but creating tens of thousands of active provider runs is unnecessary. B does not start providers. If a real app is used instead, create the state after startup via legitimate RPC/provider fixtures and assert the SQL state at capture time.

**C — ordered focused test/harness capture:** replay the new regression driver at both pinned sources (the baseline does not contain the added test, so explicitly identify how the same test/driver is supplied). Use separate caller-owned transaction/decode steps for X1. Do not count a baseline 'no matching tests' as red. A harness carrying baseline query text must disclose that fact; prefer loading the actual baseline production module. Existing focused tests can discharge corresponding parity rows when their assertions cover the row; print each row-to-test mapping and outcome, not merely a suite total.

Every transcript must identify full source SHA, driver hash/version, Node/SQLite versions, effective SQLite variable cap, seed recipe/hash, exact SQL row counts, filter inputs and expected/actual assertions. Runtime captures include command, isolated home, startup readiness or complete causal failure chain, HTTP status/response schema/counts and ID digest, and WS stream/frame kind/sequence/counts as applicable. The startup heartbeat catches its snapshot failure as a warning; cwd bootstrap has a separate conditional unscoped read. Therefore a baseline startup failure is configuration-dependent, not a required universal outcome. Capture the actual baseline startup result and causal SQL error. If baseline startup is fatal, mark HTTP/WS probes blocked by startup rather than fabricating responses; if it stays up, execute the baseline HTTP/WS probes and preserve their actual snapshot errors. R1 proves the probe works below the boundary. After captures must show healthy startup and actual authenticated delivery. Omit auth tokens/pairing URLs from uploaded logs.

**`recording` means an ordered runtime transcript, not video.** All rows that involve startup, live events, reconnect, state transitions, deferred decoding or current-time filtering are marked recording. Static service-read rows need deterministic transcripts. Fix/freeze the comparison clock for time-dependent parity; never use sleeps/polling as synchronization. Observe readiness/events, drain the effect worker where applicable, or await the named milestone. Assertion counts and sequences are proof; incidental timings are not assertions.

## Fixture matrix

Status legend: **MISSING** = mandatory fresh capture needed; **OPTIONAL** = useful additional stress, not minimum acceptance; **N/A** = static coverage, no runtime capture required. Rows sharing a seed can run in one transcript, but every row ID and assertion must be printed. 'Both' means the identical fixture at the pinned before/after pair. No row is marked captured in pass 1.

| ID / named fixture | Data and distinct input combination | Diff affected / observable assertion | Minimum capture / type | Seed and real-app feasibility | Status |
| --- | --- | --- | --- | --- | --- |
| R1 — 32,766 idle control | Exactly 32,766 live active threads; no runs, items or provider threads. No options and active location reads. | C4/C5/C6 prepare at the old limit; both succeed with exact thread membership/count, no archived rows. C1/C2/C3/C7 absent. | Both; real startup plus authenticated HTTP and initial WS control; **recording**. Also focused service assertion. | A, real app. Same generator as R2, only count differs. | MISSING |
| R2 — 32,767 idle incident | Exactly 32,767 live active threads; no runs/items/providers. Unscoped and active snapshots. | C4/C5/C6 bind 32,767 old IDs; baseline has causal `too many SQL variables`, head succeeds with all IDs. Covers issue's startup/unscoped and active read. | Both; red/green regression and real startup; **recording**. Record whether baseline read failure is fatal or logged; probe baseline endpoints if startup remains ready. | A + C. Real app seeded identically at both revisions. | MISSING |
| R3 — large authenticated HTTP delivery | R2 seed after head startup. HTTP `GET /api/orchestration/shell`, omission flags off. Also issue a request with both supported omission flags on. | Active read C4/C5/C6 occurs before omission; 200, correct schema/sequence, 32,767 IDs when all are ordinary root threads. No SQL overflow with flags on. | Head actual endpoint transcript, baseline/control as R2/R1; probe baseline if ready, otherwise label startup-blocked; static request/response transcript. | A, real app. Do not claim native/browser rendering. | MISSING |
| R4 — large WS and continued synchronization | R2 head seed. Initial subscribe without cursor; completion marker both requested and omitted; mutate one thread title by real RPC; resume at valid cursor, then force unreplayable cursor fallback. | Initial/fallback full readers and live/replay `getThreadShell`; initial membership preserved, title update received, monotone sequence/completion semantics, no missing/repeated membership after resume. | Head RPC stream + commands, baseline/control as R2/R1 (probe baseline if ready, otherwise label startup-blocked); **recording**. All interactions can share one bounded driver session. | A, real app via RPC driver; no browser needed. Wait on frames/milestones. | MISSING |
| R5 — archived population counts internally | Exactly 1 active + 32,766 archived live idle threads, plus one deleted sentinel. Unscoped, active, archive reads. | Unscoped includes 32,767 and overflows before; active succeeds with 1 on both; archive succeeds with 32,766 on both; deleted never appears. Head unscoped splits arrays exactly. | Both service harness transcript; startup/HTTP optional since R2/R3 cover them. | B (or A if actual archive RPC desired); real app feasible. | MISSING |
| E1 — empty population / no-match | Empty database, then deleted-only population, then a nonempty DB with unmatched project or family/path. No explicit ID list. | Empty target IDs skip C2–C7; schema/sequence valid, both arrays empty, no stray background work. Reader error is not expected. | Both, one static labelled harness transcript with subcase assertions. | B; all app-reachable; not separate servers. | MISSING |
| E2 — explicit empty list | Rich P0 DB, `{ threadIds: [] }`. | C1 executes with empty membership; no threads, downstream readers skipped. Demonstrates equivalence with old empty `sql.in`. | Both static harness transcript. | B; RPC older-page/search often bypasses empty hydration, so direct-store invocation is labelled harness. | MISSING |
| P0 — rich unscoped parity | Small valid DB: two projects; active, archived, deleted threads; root/subagent/fork; completed/rolled-back/queued/preparing/starting/running/waiting runs across separate threads; provider threads with and without owners/goals; runless and per-run items. Include command/dynamic-tool/subagent pending and terminal statuses, nonpending assistant item, file-change/search/web-search/compaction running/waiting and terminal controls on active and inactive runs. | Executes C2–C7 with nonempty result data. Compare canonical complete shells and explicitly assert itemCount/runless/visible count, provider owner order/goal, pending background tasks, active run/status, blockedOnThreadWait. Terminal/rolled-back/inactive-run controls excluded as before. Realistically mixed provider data proves JSON filter preserves data, not just empty-query preparation. | Both static B transcript; **recording** if statuses are transitioned rather than preseeded. Derive expectations from existing fixtures/helpers rather than invented invalid payloads. | B preferred. Real app reachable via provider/tool activity but startup recovery makes preseeded running data unsuitable as unattended startup evidence. | MISSING |
| P1 — active parity | P0 with `location: "active"`; IDs undefined. | C4–C7 as appropriate; excludes archived/deleted, retains applicable pending/provider/count data. | Both static harness; may share P0 output. | B; exact HTTP/WS read filter. | MISSING |
| P2 — archive parity | P0 with `location: "archive"`; IDs undefined. | Same membership readers for archive targets; no active leak. Fetch archive snapshot, then archive/unarchive one thread and observe archive stream move/removal if using RPC. | Both static harness minimum; **recording** for optional actual archive RPC transition. | B; real archive API/subscription reachable. | MISSING |
| P3 — project parity | P0 active + projectId set, then absent/missing project control. | Thread row project predicate AND membership; selected project only; fork ancestors from another scope may load internally without leaking into targets. | Both static harness, existing project-scoped test can cover the store contract. | B; app via listProjectThreads (postfilter includeSubagents on/off has no changed SQL branch). | MISSING |
| P4 — unsettled parity | P0 active; unsettledOnly false vs true. Include settledAt-null with settledOverride-settled, non-null settledAt and ordinary unsettled controls. | Same membership readers; true requires both no settled timestamp and no explicit settled override. | Both static harness. | B; app via PR refresh/backfill. No real PR/network refresh necessary. | MISSING |
| P5 — family parity | P0 active + familyOf root, descendant, deleted root, and missing member. Include separate family sharing worktree. | Same root family only, no unrelated or archived targets; deleted root may still identify live descendants; missing → empty. | Both static harness; **recording** if deleting the root during capture. Existing family test covers transitions. | B; app via getThreadFamily RPC on expand. | MISSING |
| P6 — worktree parity | P0 active + exact worktreePath, then missing path. Include null path and another root on same path. | Exact stored path equality and active filter; independent roots sharing path included, null/different/archived excluded. | Both static harness (getWorktreeThreadIds RPC optional). | B; real app reachable via worktree lookup, no filesystem operation needed. | MISSING |
| P7 — explicit IDs and filter intersection | P0 active + explicit IDs: one, repeated ID, nonexistent ID, string containing quote/backslash/non-ASCII; include one archived ID. Then combine IDs with project/family/worktree filters on known intersecting and disjoint data. | C1 exercised; membership neither duplicates targets nor interprets escaped text as SQL; all filter predicates remain ANDed, no scoped data leak. | Both static harness; existing app hydration RPCs can supplement but do not expose arbitrary full option combinations. | B; direct-store combined-filter harness. RPC search/older page reaches active + IDs. | MISSING |
| K1 — fork and single-thread parity | P0's run-fork target plus nested fork, archived/out-of-scope source, imported runless source items, rolled-back source run; missing/deleted source and missing/deleted target controls. No explicit ID list in ancestor reads. | C2/C3/C4/C5/C6 and C7 if target/source has running run; `getThreadShell(target)` equals its snapshot shell, inherited visibleItemCount correct, ancestors not emitted as scoped targets, absent target returns null, absent source terminates cleanly. | Both static harness; existing imported-fork and rolled-back-source focused tests can discharge relevant assertions. | B. Fork creation reachable through RPC; missing/deleted projections intentional harness controls. Cyclic invalid ancestry is unchanged guard logic, not extra minimum seed. | MISSING |
| H1 — combined running-run boundary | 16,383 then 16,384 live active threads, one non-silent stored running run per thread, at least one matching second-arm pending item (or per-run item for stronger data check). No forks, no explicit IDs. | C6+C7 share 32,766 then 32,768 old bindings. Before control succeeds / larger fails; after both succeed and second-arm items reach expected shell background/block state. C4/C5 alone remain below old limit, isolating UNION trigger. | Both static production-service harness transcript; **recording** only if transitions drive the run state. | B required for minimum proof; app technically reachable with actual live provider runs, but scale/recovery makes that inappropriate for simple seeded startup. Do not label this as real app evidence. | MISSING |
| H2 — explicit-ID initial-query boundary | Idle IDs selected with active location: 32,765-ID control, then 32,766 IDs (location adds one old parameter). Include nonexistent IDs only in separate P7 controls. | C1 old initial query fails before downstream count reads at 32,767 total variables; head returns every requested active thread in existing sort order. | Both static production-service harness transcript. | B; direct store uses same initial reader as search/page hydration. Public RPC page limits mean this exact huge array is labelled harness. | MISSING |
| S1 — settlement reader | R2 idle candidate seed (32,767 eligible) and small P0-derived candidate DB. All-candidate and scalar-thread selection; zero candidates controls: archived/deleted/pinned/disabled/settled override, active run, pending runtime request. Include pending runless background items/provider goal for an eligible candidate. | C5/C6 also fixed outside snapshot path. Large baseline fails/head reads all candidates; small before/after complete candidate parity; scalar and empty return correct sets. C7 never present. | Both static harness; **recording** only if exercising actual timed sweep (not required). | B. Real service sweep is reachable but may mutate/settle threads based on time/settings; minimum capture calls the reader directly and does not claim timed settlement was tested. | MISSING |
| X1 — deferred decode and typed failure | Small valid thread; acquire `readShellSnapshot` decode inside transaction, create second thread, then invoke prior decode. Separately selected malformed payload vs corruption outside scoped project. | Deferred snapshot excludes later insert while fresh get includes it; error remains ProjectionStoreReadError with shell context; scoped read excludes corrupt outside data. Membership changes must preserve transaction/decode behavior. | Both focused existing test/harness transcripts; **recording** for read→insert→decode ordering. No new test required. | C, labelled harness; malformed stored JSON is not an ordinary RPC seed. | MISSING |
| O1 — >32,766 distinct fork sources | 32,767 fork targets each referencing a distinct source (65,534 total thread rows), sources with runs/items; select targets only. | Stress C2/C3 fork-source membership at scale. Not necessary beyond P0/K1 exercising both readers, H2 proving JSON-list scaling and the shared encoder/SQL shape audit. Can be costly due to serial ancestor fetches, an existing behavior. | Optional both harness stress; not a minimum acceptance gate. | B. Real app bulk seed feasible; no provider processes needed. | OPTIONAL |
| N1 — dormant undefined readers | `selectShellRunRows(undefined)`, provider reader undefined, pending reader undefined. | These alternatives have no current production call site; changing list membership does not execute there. No fabricated caller required. | Source trace only, no capture. | Internal functions not exported; no ordinary real app path. | N/A — traced |
| N2 — UI variants / transport duplication | Empty/loading/error appearance, dark/light, narrow/wide, Electron shell, iOS/Android; local/remote/relay/tunnel; provider adapter selection. | No changed UI or transport branch. Server failure/success and schema/membership checked by R1–R4; P0 includes provider-owned data. No browser/native visual or OS/provider cross product required. | No visual Before/After, screenshot or video required. | Not a changed-render fixture. Do not infer native rendering from server proof. | N/A — scope exclusion |

## Minimum capture set / bundling

1. **Real app bundle:** R1 control; R2 pinned baseline SQL failure (record startup result) and head successful startup; R3 authenticated head HTTP delivery; R4 initial/live/resume/fallback head WS recording. Same deterministic idle generator. When baseline startup fails, label baseline R3/R4 blocked; when it remains ready, capture actual baseline endpoint errors. Successful control R1 validates the probe.
2. **Shared rich/empty harness bundle:** E1/E2, P0–P7, K1; one deterministic rich fixture plus empty/deleted controls and per-row assertions at both revisions. This discharges every changed clause with nonempty business data and every affected selection branch without creating a browser matrix.
3. **Boundary/other-reader harness bundle:** R5, H1, H2, S1; reuse bulk clone helper with counts/statuses/archives parameterized. H1 is specifically needed for the second-arm UNION boundary; H2 for the explicit-list clause. O1 remains optional.
4. **Focused test bundle:** fresh red/green output of the added 32,767 regression (R2), plus existing deferred-decode/typed-read tests (X1). Existing focused parity tests may replace duplicate rich harness assertions when mapped explicitly. Whole-repo tests and new permanent tests per row are not requested.

Coverage sufficiency requires all MISSING rows above to have fresh asserted results (including explicitly documented baseline-startup-blocked probes), not one independently launched server per row. Capture plans alone and CI green do not promote row statuses.

FRICTION: none

VERDICT: INSUFFICIENT R1–R5, E1–E2, P0–P7, K1, H1–H2, S1, X1 need fresh captures at the pinned revisions
