Stop-review gate is lost in every new git worktree (state keyed by rev-parse --show-toplevel)

Author: dev-seahouseCreated Sep 14, 2026Updated Sep 14, 2026

Summary

The stop-time review gate is stored per worktree, not per repository. If you enable the gate in a repository and then create a git worktree from it, the gate is off in the new worktree.

Steps to reproduce

  1. In a repository, run /codex:setup --enable-review-gate.
  2. Confirm the gate is on with /codex:setup.
  3. Create a worktree: git worktree add ../repo.feature feature.
  4. Start Claude Code in ../repo.feature and run /codex:setup.

Observed

Step 4 reports the gate as disabled, and the Stop hook returns early because config.stopReviewGate is false.

The state directory is derived from the worktree path. scripts/lib/workspace.mjs calls ensureGitRepository, which runs git rev-parse --show-toplevel (scripts/lib/git.mjs:79). In a worktree that command returns the worktree root, not the root of the main checkout. resolveStateDir in scripts/lib/state.mjs then slugs and hashes that path, so every worktree gets its own state.json, and a new one falls back to defaultState() with stopReviewGate: false.

On disk this produces one directory per worktree:

$CLAUDE_PLUGIN_DATA/state/myrepo-93ce82b5d9a11cb3/state.json        # main checkout, gate on
$CLAUDE_PLUGIN_DATA/state/myrepo-feature-3944a1266079df73/state.json # worktree, gate off

The effect is silent. Nothing reports that the gate was dropped, so a session in a worktree stops without a review while the user believes the gate is active. Each new worktree needs /codex:setup --enable-review-gate again.

Expected

The gate setting follows the repository, so worktrees of one repository share it. If the current behavior is intended, the setup output can state that the gate applies to the current worktree only.

Environment

  • codex plugin 1.0.6
  • codex-cli 0.154.0
  • Node v24.20.0
  • Linux
  • Repository with multiple git worktree checkouts