> **Amended by the lead for head 8d6e64c6c2** (after SHA and code links → 8d6e64c6c2; R8a/R8b expected outcomes and minimum evidence; probe-error recovery in both services; §6 exit-status requirement). Original: https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e166c4f17de3265f/matrix.md

# Proof audit pass 1 — runtime fixture matrix

Findings first:

1. **No render paths changed.** The complete four-file diff contains only two server services and their tests. There are no component props, layouts, themes, widths, client-platform views, or browser interactions to capture. Viewport × theme is **N/A × N/A** for every row. Here **recording** means a timestamped runtime transcript, not a screenshot or screen video.
2. **The reference matrix is incomplete for this head.** Its R1–R5 describe discovery only. Both changed services need the filesystem controls; the untouched-thread sweep needs its own timed recording; and both services need probe-error rows (at 8d6e64c6c2 both keep the worktree on a probe error). This matrix extends R1–R5 to both services, retains R6, makes R7's mandatory subcases explicit, and adds R8 for discovery probe errors.
3. **A settlement capture can accidentally test a no-op.** `thread.unsettle` sets `settledOverride:"active"`; settlement excludes every non-null override. Use separate ordinary untouched settlement threads. Visible entries in `pullRequests` also bypass the changed lookup map. R7 therefore uses an empty visible collection and a legacy `linkedPullRequest` or `branchPullRequest` reference.
4. **Observe local Git and remote PR outcomes separately.** A successful remotes span proves local `git remote` succeeded at the selected cwd. It does not prove host API success, a detected PR, sync persistence, or automatic settlement. Synthetic recognizable origins are sufficient for this narrow cwd correction. Preserve subsequent API failures rather than describing them as successful discovery.
5. **A seeded restart alone does not isolate settlement Git reads.** Both workers start together and share GitManager's local-read cache. Use disjoint no-remote settlement repos as detailed below; discovery skips them before lookup while settlement performs the real Git command.
6. No production defect was established in this proof-planning pass. No capture is accepted from an older revision. All rows below are ready to capture; evidence remains pending. This is a matrix verdict, not a merge or runtime-verification verdict.

Reviewed [#24803](https://git.cafe/pingdotgg/t3code/pull/24803), branch `fix/issue-24797`, checkout `/home/ubuntu/wt/pr-24803`. Exact before: [32ecd71726](https://git.cafe/pingdotgg/t3code/commit/32ecd71726fee16f335484c1f95cbce126d461f6); exact after: [8d6e64c6c2](https://git.cafe/pingdotgg/t3code/commit/8d6e64c6c2779f420da8cb60cf6f6f816756769c). GitCafe head/base metadata agrees, and the explicit pair's merge-base is the supplied before revision. The local `main` ref is older, so it must not replace the specified before SHA. Full hashes are `32ecd71726fee16f335484c1f95cbce126d461f6` and `8d6e64c6c2779f420da8cb60cf6f6f816756769c`.

Read-only forge snapshots: [PR metadata](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3891eb1b444d3e8f/pr-metadata.json), [revision-bound status](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/12a386823edf3e14/pr-status.json). CI status is background information, not proof of any planned runtime row.

## Shared fixtures and minimum captures

`P` is a synthetic regular project repo, outside any parent Git checkout, with an empty commit and existing non-null branch `F`. `W` is a distinct stored worktree path. `C` is a distinct regular clone/repo with the same branch and remote configuration. No synthetic remote is pushed. **Use disjoint repos for D and S.** D's P/C have a recognizable origin (for example `git@github.com:acme/project.git`) so discovery passes its identity guard. S's P/C have **no remotes**: discovery then stops at its unresolved-identity guard, while settlement (which has no such guard) performs real `git remote` and returns null on the empty remote list. This avoids discovery populating the shared Git cache first. Record both profiles in the manifest; they are identical between revisions for each service.

For R1–R5 create separate `D` discovery and `S` settlement threads per row, or equivalently capture settlement before any manual override on a shared thread. Prefer separate threads to remove that ordering hazard. Common thread data: ordinary top-level user thread, existing project, unarchived, `settledAt:null`, `settledOverride:null`, unpinned, auto-settle enabled, no snooze, no run, no user message, no pending request/guest/background work, empty `pullRequests`, null legacy PR references. Configure `sidebarAutoSettleOnMerge:true`, `sidebarAutoSettleAfterDays:null`, no overriding project settings. This enables sweeps while preventing inactivity from settling the fixture before branch lookup.

Every table entry is **recording**. READY means the plan is complete, not that evidence exists. Minimum capture dimensions are two exact source revisions × the named row/subcase × its listed service phases; viewport/theme are N/A. Files may combine rows if IDs, trigger boundaries, and trace ancestry remain unambiguous.

| Row | Fixture / data | Before → after expected observable result | Diff effect | Seed and trigger | Minimum evidence / status |
| --- | --- | --- | --- | --- | --- |
| R1 | **Folder survives without `.git`.** `worktreePath=W`; W exists, W/.git absent, F remains in P. | **D and S:** W / `not_a_repository` → P / local git success. | Changed regression target in both services. | `git init -b main P`; empty commit; add origin for D only; `git -C P branch F`; `git -C P worktree add W F`; move W/.git to an owned preserved sibling, leaving W empty. Create D/S via real RPC with their disjoint W/F. D: two settle/unsettle cycles after initial creation. S: seeded restart, no manual override. | Both sides: two forced D refreshes and one S startup sweep; parent service spans + remotes cwd/exit/cause. No remotes attempt at W after. **READY / runtime pending.** |
| R2 | **Missing folder.** `worktreePath=W`, W and W/.git absent. | **D and S:** P / local git success → same. | Preservation: false folder probe becomes false marker probe. | Use a never-created owned W; persist W/F with `thread.create`. D forced refresh; S seeded restart. | Both sides: one forced D refresh + one S startup sweep with actual P remotes operations. **READY / runtime pending.** |
| R3 | **Valid linked worktree.** W/.git is a file with valid `gitdir:` target. | **D and S:** W / local git success → same. | Preservation of marker-present true branch; normal linked-worktree layout. | `git -C P worktree add W F`; record file type and `git -C W rev-parse --git-dir`. Persist W/F. D forced refresh; S seeded restart. | Both sides: one forced D refresh + one S startup sweep at W, not P. **READY / runtime pending.** |
| R4 | **Regular repo at worktreePath.** `worktreePath=C`; C/.git is a directory; C distinct from P. | **D and S:** C / local git success → same. | Preservation of other valid marker type. | Initialize C with an empty commit, same remote profile as P (recognizable for D, absent for S), F checked out; persist C/F through RPC. A project-root-only repo does not cover this row. | Both sides: one forced D refresh + one S startup sweep at C, marker directory facts. **READY / runtime pending.** |
| R5 | **Null worktreePath.** `worktreePath:null`, branch F. | **D and S:** P / local git success → same. No filesystem probe. | Preservation of null short-circuit. | `thread.create` with branch F and null path. D forced refresh; S seeded restart. | Both sides: one forced D refresh + one S startup sweep at P. Source establishes no probe; do not invent a probe log. **READY / runtime pending.** |
| R6 | **Untouched R1 thread, periodic settlement.** One ordinary S thread, W exists without marker, no remotes or PR references, no post-create thread mutations. | Startup and periodic S: W / repeated `not_a_repository` → P / successful local Git reads; later reads may use existing cache. Lookup returns null after and thread remains eligible/unsettled. | Changed timed retry path, independent of manual refresh and discovery's foreground gate. | Create through RPC, stop the owned server, restart same isolated home with marker already absent. Keep a headless RPC observer if desired, but send no activity lease and no mutation after restart. Record settings and final projection. | Both sides: seeded startup plus **two consecutive real one-minute periodic** `ThreadSettlementServiceV2.sweep` completions. At least one fresh local Git read beneath S per side. Record cache-related absence accurately; exact 16-sweep/3-read counts are not required or predicted. **READY / runtime pending.** |
| R7a | **Settlement probe error, no stored PR. Labelled unit/service harness.** FS exists(W)=true, exists(W/.git) fails PermissionDenied; null references; git at W fails; git at P would return merged. | S chooses W and git fails → same. No auto-settle. | Preserves failure behavior while changing probe target; verifies `orElseSucceed(true)`. | Import the actual service from each specified checkout. Mock FS/path + orchestrator/projection/settings/PR dependencies using existing test patterns; record every probe, branch call, and dispatch. Start, activate, await candidate-read Queue/Deferred, drain. | Both sides: actual W branch call and failure, zero auto-settle after drain, explicit failing marker probe after only. Do not label this built-server or real-git evidence. **READY / harness pending.** |
| R7b | **Settlement probe error, stored merged PR and current open branch PR. Labelled harness.** Same FS as R7a; empty visible `pullRequests`; legacy reference to merged PR 41; matching project identity; branch lookup returns open PR 42. Merge time >= created/user-authored anchors; afterDays null. | Summary reads merged; branch recheck uses W with `refresh:true`; open PR prevents settlement → same. | Verifies a probe error retains lookup cwd, rather than omitting it and silently settling from the old merged reference. | Same harness. Use `branchPullRequest` legacy reference (or `linkedPullRequest`), not a visible association collection. Return matching repositoryKey for PR 42. | Both sides: summary call, W branch call with `refresh:true`, returned open PR, zero auto-settle after drain. Zero commands alone is insufficient. **READY / harness pending.** |
| R7c | **Readable settlement positive control. Labelled harness.** Valid W/.git; same settings/age/project identity as R7b; current PR merged at eligible time. | W branch result merged, one `thread.auto-settle` dispatch → same. | Unchanged outcome; control proves R7a/b are not blocked by unrelated eligibility/settings. | Include alongside R7a/b with distinct thread IDs; actual imported service, record probes/calls/dispatches. | Both sides: exact eligible control ID settles; error/open IDs do not. May share R7 recording. **READY / harness pending.** |
| R8a | **Discovery marker-probe error, branched thread. Labelled harness.** exists(W)=true, exists(W/.git) fails PermissionDenied; branch F; project resolves; git stub at W returns null. | D calls W normally → at 8d6e64c6c2 the marker error keeps W: D still calls W, no group warning (outcome matches before). | Newly exercised error boundary in D; same true fallback as S (keep W). | Adapt `ThreadPullRequestService.test.ts` mocked startup fixture outside source tree, with instrumented FS and git; import actual before/after service. Start/activate/read milestone/drain; reset records per side. | Both sides: probe records and D completion; a branch call at W after drain and no group warning (head: W/.git probe error recovered as true). **READY / harness pending.** |
| R8b | **Discovery marker-probe error, branchless stale PR. Labelled harness.** Same FS/project; branch null, non-null old `branchPullRequest`, empty visible collection. | D skips git but dispatches clearing sync → at 8d6e64c6c2 the marker error keeps W: no git call, clearing sync dispatched (outcome matches before). | Same new error boundary before branch-null handling; covers eligible branchless path with observable state consequence. | Same harness, distinct thread; baseline dispatch spy returns valid receipt; head fails marker probe before planning. No agent run or host access. | Both sides: no git call; clearing sync to null after drain and no group warning (head: W/.git probe error recovered as true). **READY / harness pending.** |

R1–R5 require five before/after fixture pairs, each with D and S phases. R6 is a separate timed pair (two periodic sweeps, not sixteen). R7a–c and R8a–b are five labelled harness pairs and can be captured in one runner per side. A harness is required only for deterministic probe-error/controlled PR outcomes; do not use a unit result to replace real Git in R1–R6. Existing focused regression test red/green output can supplement these recordings but does not replace them.

## Changed components, callers, branches, and capture decisions

Production changes: [discovery cwd selection](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/orchestration-v2/ThreadPullRequestService.ts#L193) and [settlement cwd map](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/orchestration-v2/ThreadSettlementService.ts#L374). Both add platform `Path` and probe `path.join(worktreePath,".git")`; both recover a probe failure as true (keep the worktree). Changed tests add Path layers, D's three filesystem cases, S's linked/emptied case and unreadable-path cases. They have no rendering.

Only production constructors are [server.ts](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/server.ts#L539), calling make/start for each worker. Test constructors call make/start/drain. Settlement pure helpers are also imported by MCP, storage cleanup, and other tests; their bodies are unchanged and they do not call the changed sweep. There is no new transport method, contract, provider adapter, renderer, or direct client caller.

| Service / entry or branch | Complete inventory and collapse decision |
| --- | --- |
| D startup and timer | Activation enqueues all-thread backfill (`refresh:false`, five attempts for settled/no-link threads), drains, then one-minute delayed/spaced opportunistic sweeps. Timer requires BackgroundPolicy permission; startup does not. R1–R5 restart covers startup. A forced D event covers fresh lookup. If additionally claiming opportunistic-timer behavior, add an R1 D timer sequence with a live foreground lease and unconstrained policy; R6 specifically covers S, not D's timer. |
| D event callers | created/unarchived/metadata-updated enqueue `refresh:false`; unsettled/checkpoint-captured enqueue true; run.updated completed/failed/cancelled/interrupted enqueue true; other statuses/events no-op. All use one synchronize and predicate. No per-provider or per-client matrix. |
| D input gates / counts | Global snapshot removes subagent children; targeted snapshot reads one thread and its sequence. Archived/ineligible settled threads are filtered; targeted/backfill exceptions exist. Empty snapshot/groups cause no lookup. Group key is projectId/worktreePath/branch. Missing project or non-null branch with unresolved project identity returns before probe. Common fixtures explicitly pass these gates; no count or title-length dimension affects the predicate. |
| D changed predicate | Null path (R5); marker file/directory true (R3/R4); existing folder false (R1); missing folder false (R2); typed probe error (R8). Null branch skips initial git but still probes if eligible through existing branch PR (R8b). |
| D downstream outcome | Non-null branch calls git with computed cwd and request.refresh. Detection null, identity mismatch, or matching detection; null detection may preserve previous terminal PR only for null worktree path. Empty visible pullRequests plus different old terminal linked PR may replace it with a detected open PR. Equal reference/no replacement has no update. These decisions are unchanged, not additional filesystem fixtures. |
| D second lookup / commit | Non-null detected PR and nonempty update plan recheck **same cwd** with `freshGitState:true`, refresh project identity, then project-root/sequence guards precede sync. A synthetic remote failure never reaches this. Do not claim this revalidation or PR persistence unless a separate real matching-PR recording shows both calls and projection. It is not necessary for the local-cwd claim. |
| D failures | Group FS/git failures log `thread branch pull request lookup failed`; per-thread planning/update and outer worker failures have distinct warnings; interrupts are not swallowed. R1 covers real Git failure and R8 covers the FS probe-error boundary: the worktree is kept and no group warning is logged. |
| S startup/timer/settings | Activation starts an immediate full sweep then one-minute spaced full sweeps. **No BackgroundPolicy gate**. Relevant settlement-settings-key changes enqueue full sweeps. Startup covers the same predicate as settings; R6 proves autonomous timer operation. |
| S event callers | PR merge stream calls runSweep(event), invalidating selected cwd caches. PR-link-updated/PR-synced/provider-session.detached/background-work-cancelled enqueue targeted sweeps. subagent.updated requires inactive work; provider-thread.updated requires no pending background work; turn-item.updated uses can-end-work and detects shell close commands for refresh; provider-session.updated excludes starting/running; run.updated accepts completed/interrupted/failed/cancelled/rolled_back. thread.settled runs separate cleanup. All selection callers share one sweep. |
| S eligibility / empty states | Disabled global/project auto-settle configuration returns; zero candidates returns. Projection + candidate gates exclude archived/override/pinned/disabled/request/guest/active/background/queued-start/snoozed states. First settleThread(null) can settle by inactivity or visible terminal links **before** lookup. Remaining threads with visible pullRequests are removed. Fixtures disable inactivity and use empty visible links. No full cross-product of unchanged gates is required. |
| S changed map | Missing project or null branch has no map entry (not a marker fallback). Otherwise null path (R5), false marker (R1/R2), true marker (R3/R4), error interpreted true (R7). Multiple candidates share lookup groups; changed cwd also feeds grouping and merge cache invalidation, not a new result state. |
| S reference vs branch lookup | Legacy reference: read summary (or matching merge event), terminal summary plus non-null branch/cwd and wouldSettle triggers `refresh:true` recheck; a matching open current PR wins. No legacy reference: branch null returns null; missing cwd errors; otherwise branch lookup uses shell-close refresh flag. R7a covers unlinked failure; R7b covers terminal-reference recheck; R7c proves eligible positive settlement. |
| S outcome/error/cleanup | ResolveAutoSettlementAt uses settings, merged/closed time, activity anchors, visible-link counts, keep-PR and inactivity controls. Dispatch includes snapshotAt to reject stale state. Group failures log automatic-settlement-skipped; outer sweep errors have separate warning. `thread.settled` closes idle terminals and conditionally runs settle scripts after rechecks; this cleanup still probes folder itself and is unchanged. No cleanup-script capture is needed for lookup selection. |

All web, desktop, mobile, MCP, scheduled task, local, relay and tunnel paths that cause these events converge on the environment's same workers. No client wire shape changes. Linux real-git evidence plus platform Path usage is the proposed minimum; do not claim macOS or Windows were executed. Present-but-stale `.git`, a missing gitdir target, bare repositories, file deletion after the probe, and invalid project roots are outside this correction; existence is not general repository validation.

## Concrete real-server seeding and evidence contract

1. Capturer owns its own subdirectory below `/tmp/lead-24803-r3/`, with a new timestamped run directory each run. Build the **exact pair** and record source SHA plus build command/result. Run the real built server (`node apps/server/dist/bin.mjs start --log-level debug`) with separate fresh isolated T3 homes/databases, explicit `T3CODE_HOME`, `T3CODE_DEV_SEED=0`, and owned ports. Do not use the live install or the lead's database. A server restart for seeded startup reuses only that side's isolated home. Do not reuse old build output without proving its SHA. No browser or app rendering is needed.
2. Synthetic Git preparation is as specified per row; an empty commit leaves the linked folder empty when its marker is moved. Keep each fixture repo outside any Git ancestor so git cannot silently discover another repository. Record timestamped lstat/stat facts, saved marker target, branch existence, origin, project root and W/C values. Preserve marker backups rather than deleting them. No shared checkout is a fixture.
3. Use authenticated real RPC (or matching project HTTP endpoint) for seeding: `projects.mutate` / `POST /api/projects/mutate` with `{type:"project.create",commandId,projectId,title,workspaceRoot:P,scripts:[]}`; then `orchestration.dispatchCommand` with `{type:"thread.create",commandId,threadId,projectId,title,createdBy:"user",creationSource:"web",modelSelection:<valid installed instance/model>,runtimeMode:"full-access",interactionMode:"default",branch:F,worktreePath:<row path or null>}`. Current [creation schema](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/packages/contracts/src/orchestrationV2.ts#L2866) accepts the stored path; it need not be a linked-worktree marker. No turn starts.
4. Set controlled settings via `server.updateSettings` with `{patch:{sidebarAutoSettleOnMerge:true,sidebarAutoSettleAfterDays:null}}`; ensure no project overrides defeat them. D fresh triggers are `thread.settle` then `thread.unsettle` with reason user and fresh command IDs. These are for D only. Persist S threads with null override and leave them untouched, then restart to get the actual S startup sweep. Creation is not itself an S sweep trigger. Do not use `thread.metadata.update` as proof S ran; S does not consume that event.
5. Record fixture and projection via real RPC state, source/server PID, settings, trigger command/event IDs, server-start/stop boundaries, and timestamped trace trees. A command receipt is not worker completion. Await the particular completed service span/event; for harnesses use Queue/Deferred milestones and drain, with TestClock for controlled time. Never conclude from a fixed sleep. No long polling or arbitrary delay belongs in a unit test.
6. In `userdata/logs/server.trace.ndjson`, require parent `ThreadPullRequestServiceV2.synchronize` for D and `ThreadSettlementServiceV2.sweep` for S. Retain parent/trace/span IDs, start/end timestamps, and every intermediate ancestor needed to correlate the actual operation. The child `GitManager.branchPullRequest.remotes` has `git.operation`, `git.cwd`, `git.args_count`; [GitManager maps it to args remote](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/git/GitManager.ts#L2465). [The VCS driver](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/vcs/GitVcsDriverCore.ts#L1108) wraps actual process execution; a successful span means exit 0 for this invocation, while failure records classified reason/exitCode in its cause. Preserve raw causes: R1/R6 baseline should include the span failure with the classified `not_a_repository` reason, not merely a service warning. The server records git's failure as "exited with a non-zero status" plus the reason classified from stderr ([GitVcsDriverCore.ts:486-511](https://git.cafe/pingdotgg/t3code/blob/8d6e64c6c2779f420da8cb60cf6f6f816756769c/apps/server/src/vcs/GitVcsDriverCore.ts#L486-L511)); it never records the numeric status, so exit 128 is not a requirement. An extra manual `git -C ... remote` is supporting fixture data, not proof the server chose that cwd.
7. Successful local Git reads can be cached for five minutes; host PR results use a separate cache. D `refresh:true` also forces fresh git state. Use the disjoint no-remote S repo profile above to ensure D skips before lookup; a restart alone cannot prevent both startup workers racing to populate the same cache. The restarted server has empty process caches. R6's second successful sweep may have no remotes child: show its completed parent and retain first fresh read; do not mislabel cached absence as an invocation. No exact cache-hit count is an acceptance requirement. If reusing recognizable origins instead, capture a genuinely fresh S child operation after cache expiry and state that alternative explicitly; a cached S parent alone cannot prove its selected cwd.
8. R6 needs no foreground lease. If capturing D's opportunistic timer as additional coverage, `server.reportClientActivity` accepts clientId/clientKind, visible/focused/recentlyInteracted true, scopes, observedAt and ttlMs (maximum 120000); renew while observing and record policy eligibility. Do not transfer that requirement to S, which has none.
9. Harness logs must state HARNESS, service import path/SHA, mocked dependencies, probes with result/error, summary calls/results, branch calls with cwd/branch/options/results, drain completion and dispatch list. For baseline error fixtures return true at exists(W); error only at exists(W/.git), which baseline never asks. This isolates the changed probe. Keep actual service unmodified. R7b must recheck W even when the probe errors; the expected open result shows why retaining cwd matters. R7c must settle. R8b must demonstrate the clearing sync on both sides (at 64b3c2cc09 the head logged a failure instead; 8d6e64c6c2 fixed that). Deterministic permission failures under a root-capable process are not claimed as real-filesystem reproduction.
10. Upload synthetic driver, fixture manifest, provenance/build record, row transcripts, raw relevant trace trees and focused red/green test transcript if supplied. Scrub bootstrap/access tokens, websocket tickets, reusable dev credentials, pairing URLs and unrelated account metadata before writing public extracts. Record host API failure honestly. Publish immutable URLs before deleting owned scratch. Stop only captured owned PIDs; leave the lead's worktree and scratch root intact.

## Scope and disposition

Completed: exact-pair full diff and changed tests; production constructors and all service event entry points; cwd predicates, branchless/reference paths, grouping, caching, error recovery and dispatch boundaries; current creation/settings/activity RPC contracts; old matrix/index/scripts as references only; GitCafe head/base verification; matrix preparation. `git diff --check` passed. Not performed: tests, builds, runtime capture, browser/computer use, source edits, PR changes, comments, pushes, or new worktrees. No server, emulator, or lease was started. Free root disk was 15 GB, above the 5 GB stop threshold.

The matrix is complete and ready for capture. Runtime statuses are intentionally pending in pass 1. No screenshot requirement applies.

FRICTION: none

VERDICT: SUFFICIENT
