TimZander / TimZander/claude

Enforce worktree-only work: block branch-create/commit in a primary checkout

Open
#205 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
0
Forks
1
Avg merge
1d 3h
Merged PRs (30d)
7

Description

Problem

The team workflow is work in a git worktree, never in the primary checkout (the start-work skill creates branches/<id>-<slug> in a worktree by default). Today this is only advisory — it lives in CLAUDE.md and the skill. An agent (or a person) can bypass it by branching manually with git checkout -b in the primary checkout, and nothing stops them.

This actually happened: a session ran git checkout -b branches/294-... directly in the primary checkout and began editing files there before it was caught. Instructions and memory are advisory; only a harness-level hook reliably prevents it.

Proposed guard: a PreToolUse hook on Bash

Add a PreToolUse hook (in settings.json) that inspects the command and denies git-mutating operations when the working tree is the primary checkout.

Match these commands:

  • git checkout -b <name> / git switch -c <name>
  • git branch <newname> (branch creation)
  • git commit (optional — stricter; may be too aggressive, see open questions)

Detect primary vs. worktree:

  • git rev-parse --git-dir → a linked worktree resolves to a path under .git/worktrees/<name>; the primary resolves to plain .git.
  • Or compare git rev-parse --show-toplevel against the known primary path.

On a primary-checkout match → deny with a message like:

Create a worktree first — use the start-work skill or git worktree add .claude/worktrees/<slug> -b branches/<id>-<slug> main. Direct branching/commits in the primary checkout are blocked.

Why a hook (not memory/instructions)

The rule already exists in CLAUDE.md and was still bypassed. A hook fails the tool call structurally, independent of what the model remembers or intends.

Open questions / scope

  • Should git commit be blocked too, or only branch creation? Blocking commits is stricter but catches the case where someone is already on a feature branch in the primary checkout. Branch-create alone is the minimal guard.
  • Allowlist for main maintenance? Occasionally legit to git pull / fast-forward main in the primary checkout — the hook should only target branch-create/commit, not reads or pulls.
  • Where to configure — global ~/.claude/settings.json (applies to every repo) vs. per-repo .claude/settings.json. Global is probably right since the worktree convention is team-wide.
  • Escape hatch for deliberate exceptions (an env var or a confirm prompt) — or keep it a hard block.

Acceptance

  • Running git checkout -b foo in the primary checkout is denied by the hook with a clear message.
  • The same command inside a worktree is allowed.
  • git status / git pull / reads in the primary checkout are unaffected.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by inspecting the existing settings.json and the per-repository .claude/settings.json or global ~/.claude/settings.json configuration, along with the start-work skill. Define how the PreToolUse Bash hook distinguishes the primary checkout from linked worktrees and which branch or commit commands it blocks. Done means the acceptance commands are denied or allowed as specified, while status, pull, and read commands remain unaffected.

Written by the indexing model from the issue text.

Assessment

Tech stack
git
Domain
developer-experience, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.