Skip to content

Insist on a Unique Worktree for All New Work, Including Session Continuations #711

Description

@ptr727

What happened

Two Claude Code sessions ran concurrently on the same machine, both working in the primary checkout of this repo, on the branch issue-706-signing-check. Session A was iterating on the signing-probe work. Session B was authoring a new host-setup/linux/README.md. Neither session created a worktree, and neither knew the other was in the tree.

Session A committed twice while session B's work sat uncommitted in the shared tree, and both commits included session B's files:

  • 0553d34 ("Make the Scratch-Probe mktemp Call Portable to macOS") swept in session B's 161-line first draft of the README.
  • 21aec10 ("Test the Default Signing Config, Not a Forced Signature") swept in the README's rewrite and session B's cspell.json additions.

No content was lost, but two commits now carry unrelated files their subjects do not describe, and session B's work was committed by a task that never saw it. This is exactly the "blanket git add -A sweeps another task's uncommitted work into the commit" hazard GOVERNANCE.md names. The README content was re-landed cleanly from a worktree in #710. Both sessions violated the isolation rule, the sweep is just the symptom that made it visible.

Why the existing wording did not prevent it

  • GOVERNANCE.md "Repository Boundaries and Write Safety" states the rule ("Each task runs in its own checkout, in its own directory, on its own feature branch") but is not packaged as a skill. AGENTS.md routes "which checkout the work happens in" to that section with no skill attached, so nothing surfaces the rule at the moment it is violated, which is the first file edit of a task. The skills that exist fire later: git-commit-conventions at commit time, pr-review-conduct at review time. By commit time the sweep can already have happened, and here it did, in the other session's commit.
  • The section's shared-tree guidance is detection-shaped rather than prevention-shaped. Its two signals (a branch that changes by itself, an edit reverted with no conflict) appear only after both tasks are already in the tree.
  • The continuation case is unstated. A session resuming prior work finds its branch already checked out in the primary checkout and naturally resumes there. Nothing says a continuation re-isolates into its own worktree.
  • The word "worktree" appears nowhere in GOVERNANCE.md and in no current skill. Propose a Repo and Worktree Layout Convention and a repo-worktree Skill #699 proposes the layout convention and a repo-worktree skill wrapping the mechanics, but as filed it covers where worktrees live and how to make one, not when one is mandatory.
  • Claude Code's own EnterWorktree tool refuses to create a worktree unless the user or the project instructions explicitly call for one. The harness default therefore steers agents away from isolation unless the carried instructions state the mandate in so many words, and today they do not.
  • git-commit-conventions says to check git status for "the maintainer's own uncommitted edits" before committing. That framing misses the sibling-agent case, and the skill defaults to staging without banning blanket staging.

Suggested improvements

  1. GOVERNANCE.md "Repository Boundaries and Write Safety": add an affirmative task-start rule. All new work, including a continuation of a prior session's task, begins by creating a unique worktree (or clone) before the first file edit. The primary checkout is the maintainer's own surface, and a session launched there isolates before writing rather than after noticing contention.
  2. Give the rule a skill that fires at the moment. Fold the mandate into Propose a Repo and Worktree Layout Convention and a repo-worktree Skill #699's proposed repo-worktree skill and write its trigger description for the moment ("about to create or edit files in a fleet repo", "starting or resuming a task"), not only for the worktree mechanics. Per skill-lifecycle, GOVERNANCE.md stays authoritative and the skill is the surfacing layer.
  3. Tighten git-commit-conventions. Stage by explicit path, never git add -A or git add ., and generalize the pre-commit git status check from "the maintainer's own uncommitted edits" to "any change this session did not make", with ask-or-stop as the response, never bundling.
  4. State the worktree mandate in the carried instruction files and the host-level agent-safety block. Claude Code's EnterWorktree tool acts only on an explicit instruction from the user or the project instructions, so the mandate has to be written down for the tool to be armed at all.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions