LearnNewsExamplesServices
Frontmatter
id15050
titleStop Codex Local mode from leaking nested review worktrees
stateClosed
labels
bugdeveloper-experienceairegressionarchitectureperformancemodel-experience
assigneesneo-gpt
createdAt1:57 AM
updatedAt3:03 AM
githubUrlhttps://github.com/neomjs/neo/issues/15050
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAt3:03 AM

Stop Codex Local mode from leaking nested review worktrees

Closed Backlog/active-chunk-5 bugdeveloper-experienceairegressionarchitectureperformancemodel-experience
neo-gpt
neo-gpt commented on 1:57 AM

Context

On 2026-07-12, the operator traced weeks of severe WebStorm indexing pressure to hundreds of disposable Git worktrees nested under the resident Codex checkout's ignored tmp/ directory. Before cleanup, live Git metadata reported 840 worktrees: 521 below the repository tmp/, 316 below /private/tmp, one resident checkout, and two other entries. git worktree prune --dry-run --verbose classified 839 registrations as stale.

The operator manually deleted the repository tmp/ directory. The same incident pass then pruned Git's stale registrations and removed the final unused external Codex worktree. Live post-cleanup state is one clean worktree: the resident checkout on dev.

This is not the same scope as #12677 / PR #12678. That cleanup is deliberately limited to .claude/worktrees/; its current JSDoc explicitly says Codex does not create this disk-growth pattern. The incident falsifies that premise. #13241 / PR #13242 also told Codex to keep identity-sensitive worktrees below the clone root. That addressed identity drift, but in Codex Desktop Local mode it turned review isolation into nested, IDE-indexed repository growth.

The Problem

Codex Desktop Local mode already has one identity-bound resident checkout. It can fetch and switch branches in place. Manually creating a worktree or clone for each review adds no required isolation in this mode and leaks persistent nested repositories when lifecycle cleanup is missed.

Three surfaces made the leak durable:

  1. .codex/CODEX.md currently directs worktrees beneath the identity-mapped clone root without distinguishing Local mode from host-managed Worktree mode.
  2. .codex/rules/pr-lifecycle.rules does not prohibit git worktree add or git clone.
  3. /tmp is intentionally ignored, so nested repositories remain invisible to ordinary git status while IDE indexing still sees them.

The result is a recurrent machine-health regression, not a request for a better cleanup schedule.

The Architectural Reality

  • Local mode: one resident checkout; review exact heads by fetching and switching or detaching in place, then restore the prior branch.
  • Worktree mode: a separate host-managed Codex surface. The app owns placement and lifecycle; an agent must not emulate it with shell-created nested worktrees.
  • .codex/CODEX.md is the existing Codex-only turn-loaded guard card.
  • .codex/rules/pr-lifecycle.rules is the existing trusted-project command-policy surface. Codex rule resolution is most-restrictive-wins, so a project forbidden decision remains effective even when a user rule previously allowed the command.
  • The Claude cleanup from #12677 remains valid for Claude's explicitly worktree-based harness; broadening it into an automatic delete loop for Codex Local mode would preserve the wrong creation model.

The Fix

  1. Rewrite the worktree bullet in .codex/CODEX.md to state the Local-mode invariant: use the resident checkout, fetch/switch in place, and never create a manual clone or worktree inside it. Name host-managed Worktree mode as a distinct lifecycle owner.
  2. Add project command-policy rules that:
    • forbid direct git worktree add;
    • forbid direct git clone;
    • allow non-destructive git worktree list and git worktree prune diagnostics;
    • allow ordinary git worktree remove, while forbidding git worktree remove --force.
  3. Verify the policy with codex execpolicy check and verify the turn-loaded guard-card path.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Evidence
Codex Local-mode checkout behavior .codex/CODEX.md via the trusted prompt hook Fetch and switch/detach in the resident checkout; never shell-create nested clones/worktrees Host-managed Worktree mode owns its own external checkout lifecycle Hook-path read + card text
Direct worktree/clone creation .codex/rules/pr-lifecycle.rules git worktree add and git clone are forbidden Use git fetch + git switch in place codex execpolicy check
Worktree diagnostics/cleanup .codex/rules/pr-lifecycle.rules list, prune, and non-force remove remain available; force removal is forbidden Inspect dirty state before removal codex execpolicy check

Decision Record impact

Aligned with ADR 0007's compaction taxonomy: this is high-severity, harness-local, and mechanically enforceable, so the right shape is one compact turn-loaded trigger plus command policy. No ADR amendment is required.

Acceptance Criteria

  • .codex/CODEX.md distinguishes resident-checkout Local mode from host-managed Worktree mode and forbids manual nested clones/worktrees in Local mode.
  • .codex/rules/pr-lifecycle.rules forbids direct git worktree add and git clone.
  • The rules still allow git worktree list, git worktree prune, and non-force git worktree remove, while forbidding git worktree remove --force.
  • codex execpolicy check proves the forbidden/allowed decisions against the combined project and resident rule sets.
  • The trusted prompt hook still injects the compact guard card.
  • Live post-cleanup proof remains exactly one registered worktree and no repository tmp/ directory.

Out of Scope

  • Host-managed Codex Worktree mode implementation or lifecycle.
  • Claude's .claude/worktrees/ cleanup contract from #12677.
  • Fleet checkout provisioning and peer onboarding.
  • IDE exclusion rules, a cleanup daemon, or recreating tmp/.

Avoided Traps

  • Do not hide the symptom from WebStorm. Excluding the leaked directory preserves disk/process waste and makes recurrence quieter.
  • Do not automate deletion of a creation pattern Local mode does not need. Prevent creation instead.
  • Do not weaken exact-head review. Fetch and switch/detach in place preserves exact-head discipline without parallel repositories.
  • Do not globalize this into AGENTS.md. The mode distinction and command policy are Codex-harness-specific.

Related

  • #12677 / PR #12678 — Claude-scoped worktree pruning; its Codex premise was falsified here.
  • #13241 / PR #13242 — predecessor identity-safe placement rule; corrected rather than duplicated.
  • #15045 / PR #15046 — resident-neutral Codex guard card.

Origin Session ID: 2ad10d40-681f-41aa-b9cf-e09ddaa23e2b

Handoff Retrieval Hints: Codex Local mode nested review worktree leak WebStorm tmp; .codex/CODEX.md; .codex/rules/pr-lifecycle.rules; git worktree list --porcelain.

Authored by GPT-5.6 Sol (Codex Desktop).

tobiu closed this issue on 3:03 AM
tobiu referenced in commit 814cfca - "fix(codex): forbid local-mode worktree leaks (#15050) (#15051)" on 3:03 AM