| name | forge-worktree-gate |
| description | WHEN: About to start any implementation task. HARD-GATE: Every task gets fresh worktree (D30). No shared state, no cross-contamination. |
| type | rigid |
| version | 1.0.0 |
| preamble-tier | 3 |
| triggers | ["worktree gate","start work in worktree","check worktree before starting"] |
| allowed-tools | ["Bash"] |
Worktree Per Task (D30 HARD-GATE)
Rule: Every single task gets a fresh git worktree. No exceptions.
Anti-Pattern Preamble: Why Agents Skip Worktrees
| Rationalization | The Truth |
|---|
| "My change is small, I can work in main without isolation" | Small changes have large blast radius. Untracked dependencies, implicit assumptions, forgotten cleanup all hide in main. Isolation is never optional. |
| "Creating worktrees adds complexity and overhead" | Worktree creation is 2 commands. Debugging cross-contamination from main is 4 hours. The math is clear. |
| "I'll be careful not to break anything, I don't need worktrees" | Vigilance is not isolation. You can't be careful about things you don't know you're doing. Worktrees prevent accidental contamination. |
| "We already have feature branches, that's sufficient isolation" | Feature branches in main still share node_modules, build artifacts, environment state. Worktrees isolate the entire filesystem context. |
| "This task doesn't touch other projects, worktree seems unnecessary" | Tasks are not isolated to single projects. Dependency chains are invisible until isolation reveals them. Always isolate. |
| "Setting up a fresh worktree takes time we don't have" | Fresh worktree: 2 min. Debugging why test passes in main but fails in isolation: 2 hours. Time calculation is backwards. |
| "The test suite passes in my working directory, we're good to go" | Your working directory has 6 months of accumulated build artifacts. Fresh worktree has none. Tests pass there? Then it's real. |
| "We can do worktree isolation retrospectively if needed" | Retrospective isolation is impossible. Once merged, the bug is live. Isolation is pre-merge, always. |
| "One task can reuse the worktree from the previous task" | Worktree reuse means state leakage. Previous task's dependency modifications, config changes, cleanup gaps all infect next task. Fresh only. |
| "Worktrees are overkill for infrastructure or config changes" | Config changes have the most subtle bugs. Fresh environment catches config mistakes that shared main never will. |
Iron Law
EVERY TASK RUNS IN ITS OWN FRESH WORKTREE. THERE IS NO EXCEPTION. A SHARED WORKTREE IS A SHARED FAILURE MODE.
Red Flags — STOP
If you notice any of these, STOP and do not proceed:
- Conductor logs
[P4.1-WORKTREE-FAIL] when this gate fails — forge-worktree-gate is a hard prerequisite for conductor-orchestrate State 4.1. If worktree validation fails here, conductor writes [P4.1-WORKTREE-FAIL] task_id=<id> repos_affected=<list> reason=<msg> to conductor.log and blocks all implementation dispatch. The pipeline cannot proceed until this gate passes. See docs/conductor-log-format.md for the full marker format.
- Agent starts editing files in the main branch directly — Shared state contamination in progress. Stop the task, create a fresh worktree, restart from there.
- Two tasks share the same
node_modules/ or dist/ directory — Worktree isolation has been broken. Both tasks are compromised. Recreate both worktrees fresh from main.
- A task's branch is based on another task's branch (not main) — Cross-task dependency introduced. Tasks must branch from main only. Rebase onto main or abort and re-isolate.
- Agent says "I'll clean up after" or "I'll reset it when done" — Cleanup-after is not isolation. The contamination already happened. Isolation must be pre-work, not post-work.
- Multiple tasks are running in the same working directory — One task will stomp on the other's changes. Stop both. Assign separate worktree directories and restart.
- Worktree directory already exists with previous task artifacts — Previous task's state is still present. Destroy and recreate fresh from main before starting.
- A task branch was merged before all sibling tasks completed — Remaining tasks may conflict with merged state. Rebase their worktrees onto updated main and verify no conflicts.
Detailed Workflow
Identify Task Scope
- Input: Locked shared-dev-spec (from council) + per-project tech plans
- Action: Break down spec into per-task work units
- One task per distinct implementation concern (e.g., "backend auth", "web form UI", "infra deployment scripts")
- Each task is <1 day of work (if >1 day, split further)
- Output: Task list with clear scope boundaries
Create Fresh Worktree Per Task
For each task:
-
Create worktree (invoke /worktree-per-project-per-task)
Creates isolated worktree:
- Branch name: feature/TASKID (e.g., feature/D123-backend-auth)
- Based on: main (always, not on other tasks' branches)
- Directory: .claude/worktrees/TASKID/
- Environment: clean slate (node_modules, build artifacts, cache all fresh)
-
Verify isolation:
- Worktree has its own package-lock.json / Cargo.lock
- No shared node_modules with other tasks
- No shared build artifacts (.next, dist, target)
- No shared test caches (.jest-cache, .pytest-cache)
-
Document task context in brain (decision ID: WKRK-YYYY-MM-DD-HH)
- Task scope (what you will and won't implement)
- Acceptance criteria (what "done" looks like)
- Dependencies on other tasks (if any)
- Worktree location and branch name
Implement In Isolation
- Input: Fresh worktree
- Action: Implement the task
- Write code, tests, infra as normal
- Do NOT reach into other worktrees or main
- Do NOT import external state (env variables from main, configs from shared directory)
- Commit early and often (worktree is your sandbox)
- Output: Task complete, all tests pass in isolated environment
Verify In Isolation
- Input: Completed task in worktree
- Action: Run verification suites
- Unit tests (for this task's code)
- Integration tests (for this task's service boundaries)
- Build verification (code compiles, no warnings)
- Output: All tests PASS in clean worktree environment
Coordinate Task Integration (If Multi-Task Feature)
If feature requires multiple tasks working together:
- Keep each task in its own worktree (do NOT merge into main yet)
- Coordinate task dependencies:
- Task A (backend) → Task B (web) → Task C (app)
- Task B waits for Task A to define API contracts
- Task C waits for web to define cache contract
- Use
/pr-set-coordinate to raise coordinated PRs (in merge order)
- PR1: Task A (backend) → main
- PR2: Task B (web) → main (after PR1 merged)
- PR3: Task C (app) → main (after PR2 merged)
Merge Task (Worktree → Main)
- Input: Task verified, worktree tests pass, ready to merge
- Action:
- Push worktree branch to remote
- Create PR (link to PR in brain decision record)
- Wait for spec-reviewer code review (forge-trust-code)
- After approval: merge to main
- Delete worktree branch (cleanup)
Cleanup Worktree
- After eval passes on main:
- Invoke
/worktree-per-project-per-task with action=cleanup
- Remove worktree directory (.claude/worktrees/TASKID/)
- Record cleanup in brain (closure to WKRK decision)
Edge Cases & Fallback Paths
Case 1: Task Discovers Unexpected Dependency on Other Task
- Symptom: "I need to implement X, but it requires changes to Y (which isn't in this task)"
- Do NOT: Expand worktree scope to include Y
- Action:
- Identify minimal interface needed from Y (contract, schema, etc.)
- Mock or stub Y in your worktree (so you can test X in isolation)
- Document the dependency in brain (WKRK decision)
- File follow-up task for Y if not already in backlog
- After Y is done: remove mock, integrate real implementation
- Re-run tests (should pass without mock)
Case 2: Worktree Accumulates Stale Node Modules / Build Artifacts
- Symptom: "Worktree tests pass, but merge to main fails (node_modules mismatch)"
- Do NOT: Reuse the worktree, ignore the mismatch
- Action:
- Delete node_modules in worktree
- Re-run npm install / cargo update
- Re-run tests (if they fail now, you found the real issue)
- Update lock files (package-lock.json)
- Commit updated lock files
Case 3: Task Touches Multiple Projects (Cross-Project Worktree)
- Symptom: "Feature requires changes to backend AND web, both in separate repos"
- Do NOT: Create separate worktrees, manually coordinate
- Action:
- Invoke
/worktree-per-project-per-task with multi_project=true
- Single worktree spans multiple project repositories
- Shared worktree environment (one node_modules tree, one build artifact tree)
- All projects in worktree tested together
- Coordinated PR creation across repos
Case 4: Previous Task Left Worktree Dirty (Uncommitted Changes)
- Symptom: "Worktree for feature X is still around with old changes"
- Do NOT: Reuse the dirty worktree
- Action:
- Check git status in worktree
- If changes are useful: cherry-pick to new task, delete old worktree
- If changes are stale: discard, delete old worktree
- Create fresh worktree for new task
Case 5: Worktree Creation Fails (Disk Full, Git Permission Error)
- Symptom: "Cannot create worktree, .claude/worktrees already has 50GB"
- Do NOT: Skip worktree, work in main
- Action:
- Investigate worktree bloat (old worktrees not cleaned up?)
- Delete old, unused worktrees
- Cleanup tool:
rm -rf .claude/worktrees/OLD_TASKID/
- Retry worktree creation
- If space still insufficient: escalate as BLOCKED (infrastructure constraint)
Case 6: Service Requires Absolute Path (Cannot Work in Worktree)
- Symptom: "Deployment script requires /opt/myapp, won't work in .claude/worktrees"
- Do NOT: Move worktree to /opt/myapp
- Action:
- Identify why service requires absolute path (hardcoded config? installer?)
- Fix the root cause (parameterize path, use relative paths)
- Verify fix in worktree
- Then deploy from worktree
Worktree Checklist
Before implementing, verify:
During implementation:
After task complete:
Additional Edge Cases
Edge Case 1: Filesystem Space Exhausted (Too Many Worktrees, Disk Full)
Situation: Cannot create fresh worktree because disk is full or storage quota exceeded. Previous worktrees were not cleaned up.
Example: .claude/worktrees/ directory is 500GB; 30 old worktrees with node_modules accumulated. Disk has <10GB free.
Do NOT: Work in main branch to save space. Space shortage is a real problem that must be fixed.
Action:
- Diagnose: which worktrees are consuming space?
du -sh .claude/worktrees/*/
- Identify old/stale worktrees:
- Which tasks are complete (merged to main)?
- Which tasks are abandoned or obsolete?
- Which worktrees have not been touched in 7+ days?
- Cleanup stale worktrees:
rm -rf .claude/worktrees/OLD_TASKID/
- If cleanup frees enough space: create fresh worktree for current task
- If cleanup is insufficient:
- Escalate as BLOCKED (disk space insufficient)
- Escalate to infrastructure: add more disk, implement automatic cleanup
- Do NOT proceed with worktree creation until space is restored
- Implement cleanup policy:
- Auto-delete worktrees after merge + 7 days
- Warn when disk usage > 80%
- Prevent new worktrees when disk < 10%
Edge Case 2: Git Corrupt in Parent Repo (Cannot Create Worktree)
Situation: Parent repository is corrupt or in bad state. Worktree creation fails because git cannot work with the repo.
Example: "fatal: not a git repository" or "corrupted object file" or "git index lock exists"
Do NOT: Skip worktree, work in main. Git corruption must be fixed.
Action:
- Diagnose: is repo actually corrupt?
git fsck --full
git status
- If index lock exists (but no git corruption):
rm .git/index.lock
git status
- If shallow clone is the issue:
git fetch --unshallow
- If actual corruption (broken objects):
- This is severe. Escalate immediately: BLOCKED (git repo corrupted)
- Do NOT attempt fixes (may worsen)
- Escalate to infrastructure/DevOps to restore from backup
- Document: what corruption was found, when, impact
- After repair: verify repo is healthy
git fsck --full
git log -1
- Then create worktree normally
Edge Case 3: Worktree Cleanup Fails (Stale Files, Permission Issues, Locks)
Situation: Worktree exists but cannot be deleted. Files are in use, permissions prevent deletion, or git locks remain.
Example: "Permission denied: .claude/worktrees/TASKID/" or "Cannot delete, files in use by another process" or ".git/HEAD is locked"
Do NOT: Leave dirty worktrees around. Accumulation of dirty worktrees blocks future work.
Action:
- Identify: why won't cleanup work?
- Files locked by running process? (kill process, wait for release)
- Permission issue? (running as wrong user, file ownership)
- Git lock exists? (left from interrupted operation)
- Submodule sync incomplete?
- If files locked:
- Find process:
lsof +D .claude/worktrees/TASKID/
- Kill process:
kill <PID>
- Wait for file descriptors to close
- Retry cleanup:
rm -rf .claude/worktrees/TASKID/
- If permission issue:
- Check file ownership:
ls -la .claude/worktrees/TASKID/
- Fix ownership (if running as different user):
chown -R $USER .claude/worktrees/TASKID/
- Retry cleanup
- If git lock exists:
- Remove lock:
rm .claude/worktrees/TASKID/.git/HEAD.lock
- Retry cleanup
- If cleanup still fails:
- Force delete (use with caution):
rm -rf --force .claude/worktrees/TASKID/
- Document: what was forced, why, what data might be lost
- Escalate: NEEDS_COORDINATION (cleanup failed, potential data loss, manual intervention required)
Output: WORKTREE CREATED (ready to implement) or BLOCKED (disk space full after cleanup, git repo corrupted, worktree cleanup failed)
Edge Case 4: Worktree Branch Diverged from Main During Long-Running Task
Symptom: Task was started in a worktree 3 days ago. Meanwhile, 12 commits landed on main (a security hotfix, an API change). The worktree branch is now 12 commits behind main, and the task's code touches files modified by those commits.
Do NOT: Ignore the divergence and continue working — the merge conflict will be larger and more complex the longer it's ignored.
Action:
- Before resuming work in any worktree older than 24 hours, check divergence:
git log --oneline HEAD..origin/main
- If behind by more than 5 commits or if main touched the same files: rebase the worktree branch before continuing
- If there are conflicts during rebase: resolve them before writing new code — do not stack new work on top of unresolved conflicts
- After rebasing, re-run verification to confirm no regressions from the main commits
- Escalation: NEEDS_COORDINATION if a main commit changed the API contract the task depends on — the task spec may need updating before implementation continues
Edge Case 5: Task Requires Multiple Repos but Worktrees Are in Different Repos
Symptom: A cross-repo task requires synchronized changes to backend/ and web/. Two separate worktrees are created — one in each repo. But the changes must land together (atomic across repos) to not break the running product.
Do NOT: Merge one repo's worktree before the other is ready — partial cross-repo merges break integration.
Action:
- Coordinate merge order per the product.md
Merge Order field — typically backend first, then frontend
- Both worktrees should be complete and verified independently before either is merged
- After merging the first repo, immediately start the eval for the combined state — don't wait for the second merge
- If the first merge causes eval to fail (because the second repo isn't merged yet), that is expected — document as "partial merge, second repo pending"
- Merge the second repo within the same session to minimize the window where the system is in a partially-migrated state
- Escalation: NEEDS_COORDINATION — notify all surface leads before the first merge so they're aware a partial state window exists
Checklist
Before starting implementation in worktree:
Post-Implementation Checklist