# Proof audit PASS 1: deleted-worktree recovery

PR [#18359](https://git.cafe/pingdotgg/t3code/pulls/18359), [GitHub mirror #18359](https://github.com/pingdotgg/t3code/pull/18359).
Audited local head [394f9be](https://git.cafe/pingdotgg/t3code/commit/394f9be427e329ba0d353d3d6c879fe7dee7e939), base [dd5b540](https://git.cafe/pingdotgg/t3code/commit/dd5b5401e1f240f4314af29edf431369d182f386). Complete three-dot diff: four files, 338 insertions, 56 deletions. Read-only audit; no runtime execution, tests, screenshots, or live-state access performed by this reviewer.

Scope: ProviderTurnStartService recovery and pre-start failure settlement; real-Git testkit and two tests; GitVcsDriverCore local branch formatting. Product policy is to recreate a missing branch from the project's CURRENT NAMED LOCAL branch. No remote restoration. No UI proof is required. All interaction/order/time evidence below is a server runtime transcript, not a screenshot or video.

## Fixture and exact oracles

Use a fresh real repository P outside the checkout, e.g. /tmp/ev-18359-fixture/project. Use the isolated server's configured managed root M (default /tmp/ev-18359/worktrees); W=M/project/restore has exactly two path segments below M. Persist thread branch feature/restore and worktreePath W through supported server APIs.

Create base commit A on main with base.txt containing `base\n`. Create feature/restore at A, commit thread.txt containing `thread work\n`; record its actual full SHA as T. Switch P to project-current at A, commit project.txt containing `new project code\n`; record its full SHA as C. Require T != C. Add tag feature/restore at C and tag project-current at T. Record refs using fully qualified refs/heads and refs/tags. Prompts must only read/describe files and report cwd/HEAD: no edits, commits, branch changes, or network operations. Capture Git state immediately before provider startup where possible; otherwise compare after a read-only turn and account separately for server checkpoint refs. Worktree deletion discards uncommitted files; no claim of restoring them is permitted.

## Matrix

| ID / proof lane | Setup and action | Exact expected result and required evidence |
| --- | --- | --- |
| R0 runtime baseline | Register P and managed W, run a real Codex turn before deletion; existing directory and feature/restore retained. | Provider works with cwd W. Record IDs, full SHAs, files, start/completion events, and real provider identity. Existing workspace is not recreated. This establishes a usable native conversation for the recovery rows. |
| R1 runtime + real-Git test | Delete W only, leaving stale worktree registration and refs/heads/feature/restore=T. Continue same thread. Keep crossed tags. | Prune then recreate at W on feature/restore; HEAD=T, base.txt and thread.txt exact, project.txt absent. refs/heads/feature/restore stays T, P remains project-current at C. Tag collision must not make branch look absent or choose C. Real Codex starts only after W exists, cwd=W, and completes the read-only turn. |
| R2 runtime + real-Git test | Delete W, prune registration, delete refs/heads/feature/restore. Project currently project-current at C. Continue same thread, reusing running server/workflow. | Create refs/heads/feature/restore=C and W HEAD=C on feature/restore. base.txt and project.txt exact, thread.txt absent. P remains project-current at C; crossed tags unchanged. Real Codex starts at W and completes. This follows current named project branch, not original main=A, prior T, tag T, or a remote. |
| R3 runtime + real-Git test | Delete W, prune, delete feature/restore again; detach P at C. Continue same thread. | W remains absent and refs/heads/feature/restore absent (tag alone does not count). Run, attempt, node settle failed before start with null startedAt. Persist error title `Couldn't recreate thread workspace`, class provider_error, message `Could not recreate branch 'feature/restore' at W: the project workspace has no current branch to start it from (detached HEAD?).` Substitute exact W. No provider session open/root-run start for this failed attempt; an already existing idle provider process is not evidence of a new start. Record durable failure and event/provider-start counts correlated by run/attempt IDs. |
| R4 runtime retry | After R3, switch P back to project-current at C without restarting server or changing thread metadata. Send a new Continue on the same thread. | Fresh attempt succeeds, W recreated on feature/restore at C with project.txt exact and thread.txt absent. Prior failed run/error stays in history; new run reaches provider and completes, cwd=W. Proves repair/retry and fresh local status, not a permanently poisoned conversation. |
| T1 test-only injected interrupt/retry | createWorktree first interrupts; later calls fail GitCommandError with private diagnostic; call start, start(willRetry=true), then final start. | Interrupt remains interruption; no settlement events and status starting. Retryable typed failure becomes ProviderTurnStartError with no settlement or provider start. Final failure settles exactly once; run/attempt/node failed, startedAt null; error title above and message `Could not recreate the worktree for branch 'feature/restore' at W.` Private diagnostic absent from persisted events. Exactly 3 create calls in existing test. No sleeps/elapsed-time assertions or killing real processes required. |
| T2 test-only boundary regression | Existing table: normal managed path and real symlinked managed root; outside path, escaping symlink, too-deep path, non-normalized '..' (including after symlink), relative path. | First two recreate once; all invalid locations zero create calls. No runtime deletion outside the fixture. This is guard coverage, not a claim invalid paths universally forbid provider startup. |
| T3 test-only ordinary-path preservation | Existing service suite: normal startup, commands handled before recovery, session and other startup failures, abandoned failed turn continuation. | Existing 32 tests preserved. No new recovery attempt when worktree/branch null, directory exists, managed check rejects, or project lookup absent/fails; filesystem exists failure conservatively skips recreation. These bypasses do NOT gain recovery-failure settlement guarantees. Review/test as applicable; do not manufacture UI cases. |
| T4 test-only shared Git branch listing | Local branch names, slash names, crossed branch/tag names; inspect driver consumers. | listLocalBranchNames returns exact heads such as feature/restore, not heads/feature/restore or a tag-disambiguated spelling. Existing real-Git test covers branch/tag collision. Selection enumerates branches and uses includes, O(local branch count); no regex/parser or new performance benchmark needed. |
| T5 optional test-only typed failure breadth | prune/list/status/create fail with typed Git errors (e.g. branch already checked out elsewhere, missing project repo, permission error). | Same sanitized generic recovery error, no provider open/root start, retryable vs final settlement contract as T1; no promise of rollback of partial Git side effects. Existing injection covers create failure; other phases are structurally wrapped, not individually demonstrated by current tests. Avoid expanding minimum proof into destructive runtime permission/process experiments. |

## Minimum proof set and status

1. Retain exact failing-then-passing transcript for the TWO new service tests: run the new tests against the main SERVICE implementation and show they fail for recovery/settlement assertions; run branch tests and show 34 pass, preserving main's 32. Dispatcher reports this is already done (2 fail / 34 pass / 32 preserved); this audit did not independently rerun or inspect the logs. Do not claim the retained-branch subcase alone fails on main. Show commands, implementation/version used, exit codes and failing assertion names. Avoid generic dependency/setup failures as regression proof.
2. One short isolated real-server transcript covering R0–R4 in order, with real Git and real Codex, same thread/server for failure and retry. Include all initial SHA definitions and per-row refs/files, durable run states, provider ordering/counts, and final success. R1/R2/R3 are also covered by the real-Git test, but that harness mocks provider startup; it cannot replace the real-provider transcript.
3. T1 and existing T2/T3 suite outputs supply failure injection, interrupt and guard evidence. T4 is covered by crossed tags plus source inspection. T5 is optional depth, not a requirement to add code/tests in this pass.

PASS 1 proof plan is adequate for this server-only change. Actual runtime proof remains unverified by this read-only audit; two prior round-1 MERGE reviews are supplied context, not runtime evidence. No code changes requested.

## Execution suggestions for the proof owner

- Start from /home/ubuntu/wt/pr-18359 with `vp run dev --no-seed --home-dir /tmp/ev-18359`; capture actual dev-runner ports. Do not use live userdata, migration, implicit seeding, VITE_HTTP_URL, or VITE_WS_URL. If that scratch home already holds another run, choose an explicitly reviewed clean scratch location rather than deleting unknown state.
- Use the authenticated typed WebSocket RPC client against this isolated server. Inspect packages/contracts/src/orchestrationV2.ts and apps/server/src/ws.ts for current schemas: orchestration.dispatchCommand, thread.create, thread.metadata.update, and the actual message-submission command; orchestration.subscribeThread for durable snapshots/events. Project registration uses the current project API. Do not invent a `turn.start` CLI/RPC, bypass guards with DB writes, or call the service in-process as a substitute for the runtime server. Configure real Codex auth/provider through supported isolated configuration; never paste credentials into transcript.
- Focused check: `vp test run apps/server/src/orchestration-v2/ProviderTurnStartService.test.ts`. Use its two exact new test names when isolating red/green evidence. Preserve external logs; no checkout edits by this reviewer.
- Capture `git -C P symbolic-ref --quiet --short HEAD`, `git -C P rev-parse HEAD`, `git -C P show-ref --heads --tags`, `git -C P worktree list --porcelain`, and corresponding W branch/HEAD/files before/after each step. A detached symbolic-ref failure is expected; record it, not an aborted fixture script. Only remove W after verifying the exact fixture path, with the prior turn fully stopped; prune before branch deletion.
- Include timestamped ordered events for recovery, provider start, durable failure, and retry, but assert order/counts rather than elapsed-time thresholds. Await persisted completion/failure milestones; no sleep-based success criteria. Stop only the server PID captured at spawn. Do not kill by pattern.

## Expected capture audit criteria

Server transcripts only; no screenshots or videos. Each row labels setup/action/result and IDs; records real Git SHAs and exact file contents/absence; identifies isolated home, server head and real Codex; proves failures precede any provider open/start; shows sanitized persisted messages (not merely log warnings); shows retry after restoring a named branch without server restart. Never infer no provider start from no text output alone. Red/green tests and runtime logs must be distinguished. Scrub tokens, pairing URLs, account data and private diagnostics before upload. No live-data paths or customer conversations. This matrix is a plan, not an execution certificate.

## FRICTION

- scope | Downstream web rendering can tempt UI evidence requirements | Dispatcher explicitly defines this as server-only; use runtime transcripts for interaction/time rows, no captures.
- isolation | Default dev seeding could read live userdata | Explicit --no-seed --home-dir /tmp/ev-18359; fresh real repository, no migration or live DB access.
- observability | A provider answer alone cannot prove pre-start failure or selected Git tip | Correlate durable run/attempt IDs, provider start records and exact refs/files.
- fixture | Crossed tags and stale project-status cache can hide wrong selection | Keep crossed tags and reuse one server/workflow across external checkouts and repair.
- evidence | Reported 2-red/34-green results can be mistaken for reviewed artifacts | Label as dispatcher-reported until exact transcripts are attached; mock provider tests do not establish real Codex runtime.
- tooling | No operations EVIDENCE.md supplied | Use authoritative server-only instructions in the task; do not invent screenshot requirements or a new policy.
