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