From 9b3e08926e18860e494cbf63485fd8c92280b034 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 3 Apr 2026 11:12:36 -0400 Subject: [PATCH] fix(worktree): executor agents verify and fix branch base on Windows When EnterWorktree creates a branch from main instead of the current HEAD (a known issue on Windows), executor agents now detect the mismatch and reset their branch base to the correct commit before starting work. - execute-phase: capture EXPECTED_BASE before spawning, inject block into executor prompts - execute-plan: document Pattern A worktree_branch_check requirement - quick.md: inject worktree_branch_check into executor prompt - diagnose-issues: inject worktree_branch_check into debugger prompts - settings: add workflow.use_worktrees option so Windows users can disable worktree isolation via /gsd:settings without editing files Closes #1510 Co-Authored-By: Claude Sonnet 4.6 --- get-shit-done/workflows/diagnose-issues.md | 3 ++- get-shit-done/workflows/execute-phase.md | 28 ++++++++++++++++++++++ get-shit-done/workflows/execute-plan.md | 2 +- get-shit-done/workflows/quick.md | 14 +++++++++++ get-shit-done/workflows/settings.md | 13 +++++++++- 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/get-shit-done/workflows/diagnose-issues.md b/get-shit-done/workflows/diagnose-issues.md index 47f3e09d6..99cc12b86 100644 --- a/get-shit-done/workflows/diagnose-issues.md +++ b/get-shit-done/workflows/diagnose-issues.md @@ -88,6 +88,7 @@ This runs in parallel - all gaps investigated simultaneously. ```bash AGENT_SKILLS_DEBUGGER=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-debugger 2>/dev/null) +EXPECTED_BASE=$(git rev-parse HEAD) ``` **Spawn debug agents in parallel:** @@ -96,7 +97,7 @@ For each gap, fill the debug-subagent-prompt template and spawn: ``` Task( - prompt=filled_debug_subagent_prompt + "\n\n\n- {phase_dir}/{phase_num}-UAT.md\n- .planning/STATE.md\n\n${AGENT_SKILLS_DEBUGGER}", + prompt=filled_debug_subagent_prompt + "\n\n\nFIRST ACTION: run git merge-base HEAD {EXPECTED_BASE} — if result differs from {EXPECTED_BASE}, run git reset --soft {EXPECTED_BASE} to correct the branch base (fixes Windows EnterWorktree creating branches from main).\n\n\n\n- {phase_dir}/{phase_num}-UAT.md\n- .planning/STATE.md\n\n${AGENT_SKILLS_DEBUGGER}", subagent_type="gsd-debugger", ${USE_WORKTREES !== "false" ? 'isolation="worktree",' : ''} description="Debug: {truth_short}" diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index 5077b9b0e..d3a2690ba 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -244,6 +244,11 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT **Worktree mode** (`USE_WORKTREES` is not `false`): + Before spawning, capture the current HEAD: + ```bash + EXPECTED_BASE=$(git rev-parse HEAD) + ``` + ``` Task( subagent_type="gsd-executor", @@ -256,6 +261,29 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT Commit each task atomically. Create SUMMARY.md. Update STATE.md and ROADMAP.md. + + FIRST ACTION before any other work: verify this worktree's branch is based on the correct commit. + + Run: + ```bash + ACTUAL_BASE=$(git merge-base HEAD {EXPECTED_BASE}) + CURRENT_HEAD=$(git rev-parse HEAD) + ``` + + If `ACTUAL_BASE` != `{EXPECTED_BASE}` (i.e. the worktree branch was created from an older + base such as `main` instead of the feature branch HEAD), rebase onto the correct base: + ```bash + git rebase --onto {EXPECTED_BASE} $(git rev-parse --abbrev-ref HEAD~1 2>/dev/null || git rev-parse HEAD^) HEAD 2>/dev/null || true + # If rebase fails or is a no-op, reset the branch to start from the correct base: + git reset --soft {EXPECTED_BASE} + ``` + + If `ACTUAL_BASE` == `{EXPECTED_BASE}`: the branch base is correct, proceed immediately. + + This check fixes a known issue on Windows where `EnterWorktree` creates branches from + `main` instead of the current feature branch HEAD. + + You are running as a PARALLEL executor agent. Use --no-verify on all git commits to avoid pre-commit hook contention with other agents. The diff --git a/get-shit-done/workflows/execute-plan.md b/get-shit-done/workflows/execute-plan.md index 920e92ab9..345e64073 100644 --- a/get-shit-done/workflows/execute-plan.md +++ b/get-shit-done/workflows/execute-plan.md @@ -72,7 +72,7 @@ grep -n "type=\"checkpoint" .planning/phases/XX-name/{phase}-{plan}-PLAN.md | Verify-only | B (segmented) | Segments between checkpoints. After none/human-verify → SUBAGENT. After decision/human-action → MAIN | | Decision | C (main) | Execute entirely in main context | -**Pattern A:** init_agent_tracking → spawn Task(subagent_type="gsd-executor", model=executor_model) with prompt: execute plan at [path], autonomous, all tasks + SUMMARY + commit, follow deviation/auth rules, report: plan name, tasks, SUMMARY path, commit hash → track agent_id → wait → update tracking → report. **Include `isolation="worktree"` only if `workflow.use_worktrees` is not `false`** (read via `config-get workflow.use_worktrees`). +**Pattern A:** init_agent_tracking → capture `EXPECTED_BASE=$(git rev-parse HEAD)` → spawn Task(subagent_type="gsd-executor", model=executor_model) with prompt: execute plan at [path], autonomous, all tasks + SUMMARY + commit, follow deviation/auth rules, report: plan name, tasks, SUMMARY path, commit hash → track agent_id → wait → update tracking → report. **Include `isolation="worktree"` only if `workflow.use_worktrees` is not `false`** (read via `config-get workflow.use_worktrees`). **When using `isolation="worktree"`, include a `` block in the prompt** instructing the executor to run `git merge-base HEAD {EXPECTED_BASE}` and, if the result differs from `{EXPECTED_BASE}`, reset the branch base with `git reset --soft {EXPECTED_BASE}` before starting work. This corrects a known issue on Windows where `EnterWorktree` creates branches from `main` instead of the feature branch HEAD. **Pattern B:** Execute segment-by-segment. Autonomous segments: spawn subagent for assigned tasks only (no SUMMARY/commit). Checkpoints: main context. After all segments: aggregate, create SUMMARY, commit. See segment_execution. diff --git a/get-shit-done/workflows/quick.md b/get-shit-done/workflows/quick.md index 0f3d8a11f..e78eaae11 100644 --- a/get-shit-done/workflows/quick.md +++ b/get-shit-done/workflows/quick.md @@ -550,6 +550,11 @@ Offer: 1) Force proceed, 2) Abort **Step 6: Spawn executor** +Capture current HEAD before spawning (used for worktree branch check): +```bash +EXPECTED_BASE=$(git rev-parse HEAD) +``` + Spawn gsd-executor with plan reference: ``` @@ -557,6 +562,15 @@ Task( prompt=" Execute quick task ${quick_id}. +${USE_WORKTREES !== "false" ? ` + +FIRST ACTION before any other work: verify this worktree branch is based on the correct commit. +Run: git merge-base HEAD ${EXPECTED_BASE} +If the result differs from ${EXPECTED_BASE}, run: git reset --soft ${EXPECTED_BASE} +This corrects a known issue on Windows where EnterWorktree creates branches from main instead of the feature branch HEAD. + +` : ''} + - ${QUICK_DIR}/${quick_id}-PLAN.md (Plan) - .planning/STATE.md (Project state) diff --git a/get-shit-done/workflows/settings.md b/get-shit-done/workflows/settings.md index 17c1bd593..d463b1130 100644 --- a/get-shit-done/workflows/settings.md +++ b/get-shit-done/workflows/settings.md @@ -34,6 +34,7 @@ Parse current values (default to `true` if not present): - `workflow.ui_safety_gate` — prompt to run /gsd:ui-phase before planning frontend phases (default: true if absent) - `model_profile` — which model each agent uses (default: `balanced`) - `git.branching_strategy` — branching approach (default: `"none"`) +- `workflow.use_worktrees` — whether parallel executor agents run in worktree isolation (default: `true`) @@ -153,6 +154,15 @@ AskUserQuestion([ { label: "No (Recommended)", description: "Run smart discuss before each phase — surfaces gray areas and captures decisions." }, { label: "Yes", description: "Skip discuss in /gsd:autonomous — chain directly to plan. Best for backend/pipeline work where phase descriptions are the spec." } ] + }, + { + question: "Use git worktrees for parallel agent isolation?", + header: "Worktrees", + multiSelect: false, + options: [ + { label: "Yes (Recommended)", description: "Each parallel executor runs in its own worktree branch — no conflicts between agents." }, + { label: "No", description: "Disable worktree isolation. Use on platforms where EnterWorktree is broken (e.g. Windows with feature branches). Agents run sequentially on the main working tree." } + ] } ]) ``` @@ -176,7 +186,8 @@ Merge new settings into existing config.json: "text_mode": true/false, "research_before_questions": true/false, "discuss_mode": "discuss" | "assumptions", - "skip_discuss": true/false + "skip_discuss": true/false, + "use_worktrees": true/false }, "git": { "branching_strategy": "none" | "phase" | "milestone",