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",