Insist on a Unique Worktree for Every Task and Package It as the repo-worktree Skill - #717
Conversation
GOVERNANCE.md "Verification Discipline" already covers a clone that fetched stale content, but not a clone that fetched correctly from the wrong ref. Add a sibling bullet requiring a "does not exist" claim to name the branch it was checked against and to check the branch the repo's own model designates as current before asserting absence repo-wide. Mirror the same rule in the agent-conduct skill's "Before Claiming Done" excerpt. Fixes #714 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both GOVERNANCE.md "Branching Model" and the operational-vs-release-workflow skill described the develop -> main flow without ever stating the specific trap that caused #714: GitHub's own 'default branch' repository setting reads main, but develop is where work starts and where in-flight content lives. A tool that branches from 'the default branch' lands on main and can silently miss content already merged to develop. State that explicitly in both places. Refs #714 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Address Copilot review feedback on PR #716: 'a fresh worktree, a new clone' overclaimed that any newly created worktree lands on the default branch, when the actual pitfall is one that defaults to it. Rephrase both spots as 'a worktree or clone that defaults to the default branch'. Also run scripts/build_dist.py, which the prior two commits left stale (the CI 'Lint sources job' check caught this) since .agents/skills content is mirrored into .claude-plugin/fleet-skills. Refs #714 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…o issue-711-worktree-mandate # Conflicts: # .claude-plugin/fleet-skills/.source-digest
The bold span opening the branching-model addition broke across a hard-wrapped line, the last GOVERNANCE.md pattern of its kind and inconsistent with the majority style. Address Copilot's on-head finding by keeping each bold span on one line. Refs #714 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-worktree Skill All new work, a continuation of a prior session's task included, now begins by creating its own git worktree before the first file edit, based on the branch work starts on rather than whichever branch a tool defaulted to. The rule lands in GOVERNANCE.md "Repository Boundaries and Write Safety", is surfaced at the task-start moment by a new repo-worktree skill that also carries the fleet worktree layout convention and cleanup mechanics, and is mirrored into the host-wide agent-safety block so Claude Code's EnterWorktree tool is armed even outside a conformant repo. git-commit-conventions now requires staging by explicit path, never a blanket add, and treats any change the session did not make as a stop rather than something to bundle. Includes the fix-714-branch-verification branch (PR #716), so the base-branch rule and the worktree mandate land as one consolidated update, and this pull request supersedes PR #716. Closes #711. Closes #714. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR consolidates governance and skill updates to require that every task (including continuations) isolates into its own git worktree before the first file edit, and it packages the mechanics as a new repo-worktree skill to ensure the rule is surfaced at the right moment.
Changes:
- Adds an explicit “worktree before first edit” mandate to GOVERNANCE/host safety guidance (including continuation re-isolation).
- Introduces the new
repo-worktreeSkill (source + generated plugin), including base-branch guidance and worktree lifecycle mechanics. - Tightens
git-commit-conventionsto forbid blanket staging and strengthens the pre-commitgit statusstop condition; propagates base-branch/negative-existence guidance to relevant skills.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| host-setup/agent-safety/README.md | Updates kit documentation to reflect the new worktree-before-edit mandate in the host-wide safety block. |
| host-setup/agent-safety/claude-md-safety.md | Adds the explicit host-wide “isolate into a worktree before first edit” rule so tools like EnterWorktree are “armed” by policy text. |
| GOVERNANCE.md | Adds the affirmative task-start worktree rule, tightens git staging summary language, and adds base-branch guidance + negative-existence-claim rule. |
| AGENTS.md | Updates the rules map to annotate that task isolation is surfaced by the new repo-worktree skill. |
| .claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md | Adds the generated repo-worktree skill content to the Claude plugin distribution. |
| .claude-plugin/fleet-skills/skills/operational-vs-release-workflow/SKILL.md | Adds “default branch is main but work starts on develop” guidance to the generated workflow skill. |
| .claude-plugin/fleet-skills/skills/git-commit-conventions/SKILL.md | Updates the generated git skill to forbid blanket staging and strengthen git status checks. |
| .claude-plugin/fleet-skills/skills/agent-conduct/SKILL.md | Updates the generated conduct skill to include the “does not exist” branch-naming requirement. |
| .claude-plugin/fleet-skills/.source-digest | Updates the plugin source digest to reflect regenerated skill content. |
| .claude-plugin/fleet-skills/.claude-plugin/plugin.json | Registers the new repo-worktree skill in the plugin manifest. |
| .agents/skills/repo-worktree/SKILL.md | Adds the source repo-worktree skill (mandate + mechanics) for fleet skill installation. |
| .agents/skills/operational-vs-release-workflow/SKILL.md | Adds base-branch/default-branch guidance to the source workflow skill. |
| .agents/skills/git-commit-conventions/SKILL.md | Tightens staging/commit hygiene rules in the source git skill. |
| .agents/skills/agent-conduct/SKILL.md | Adds the “does not exist” branch-checking rule to the source conduct skill. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Copilot round 1 on PR #717: the Git and Commit Rules summary paragraph edited by this PR joins the one-logical-paragraph-per-line rule it was already subject to, and the host-wide staging sentence gets its own subject instead of dangling off the isolation clause. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (3)
GOVERNANCE.md:58
- The Branching Model note says the default-branch setting is
mainbut work starts ondevelop"on both fleet workflow models", yet the last sentence narrows the guidance to only arelease-model repo. This is internally inconsistent and could mislead readers working in anoperationalrepo (which also starts ondevelop).
**GitHub's own "default branch" repository setting reads `main`, but `develop` is where work starts and where in-flight content lives**, so a worktree or clone that defaults to "the default branch" lands on `main` and can silently miss content already merged to `develop` but not yet promoted. Branch from `develop` for a `release`-model repo unless the task is explicitly about `main`-only content.
.agents/skills/repo-worktree/SKILL.md:7
- The skill description says to base work on
develop"for a release-model repo", but later in this same skill it states that both workflow models start work ondevelop. Please make the description match the rule it documents to avoid confusion for operational repos.
feature branch before its first file edit, based on the branch work starts on (develop for a
release-model repo, never whichever branch a tool defaulted to). Also wraps the mechanics:
.claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md:7
- Same inconsistency as the source skill file: this generated copy says
developis the base only for a release-model repo, but the skill body states both models start ondevelop. Align the description so the packaged skill doesn’t give mixed guidance.
feature branch before its first file edit, based on the branch work starts on (develop for a
release-model repo, never whichever branch a tool defaulted to). Also wraps the mechanics:
Copilot round 2 on PR #717: operational repos also start work on develop (direct-to-develop commits), so the Branching Model sentence and the repo-worktree skill description drop the release-model qualifier that contradicted the skill body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the three suppressed round-2 findings, which are one inconsistency in three places: the GOVERNANCE.md Branching Model sentence and the repo-worktree skill description (source and generated copy) qualified the develop base as release-model-only while the skill body states both workflow models start work on develop. Fixed in 8f1fac6: the GOVERNANCE sentence now reads "Branch from |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (2)
GOVERNANCE.md:45
- This paragraph is now a single very long line, which is inconsistent with the surrounding hard-wrapped prose and makes future diffs/edits harder. Please wrap it similarly to the rest of this file.
The fleet's mechanical git rules: default to staging rather than committing and stage by explicit path only, never a blanket add, commit means commit and push, every commit is signed and carries the committer's own verified GitHub `noreply` identity, never force push, a history rewrite re-identifies only the commits it touches that aren't yours, and destructive git commands run only on explicit instruction.
.agents/skills/repo-worktree/SKILL.md:72
- The skill mandates that continuations “re-isolate”, but the only concrete command sequence shown here creates a new branch from origin/develop. Consider adding a short example for attaching an existing task branch (local or origin/) to a new worktree so continuations don’t accidentally fork a fresh branch.
Note: the same change likely needs to be mirrored into the generated copy at .claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md to keep them in sync.
```sh
git -C ~/repos/<Repo> fetch origin develop
git -C ~/repos/<Repo> worktree add ~/repos/worktrees/<Repo>-<task-slug> -b <task-branch> origin/develop
</details>
Copilot round 3 on PR #717: the skill mandated that continuations re-isolate but only showed the new-branch sequence, so a continuation could accidentally fork a fresh branch. The added sequence attaches the existing task branch, and the prose names git's own refusal to attach a checked-out branch as the mandate working. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the two suppressed round-3 findings: GOVERNANCE.md:45 — "This paragraph is now a single very long line, which is inconsistent with the surrounding hard-wrapped prose... Please wrap it." Declined: the committed style rule is the opposite. The .agents/skills/repo-worktree/SKILL.md:72 — "the only concrete command sequence shown here creates a new branch... add a short example for attaching an existing task branch." Fixed in e9a9711: a continuation sequence now attaches the existing task branch ( |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md:77
- The continuation snippet uses
git fetch origin <task-branch>but then callsgit worktree add ... <task-branch>, which expects a local branch ref. If the base clone doesn't already have a local<task-branch>(e.g., fresh clone / only remote-tracking exists), theworktree addstep can fail.
git -C ~/repos/<Repo> fetch origin <task-branch>
.agents/skills/repo-worktree/SKILL.md:77
- The continuation snippet uses
git fetch origin <task-branch>but then callsgit worktree add ... <task-branch>, which expects a local branch ref. If the base clone doesn't already have a local<task-branch>(e.g., fresh clone / only remote-tracking exists), theworktree addstep can fail.
git -C ~/repos/<Repo> fetch origin <task-branch>
…rk Cold Copilot round 4 on PR #717 claimed the continuation snippet fails on a clone holding only the remote-tracking ref. It does not: git's checkout DWIM creates the local tracking branch, verified against git 2.47 with a constructed two-repo case. The sentence lands anyway, so the next reader does not have to re-derive why the command works on a fresh clone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the round-4 suppressed finding (raised identically against the source and generated copies of "The continuation snippet uses Declined as a defect: the failure does not reproduce. git init a && git -C a commit --allow-empty -m base && git -C a branch task-x
git clone a b # b has only remote-tracking origin/task-x
git -C b worktree add ../wt task-x
# Preparing worktree (new branch 'task-x')
# branch 'task-x' set up to track 'origin/task-x'. -> exit 0054b42a documents that guessing inline anyway, so the next reader does not have to re-derive why the snippet works on a fresh clone. The generated copy is regenerated in the same commit. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.agents/skills/repo-worktree/SKILL.md:83
- This text implies
git worktree add … <task-branch>will “guess” and create a local branch trackingorigin/<task-branch>when only the remote-tracking ref exists. In practicegit worktree addcommonly requires an existing local branch (or an explicit-b … origin/<task-branch>), so this guidance can fail on a fresh clone / remote-only branch. Update the continuation instructions to include an explicit remote-based form (and keep the existing local-branch form as a separate case).
When the base clone holds only the remote-tracking ref, the same command creates the local
branch tracking `origin/<task-branch>` through git's ordinary checkout guessing, so a fresh
clone needs no separate branch setup. Git refuses to attach a branch that is already checked
.agents/skills/repo-worktree/SKILL.md:85
- There’s an awkward hard line break splitting the sentence “and that refusal is the mandate working …” across two lines, which reads like a formatting glitch. Join it into one sentence/paragraph for readability.
clone needs no separate branch setup. Git refuses to attach a branch that is already checked
out somewhere else, and that refusal is
the mandate working, since the branch sitting checked out in a shared tree is the hazard the
Copilot round 5 on PR #717: the previous edit left one short line splitting a sentence mid-clause, which read as a formatting glitch inside the skill's wrapped style. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the two suppressed round-5 findings: .agents/skills/repo-worktree/SKILL.md:83 — "In practice .agents/skills/repo-worktree/SKILL.md:85 — "awkward hard line break splitting the sentence... reads like a formatting glitch." Fixed in 21aa9ac: the paragraph is rewrapped evenly, no mid-clause short line. The generated copy is regenerated in the same commit. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (1)
GOVERNANCE.md:45
- This sentence reads ambiguously because the conjunction joins two parallel clauses without a separating comma ("default to staging rather than committing and stage..."). Adding a comma after "committing" makes the list of rules parse correctly.
The fleet's mechanical git rules: default to staging rather than committing and stage by explicit path only, never a blanket add, commit means commit and push, every commit is signed and carries the committer's own verified GitHub `noreply` identity, never force push, a history rewrite re-identifies only the commits it touches that aren't yours, and destructive git commands run only on explicit instruction.
Copilot round 6 on PR #717: the two staging rules read as one garbled clause without a separator, so they become two list items. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the suppressed round-6 finding: GOVERNANCE.md:45 — "the conjunction joins two parallel clauses without a separating comma ('default to staging rather than committing and stage...')" Fixed in 6b85350: the two staging rules are now separate list items, "default to staging rather than committing, stage by explicit path only and never with a blanket add, ...". |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (1)
.agents/skills/repo-worktree/SKILL.md:7
- The skill description says the worktree should be based on “develop on both fleet workflow models”, but the skill body (and GOVERNANCE.md) includes an explicit exception for tasks that are about
main-only content. Consider updating the description to include that exception so the short summary doesn’t encourage always branching fromdevelop.
feature branch before its first file edit, based on the branch work starts on (develop on both
fleet workflow models, never whichever branch a tool defaulted to). Also wraps the mechanics:
Copilot round 7 on PR #717: the description's short summary said develop with no exception, encouraging always branching from develop, while the body and GOVERNANCE.md state the main-only-content exception. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Answering the suppressed round-7 finding: .agents/skills/repo-worktree/SKILL.md:7 — "Consider updating the description to include that exception so the short summary doesn't encourage always branching from |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.agents/skills/repo-worktree/SKILL.md:72
- The worktree-creation example hardcodes
develop, but the skill (and GOVERNANCE) says the base branch is the branch work starts on and can bemainfor main-only tasks. Using a<base-branch>placeholder here avoids contradicting the rule and reduces the chance of copy/pasting the wrong ref.
git -C ~/repos/<Repo> fetch origin develop
git -C ~/repos/<Repo> worktree add ~/repos/worktrees/<Repo>-<task-slug> -b <task-branch> origin/develop
.claude-plugin/fleet-skills/skills/repo-worktree/SKILL.md:72
- Same issue as the source skill: this example hardcodes
developeven though the rule is to base the worktree on the branch work starts on (sometimesmain). Consider using a<base-branch>placeholder so the example stays consistent with the mandate.
git -C ~/repos/<Repo> fetch origin develop
git -C ~/repos/<Repo> worktree add ~/repos/worktrees/<Repo>-<task-slug> -b <task-branch> origin/develop
|
Answering the suppressed round-8 finding (raised identically against the source and generated copies of "The worktree-creation example hardcodes Declined: the concrete |
…Python CI Gates (#718) Thirty-one squashes, `56f4d7d..d54862a`. 115 files, +20436/-5298. **Merge with a merge commit, never a squash, and never with `--delete-branch`.** This pull request's head is `develop` itself. ## What lands **Fleet Skills.** The `.agents/skills/` source tree, the generated `.claude-plugin/` distribution, `scripts/build_dist.py` with its `--check` gate, and `scripts/skills_install.py` with its host stamp (#676). Packaged as skills on top of the scaffold: PR review conduct and Copilot instructions upkeep (#677), comment and doc style (#678), resync-a-repo and fleet-conformance-check (#679), the per-language codestyles (#680), git commit conventions and operational vs release workflow (#681), stand up a repo (#683), and repo-worktree (#717). Coverage gaps closed in three passes (#690, #691, #692) plus the P4 sentence-length opt-in (#697). **Host setup.** The Windows host-setup tooling and its PowerShell gate (#674), the Windows bootstrap loader (#682), Docker install and upgrade on Linux and Windows with a version floor (#701, #705), a `uv` floor in `spec/host-tools.json` (#698), self-healing of a shadowing `uv`, `jq`, or `git-restore-mtime` copy (#689), node's real winget package id (#696), and a README for the Linux host-setup nuances (#710). **Python and CI.** Python tooling in CI with the script tests moved to `scripts/tests` (#704), `ruff format` adopted and gated (#709), and the PSScriptAnalyzer claim conditioned on repos that carry `.ps1` files (#686). **Conduct rules.** Triage-order and scope guardrails in pr-review-conduct (#684), `pr_review.py wait` requesting a review rather than only polling for one (#685), a tech-agnostic signed-commit verification (#708), execution rather than analogy to verify platform-specific code (#715), and a unique worktree for every task (#717). **Docs.** The fleet map and gap register with peer messaging declared (#687), mermaid flow diagrams in the kept-authority docs (#702), and the map pointed at the shipped diagrams and current tooling (#703). ## Issues this promotion closes Each landed on `develop` on its own pull request. The keyword fires only on a merge into `main`, so it sits here rather than on the feature pull requests. Closes #700 Closes #707 Closes #711 Closes #712 Closes #714 Closes #688 #699 stays open on purpose: #717 shipped the layout convention and the skill, and the physical migration of existing checkouts is still tracked there. ## Review record Every squash closed its own Copilot loop on its own pull request before merging to `develop`. This promotion carries no new content of its own, so its review is the merged tree as a whole. ## Consequence worth stating The `GOVERNANCE.md` and `AGENTS.md` sections these squashes changed become the canonical the moment this reaches `main`, and every carrying repository reads as drifted from that point until it resyncs. That is the ordinary consequence of a canonical moving rather than a defect. The Skills installer added here is also how a machine picks the new skills up, so a session that keeps restating a rule already packaged as a skill is the signal to run it.
What this does
One consolidated update covering #711 and #714, per the maintainer's direction that the two land together rather than as scattered rules. It includes the
fix-714-branch-verificationbranch (all of PR #716 plus its unpushed Copilot nit-fix commit), so this PR supersedes #716, which can be closed unmerged.The worktree mandate (#711)
repo-worktreeskill (kept-authority shape: GOVERNANCE keeps the law, the skill is the task-start surface) carrying the mandate's trigger moments plus the mechanics as its own content: base-branch choice, the Propose a Repo and Worktree Layout Convention and a repo-worktree Skill #699 layout convention (~/repos/<Repo>,~/repos/worktrees/<Repo>-<task-slug>), thegit worktree add+EnterWorktree path:sequence, listing, and post-merge cleanup. The physical migration of existing checkouts stays tracked in Propose a Repo and Worktree Layout Convention and a repo-worktree Skill #699.git-commit-conventionstightened: stage by explicit path, nevergit add -Aorgit add ., and the pre-commitgit statuscheck generalizes from "the maintainer's own uncommitted edits" to "any change this session did not make", with ask-or-stop as the response, never bundling. The GOVERNANCE "Git and Commit Rules" summary matches.host-setup/agent-safety/claude-md-safety.md) gains the same task-start bullet, naming "worktree" in so many words so Claude Code'sEnterWorktreetool is armed even in sessions noAGENTS.mdreaches. Machines pick it up on their next installer re-run (Roll out global ~/.claude/CLAUDE.md safety rules to all machines #365 cadence).The base-branch rule (#714, from PR #716)
Carried in unchanged apart from consolidation cross-links: GitHub's default-branch setting reads
mainbut work starts ondevelop, so a worktree defaulted to "the default branch" silently misses in-flight content, and a "does not exist" claim names the branch it was checked against.Verification
build_dist.py --checkclean (both skill trees regenerated and committed together)prose_lint.py,repo_gate.py,host_gate.pyall passtest_build_dist.py(19),test_prose_lint.py(244),test_repo_gate.py(70),test_host_gate.py(72),test_skills_install.py(29),host-setup/agent-safety/test_install.py(45),spec/validate.pyall passCloses #711. Closes #714. Supersedes #716.
🤖 Generated with Claude Code