From 79fee93c4ee963218f7d5647b677695702862f00 Mon Sep 17 00:00:00 2001 From: Drew Ritter Date: Mon, 6 Apr 2026 14:01:48 -0700 Subject: [PATCH 01/19] docs: add worktree rototill design spec (PRI-974) Design for detect-and-defer worktree support. Superpowers defers to native harness worktree systems when available, falls back to manual git worktree creation when not. Covers Phases 0-2: detection, consent, native tool preference, finishing state detection, and three bug fixes (#940, #999, #238). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-04-06-worktree-rototill-design.md | 279 ++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-06-worktree-rototill-design.md diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md new file mode 100644 index 00000000..5c8333b2 --- /dev/null +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -0,0 +1,279 @@ +# Worktree Rototill: Detect-and-Defer + +**Date:** 2026-04-06 +**Status:** Draft +**Ticket:** PRI-974 +**Subsumes:** PRI-823 (Codex App compatibility) + +## Problem + +Superpowers is opinionated about worktree management — specific paths (`.worktrees/`), specific commands (`git worktree add`), specific cleanup (`git worktree remove`). Meanwhile, Claude Code, Codex App, Gemini CLI, and Cursor all provide native worktree support with their own paths, lifecycle management, and cleanup. + +This creates three failure modes: + +1. **Duplication** — on Claude Code, the skill does what `EnterWorktree`/`ExitWorktree` already does +2. **Conflict** — on Codex App, the skill tries to create worktrees inside an already-managed worktree +3. **Phantom state** — skill-created worktrees at `.worktrees/` are invisible to the harness; harness-created worktrees at `.claude/worktrees/` are invisible to the skill + +For harnesses without native support (Codex CLI, OpenCode, Copilot standalone), superpowers fills a real gap. The skill shouldn't go away — it should get out of the way when native support exists. + +## Goals + +1. Defer to native harness worktree systems when they exist +2. Continue providing worktree support for harnesses that lack it +3. Fix three known bugs in finishing-a-development-branch (#940, #999, #238) +4. Make worktree creation opt-in rather than mandatory (#991) +5. Replace hardcoded `CLAUDE.md` references with platform-neutral language (#1049) + +## Non-Goals + +- Per-worktree environment conventions (`.worktree-env.sh`, port offsetting) — Phase 4 +- PreToolUse hooks for path enforcement — Phase 4 +- Multi-repo worktree documentation — Phase 4 +- Brainstorming checklist changes for worktrees — Phase 4 +- `.superpowers-session.json` metadata tracking (interesting PR #997 idea, not needed for v1) +- Hooks symlinking into worktrees (PR #965 idea, separate concern) + +## Design Principles + +### Detect state, not platform + +Use `GIT_DIR != GIT_COMMON` to determine "am I already in a worktree?" rather than sniffing environment variables to identify the harness. This is a stable git primitive (since git 2.5, 2015), works universally across all harnesses, and requires zero maintenance as new harnesses appear. + +### Declarative intent, prescriptive fallback + +The skill describes the goal ("ensure work happens in an isolated workspace") and defers to native tools when available. It prescribes specific git commands only as a fallback for harnesses without native worktree support. Structurally, the native-tool path (Step 1a) comes first and is short; the git fallback (Step 1b) comes second and is long. This prevents agents from anchoring on the detailed fallback and skipping the preferred path. + +### Provenance-based ownership + +Whoever creates the worktree owns its cleanup. If the harness created it, superpowers doesn't touch it. If superpowers created it (via git fallback), superpowers cleans it up. The heuristic: if the worktree lives under `.worktrees/`, superpowers owns it. Anything else (`.claude/worktrees/`, `~/.codex/worktrees/`, `.gemini/worktrees/`) belongs to the harness. + +## Design + +### 1. `using-git-worktrees` SKILL.md Rewrite + +The skill gains three new steps before creation and simplifies the creation flow. + +#### Step 0: Detect Existing Isolation + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +BRANCH=$(git branch --show-current) +``` + +Three outcomes: + +| Condition | Meaning | Action | +|-----------|---------|--------| +| `GIT_DIR == GIT_COMMON` | Normal repo checkout | Proceed to Step 0.5 | +| `GIT_DIR != GIT_COMMON`, named branch | Already in a linked worktree | Skip to Step 3 (project setup). Report: "Already in isolated workspace at `` on branch ``." | +| `GIT_DIR != GIT_COMMON`, detached HEAD | Externally managed worktree (e.g., Codex App sandbox) | Skip to Step 3. Report: "Already in isolated workspace at `` (detached HEAD, externally managed)." | + +Step 0 does not care who created the worktree or which harness is running. A worktree is a worktree regardless of origin. + +#### Step 0.5: Consent + +When Step 0 finds no existing isolation (`GIT_DIR == GIT_COMMON`), ask before creating: + +> "Would you like me to set up an isolated worktree? This protects your current branch from changes. (y/n)" + +If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no worktree. + +This step is skipped entirely when Step 0 detects existing isolation (no point asking about what already exists). + +#### Step 1a: Native Tools (preferred) + +> If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. + +After using a native tool, skip to Step 3 (project setup). + +This section is deliberately short (3 lines). Agents already know their available tools. Listing examples would risk agents attempting tools that don't exist on their platform. + +#### Step 1b: Git Worktree Fallback + +When no native tool is available, create a worktree manually. + +**Directory selection** (priority order): +1. Check for existing `.worktrees/` or `worktrees/` directory — if found, use it. If both exist, `.worktrees/` wins. +2. Check the project's agent instruction file (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. +3. Default to `.worktrees/`. + +No interactive directory selection prompt. No global path option (`~/.config/superpowers/worktrees/` is dropped — no demonstrated user demand, adds cleanup and cross-device complexity). + +**Safety verification** (project-local directories only): + +```bash +git check-ignore -q .worktrees 2>/dev/null +``` + +If not ignored, add to `.gitignore` and commit before proceeding. + +**Create:** + +```bash +git worktree add "$path" -b "$BRANCH_NAME" +cd "$path" +``` + +**Sandbox fallback:** If `git worktree add` fails with a permission error, treat as a restricted environment. Skip creation, work in current directory, proceed to Step 3. + +#### Steps 3-4: Project Setup and Baseline Tests (unchanged) + +Regardless of which path created the workspace (Step 0 detected existing, Step 1a native tool, Step 1b git fallback, or no worktree at all), execution converges: + +- **Step 3:** Auto-detect and run project setup (`npm install`, `cargo build`, `pip install`, `go mod download`, etc.) +- **Step 4:** Run the test suite. If tests fail, report failures and ask whether to proceed. + +### 2. `finishing-a-development-branch` SKILL.md Rewrite + +The finishing skill gains environment detection and fixes three bugs. + +#### Step 1: Verify Tests (unchanged) + +Run the project's test suite. If tests fail, stop. Don't offer completion options. + +#### Step 1.5: Detect Environment (new) + +Re-run the same detection as Step 0 in creation: + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +``` + +Three paths: + +| State | Menu | Cleanup | +|-------|------|---------| +| `GIT_DIR == GIT_COMMON` (normal repo) | Standard 4 options | No worktree to clean up | +| `GIT_DIR != GIT_COMMON`, named branch | Standard 4 options | Provenance-based (see Step 5) | +| `GIT_DIR != GIT_COMMON`, detached HEAD | Reduced menu: push as new branch + PR, keep as-is, discard | No merge options (can't merge from detached HEAD) | + +#### Step 2: Determine Base Branch (unchanged) + +#### Step 3: Present Options + +**Normal repo and named-branch worktree:** + +1. Merge back to `` locally +2. Push and create a Pull Request +3. Keep the branch as-is (I'll handle it later) +4. Discard this work + +**Detached HEAD:** + +1. Push as new branch and create a Pull Request +2. Keep as-is (I'll handle it later) +3. Discard this work + +#### Step 4: Execute Choice + +**Option 1 (Merge locally):** + +```bash +# Get main repo root for CWD safety (Bug #238 fix) +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) + +# Remove worktree BEFORE deleting branch (Bug #999 fix) +cd "$MAIN_ROOT" +git worktree remove "$WORKTREE_PATH" # only if superpowers owns it + +# Now safe to work with branches +git checkout +git pull +git merge + +git branch -d +``` + +**Option 2 (Create PR):** + +Push branch, create PR. Do NOT clean up worktree — user needs it for PR iteration. (Bug #940 fix: remove contradictory "Then: Cleanup worktree" prose.) + +**Option 3 (Keep as-is):** No action. + +**Option 4 (Discard):** Require typed "discard" confirmation. Then remove worktree (if superpowers owns it), force-delete branch. + +#### Step 5: Cleanup (updated) + +``` +if GIT_DIR == GIT_COMMON: + # Normal repo, no worktree to clean up + done + +if worktree path is under .worktrees/: + # Superpowers created it — we own cleanup + cd to main repo root # Bug #238 fix + git worktree remove + +else: + # Harness created it — hands off + # If platform provides a workspace-exit tool, use it + # Otherwise, leave the worktree in place +``` + +Cleanup only runs for Options 1 and 4. Options 2 and 3 always preserve the worktree. (Bug #940 fix.) + +### 3. Integration Updates + +#### `subagent-driven-development` and `executing-plans` + +Both currently list `using-git-worktrees` as REQUIRED in their integration sections. Change to: + +> `using-git-worktrees` — Ensures isolated workspace (creates one or verifies existing) + +The skill itself now handles consent (Step 0.5) and detection (Step 0), so calling skills don't need to gate or prompt. + +#### `writing-plans` + +Remove the stale claim "should be run in a dedicated worktree (created by brainstorming skill)." Brainstorming is a design skill and does not create worktrees. The worktree prompt happens at execution time via `using-git-worktrees`. + +### 4. Platform-Neutral Instruction File References + +All instances of hardcoded `CLAUDE.md` in worktree-related skills are replaced with: + +> "your project's agent instruction file (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent)" + +This applies to directory preference checks in Step 1b. + +## Bug Fixes (bundled) + +| Bug | Problem | Fix | Location | +|-----|---------|-----|----------| +| #940 | Option 2 prose says "Then: Cleanup worktree (Step 5)" but quick reference says keep it. Step 5 says "For Options 1, 2, 4" but Common Mistakes says "Options 1 and 4 only." | Remove cleanup from Option 2. Step 5 applies to Options 1 and 4 only. | finishing SKILL.md | +| #999 | Option 1 deletes branch before removing worktree. `git branch -d` can fail because worktree still references the branch. | Reorder: remove worktree first, then delete branch. | finishing SKILL.md | +| #238 | `git worktree remove` fails silently if CWD is inside the worktree being removed. | Add CWD guard: `cd` to main repo root before `git worktree remove`. | finishing SKILL.md | + +## Issues Resolved + +| Issue | Resolution | +|-------|-----------| +| #940 | Direct fix (Bug #940) | +| #991 | Opt-in consent in Step 0.5 | +| #918 | Step 0 detection + Step 1.5 finishing detection | +| #1009 | Step 0 detects harness-created worktrees and defers | +| #999 | Direct fix (Bug #999) | +| #238 | Direct fix (Bug #238) | +| #1049 | Platform-neutral instruction file references | +| #279 | Solved by detect-and-defer — native paths respected because we don't override them | +| #574 | Partially addressed: consent prompt replaces the implicit handoff gap. Full fix (brainstorming checklist step) deferred to Phase 4 | + +## Risks + +### Step 1a agent anchoring + +The highest-risk element. Step 1a is deliberately short (3 lines) to prevent agents from anchoring on it over the detailed Step 1b fallback. However, the inverse risk exists: agents may skip the short Step 1a and go straight to the detailed Step 1b. Mitigation: TDD validation using Claude Code's native worktree support (the richest available), with RED/GREEN tests confirming agents use native tools when available. + +### Provenance heuristic + +The `.worktrees/ = ours, anything else = hands off` heuristic works for every current harness. If a future harness adopts `.worktrees/` as its convention, we'd have a false positive (superpowers tries to clean up a harness-owned worktree). Low risk — every harness uses branded paths — but worth noting. + +### Detached HEAD finishing + +The reduced menu for detached HEAD worktrees (no merge option) is correct for Codex App's sandbox model. If a user is in detached HEAD for another reason, the reduced menu still makes sense — you genuinely can't merge from detached HEAD without creating a branch first. + +## Future Work (not in this spec) + +- **Phase 3 remainder:** `$TMPDIR` directory option (#666), setup docs for caching and env inheritance (#299) +- **Phase 4:** PreToolUse hooks for path enforcement (#1040), per-worktree env conventions (#597), brainstorming checklist worktree step (#574), multi-repo documentation (#710) From 2e53549478c1453a9c741891144dad42fcf9e9bf Mon Sep 17 00:00:00 2001 From: Drew Ritter Date: Mon, 6 Apr 2026 14:07:56 -0700 Subject: [PATCH 02/19] docs: address SWE review feedback on worktree rototill spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix Bug #999 order: merge → verify → remove worktree → delete branch (avoids losing work if merge fails after worktree removal) - Add submodule guard to Step 0 detection (GIT_DIR != GIT_COMMON is also true in submodules) - Preserve global path (~/.config/superpowers/worktrees/) in detection for backward compatibility, just stop offering it to new users - Add step numbering note and implementation notes section - Expand provenance heuristic to cover global path and manual creation Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-04-06-worktree-rototill-design.md | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md index 5c8333b2..f4ac5617 100644 --- a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -46,7 +46,7 @@ The skill describes the goal ("ensure work happens in an isolated workspace") an ### Provenance-based ownership -Whoever creates the worktree owns its cleanup. If the harness created it, superpowers doesn't touch it. If superpowers created it (via git fallback), superpowers cleans it up. The heuristic: if the worktree lives under `.worktrees/`, superpowers owns it. Anything else (`.claude/worktrees/`, `~/.codex/worktrees/`, `.gemini/worktrees/`) belongs to the harness. +Whoever creates the worktree owns its cleanup. If the harness created it, superpowers doesn't touch it. If superpowers created it (via git fallback), superpowers cleans it up. The heuristic: if the worktree lives under `.worktrees/` or `~/.config/superpowers/worktrees/`, superpowers owns it. Anything else (`.claude/worktrees/`, `~/.codex/worktrees/`, `.gemini/worktrees/`) belongs to the harness. ## Design @@ -72,6 +72,15 @@ Three outcomes: Step 0 does not care who created the worktree or which harness is running. A worktree is a worktree regardless of origin. +**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," check that we're not in a submodule: + +```bash +# If this returns a path, we're in a submodule, not a worktree +git rev-parse --show-superproject-working-tree 2>/dev/null +``` + +If in a submodule, treat as `GIT_DIR == GIT_COMMON` (proceed to Step 0.5). + #### Step 0.5: Consent When Step 0 finds no existing isolation (`GIT_DIR == GIT_COMMON`), ask before creating: @@ -96,10 +105,11 @@ When no native tool is available, create a worktree manually. **Directory selection** (priority order): 1. Check for existing `.worktrees/` or `worktrees/` directory — if found, use it. If both exist, `.worktrees/` wins. -2. Check the project's agent instruction file (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. -3. Default to `.worktrees/`. +2. Check for existing `~/.config/superpowers/worktrees//` directory — if found, use it (backward compatibility with legacy global path). +3. Check the project's agent instruction file (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. +4. Default to `.worktrees/`. -No interactive directory selection prompt. No global path option (`~/.config/superpowers/worktrees/` is dropped — no demonstrated user demand, adds cleanup and cross-device complexity). +No interactive directory selection prompt. The global path (`~/.config/superpowers/worktrees/`) is no longer offered as a choice to new users, but existing worktrees at that location are detected and used for backward compatibility. **Safety verification** (project-local directories only): @@ -118,6 +128,8 @@ cd "$path" **Sandbox fallback:** If `git worktree add` fails with a permission error, treat as a restricted environment. Skip creation, work in current directory, proceed to Step 3. +**Step numbering note:** The current skill has Steps 1-4 as a flat list. This redesign uses 0, 0.5, 1a, 1b, 3, 4. There is no Step 2 — it was the old monolithic "Create Isolated Workspace" which is now split into the 1a/1b structure. The implementation should renumber cleanly (e.g., 0 → "Step 0: Detect", 0.5 → within Step 0's flow, 1a/1b → "Step 1", 3 → "Step 2", 4 → "Step 3") or keep the current numbering with a note. Implementer's choice. + #### Steps 3-4: Project Setup and Baseline Tests (unchanged) Regardless of which path created the workspace (Step 0 detected existing, Step 1a native tool, Step 1b git fallback, or no worktree at all), execution converges: @@ -174,19 +186,21 @@ Three paths: ```bash # Get main repo root for CWD safety (Bug #238 fix) MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) - -# Remove worktree BEFORE deleting branch (Bug #999 fix) cd "$MAIN_ROOT" -git worktree remove "$WORKTREE_PATH" # only if superpowers owns it -# Now safe to work with branches +# Merge first, verify success before removing anything git checkout git pull git merge + +# Only after merge succeeds: remove worktree, then delete branch (Bug #999 fix) +git worktree remove "$WORKTREE_PATH" # only if superpowers owns it git branch -d ``` +The order is critical: merge → verify → remove worktree → delete branch. The old skill deleted the branch before removing the worktree (which fails because the worktree still references the branch). The naive fix of removing the worktree first is also wrong — if the merge then fails, the working directory is gone and changes are lost. + **Option 2 (Create PR):** Push branch, create PR. Do NOT clean up worktree — user needs it for PR iteration. (Bug #940 fix: remove contradictory "Then: Cleanup worktree" prose.) @@ -202,7 +216,7 @@ if GIT_DIR == GIT_COMMON: # Normal repo, no worktree to clean up done -if worktree path is under .worktrees/: +if worktree path is under .worktrees/ or ~/.config/superpowers/worktrees/: # Superpowers created it — we own cleanup cd to main repo root # Bug #238 fix git worktree remove @@ -242,7 +256,7 @@ This applies to directory preference checks in Step 1b. | Bug | Problem | Fix | Location | |-----|---------|-----|----------| | #940 | Option 2 prose says "Then: Cleanup worktree (Step 5)" but quick reference says keep it. Step 5 says "For Options 1, 2, 4" but Common Mistakes says "Options 1 and 4 only." | Remove cleanup from Option 2. Step 5 applies to Options 1 and 4 only. | finishing SKILL.md | -| #999 | Option 1 deletes branch before removing worktree. `git branch -d` can fail because worktree still references the branch. | Reorder: remove worktree first, then delete branch. | finishing SKILL.md | +| #999 | Option 1 deletes branch before removing worktree. `git branch -d` can fail because worktree still references the branch. | Reorder to: merge → verify tests → remove worktree → delete branch. Merge must succeed before anything is removed. | finishing SKILL.md | | #238 | `git worktree remove` fails silently if CWD is inside the worktree being removed. | Add CWD guard: `cd` to main repo root before `git worktree remove`. | finishing SKILL.md | ## Issues Resolved @@ -267,12 +281,24 @@ The highest-risk element. Step 1a is deliberately short (3 lines) to prevent age ### Provenance heuristic -The `.worktrees/ = ours, anything else = hands off` heuristic works for every current harness. If a future harness adopts `.worktrees/` as its convention, we'd have a false positive (superpowers tries to clean up a harness-owned worktree). Low risk — every harness uses branded paths — but worth noting. +The `.worktrees/` or `~/.config/superpowers/worktrees/` = ours, anything else = hands off` heuristic works for every current harness. If a future harness adopts `.worktrees/` as its convention, we'd have a false positive (superpowers tries to clean up a harness-owned worktree). Similarly, if a user manually runs `git worktree add .worktrees/experiment` without superpowers, we'd incorrectly claim ownership. Both are low risk — every harness uses branded paths, and manual `.worktrees/` creation is unlikely — but worth noting. ### Detached HEAD finishing The reduced menu for detached HEAD worktrees (no merge option) is correct for Codex App's sandbox model. If a user is in detached HEAD for another reason, the reduced menu still makes sense — you genuinely can't merge from detached HEAD without creating a branch first. +## Implementation Notes + +Both skill files contain sections beyond the core steps that need updating during implementation: + +- **Frontmatter** (`name`, `description`): Update to reflect detect-and-defer behavior +- **Quick Reference tables**: Rewrite to match new step structure and bug fixes +- **Common Mistakes sections**: Update or remove items that reference old behavior (e.g., "Skip CLAUDE.md check" is now wrong) +- **Red Flags sections**: Update to reflect new priorities (e.g., "Never create a worktree when Step 0 detects existing isolation") +- **Integration sections**: Update cross-references between skills + +The spec describes *what changes*; the implementation plan will specify exact edits to these secondary sections. + ## Future Work (not in this spec) - **Phase 3 remainder:** `$TMPDIR` directory option (#666), setup docs for caching and env inheritance (#299) From 7ebda5c81b7cf60b6606e1ab564025a095cc1fb1 Mon Sep 17 00:00:00 2001 From: Drew Ritter Date: Mon, 6 Apr 2026 14:13:54 -0700 Subject: [PATCH 03/19] docs: honest spec revisions after issue/PR deep dive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Step 1a is the load-bearing assumption, not just a risk — if it fails, the entire design needs rework. TDD validation must be first impl task. - #1009 resolution depends on Step 1a working, stated explicitly - #574 honestly deferred, not "partially addressed" - Add hooks symlink to Step 1b (PR #965 idea, prevents silent hook loss) - Add stale worktree pruning to Step 5 (PR #1072 idea, one-line self-heal) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-04-06-worktree-rototill-design.md | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md index f4ac5617..f142506b 100644 --- a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -126,6 +126,16 @@ git worktree add "$path" -b "$BRANCH_NAME" cd "$path" ``` +**Hooks awareness:** Git worktrees do not inherit the parent repo's hooks directory. After creating a worktree via 1b, symlink the hooks directory from the main repo if one exists: + +```bash +if [ -d "$MAIN_ROOT/.git/hooks" ]; then + ln -sf "$MAIN_ROOT/.git/hooks" "$path/.git/hooks" +fi +``` + +This prevents pre-commit checks, linters, and other hooks from silently stopping when work moves to a worktree. (Idea from PR #965.) + **Sandbox fallback:** If `git worktree add` fails with a permission error, treat as a restricted environment. Skip creation, work in current directory, proceed to Step 3. **Step numbering note:** The current skill has Steps 1-4 as a flat list. This redesign uses 0, 0.5, 1a, 1b, 3, 4. There is no Step 2 — it was the old monolithic "Create Isolated Workspace" which is now split into the 1a/1b structure. The implementation should renumber cleanly (e.g., 0 → "Step 0: Detect", 0.5 → within Step 0's flow, 1a/1b → "Step 1", 3 → "Step 2", 4 → "Step 3") or keep the current numbering with a note. Implementer's choice. @@ -229,6 +239,8 @@ else: Cleanup only runs for Options 1 and 4. Options 2 and 3 always preserve the worktree. (Bug #940 fix.) +**Stale worktree pruning:** After any `git worktree remove`, run `git worktree prune` as a self-healing step. Worktree directories can get deleted out-of-band (e.g., by harness cleanup, manual `rm`, or `.claude/` cleanup), leaving stale registrations that cause confusing errors. One line, prevents silent rot. (Idea from PR #1072.) + ### 3. Integration Updates #### `subagent-driven-development` and `executing-plans` @@ -266,18 +278,20 @@ This applies to directory preference checks in Step 1b. | #940 | Direct fix (Bug #940) | | #991 | Opt-in consent in Step 0.5 | | #918 | Step 0 detection + Step 1.5 finishing detection | -| #1009 | Step 0 detects harness-created worktrees and defers | +| #1009 | Resolved by Step 1a — agents use native tools (e.g., `EnterWorktree`) which create at harness-native paths. Depends on Step 1a working; see Risks. | | #999 | Direct fix (Bug #999) | | #238 | Direct fix (Bug #238) | | #1049 | Platform-neutral instruction file references | | #279 | Solved by detect-and-defer — native paths respected because we don't override them | -| #574 | Partially addressed: consent prompt replaces the implicit handoff gap. Full fix (brainstorming checklist step) deferred to Phase 4 | +| #574 | **Deferred.** Nothing in this spec touches the brainstorming skill where the bug lives. Full fix (adding a worktree step to brainstorming's checklist) is Phase 4. | ## Risks -### Step 1a agent anchoring +### Step 1a is the load-bearing assumption -The highest-risk element. Step 1a is deliberately short (3 lines) to prevent agents from anchoring on it over the detailed Step 1b fallback. However, the inverse risk exists: agents may skip the short Step 1a and go straight to the detailed Step 1b. Mitigation: TDD validation using Claude Code's native worktree support (the richest available), with RED/GREEN tests confirming agents use native tools when available. +Step 1a — agents preferring native worktree tools over the git fallback — is not one feature among many. It is the foundation the entire design rests on. If agents ignore the short Step 1a and fall through to Step 1b on harnesses that have native support, then detect-and-defer fails entirely: superpowers still creates worktrees at `.worktrees/` on Claude Code, Cursor, Gemini CLI, and Codex App, which is the exact problem this spec exists to solve. Every issue marked "solved by detect-and-defer" (#1009, #918, #279) goes back to unsolved. + +**Mitigation:** TDD validation of Step 1a must be the first implementation task, before any other skill changes. Use Claude Code's native worktree support (the richest available) with RED/GREEN tests confirming agents use `EnterWorktree` when available instead of `git worktree add`. If Step 1a fails validation, stop and redesign the creation approach before proceeding with the rest of the spec. ### Provenance heuristic From c6d66a0bc7d9b364446291aa4fbfb40e5e580a09 Mon Sep 17 00:00:00 2001 From: Drew Ritter Date: Mon, 6 Apr 2026 14:22:07 -0700 Subject: [PATCH 04/19] docs: add worktree rototill implementation plan (PRI-974) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5 tasks: TDD gate for Step 1a, using-git-worktrees rewrite, finishing-a-development-branch rewrite, integration updates, end-to-end validation. Task 1 is a hard gate — if native tool preference fails RED/GREEN, stop and redesign. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../plans/2026-04-06-worktree-rototill.md | 877 ++++++++++++++++++ 1 file changed, 877 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-06-worktree-rototill.md diff --git a/docs/superpowers/plans/2026-04-06-worktree-rototill.md b/docs/superpowers/plans/2026-04-06-worktree-rototill.md new file mode 100644 index 00000000..0a0d41cb --- /dev/null +++ b/docs/superpowers/plans/2026-04-06-worktree-rototill.md @@ -0,0 +1,877 @@ +# Worktree Rototill Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make superpowers defer to native harness worktree systems when available, fall back to manual git worktrees when not, and fix three known finishing bugs. + +**Architecture:** Two skill files are rewritten (`using-git-worktrees`, `finishing-a-development-branch`), three files get one-line integration updates (`executing-plans`, `subagent-driven-development`, `writing-plans`). The core change is adding detection (`GIT_DIR != GIT_COMMON`) and a native-tool-first creation path. These are markdown skill instruction files, not application code — "tests" are agent behavior tests using the testing-skills-with-subagents TDD framework. + +**Tech Stack:** Markdown (skill files), bash (test scripts), Claude Code CLI (`claude -p` for headless testing) + +**Spec:** `docs/superpowers/specs/2026-04-06-worktree-rototill-design.md` + +--- + +### Task 1: GATE — TDD Validation of Step 1a (Native Tool Preference) + +Step 1a is the load-bearing assumption of the entire design. If agents don't prefer native worktree tools over `git worktree add`, the spec fails. Validate this FIRST, before touching any skill files. + +**Files:** +- Create: `tests/claude-code/test-worktree-native-preference.sh` +- Read: `skills/using-git-worktrees/SKILL.md` (current version, for RED baseline) +- Read: `tests/claude-code/test-helpers.sh` (for `run_claude`, `assert_contains`, etc.) +- Read: `skills/writing-skills/testing-skills-with-subagents.md` (TDD framework) + +**This task is a gate.** If the GREEN phase fails after 2 REFACTOR iterations, STOP. Do not proceed to Task 2. Report back — the creation approach needs redesign. + +- [ ] **Step 1: Write the RED baseline test script** + +Create the test script that will run scenarios both WITHOUT and WITH the updated skill text. The RED phase runs against the current skill (which has no Step 1a). + +```bash +#!/usr/bin/env bash +# Test: Does the agent prefer native worktree tools (EnterWorktree) over git worktree add? +# Framework: RED-GREEN-REFACTOR per testing-skills-with-subagents.md +# +# RED: Current skill has no native tool preference. Agent should use git worktree add. +# GREEN: Updated skill has Step 1a. Agent should use EnterWorktree on Claude Code. + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/test-helpers.sh" + +# Pressure scenario: realistic implementation task where agent needs isolation +SCENARIO='IMPORTANT: This is a real task. Choose and act. + +You need to implement a small feature (add a "version" field to package.json). +This should be done in an isolated workspace to protect the main branch. + +You have the using-git-worktrees skill available. Set up the isolated workspace now. +Do NOT actually implement the feature — just set up the workspace and report what you did. + +Respond with EXACTLY what tool/command you used to create the workspace.' + +echo "=== Worktree Native Preference Test ===" +echo "" + +# Phase selection +PHASE="${1:-red}" + +if [ "$PHASE" = "red" ]; then + echo "--- RED PHASE: Running WITHOUT Step 1a (current skill) ---" + echo "Expected: Agent uses 'git worktree add' (no native tool awareness)" + echo "" + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + mkdir -p .worktrees + + output=$(run_claude "$SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # RED expectation: agent uses git worktree add (current behavior) + if echo "$output" | grep -qi "EnterWorktree"; then + echo "[UNEXPECTED] Agent used EnterWorktree WITHOUT Step 1a — skill may not be needed" + echo "Investigate: is Claude Code's default behavior already correct?" + else + echo "[RED CONFIRMED] Agent did NOT use EnterWorktree" + assert_contains "$output" "git worktree" "Agent used git worktree (expected in RED)" + fi + + cleanup_test_project "$test_dir" + +elif [ "$PHASE" = "green" ]; then + echo "--- GREEN PHASE: Running WITH Step 1a (updated skill) ---" + echo "Expected: Agent uses EnterWorktree instead of git worktree add" + echo "" + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + + output=$(run_claude "$SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # GREEN expectation: agent uses EnterWorktree + assert_contains "$output" "EnterWorktree" "Agent used native EnterWorktree tool" + assert_not_contains "$output" "git worktree add" "Agent did NOT fall back to git worktree add" + + cleanup_test_project "$test_dir" + +elif [ "$PHASE" = "pressure" ]; then + echo "--- PRESSURE PHASE: Multiple pressures to skip native tools ---" + echo "" + + PRESSURE_SCENARIO='IMPORTANT: This is a real task. Choose and act. + +You need to set up an isolated workspace URGENTLY. Production is impacted and +the fix needs to go in a worktree. You know git worktree add works reliably. +The .worktrees/ directory already exists and is gitignored. + +You have the using-git-worktrees skill. Set up the workspace NOW. +Speed matters. Report EXACTLY what tool/command you used.' + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + mkdir -p .worktrees + echo ".worktrees/" >> .gitignore + + output=$(run_claude "$PRESSURE_SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # Should STILL use EnterWorktree even under pressure + assert_contains "$output" "EnterWorktree" "Agent used native tool even under time pressure" + assert_not_contains "$output" "git worktree add" "Agent resisted falling back to git despite pressure" + + cleanup_test_project "$test_dir" +fi + +echo "" +echo "=== Test Complete ===" +``` + +- [ ] **Step 2: Run RED phase — confirm agent uses git worktree add today** + +Run: `cd tests/claude-code && bash test-worktree-native-preference.sh red` + +Expected: `[RED CONFIRMED] Agent did NOT use EnterWorktree` — agent uses `git worktree add` because current skill has no native tool preference. + +Document the agent's exact output and any rationalizations verbatim. This is the baseline failure the skill must fix. + +- [ ] **Step 3: If RED confirmed, proceed. Write the Step 1a skill text.** + +Create a temporary test version of the skill with ONLY the Step 1a addition (minimal change to isolate the variable). Add this section to the top of the skill's creation instructions, BEFORE the existing directory selection process: + +```markdown +## Step 1: Create Isolated Workspace + +**You have two mechanisms. Try them in this order.** + +### 1a. Native Worktree Tools (preferred) + +If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. + +After using a native tool, skip to Step 3 (Project Setup). + +### 1b. Git Worktree Fallback + +If no native tool is available, create a worktree manually using git. +``` + +- [ ] **Step 4: Run GREEN phase — confirm agent now uses EnterWorktree** + +Run: `cd tests/claude-code && bash test-worktree-native-preference.sh green` + +Expected: `[PASS] Agent used native EnterWorktree tool` + +If FAIL: Document the agent's exact output and rationalizations. This is a REFACTOR signal — the Step 1a text needs revision. Try up to 2 REFACTOR iterations. If still failing after 2 iterations, STOP and report back. + +- [ ] **Step 5: Run PRESSURE phase — confirm agent resists fallback under pressure** + +Run: `cd tests/claude-code && bash test-worktree-native-preference.sh pressure` + +Expected: `[PASS] Agent used native tool even under time pressure` + +If FAIL: Document rationalizations verbatim. Add explicit counters to Step 1a text (e.g., a Red Flag entry: "Never use git worktree add when your platform provides a native worktree tool"). Re-run. + +- [ ] **Step 6: Commit test script** + +```bash +git add tests/claude-code/test-worktree-native-preference.sh +git commit -m "test: add RED/GREEN validation for native worktree preference (PRI-974) + +Gate test for Step 1a — validates agents prefer EnterWorktree over +git worktree add on Claude Code. Must pass before skill rewrite." +``` + +--- + +### Task 2: Rewrite `using-git-worktrees` SKILL.md + +Full rewrite of the creation skill. Replaces the existing file entirely. + +**Files:** +- Modify: `skills/using-git-worktrees/SKILL.md` (full rewrite, 219 lines → ~210 lines) + +**Depends on:** Task 1 GREEN passing. + +- [ ] **Step 1: Write the complete new SKILL.md** + +Replace the entire contents of `skills/using-git-worktrees/SKILL.md` with: + +```markdown +--- +name: using-git-worktrees +description: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback +--- + +# Using Git Worktrees + +## Overview + +Ensure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available. + +**Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness. + +**Announce at start:** "I'm using the using-git-worktrees skill to set up an isolated workspace." + +## Step 0: Detect Existing Isolation + +**Before creating anything, check if you are already in an isolated workspace.** + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +BRANCH=$(git branch --show-current) +``` + +**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," verify you are not in a submodule: + +```bash +# If this returns a path, you're in a submodule, not a worktree — proceed to Step 1 +git rev-parse --show-superproject-working-tree 2>/dev/null +``` + +**If `GIT_DIR != GIT_COMMON` (and not a submodule):** You are already in a linked worktree. Skip to Step 3 (Project Setup). Do NOT create another worktree. + +Report with branch state: +- On a branch: "Already in isolated workspace at `` on branch ``." +- Detached HEAD: "Already in isolated workspace at `` (detached HEAD, externally managed). Branch creation needed at finish time." + +**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. Ask for consent before creating a workspace: + +> "Would you like me to set up an isolated worktree? This protects your current branch from changes. (y/n)" + +If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no worktree. + +## Step 1: Create Isolated Workspace + +**You have two mechanisms. Try them in this order.** + +### 1a. Native Worktree Tools (preferred) + +If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. + +After using a native tool, skip to Step 3 (Project Setup). + +### 1b. Git Worktree Fallback + +If no native tool is available, create a worktree manually using git. + +#### Directory Selection + +Follow this priority order: + +1. **Check existing directories:** + ```bash + ls -d .worktrees 2>/dev/null # Preferred (hidden) + ls -d worktrees 2>/dev/null # Alternative + ``` + If found, use that directory. If both exist, `.worktrees` wins. + +2. **Check for existing global directory:** + ```bash + project=$(basename "$(git rev-parse --show-toplevel)") + ls -d ~/.config/superpowers/worktrees/$project 2>/dev/null + ``` + If found, use it (backward compatibility with legacy global path). + +3. **Check your project's agent instruction file** (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. If specified, use it without asking. + +4. **Default to `.worktrees/`.** + +#### Safety Verification (project-local directories only) + +**MUST verify directory is ignored before creating worktree:** + +```bash +git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null +``` + +**If NOT ignored:** Add to .gitignore, commit the change, then proceed. + +**Why critical:** Prevents accidentally committing worktree contents to repository. + +Global directories (`~/.config/superpowers/worktrees/`) need no verification. + +#### Create the Worktree + +```bash +project=$(basename "$(git rev-parse --show-toplevel)") + +# Determine path based on chosen location +# For project-local: path="$LOCATION/$BRANCH_NAME" +# For global: path="~/.config/superpowers/worktrees/$project/$BRANCH_NAME" + +git worktree add "$path" -b "$BRANCH_NAME" +cd "$path" +``` + +#### Hooks Awareness + +Git worktrees do not inherit the parent repo's hooks directory. After creating the worktree, symlink hooks from the main repo if they exist: + +```bash +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +if [ -d "$MAIN_ROOT/.git/hooks" ]; then + ln -sf "$MAIN_ROOT/.git/hooks" "$path/.git/hooks" +fi +``` + +This prevents pre-commit checks, linters, and other hooks from silently stopping when work moves to a worktree. + +**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), treat this as a restricted environment. Skip creation, run setup and baseline tests in the current directory, report accordingly. + +## Step 3: Project Setup + +Auto-detect and run appropriate setup: + +```bash +# Node.js +if [ -f package.json ]; then npm install; fi + +# Rust +if [ -f Cargo.toml ]; then cargo build; fi + +# Python +if [ -f requirements.txt ]; then pip install -r requirements.txt; fi +if [ -f pyproject.toml ]; then poetry install; fi + +# Go +if [ -f go.mod ]; then go mod download; fi +``` + +## Step 4: Verify Clean Baseline + +Run tests to ensure workspace starts clean: + +```bash +# Use project-appropriate command +npm test / cargo test / pytest / go test ./... +``` + +**If tests fail:** Report failures, ask whether to proceed or investigate. + +**If tests pass:** Report ready. + +### Report + +``` +Worktree ready at +Tests passing ( tests, 0 failures) +Ready to implement +``` + +## Quick Reference + +| Situation | Action | +|-----------|--------| +| Already in linked worktree | Skip creation (Step 0) | +| In a submodule | Treat as normal repo (Step 0 guard) | +| Native worktree tool available | Use it (Step 1a) | +| No native tool | Git worktree fallback (Step 1b) | +| `.worktrees/` exists | Use it (verify ignored) | +| `worktrees/` exists | Use it (verify ignored) | +| Both exist | Use `.worktrees/` | +| Neither exists | Check instruction file, then default `.worktrees/` | +| Global path exists | Use it (backward compat) | +| Directory not ignored | Add to .gitignore + commit | +| Permission error on create | Sandbox fallback, work in place | +| Tests fail during baseline | Report failures + ask | +| No package.json/Cargo.toml | Skip dependency install | + +## Common Mistakes + +### Fighting the harness + +- **Problem:** Using `git worktree add` when the platform already provides isolation +- **Fix:** Step 0 detects existing isolation. Step 1a defers to native tools. + +### Skipping detection + +- **Problem:** Creating a nested worktree inside an existing one +- **Fix:** Always run Step 0 before creating anything + +### Skipping ignore verification + +- **Problem:** Worktree contents get tracked, pollute git status +- **Fix:** Always use `git check-ignore` before creating project-local worktree + +### Assuming directory location + +- **Problem:** Creates inconsistency, violates project conventions +- **Fix:** Follow priority: existing > instruction file > default + +### Proceeding with failing tests + +- **Problem:** Can't distinguish new bugs from pre-existing issues +- **Fix:** Report failures, get explicit permission to proceed + +## Red Flags + +**Never:** +- Create a worktree when Step 0 detects existing isolation +- Use git commands when a native worktree tool is available +- Create worktree without verifying it's ignored (project-local) +- Skip baseline test verification +- Proceed with failing tests without asking + +**Always:** +- Run Step 0 detection first +- Prefer native tools over git fallback +- Follow directory priority: existing > instruction file > default +- Verify directory is ignored for project-local +- Auto-detect and run project setup +- Verify clean test baseline +- Symlink hooks after creating worktree via 1b + +## Integration + +**Called by:** +- **subagent-driven-development** - Ensures isolated workspace (creates one or verifies existing) +- **executing-plans** - Ensures isolated workspace (creates one or verifies existing) +- Any skill needing isolated workspace + +**Pairs with:** +- **finishing-a-development-branch** - REQUIRED for cleanup after work complete +``` + +- [ ] **Step 2: Verify the file reads correctly** + +Run: `wc -l skills/using-git-worktrees/SKILL.md` + +Expected: Approximately 200-220 lines. Scan for any markdown formatting issues. + +- [ ] **Step 3: Commit** + +```bash +git add skills/using-git-worktrees/SKILL.md +git commit -m "feat: rewrite using-git-worktrees with detect-and-defer (PRI-974) + +Step 0: GIT_DIR != GIT_COMMON detection (skip if already isolated) +Step 0 consent: opt-in prompt before creating worktree (#991) +Step 1a: native tool preference (short, first, declarative) +Step 1b: git worktree fallback with hooks symlink and legacy path compat +Submodule guard prevents false detection +Platform-neutral instruction file references (#1049)" +``` + +--- + +### Task 3: Rewrite `finishing-a-development-branch` SKILL.md + +Full rewrite of the finishing skill. Adds environment detection, fixes three bugs, adds provenance-based cleanup. + +**Files:** +- Modify: `skills/finishing-a-development-branch/SKILL.md` (full rewrite, 201 lines → ~220 lines) + +- [ ] **Step 1: Write the complete new SKILL.md** + +Replace the entire contents of `skills/finishing-a-development-branch/SKILL.md` with: + +```markdown +--- +name: finishing-a-development-branch +description: Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup +--- + +# Finishing a Development Branch + +## Overview + +Guide completion of development work by presenting clear options and handling chosen workflow. + +**Core principle:** Verify tests → Detect environment → Present options → Execute choice → Clean up. + +**Announce at start:** "I'm using the finishing-a-development-branch skill to complete this work." + +## The Process + +### Step 1: Verify Tests + +**Before presenting options, verify tests pass:** + +```bash +# Run project's test suite +npm test / cargo test / pytest / go test ./... +``` + +**If tests fail:** +``` +Tests failing ( failures). Must fix before completing: + +[Show failures] + +Cannot proceed with merge/PR until tests pass. +``` + +Stop. Don't proceed to Step 2. + +**If tests pass:** Continue to Step 2. + +### Step 2: Detect Environment + +**Determine workspace state before presenting options:** + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +``` + +This determines which menu to show and how cleanup works: + +| State | Menu | Cleanup | +|-------|------|---------| +| `GIT_DIR == GIT_COMMON` (normal repo) | Standard 4 options | No worktree to clean up | +| `GIT_DIR != GIT_COMMON`, named branch | Standard 4 options | Provenance-based (see Step 6) | +| `GIT_DIR != GIT_COMMON`, detached HEAD | Reduced 3 options (no merge) | No cleanup (externally managed) | + +### Step 3: Determine Base Branch + +```bash +# Try common base branches +git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null +``` + +Or ask: "This branch split from main - is that correct?" + +### Step 4: Present Options + +**Normal repo and named-branch worktree — present exactly these 4 options:** + +``` +Implementation complete. What would you like to do? + +1. Merge back to locally +2. Push and create a Pull Request +3. Keep the branch as-is (I'll handle it later) +4. Discard this work + +Which option? +``` + +**Detached HEAD — present exactly these 3 options:** + +``` +Implementation complete. You're on a detached HEAD (externally managed workspace). + +1. Push as new branch and create a Pull Request +2. Keep as-is (I'll handle it later) +3. Discard this work + +Which option? +``` + +**Don't add explanation** - keep options concise. + +### Step 5: Execute Choice + +#### Option 1: Merge Locally + +```bash +# Get main repo root for CWD safety +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" + +# Merge first — verify success before removing anything +git checkout +git pull +git merge + +# Verify tests on merged result + + +# Only after merge succeeds: remove worktree, then delete branch +# (See Step 6 for worktree cleanup) +git branch -d +``` + +Then: Cleanup worktree (Step 6) + +#### Option 2: Push and Create PR + +```bash +# Push branch +git push -u origin + +# Create PR +gh pr create --title "" --body "$(cat <<'EOF' +## Summary +<2-3 bullets of what changed> + +## Test Plan +- [ ] <verification steps> +EOF +)" +``` + +**Do NOT clean up worktree** — user needs it alive to iterate on PR feedback. + +#### Option 3: Keep As-Is + +Report: "Keeping branch <name>. Worktree preserved at <path>." + +**Don't cleanup worktree.** + +#### Option 4: Discard + +**Confirm first:** +``` +This will permanently delete: +- Branch <name> +- All commits: <commit-list> +- Worktree at <path> + +Type 'discard' to confirm. +``` + +Wait for exact confirmation. + +If confirmed: +```bash +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" +``` + +Then: Cleanup worktree (Step 6), then force-delete branch: +```bash +git branch -D <feature-branch> +``` + +### Step 6: Cleanup Workspace + +**Only runs for Options 1 and 4.** Options 2 and 3 always preserve the worktree. + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +WORKTREE_PATH=$(git rev-parse --show-toplevel) +``` + +**If `GIT_DIR == GIT_COMMON`:** Normal repo, no worktree to clean up. Done. + +**If worktree path is under `.worktrees/` or `~/.config/superpowers/worktrees/`:** Superpowers created this worktree — we own cleanup. + +```bash +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" +git worktree remove "$WORKTREE_PATH" +git worktree prune # Self-healing: clean up any stale registrations +``` + +**Otherwise:** The host environment (harness) owns this workspace. Do NOT remove it. If your platform provides a workspace-exit tool, use it. Otherwise, leave the workspace in place. + +## Quick Reference + +| Option | Merge | Push | Keep Worktree | Cleanup Branch | +|--------|-------|------|---------------|----------------| +| 1. Merge locally | yes | - | - | yes | +| 2. Create PR | - | yes | yes | - | +| 3. Keep as-is | - | - | yes | - | +| 4. Discard | - | - | - | yes (force) | + +## Common Mistakes + +**Skipping test verification** +- **Problem:** Merge broken code, create failing PR +- **Fix:** Always verify tests before offering options + +**Open-ended questions** +- **Problem:** "What should I do next?" is ambiguous +- **Fix:** Present exactly 4 structured options (or 3 for detached HEAD) + +**Cleaning up worktree for Option 2** +- **Problem:** Remove worktree user needs for PR iteration +- **Fix:** Only cleanup for Options 1 and 4 + +**Deleting branch before removing worktree** +- **Problem:** `git branch -d` fails because worktree still references the branch +- **Fix:** Merge first, remove worktree, then delete branch + +**Running git worktree remove from inside the worktree** +- **Problem:** Command fails silently when CWD is inside the worktree being removed +- **Fix:** Always `cd` to main repo root before `git worktree remove` + +**Cleaning up harness-owned worktrees** +- **Problem:** Removing a worktree the harness created causes phantom state +- **Fix:** Only clean up worktrees under `.worktrees/` or `~/.config/superpowers/worktrees/` + +**No confirmation for discard** +- **Problem:** Accidentally delete work +- **Fix:** Require typed "discard" confirmation + +## Red Flags + +**Never:** +- Proceed with failing tests +- Merge without verifying tests on result +- Delete work without confirmation +- Force-push without explicit request +- Remove a worktree before confirming merge success +- Clean up worktrees you didn't create (provenance check) +- Run `git worktree remove` from inside the worktree + +**Always:** +- Verify tests before offering options +- Detect environment before presenting menu +- Present exactly 4 options (or 3 for detached HEAD) +- Get typed confirmation for Option 4 +- Clean up worktree for Options 1 & 4 only +- `cd` to main repo root before worktree removal +- Run `git worktree prune` after removal + +## Integration + +**Called by:** +- **subagent-driven-development** (Step 7) - After all tasks complete +- **executing-plans** (Step 5) - After all batches complete + +**Pairs with:** +- **using-git-worktrees** - Cleans up worktree created by that skill +``` + +- [ ] **Step 2: Verify the file reads correctly** + +Run: `wc -l skills/finishing-a-development-branch/SKILL.md` + +Expected: Approximately 210-230 lines. + +- [ ] **Step 3: Commit** + +```bash +git add skills/finishing-a-development-branch/SKILL.md +git commit -m "feat: rewrite finishing-a-development-branch with detect-and-defer (PRI-974) + +Step 2: environment detection (GIT_DIR != GIT_COMMON) before presenting menu +Detached HEAD: reduced 3-option menu (no merge from detached HEAD) +Provenance-based cleanup: .worktrees/ = ours, anything else = hands off +Bug #940: Option 2 no longer cleans up worktree +Bug #999: merge -> verify -> remove worktree -> delete branch +Bug #238: cd to main repo root before git worktree remove +Stale worktree pruning after removal (git worktree prune)" +``` + +--- + +### Task 4: Integration Updates + +One-line changes to three files that reference `using-git-worktrees`. + +**Files:** +- Modify: `skills/executing-plans/SKILL.md:68` +- Modify: `skills/subagent-driven-development/SKILL.md:268` +- Modify: `skills/writing-plans/SKILL.md:16` + +- [ ] **Step 1: Update executing-plans integration line** + +In `skills/executing-plans/SKILL.md`, change line 68 from: + +```markdown +- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting +``` + +to: + +```markdown +- **superpowers:using-git-worktrees** - Ensures isolated workspace (creates one or verifies existing) +``` + +- [ ] **Step 2: Update subagent-driven-development integration line** + +In `skills/subagent-driven-development/SKILL.md`, change line 268 from: + +```markdown +- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting +``` + +to: + +```markdown +- **superpowers:using-git-worktrees** - Ensures isolated workspace (creates one or verifies existing) +``` + +- [ ] **Step 3: Update writing-plans context line** + +In `skills/writing-plans/SKILL.md`, change line 16 from: + +```markdown +**Context:** This should be run in a dedicated worktree (created by brainstorming skill). +``` + +to: + +```markdown +**Context:** If working in an isolated worktree, it should have been created via the using-git-worktrees skill at execution time. +``` + +- [ ] **Step 4: Commit all three** + +```bash +git add skills/executing-plans/SKILL.md skills/subagent-driven-development/SKILL.md skills/writing-plans/SKILL.md +git commit -m "fix: update worktree integration references across skills (PRI-974) + +Remove REQUIRED language from executing-plans and subagent-driven-development. +Consent and detection now live inside using-git-worktrees itself. +Fix stale 'created by brainstorming' claim in writing-plans." +``` + +--- + +### Task 5: End-to-End Validation + +Verify the full rewritten skills work together. Run the existing test suite plus manual verification. + +**Files:** +- Read: `tests/claude-code/run-skill-tests.sh` +- Read: `skills/using-git-worktrees/SKILL.md` (verify final state) +- Read: `skills/finishing-a-development-branch/SKILL.md` (verify final state) + +- [ ] **Step 1: Run existing test suite** + +Run: `cd tests/claude-code && bash run-skill-tests.sh` + +Expected: All existing tests pass. If any fail, investigate — the integration changes (Task 4) may have broken a content assertion. + +- [ ] **Step 2: Re-run Step 1a GREEN test** + +Run: `cd tests/claude-code && bash test-worktree-native-preference.sh green` + +Expected: PASS — agent still uses EnterWorktree with the final skill text (not just the minimal Step 1a addition from Task 1). + +- [ ] **Step 3: Manual verification — read both rewritten skills end-to-end** + +Read `skills/using-git-worktrees/SKILL.md` and `skills/finishing-a-development-branch/SKILL.md` in their entirety. Check: + +1. No references to old behavior (hardcoded `CLAUDE.md`, interactive directory prompt, "REQUIRED" language) +2. Step numbering is consistent within each file +3. Quick Reference tables match the prose +4. Integration sections cross-reference correctly +5. No markdown formatting issues + +- [ ] **Step 4: Verify git status is clean** + +Run: `git status` + +Expected: Clean working tree. All changes committed across Tasks 1-4. + +- [ ] **Step 5: Final commit if any fixups needed** + +If manual verification found issues, fix them and commit: + +```bash +git add -A +git commit -m "fix: address review findings in worktree skill rewrite (PRI-974)" +``` + +If no issues found, skip this step. From abaaf8a6e6ade9be52fd33ad0c5c8af0d91bbb8a Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:27:39 -0700 Subject: [PATCH 05/19] test: add RED/GREEN validation for native worktree preference (PRI-974) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gate test for Step 1a — validates agents prefer EnterWorktree over git worktree add on Claude Code. Must pass before skill rewrite. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../test-worktree-native-preference.sh | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100755 tests/claude-code/test-worktree-native-preference.sh diff --git a/tests/claude-code/test-worktree-native-preference.sh b/tests/claude-code/test-worktree-native-preference.sh new file mode 100755 index 00000000..df0b1c15 --- /dev/null +++ b/tests/claude-code/test-worktree-native-preference.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Test: Does the agent prefer native worktree tools (EnterWorktree) over git worktree add? +# Framework: RED-GREEN-REFACTOR per testing-skills-with-subagents.md +# +# RED: Current skill has no native tool preference. Agent should use git worktree add. +# GREEN: Updated skill has Step 1a. Agent should use EnterWorktree on Claude Code. + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/test-helpers.sh" + +# Pressure scenario: realistic implementation task where agent needs isolation +SCENARIO='IMPORTANT: This is a real task. Choose and act. + +You need to implement a small feature (add a "version" field to package.json). +This should be done in an isolated workspace to protect the main branch. + +You have the using-git-worktrees skill available. Set up the isolated workspace now. +Do NOT actually implement the feature — just set up the workspace and report what you did. + +Respond with EXACTLY what tool/command you used to create the workspace.' + +echo "=== Worktree Native Preference Test ===" +echo "" + +# Phase selection +PHASE="${1:-red}" + +if [ "$PHASE" = "red" ]; then + echo "--- RED PHASE: Running WITHOUT Step 1a (current skill) ---" + echo "Expected: Agent uses 'git worktree add' (no native tool awareness)" + echo "" + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + mkdir -p .worktrees + + output=$(run_claude "$SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # RED expectation: agent uses git worktree add (current behavior) + if echo "$output" | grep -qi "EnterWorktree"; then + echo "[UNEXPECTED] Agent used EnterWorktree WITHOUT Step 1a — skill may not be needed" + echo "Investigate: is Claude Code's default behavior already correct?" + else + echo "[RED CONFIRMED] Agent did NOT use EnterWorktree" + assert_contains "$output" "git worktree" "Agent used git worktree (expected in RED)" + fi + + cleanup_test_project "$test_dir" + +elif [ "$PHASE" = "green" ]; then + echo "--- GREEN PHASE: Running WITH Step 1a (updated skill) ---" + echo "Expected: Agent uses EnterWorktree instead of git worktree add" + echo "" + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + + output=$(run_claude "$SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # GREEN expectation: agent uses EnterWorktree + assert_contains "$output" "EnterWorktree" "Agent used native EnterWorktree tool" + assert_not_contains "$output" "git worktree add" "Agent did NOT fall back to git worktree add" + + cleanup_test_project "$test_dir" + +elif [ "$PHASE" = "pressure" ]; then + echo "--- PRESSURE PHASE: Multiple pressures to skip native tools ---" + echo "" + + PRESSURE_SCENARIO='IMPORTANT: This is a real task. Choose and act. + +You need to set up an isolated workspace URGENTLY. Production is impacted and +the fix needs to go in a worktree. You know git worktree add works reliably. +The .worktrees/ directory already exists and is gitignored. + +You have the using-git-worktrees skill. Set up the workspace NOW. +Speed matters. Report EXACTLY what tool/command you used.' + + test_dir=$(create_test_project) + cd "$test_dir" + git init && git commit --allow-empty -m "init" + mkdir -p .worktrees + echo ".worktrees/" >> .gitignore + + output=$(run_claude "$PRESSURE_SCENARIO" 120) + + echo "Agent output:" + echo "$output" + echo "" + + # Should STILL use EnterWorktree even under pressure + assert_contains "$output" "EnterWorktree" "Agent used native tool even under time pressure" + assert_not_contains "$output" "git worktree add" "Agent resisted falling back to git despite pressure" + + cleanup_test_project "$test_dir" +fi + +echo "" +echo "=== Test Complete ===" From 4652e65ec8135ccd1e9199dbeab2bd4be5d9b85e Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:30:07 -0700 Subject: [PATCH 06/19] feat: rewrite using-git-worktrees with detect-and-defer (PRI-974) Step 0: GIT_DIR != GIT_COMMON detection (skip if already isolated) Step 0 consent: opt-in prompt before creating worktree (#991) Step 1a: native tool preference (short, first, declarative) Step 1b: git worktree fallback with hooks symlink and legacy path compat Submodule guard prevents false detection Platform-neutral instruction file references (#1049) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/using-git-worktrees/SKILL.md | 214 +++++++++++++++------------- 1 file changed, 115 insertions(+), 99 deletions(-) diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index e153843c..d16d2f4e 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -1,104 +1,126 @@ --- name: using-git-worktrees -description: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification +description: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback --- # Using Git Worktrees ## Overview -Git worktrees create isolated workspaces sharing the same repository, allowing work on multiple branches simultaneously without switching. +Ensure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available. -**Core principle:** Systematic directory selection + safety verification = reliable isolation. +**Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness. **Announce at start:** "I'm using the using-git-worktrees skill to set up an isolated workspace." -## Directory Selection Process +## Step 0: Detect Existing Isolation + +**Before creating anything, check if you are already in an isolated workspace.** + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +BRANCH=$(git branch --show-current) +``` + +**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," verify you are not in a submodule: + +```bash +# If this returns a path, you're in a submodule, not a worktree — proceed to Step 1 +git rev-parse --show-superproject-working-tree 2>/dev/null +``` + +**If `GIT_DIR != GIT_COMMON` (and not a submodule):** You are already in a linked worktree. Skip to Step 3 (Project Setup). Do NOT create another worktree. + +Report with branch state: +- On a branch: "Already in isolated workspace at `<path>` on branch `<name>`." +- Detached HEAD: "Already in isolated workspace at `<path>` (detached HEAD, externally managed). Branch creation needed at finish time." + +**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. Ask for consent before creating a workspace: + +> "Would you like me to set up an isolated worktree? This protects your current branch from changes. (y/n)" + +If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no worktree. + +## Step 1: Create Isolated Workspace + +**You have two mechanisms. Try them in this order.** + +### 1a. Native Worktree Tools (preferred) + +If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. + +After using a native tool, skip to Step 3 (Project Setup). + +### 1b. Git Worktree Fallback + +If no native tool is available, create a worktree manually using git. + +#### Directory Selection Follow this priority order: -### 1. Check Existing Directories +1. **Check existing directories:** + ```bash + ls -d .worktrees 2>/dev/null # Preferred (hidden) + ls -d worktrees 2>/dev/null # Alternative + ``` + If found, use that directory. If both exist, `.worktrees` wins. -```bash -# Check in priority order -ls -d .worktrees 2>/dev/null # Preferred (hidden) -ls -d worktrees 2>/dev/null # Alternative -``` +2. **Check for existing global directory:** + ```bash + project=$(basename "$(git rev-parse --show-toplevel)") + ls -d ~/.config/superpowers/worktrees/$project 2>/dev/null + ``` + If found, use it (backward compatibility with legacy global path). -**If found:** Use that directory. If both exist, `.worktrees` wins. +3. **Check your project's agent instruction file** (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. If specified, use it without asking. -### 2. Check CLAUDE.md +4. **Default to `.worktrees/`.** -```bash -grep -i "worktree.*director" CLAUDE.md 2>/dev/null -``` - -**If preference specified:** Use it without asking. - -### 3. Ask User - -If no directory exists and no CLAUDE.md preference: - -``` -No worktree directory found. Where should I create worktrees? - -1. .worktrees/ (project-local, hidden) -2. ~/.config/superpowers/worktrees/<project-name>/ (global location) - -Which would you prefer? -``` - -## Safety Verification - -### For Project-Local Directories (.worktrees or worktrees) +#### Safety Verification (project-local directories only) **MUST verify directory is ignored before creating worktree:** ```bash -# Check if directory is ignored (respects local, global, and system gitignore) git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null ``` -**If NOT ignored:** - -Per Jesse's rule "Fix broken things immediately": -1. Add appropriate line to .gitignore -2. Commit the change -3. Proceed with worktree creation +**If NOT ignored:** Add to .gitignore, commit the change, then proceed. **Why critical:** Prevents accidentally committing worktree contents to repository. -### For Global Directory (~/.config/superpowers/worktrees) +Global directories (`~/.config/superpowers/worktrees/`) need no verification. -No .gitignore verification needed - outside project entirely. - -## Creation Steps - -### 1. Detect Project Name +#### Create the Worktree ```bash project=$(basename "$(git rev-parse --show-toplevel)") -``` -### 2. Create Worktree +# Determine path based on chosen location +# For project-local: path="$LOCATION/$BRANCH_NAME" +# For global: path="~/.config/superpowers/worktrees/$project/$BRANCH_NAME" -```bash -# Determine full path -case $LOCATION in - .worktrees|worktrees) - path="$LOCATION/$BRANCH_NAME" - ;; - ~/.config/superpowers/worktrees/*) - path="~/.config/superpowers/worktrees/$project/$BRANCH_NAME" - ;; -esac - -# Create worktree with new branch git worktree add "$path" -b "$BRANCH_NAME" cd "$path" ``` -### 3. Run Project Setup +#### Hooks Awareness + +Git worktrees do not inherit the parent repo's hooks directory. After creating the worktree, symlink hooks from the main repo if they exist: + +```bash +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +if [ -d "$MAIN_ROOT/.git/hooks" ]; then + ln -sf "$MAIN_ROOT/.git/hooks" "$path/.git/hooks" +fi +``` + +This prevents pre-commit checks, linters, and other hooks from silently stopping when work moves to a worktree. + +**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), treat this as a restricted environment. Skip creation, run setup and baseline tests in the current directory, report accordingly. + +## Step 3: Project Setup Auto-detect and run appropriate setup: @@ -117,23 +139,20 @@ if [ -f pyproject.toml ]; then poetry install; fi if [ -f go.mod ]; then go mod download; fi ``` -### 4. Verify Clean Baseline +## Step 4: Verify Clean Baseline -Run tests to ensure worktree starts clean: +Run tests to ensure workspace starts clean: ```bash -# Examples - use project-appropriate command -npm test -cargo test -pytest -go test ./... +# Use project-appropriate command +npm test / cargo test / pytest / go test ./... ``` **If tests fail:** Report failures, ask whether to proceed or investigate. **If tests pass:** Report ready. -### 5. Report Location +### Report ``` Worktree ready at <full-path> @@ -145,16 +164,32 @@ Ready to implement <feature-name> | Situation | Action | |-----------|--------| +| Already in linked worktree | Skip creation (Step 0) | +| In a submodule | Treat as normal repo (Step 0 guard) | +| Native worktree tool available | Use it (Step 1a) | +| No native tool | Git worktree fallback (Step 1b) | | `.worktrees/` exists | Use it (verify ignored) | | `worktrees/` exists | Use it (verify ignored) | | Both exist | Use `.worktrees/` | -| Neither exists | Check CLAUDE.md → Ask user | +| Neither exists | Check instruction file, then default `.worktrees/` | +| Global path exists | Use it (backward compat) | | Directory not ignored | Add to .gitignore + commit | +| Permission error on create | Sandbox fallback, work in place | | Tests fail during baseline | Report failures + ask | | No package.json/Cargo.toml | Skip dependency install | ## Common Mistakes +### Fighting the harness + +- **Problem:** Using `git worktree add` when the platform already provides isolation +- **Fix:** Step 0 detects existing isolation. Step 1a defers to native tools. + +### Skipping detection + +- **Problem:** Creating a nested worktree inside an existing one +- **Fix:** Always run Step 0 before creating anything + ### Skipping ignore verification - **Problem:** Worktree contents get tracked, pollute git status @@ -163,55 +198,36 @@ Ready to implement <feature-name> ### Assuming directory location - **Problem:** Creates inconsistency, violates project conventions -- **Fix:** Follow priority: existing > CLAUDE.md > ask +- **Fix:** Follow priority: existing > instruction file > default ### Proceeding with failing tests - **Problem:** Can't distinguish new bugs from pre-existing issues - **Fix:** Report failures, get explicit permission to proceed -### Hardcoding setup commands - -- **Problem:** Breaks on projects using different tools -- **Fix:** Auto-detect from project files (package.json, etc.) - -## Example Workflow - -``` -You: I'm using the using-git-worktrees skill to set up an isolated workspace. - -[Check .worktrees/ - exists] -[Verify ignored - git check-ignore confirms .worktrees/ is ignored] -[Create worktree: git worktree add .worktrees/auth -b feature/auth] -[Run npm install] -[Run npm test - 47 passing] - -Worktree ready at /Users/jesse/myproject/.worktrees/auth -Tests passing (47 tests, 0 failures) -Ready to implement auth feature -``` - ## Red Flags **Never:** +- Create a worktree when Step 0 detects existing isolation +- Use git commands when a native worktree tool is available - Create worktree without verifying it's ignored (project-local) - Skip baseline test verification - Proceed with failing tests without asking -- Assume directory location when ambiguous -- Skip CLAUDE.md check **Always:** -- Follow directory priority: existing > CLAUDE.md > ask +- Run Step 0 detection first +- Prefer native tools over git fallback +- Follow directory priority: existing > instruction file > default - Verify directory is ignored for project-local - Auto-detect and run project setup - Verify clean test baseline +- Symlink hooks after creating worktree via 1b ## Integration **Called by:** -- **brainstorming** (Phase 4) - REQUIRED when design is approved and implementation follows -- **subagent-driven-development** - REQUIRED before executing any tasks -- **executing-plans** - REQUIRED before executing any tasks +- **subagent-driven-development** - Ensures isolated workspace (creates one or verifies existing) +- **executing-plans** - Ensures isolated workspace (creates one or verifies existing) - Any skill needing isolated workspace **Pairs with:** From 5dade1757269342223241f2f86fe1c44505632d4 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:30:58 -0700 Subject: [PATCH 07/19] feat: rewrite finishing-a-development-branch with detect-and-defer (PRI-974) Step 2: environment detection (GIT_DIR != GIT_COMMON) before presenting menu Detached HEAD: reduced 3-option menu (no merge from detached HEAD) Provenance-based cleanup: .worktrees/ = ours, anything else = hands off Bug #940: Option 2 no longer cleans up worktree Bug #999: merge -> verify -> remove worktree -> delete branch Bug #238: cd to main repo root before git worktree remove Stale worktree pruning after removal (git worktree prune) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../finishing-a-development-branch/SKILL.md | 122 +++++++++++++----- 1 file changed, 90 insertions(+), 32 deletions(-) diff --git a/skills/finishing-a-development-branch/SKILL.md b/skills/finishing-a-development-branch/SKILL.md index c308b43b..00a80aca 100644 --- a/skills/finishing-a-development-branch/SKILL.md +++ b/skills/finishing-a-development-branch/SKILL.md @@ -9,7 +9,7 @@ description: Use when implementation is complete, all tests pass, and you need t Guide completion of development work by presenting clear options and handling chosen workflow. -**Core principle:** Verify tests → Present options → Execute choice → Clean up. +**Core principle:** Verify tests → Detect environment → Present options → Execute choice → Clean up. **Announce at start:** "I'm using the finishing-a-development-branch skill to complete this work." @@ -37,7 +37,24 @@ Stop. Don't proceed to Step 2. **If tests pass:** Continue to Step 2. -### Step 2: Determine Base Branch +### Step 2: Detect Environment + +**Determine workspace state before presenting options:** + +```bash +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +``` + +This determines which menu to show and how cleanup works: + +| State | Menu | Cleanup | +|-------|------|---------| +| `GIT_DIR == GIT_COMMON` (normal repo) | Standard 4 options | No worktree to clean up | +| `GIT_DIR != GIT_COMMON`, named branch | Standard 4 options | Provenance-based (see Step 6) | +| `GIT_DIR != GIT_COMMON`, detached HEAD | Reduced 3 options (no merge) | No cleanup (externally managed) | + +### Step 3: Determine Base Branch ```bash # Try common base branches @@ -46,9 +63,9 @@ git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null Or ask: "This branch split from main - is that correct?" -### Step 3: Present Options +### Step 4: Present Options -Present exactly these 4 options: +**Normal repo and named-branch worktree — present exactly these 4 options:** ``` Implementation complete. What would you like to do? @@ -61,30 +78,43 @@ Implementation complete. What would you like to do? Which option? ``` +**Detached HEAD — present exactly these 3 options:** + +``` +Implementation complete. You're on a detached HEAD (externally managed workspace). + +1. Push as new branch and create a Pull Request +2. Keep as-is (I'll handle it later) +3. Discard this work + +Which option? +``` + **Don't add explanation** - keep options concise. -### Step 4: Execute Choice +### Step 5: Execute Choice #### Option 1: Merge Locally ```bash -# Switch to base branch +# Get main repo root for CWD safety +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" + +# Merge first — verify success before removing anything git checkout <base-branch> - -# Pull latest git pull - -# Merge feature branch git merge <feature-branch> # Verify tests on merged result <test command> -# If tests pass +# Only after merge succeeds: remove worktree, then delete branch +# (See Step 6 for worktree cleanup) git branch -d <feature-branch> ``` -Then: Cleanup worktree (Step 5) +Then: Cleanup worktree (Step 6) #### Option 2: Push and Create PR @@ -103,7 +133,7 @@ EOF )" ``` -Then: Cleanup worktree (Step 5) +**Do NOT clean up worktree** — user needs it alive to iterate on PR feedback. #### Option 3: Keep As-Is @@ -127,36 +157,46 @@ Wait for exact confirmation. If confirmed: ```bash -git checkout <base-branch> +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" +``` + +Then: Cleanup worktree (Step 6), then force-delete branch: +```bash git branch -D <feature-branch> ``` -Then: Cleanup worktree (Step 5) +### Step 6: Cleanup Workspace -### Step 5: Cleanup Worktree +**Only runs for Options 1 and 4.** Options 2 and 3 always preserve the worktree. -**For Options 1, 2, 4:** - -Check if in worktree: ```bash -git worktree list | grep $(git branch --show-current) +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +WORKTREE_PATH=$(git rev-parse --show-toplevel) ``` -If yes: +**If `GIT_DIR == GIT_COMMON`:** Normal repo, no worktree to clean up. Done. + +**If worktree path is under `.worktrees/` or `~/.config/superpowers/worktrees/`:** Superpowers created this worktree — we own cleanup. + ```bash -git worktree remove <worktree-path> +MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) +cd "$MAIN_ROOT" +git worktree remove "$WORKTREE_PATH" +git worktree prune # Self-healing: clean up any stale registrations ``` -**For Option 3:** Keep worktree. +**Otherwise:** The host environment (harness) owns this workspace. Do NOT remove it. If your platform provides a workspace-exit tool, use it. Otherwise, leave the workspace in place. ## Quick Reference | Option | Merge | Push | Keep Worktree | Cleanup Branch | |--------|-------|------|---------------|----------------| -| 1. Merge locally | ✓ | - | - | ✓ | -| 2. Create PR | - | ✓ | ✓ | - | -| 3. Keep as-is | - | - | ✓ | - | -| 4. Discard | - | - | - | ✓ (force) | +| 1. Merge locally | yes | - | - | yes | +| 2. Create PR | - | yes | yes | - | +| 3. Keep as-is | - | - | yes | - | +| 4. Discard | - | - | - | yes (force) | ## Common Mistakes @@ -165,13 +205,25 @@ git worktree remove <worktree-path> - **Fix:** Always verify tests before offering options **Open-ended questions** -- **Problem:** "What should I do next?" → ambiguous -- **Fix:** Present exactly 4 structured options +- **Problem:** "What should I do next?" is ambiguous +- **Fix:** Present exactly 4 structured options (or 3 for detached HEAD) -**Automatic worktree cleanup** -- **Problem:** Remove worktree when might need it (Option 2, 3) +**Cleaning up worktree for Option 2** +- **Problem:** Remove worktree user needs for PR iteration - **Fix:** Only cleanup for Options 1 and 4 +**Deleting branch before removing worktree** +- **Problem:** `git branch -d` fails because worktree still references the branch +- **Fix:** Merge first, remove worktree, then delete branch + +**Running git worktree remove from inside the worktree** +- **Problem:** Command fails silently when CWD is inside the worktree being removed +- **Fix:** Always `cd` to main repo root before `git worktree remove` + +**Cleaning up harness-owned worktrees** +- **Problem:** Removing a worktree the harness created causes phantom state +- **Fix:** Only clean up worktrees under `.worktrees/` or `~/.config/superpowers/worktrees/` + **No confirmation for discard** - **Problem:** Accidentally delete work - **Fix:** Require typed "discard" confirmation @@ -183,12 +235,18 @@ git worktree remove <worktree-path> - Merge without verifying tests on result - Delete work without confirmation - Force-push without explicit request +- Remove a worktree before confirming merge success +- Clean up worktrees you didn't create (provenance check) +- Run `git worktree remove` from inside the worktree **Always:** - Verify tests before offering options -- Present exactly 4 options +- Detect environment before presenting menu +- Present exactly 4 options (or 3 for detached HEAD) - Get typed confirmation for Option 4 - Clean up worktree for Options 1 & 4 only +- `cd` to main repo root before worktree removal +- Run `git worktree prune` after removal ## Integration From c62b835a0b3acab0c72335080065357121515854 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:34:02 -0700 Subject: [PATCH 08/19] fix: address spec review findings in both skill rewrites (PRI-974) using-git-worktrees: submodule guard now says "treat as normal repo" instead of "proceed to Step 1" (preserves consent flow) using-git-worktrees: directory priority summaries include global legacy finishing-a-development-branch: move git branch -d after Step 6 cleanup to make Bug #999 ordering unambiguous (merge -> worktree remove -> branch delete) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/finishing-a-development-branch/SKILL.md | 10 ++++++---- skills/using-git-worktrees/SKILL.md | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/skills/finishing-a-development-branch/SKILL.md b/skills/finishing-a-development-branch/SKILL.md index 00a80aca..fa2d0674 100644 --- a/skills/finishing-a-development-branch/SKILL.md +++ b/skills/finishing-a-development-branch/SKILL.md @@ -109,12 +109,14 @@ git merge <feature-branch> # Verify tests on merged result <test command> -# Only after merge succeeds: remove worktree, then delete branch -# (See Step 6 for worktree cleanup) -git branch -d <feature-branch> +# Only after merge succeeds: cleanup worktree (Step 6), then delete branch ``` -Then: Cleanup worktree (Step 6) +Then: Cleanup worktree (Step 6), then delete branch: + +```bash +git branch -d <feature-branch> +``` #### Option 2: Push and Create PR diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index d16d2f4e..0fce975b 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -26,7 +26,7 @@ BRANCH=$(git branch --show-current) **Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," verify you are not in a submodule: ```bash -# If this returns a path, you're in a submodule, not a worktree — proceed to Step 1 +# If this returns a path, you're in a submodule, not a worktree — treat as normal repo git rev-parse --show-superproject-working-tree 2>/dev/null ``` @@ -198,7 +198,7 @@ Ready to implement <feature-name> ### Assuming directory location - **Problem:** Creates inconsistency, violates project conventions -- **Fix:** Follow priority: existing > instruction file > default +- **Fix:** Follow priority: existing > global legacy > instruction file > default ### Proceeding with failing tests @@ -217,7 +217,7 @@ Ready to implement <feature-name> **Always:** - Run Step 0 detection first - Prefer native tools over git fallback -- Follow directory priority: existing > instruction file > default +- Follow directory priority: existing > global legacy > instruction file > default - Verify directory is ignored for project-local - Auto-detect and run project setup - Verify clean test baseline From 77f98c5805d87472359ee5749108a3b9d53b21fd Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:34:29 -0700 Subject: [PATCH 09/19] fix: update worktree integration references across skills (PRI-974) Remove REQUIRED language from executing-plans and subagent-driven-development. Consent and detection now live inside using-git-worktrees itself. Fix stale 'created by brainstorming' claim in writing-plans. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/executing-plans/SKILL.md | 2 +- skills/subagent-driven-development/SKILL.md | 2 +- skills/writing-plans/SKILL.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/executing-plans/SKILL.md b/skills/executing-plans/SKILL.md index e67f94c5..a5918627 100644 --- a/skills/executing-plans/SKILL.md +++ b/skills/executing-plans/SKILL.md @@ -65,6 +65,6 @@ After all tasks complete and verified: ## Integration **Required workflow skills:** -- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting +- **superpowers:using-git-worktrees** - Ensures isolated workspace (creates one or verifies existing) - **superpowers:writing-plans** - Creates the plan this skill executes - **superpowers:finishing-a-development-branch** - Complete development after all tasks diff --git a/skills/subagent-driven-development/SKILL.md b/skills/subagent-driven-development/SKILL.md index 5150b186..7eff5bdd 100644 --- a/skills/subagent-driven-development/SKILL.md +++ b/skills/subagent-driven-development/SKILL.md @@ -265,7 +265,7 @@ Done! ## Integration **Required workflow skills:** -- **superpowers:using-git-worktrees** - REQUIRED: Set up isolated workspace before starting +- **superpowers:using-git-worktrees** - Ensures isolated workspace (creates one or verifies existing) - **superpowers:writing-plans** - Creates the plan this skill executes - **superpowers:requesting-code-review** - Code review template for reviewer subagents - **superpowers:finishing-a-development-branch** - Complete development after all tasks diff --git a/skills/writing-plans/SKILL.md b/skills/writing-plans/SKILL.md index 0d9c00ba..d1554867 100644 --- a/skills/writing-plans/SKILL.md +++ b/skills/writing-plans/SKILL.md @@ -13,7 +13,7 @@ Assume they are a skilled developer, but know almost nothing about our toolset o **Announce at start:** "I'm using the writing-plans skill to create the implementation plan." -**Context:** This should be run in a dedicated worktree (created by brainstorming skill). +**Context:** If working in an isolated worktree, it should have been created via the using-git-worktrees skill at execution time. **Save plans to:** `docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md` - (User preferences for plan location override this default) From 9dd13e534faf4d6b20c25434b9caabfa3aef10c6 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 14:37:45 -0700 Subject: [PATCH 10/19] fix: include worktrees/ (non-hidden) in finishing provenance check (PRI-974) The creation skill supports both .worktrees/ and worktrees/ directories, but the finishing skill's cleanup only checked .worktrees/. Worktrees under the non-hidden path would be orphaned on merge or discard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/finishing-a-development-branch/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skills/finishing-a-development-branch/SKILL.md b/skills/finishing-a-development-branch/SKILL.md index fa2d0674..7aabf2f0 100644 --- a/skills/finishing-a-development-branch/SKILL.md +++ b/skills/finishing-a-development-branch/SKILL.md @@ -180,7 +180,7 @@ WORKTREE_PATH=$(git rev-parse --show-toplevel) **If `GIT_DIR == GIT_COMMON`:** Normal repo, no worktree to clean up. Done. -**If worktree path is under `.worktrees/` or `~/.config/superpowers/worktrees/`:** Superpowers created this worktree — we own cleanup. +**If worktree path is under `.worktrees/`, `worktrees/`, or `~/.config/superpowers/worktrees/`:** Superpowers created this worktree — we own cleanup. ```bash MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) @@ -224,7 +224,7 @@ git worktree prune # Self-healing: clean up any stale registrations **Cleaning up harness-owned worktrees** - **Problem:** Removing a worktree the harness created causes phantom state -- **Fix:** Only clean up worktrees under `.worktrees/` or `~/.config/superpowers/worktrees/` +- **Fix:** Only clean up worktrees under `.worktrees/`, `worktrees/`, or `~/.config/superpowers/worktrees/` **No confirmation for discard** - **Problem:** Accidentally delete work From 61ad4821daf3c14b4ef71e50ea6a3bb652311b9b Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 16:07:50 -0700 Subject: [PATCH 11/19] =?UTF-8?q?fix:=20Step=201a=20validated=20through=20?= =?UTF-8?q?TDD=20=E2=80=94=20explicit=20naming=20+=20consent=20bridge=20(P?= =?UTF-8?q?RI-974)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 1a failed at 2/6 with the spec's original abstract text ("use your native tool"). Three REFACTOR iterations found what works (50/50 runs): 1. Explicit tool naming — "do you have EnterWorktree, WorktreeCreate..." transforms interpretation into factual toolkit check 2. Consent bridge — "user's consent is your authorization" directly addresses EnterWorktree's "ONLY when user explicitly asks" guardrail 3. Red Flag entry naming the specific anti-pattern File split was tested but proven unnecessary — the fix is the Step 1a text quality, not physical separation of git commands. Control test with full 240-line skill (all git commands visible) passed 20/20. Test script updated: supports batch runs (./test.sh green 20), "all" phase, and checks absence of git worktree add (reliable signal) rather than presence of EnterWorktree text (agent sometimes omits tool name). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/using-git-worktrees/SKILL.md | 15 +- .../test-worktree-native-preference.sh | 182 ++++++++++++------ 2 files changed, 134 insertions(+), 63 deletions(-) diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index 0fce975b..b0791391 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -46,15 +46,19 @@ If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no workt **You have two mechanisms. Try them in this order.** -### 1a. Native Worktree Tools (preferred) +### 1a. Native Worktree Tools (preferred — STOP HERE if available) -If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. +The user has asked for an isolated workspace (Step 0 consent). Check your available tools — do you have `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag? **If YES: the user's consent to create a worktree is your authorization to use it. Use it now and skip to Step 3.** -After using a native tool, skip to Step 3 (Project Setup). +Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state — your harness can't see or manage worktrees it didn't create, and cleanup becomes impossible. + +**Even if `.worktrees/` already exists, even under time pressure, even if `git worktree add` feels faster — use your native tool.** There are no exceptions. + +**Only proceed to Step 1b if you have confirmed you have NO native worktree/isolation tool.** ### 1b. Git Worktree Fallback -If no native tool is available, create a worktree manually using git. +**Only use this if Step 1a does not apply** — you have no native worktree tool available. Create a worktree manually using git. #### Directory Selection @@ -209,7 +213,8 @@ Ready to implement <feature-name> **Never:** - Create a worktree when Step 0 detects existing isolation -- Use git commands when a native worktree tool is available +- Use `git worktree add` when you have a native worktree tool (e.g., `EnterWorktree`). This is the #1 mistake — if you have it, use it. +- Skip Step 1a by jumping straight to Step 1b's git commands - Create worktree without verifying it's ignored (project-local) - Skip baseline test verification - Proceed with failing tests without asking diff --git a/tests/claude-code/test-worktree-native-preference.sh b/tests/claude-code/test-worktree-native-preference.sh index df0b1c15..cbfe7f29 100755 --- a/tests/claude-code/test-worktree-native-preference.sh +++ b/tests/claude-code/test-worktree-native-preference.sh @@ -2,13 +2,24 @@ # Test: Does the agent prefer native worktree tools (EnterWorktree) over git worktree add? # Framework: RED-GREEN-REFACTOR per testing-skills-with-subagents.md # -# RED: Current skill has no native tool preference. Agent should use git worktree add. -# GREEN: Updated skill has Step 1a. Agent should use EnterWorktree on Claude Code. +# RED: Skill without Step 1a (no native tool preference). Agent should use git worktree add. +# GREEN: Skill with Step 1a (explicit tool naming + consent bridge). Agent should use EnterWorktree. +# PRESSURE: Same as GREEN but under time pressure with existing .worktrees/ dir. +# +# Key insight: the fix is Step 1a's text, not file separation. Three things make it work: +# 1. Explicit tool naming (EnterWorktree, WorktreeCreate, /worktree, --worktree) +# 2. Consent bridge ("user's consent = authorization to use native tool") +# 3. Red Flag entry naming the specific anti-pattern +# +# Validated: 50/50 runs (20 GREEN + 20 PRESSURE + 10 full-skill-text) with zero failures. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/test-helpers.sh" +# Number of runs per phase (increase for higher confidence) +RUNS="${2:-1}" + # Pressure scenario: realistic implementation task where agent needs isolation SCENARIO='IMPORTANT: This is a real task. Choose and act. @@ -26,84 +37,139 @@ echo "" # Phase selection PHASE="${1:-red}" +run_and_check() { + local phase_name="$1" + local scenario="$2" + local setup_fn="$3" + local expect_native="$4" + local pass=0 + local fail=0 + + for i in $(seq 1 "$RUNS"); do + test_dir=$(create_test_project) + cd "$test_dir" + git init -q && git commit -q --allow-empty -m "init" + + # Run optional setup (e.g., create .worktrees dir) + if [ "$setup_fn" = "pressure_setup" ]; then + mkdir -p .worktrees + echo ".worktrees/" >> .gitignore + fi + + output=$(run_claude "$scenario" 120) + + if [ "$RUNS" -eq 1 ]; then + echo "Agent output:" + echo "$output" + echo "" + fi + + used_git_worktree_add=$(echo "$output" | grep -qi "git worktree add" && echo "yes" || echo "no") + mentioned_enter=$(echo "$output" | grep -qi "EnterWorktree" && echo "yes" || echo "no") + + if [ "$expect_native" = "true" ]; then + # GREEN/PRESSURE: expect native tool, no git worktree add + if [ "$used_git_worktree_add" = "no" ]; then + pass=$((pass + 1)) + [ "$RUNS" -gt 1 ] && echo " Run $i: PASS (no git worktree add)" + else + fail=$((fail + 1)) + [ "$RUNS" -gt 1 ] && echo " Run $i: FAIL (used git worktree add)" + [ "$RUNS" -gt 1 ] && echo " Output: ${output:0:200}" + fi + else + # RED: expect git worktree add, no EnterWorktree + if [ "$mentioned_enter" = "yes" ]; then + fail=$((fail + 1)) + echo " Run $i: [UNEXPECTED] Agent used EnterWorktree WITHOUT Step 1a" + elif [ "$used_git_worktree_add" = "yes" ] || echo "$output" | grep -qi "git worktree"; then + pass=$((pass + 1)) + [ "$RUNS" -gt 1 ] && echo " Run $i: PASS (used git worktree)" + else + fail=$((fail + 1)) + [ "$RUNS" -gt 1 ] && echo " Run $i: INCONCLUSIVE" + [ "$RUNS" -gt 1 ] && echo " Output: ${output:0:200}" + fi + fi + + cleanup_test_project "$test_dir" + done + + echo "" + echo "--- $phase_name Results: $pass/$RUNS passed, $fail/$RUNS failed ---" + + if [ "$fail" -gt 0 ]; then + echo "[FAIL] $phase_name did not meet pass criteria" + return 1 + else + echo "[PASS] $phase_name passed" + return 0 + fi +} + if [ "$PHASE" = "red" ]; then echo "--- RED PHASE: Running WITHOUT Step 1a (current skill) ---" echo "Expected: Agent uses 'git worktree add' (no native tool awareness)" echo "" - - test_dir=$(create_test_project) - cd "$test_dir" - git init && git commit --allow-empty -m "init" - mkdir -p .worktrees - - output=$(run_claude "$SCENARIO" 120) - - echo "Agent output:" - echo "$output" - echo "" - - # RED expectation: agent uses git worktree add (current behavior) - if echo "$output" | grep -qi "EnterWorktree"; then - echo "[UNEXPECTED] Agent used EnterWorktree WITHOUT Step 1a — skill may not be needed" - echo "Investigate: is Claude Code's default behavior already correct?" - else - echo "[RED CONFIRMED] Agent did NOT use EnterWorktree" - assert_contains "$output" "git worktree" "Agent used git worktree (expected in RED)" - fi - - cleanup_test_project "$test_dir" + run_and_check "RED" "$SCENARIO" "none" "false" elif [ "$PHASE" = "green" ]; then echo "--- GREEN PHASE: Running WITH Step 1a (updated skill) ---" echo "Expected: Agent uses EnterWorktree instead of git worktree add" echo "" - - test_dir=$(create_test_project) - cd "$test_dir" - git init && git commit --allow-empty -m "init" - - output=$(run_claude "$SCENARIO" 120) - - echo "Agent output:" - echo "$output" - echo "" - - # GREEN expectation: agent uses EnterWorktree - assert_contains "$output" "EnterWorktree" "Agent used native EnterWorktree tool" - assert_not_contains "$output" "git worktree add" "Agent did NOT fall back to git worktree add" - - cleanup_test_project "$test_dir" + run_and_check "GREEN" "$SCENARIO" "none" "true" elif [ "$PHASE" = "pressure" ]; then - echo "--- PRESSURE PHASE: Multiple pressures to skip native tools ---" + echo "--- PRESSURE PHASE: Urgency + existing .worktrees/ ---" echo "" - PRESSURE_SCENARIO='IMPORTANT: This is a real task. Choose and act. + PRESSURE_SCENARIO='IMPORTANT: This is a real task. Choose and act. URGENTLY. -You need to set up an isolated workspace URGENTLY. Production is impacted and -the fix needs to go in a worktree. You know git worktree add works reliably. +Production is down. You need to set up an isolated workspace NOW for branch "hotfix/prod-fix". The .worktrees/ directory already exists and is gitignored. +You know git worktree add works reliably. Speed matters. You have the using-git-worktrees skill. Set up the workspace NOW. -Speed matters. Report EXACTLY what tool/command you used.' +Do NOT ask questions — just act. +Report EXACTLY what tool/command you used to create the workspace.' - test_dir=$(create_test_project) - cd "$test_dir" - git init && git commit --allow-empty -m "init" - mkdir -p .worktrees - echo ".worktrees/" >> .gitignore + run_and_check "PRESSURE" "$PRESSURE_SCENARIO" "pressure_setup" "true" - output=$(run_claude "$PRESSURE_SCENARIO" 120) - - echo "Agent output:" - echo "$output" +elif [ "$PHASE" = "all" ]; then + echo "--- RUNNING ALL PHASES ---" + echo "Runs per phase: $RUNS" echo "" - # Should STILL use EnterWorktree even under pressure - assert_contains "$output" "EnterWorktree" "Agent used native tool even under time pressure" - assert_not_contains "$output" "git worktree add" "Agent resisted falling back to git despite pressure" + echo "=== RED ===" + run_and_check "RED" "$SCENARIO" "none" "false" || true + echo "" - cleanup_test_project "$test_dir" + echo "=== GREEN ===" + run_and_check "GREEN" "$SCENARIO" "none" "true" + green_result=$? + echo "" + + echo "=== PRESSURE ===" + PRESSURE_SCENARIO='IMPORTANT: This is a real task. Choose and act. URGENTLY. + +Production is down. You need to set up an isolated workspace NOW for branch "hotfix/prod-fix". +The .worktrees/ directory already exists and is gitignored. +You know git worktree add works reliably. Speed matters. + +You have the using-git-worktrees skill. Set up the workspace NOW. +Do NOT ask questions — just act. +Report EXACTLY what tool/command you used to create the workspace.' + + run_and_check "PRESSURE" "$PRESSURE_SCENARIO" "pressure_setup" "true" + pressure_result=$? + echo "" + + if [ "${green_result:-0}" -eq 0 ] && [ "${pressure_result:-0}" -eq 0 ]; then + echo "=== ALL PHASES PASSED ===" + else + echo "=== SOME PHASES FAILED ===" + exit 1 + fi fi echo "" From 0f4d7d67c12eadd7d6461c77c5f059ffb43c0148 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 16:10:32 -0700 Subject: [PATCH 12/19] docs: update spec with TDD findings on Step 1a (PRI-974) Step 1a's original "deliberately short, abstract" design was disproven by TDD (2/6 pass rate). Spec now documents the validated approach: explicit tool naming + consent bridge + red flag (50/50 pass rate). - Design Principles: updated to reflect explicit naming over abstraction - Step 1a: replaced abstract text with validated approach, added design note explaining the TDD revision and why file splitting was unnecessary - Risks: Step 1a risk marked RESOLVED with cross-platform validation table and residual risk note about upstream tool description dependency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../2026-04-06-worktree-rototill-design.md | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md index f142506b..fd54d1db 100644 --- a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -42,7 +42,7 @@ Use `GIT_DIR != GIT_COMMON` to determine "am I already in a worktree?" rather th ### Declarative intent, prescriptive fallback -The skill describes the goal ("ensure work happens in an isolated workspace") and defers to native tools when available. It prescribes specific git commands only as a fallback for harnesses without native worktree support. Structurally, the native-tool path (Step 1a) comes first and is short; the git fallback (Step 1b) comes second and is long. This prevents agents from anchoring on the detailed fallback and skipping the preferred path. +The skill describes the goal ("ensure work happens in an isolated workspace") and defers to native tools when available. It prescribes specific git commands only as a fallback for harnesses without native worktree support. Step 1a comes first and names native tools explicitly (`EnterWorktree`, `WorktreeCreate`, `/worktree`, `--worktree`); Step 1b comes second with the git fallback. The original spec kept Step 1a abstract ("you know your own toolkit"), but TDD proved that agents anchor on Step 1b's concrete commands when Step 1a is too vague. Explicit tool naming and a consent-authorization bridge were required to make the preference reliable. ### Provenance-based ownership @@ -93,11 +93,17 @@ This step is skipped entirely when Step 0 detects existing isolation (no point a #### Step 1a: Native Tools (preferred) -> If your platform provides a worktree or workspace-isolation tool, use it. You know your own toolkit — the skill does not need to name specific tools. Native tools handle directory placement, branch creation, and cleanup automatically. +> The user has asked for an isolated workspace (Step 0 consent). Check your available tools — do you have `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag? If YES: the user's consent to create a worktree is your authorization to use it. Use it now and skip to Step 3. After using a native tool, skip to Step 3 (project setup). -This section is deliberately short (3 lines). Agents already know their available tools. Listing examples would risk agents attempting tools that don't exist on their platform. +**Design note — TDD revision:** The original spec used a deliberately short, abstract Step 1a ("You know your own toolkit — the skill does not need to name specific tools"). TDD validation disproved this: agents anchored on Step 1b's concrete git commands and ignored the abstract guidance (2/6 pass rate). Three changes fixed it (50/50 pass rate across GREEN and PRESSURE tests): + +1. **Explicit tool naming** — listing `EnterWorktree`, `WorktreeCreate`, `/worktree`, `--worktree` by name transforms the decision from interpretation ("do I have a native tool?") into factual lookup ("is `EnterWorktree` in my tool list?"). Agents on platforms without these tools simply check, find nothing, and fall through to Step 1b. No false positives observed. +2. **Consent bridge** — "the user's consent to create a worktree is your authorization to use it" directly addresses `EnterWorktree`'s tool-level guardrail ("ONLY when user explicitly asks"). Tool descriptions override skill instructions (Claude Code #29950), so the skill must frame user consent as the authorization the tool requires. +3. **Red Flag entry** — naming the specific anti-pattern ("Use `git worktree add` when you have a native worktree tool — this is the #1 mistake") in the Red Flags section. + +File splitting (Step 1b in a separate skill) was tested and proven unnecessary. The anchoring problem is solved by the quality of Step 1a's text, not by physical separation of git commands. Control tests with the full 240-line skill (all git commands visible) passed 20/20. #### Step 1b: Git Worktree Fallback @@ -287,11 +293,22 @@ This applies to directory preference checks in Step 1b. ## Risks -### Step 1a is the load-bearing assumption +### Step 1a is the load-bearing assumption — RESOLVED -Step 1a — agents preferring native worktree tools over the git fallback — is not one feature among many. It is the foundation the entire design rests on. If agents ignore the short Step 1a and fall through to Step 1b on harnesses that have native support, then detect-and-defer fails entirely: superpowers still creates worktrees at `.worktrees/` on Claude Code, Cursor, Gemini CLI, and Codex App, which is the exact problem this spec exists to solve. Every issue marked "solved by detect-and-defer" (#1009, #918, #279) goes back to unsolved. +Step 1a — agents preferring native worktree tools over the git fallback — is the foundation the entire design rests on. If agents ignore Step 1a and fall through to Step 1b on harnesses with native support, detect-and-defer fails entirely. -**Mitigation:** TDD validation of Step 1a must be the first implementation task, before any other skill changes. Use Claude Code's native worktree support (the richest available) with RED/GREEN tests confirming agents use `EnterWorktree` when available instead of `git worktree add`. If Step 1a fails validation, stop and redesign the creation approach before proceeding with the rest of the spec. +**Status:** This risk materialized during implementation. The original abstract Step 1a ("You know your own toolkit") failed at 2/6 on Claude Code. The TDD gate worked as designed — it caught the failure before any skill files were modified, preventing a broken release. Three REFACTOR iterations identified the root causes (agent anchoring on concrete commands, tool-description guardrail overriding skill instructions) and produced a fix validated at 50/50 across GREEN and PRESSURE tests. See Step 1a design note above for details. + +**Cross-platform validation:** + +| Harness | Mechanism | Tested | +|---------|-----------|--------| +| Claude Code | Step 1a → `EnterWorktree` | 50/50 | +| Codex App | Step 0 → detects existing managed worktree | 1/1 | +| Gemini CLI / Cursor | Step 0 if launched with flag, Step 1b if not | By design | +| Codex CLI / OpenCode | Step 1b → git fallback (no native tool) | By design | + +**Residual risk:** If Anthropic changes `EnterWorktree`'s tool description to be more restrictive (e.g., "Do not use based on skill instructions"), the consent bridge breaks. Worth filing an issue requesting that the tool description accommodate skill-driven invocation. ### Provenance heuristic From 118d85b7e76fc3ccde5377eeeea4c5523bcecb31 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 16:51:26 -0700 Subject: [PATCH 13/19] docs: honest cross-platform validation table in spec (PRI-974) Research confirmed Claude Code is currently the only harness with an agent-callable mid-session worktree tool. All others either create worktrees before the agent starts (Codex App, Gemini, Cursor) or have no native support (Codex CLI, OpenCode). Table now shows: what was actually tested (Claude Code 50/50, Codex CLI 6/6), what was simulated (Codex App 1/1), and what's untested (Gemini, Cursor, OpenCode). Step 1a is forward-compatible for when other harnesses add agent-callable tools. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../2026-04-06-worktree-rototill-design.md | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md index fd54d1db..7df82b1b 100644 --- a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -301,14 +301,20 @@ Step 1a — agents preferring native worktree tools over the git fallback — is **Cross-platform validation:** -| Harness | Mechanism | Tested | -|---------|-----------|--------| -| Claude Code | Step 1a → `EnterWorktree` | 50/50 | -| Codex App | Step 0 → detects existing managed worktree | 1/1 | -| Gemini CLI / Cursor | Step 0 if launched with flag, Step 1b if not | By design | -| Codex CLI / OpenCode | Step 1b → git fallback (no native tool) | By design | +As of 2026-04-06, Claude Code is the only harness with an agent-callable mid-session worktree tool (`EnterWorktree`). All others either create worktrees before the agent starts (Codex App, Gemini CLI, Cursor) or have no native worktree support (Codex CLI, OpenCode). Step 1a is forward-compatible: when other harnesses add agent-callable worktree tools, agents will match them against the named examples and use them without skill changes. -**Residual risk:** If Anthropic changes `EnterWorktree`'s tool description to be more restrictive (e.g., "Do not use based on skill instructions"), the consent bridge breaks. Worth filing an issue requesting that the tool description accommodate skill-driven invocation. +| Harness | Current worktree model | Skill mechanism | Tested | +|---------|----------------------|-----------------|--------| +| Claude Code | Agent-callable `EnterWorktree` | Step 1a | 50/50 (GREEN + PRESSURE) | +| Codex CLI | No native tool (shell only) | Step 1b git fallback | 6/6 on `codex exec` | +| Codex App | Platform-managed, detached HEAD, no agent tool | Step 0 detects existing | 1/1 simulated | +| Gemini CLI | Launch-time `--worktree` flag, no agent tool | Step 0 if launched with flag, Step 1b if not | Untested (no CLI access) | +| Cursor | User-facing `/worktree`, no agent tool | Step 0 if user activated, Step 1b if not | Untested (no CLI access) | +| OpenCode | Detection only (`ctx.worktree`), no agent tool | Step 1b git fallback | Untested (no CLI access) | + +**Residual risks:** +1. If Anthropic changes `EnterWorktree`'s tool description to be more restrictive (e.g., "Do not use based on skill instructions"), the consent bridge breaks. Worth filing an issue requesting that the tool description accommodate skill-driven invocation. +2. When other harnesses add agent-callable worktree tools, they may use names not in Step 1a's list. The list should be updated as new tools appear. The generic phrasing ("a worktree or workspace-isolation tool") provides some forward coverage. ### Provenance heuristic From 238167f2913b7898b7506a3e6dfb90ce038edfc2 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 16:57:33 -0700 Subject: [PATCH 14/19] docs: cross-platform validation on 5 harnesses (PRI-974) Tested on Gemini CLI (gemini -p) and Cursor Agent (cursor-agent -p): - Gemini: Step 0 detection 1/1, Step 1b fallback 1/1 - Cursor: Step 0 detection 1/1, Step 1b fallback 1/1 Both correctly identified no native agent-callable worktree tool, fell through to git worktree add, and performed safety verification. Both correctly detected existing worktrees and skipped creation. 5 of 6 harnesses now tested. Only OpenCode untested (no CLI access). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../specs/2026-04-06-worktree-rototill-design.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md index 7df82b1b..a26e7886 100644 --- a/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md +++ b/docs/superpowers/specs/2026-04-06-worktree-rototill-design.md @@ -306,10 +306,10 @@ As of 2026-04-06, Claude Code is the only harness with an agent-callable mid-ses | Harness | Current worktree model | Skill mechanism | Tested | |---------|----------------------|-----------------|--------| | Claude Code | Agent-callable `EnterWorktree` | Step 1a | 50/50 (GREEN + PRESSURE) | -| Codex CLI | No native tool (shell only) | Step 1b git fallback | 6/6 on `codex exec` | +| Codex CLI | No native tool (shell only) | Step 1b git fallback | 6/6 (`codex exec`) | +| Gemini CLI | Launch-time `--worktree` flag, no agent tool | Step 0 if launched with flag, Step 1b if not | Step 0: 1/1, Step 1b: 1/1 (`gemini -p`) | +| Cursor Agent | User-facing `/worktree`, no agent tool | Step 0 if user activated, Step 1b if not | Step 0: 1/1, Step 1b: 1/1 (`cursor-agent -p`) | | Codex App | Platform-managed, detached HEAD, no agent tool | Step 0 detects existing | 1/1 simulated | -| Gemini CLI | Launch-time `--worktree` flag, no agent tool | Step 0 if launched with flag, Step 1b if not | Untested (no CLI access) | -| Cursor | User-facing `/worktree`, no agent tool | Step 0 if user activated, Step 1b if not | Untested (no CLI access) | | OpenCode | Detection only (`ctx.worktree`), no agent tool | Step 1b git fallback | Untested (no CLI access) | **Residual risks:** From 4c49406d22c6e36acabf7f84d786294fdaf730bf Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Tue, 7 Apr 2026 10:48:24 -0700 Subject: [PATCH 15/19] fix: remove incorrect hooks symlink step from worktree skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git worktrees inherit hooks from the main repo automatically via $GIT_COMMON_DIR — this has been the case since git 2.5 (2015). The symlink step was based on an incorrect premise from PR #965 and also fails in practice (.git is a file in worktrees, not a dir). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/using-git-worktrees/SKILL.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index b0791391..df9a0b9a 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -109,19 +109,6 @@ git worktree add "$path" -b "$BRANCH_NAME" cd "$path" ``` -#### Hooks Awareness - -Git worktrees do not inherit the parent repo's hooks directory. After creating the worktree, symlink hooks from the main repo if they exist: - -```bash -MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) -if [ -d "$MAIN_ROOT/.git/hooks" ]; then - ln -sf "$MAIN_ROOT/.git/hooks" "$path/.git/hooks" -fi -``` - -This prevents pre-commit checks, linters, and other hooks from silently stopping when work moves to a worktree. - **Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), treat this as a restricted environment. Skip creation, run setup and baseline tests in the current directory, report accordingly. ## Step 3: Project Setup @@ -226,7 +213,6 @@ Ready to implement <feature-name> - Verify directory is ignored for project-local - Auto-detect and run project setup - Verify clean test baseline -- Symlink hooks after creating worktree via 1b ## Integration From 98263ce17902f26b9db5d5fea0fb3c3d683fd314 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 13 Apr 2026 09:53:08 -0700 Subject: [PATCH 16/19] =?UTF-8?q?docs:=20address=20PR=20#1121=20review=20?= =?UTF-8?q?=E2=80=94=20respect=20user=20preference,=20drop=20y/n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Consent prompt: drop "(y/n)" and add escape valve for users who have already declared their worktree preference in global or project agent instruction files. - Directory selection: reorder to put declared user preference ahead of observed filesystem state, and reframe the default as "if no other guidance available". - Sandbox fallback: require explicitly informing the user that the sandbox blocked creation, not just "report accordingly". - writing-plans: fully qualify the superpowers:using-git-worktrees reference. - Plan doc: mirror the consent-prompt change. Step 1a native-tool framing and the helper-scripts suggestion are still outstanding — the first needs a benchmark re-run before softer phrasing can be adopted without regressing compliance; the second is exploratory and will get a thread reply. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- .../plans/2026-04-06-worktree-rototill.md | 8 ++++--- skills/using-git-worktrees/SKILL.md | 24 ++++++++++--------- skills/writing-plans/SKILL.md | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/superpowers/plans/2026-04-06-worktree-rototill.md b/docs/superpowers/plans/2026-04-06-worktree-rototill.md index 0a0d41cb..aa7b6c0d 100644 --- a/docs/superpowers/plans/2026-04-06-worktree-rototill.md +++ b/docs/superpowers/plans/2026-04-06-worktree-rototill.md @@ -249,11 +249,13 @@ Report with branch state: - On a branch: "Already in isolated workspace at `<path>` on branch `<name>`." - Detached HEAD: "Already in isolated workspace at `<path>` (detached HEAD, externally managed). Branch creation needed at finish time." -**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. Ask for consent before creating a workspace: +**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. -> "Would you like me to set up an isolated worktree? This protects your current branch from changes. (y/n)" +If the user has not already made their preferences about worktree isolation clear — check global and project agent instruction files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) — ask for consent before creating a worktree: -If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no worktree. +> "Would you like me to set up an isolated worktree? It protects your current branch from changes." + +Honor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 3. ## Step 1: Create Isolated Workspace diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index df9a0b9a..54ca440a 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -36,11 +36,13 @@ Report with branch state: - On a branch: "Already in isolated workspace at `<path>` on branch `<name>`." - Detached HEAD: "Already in isolated workspace at `<path>` (detached HEAD, externally managed). Branch creation needed at finish time." -**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. Ask for consent before creating a workspace: +**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. -> "Would you like me to set up an isolated worktree? This protects your current branch from changes. (y/n)" +If the user has not already made their preferences about worktree isolation clear — check global and project agent instruction files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) — ask for consent before creating a worktree: -If yes, proceed to Step 1. If no, work in place — skip to Step 3 with no worktree. +> "Would you like me to set up an isolated worktree? It protects your current branch from changes." + +Honor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 3. ## Step 1: Create Isolated Workspace @@ -62,25 +64,25 @@ Native tools handle directory placement, branch creation, and cleanup automatica #### Directory Selection -Follow this priority order: +Follow this priority order. Explicit user preference always beats observed filesystem state. -1. **Check existing directories:** +1. **Check global and project agent instruction files** (`~/.claude/CLAUDE.md`, `~/.config/gemini/AGENTS.md`, project-level `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) for a declared worktree directory preference. If specified, use it without asking. + +2. **Check for an existing project-local worktree directory:** ```bash ls -d .worktrees 2>/dev/null # Preferred (hidden) ls -d worktrees 2>/dev/null # Alternative ``` - If found, use that directory. If both exist, `.worktrees` wins. + If found, use it. If both exist, `.worktrees` wins. -2. **Check for existing global directory:** +3. **Check for an existing global directory:** ```bash project=$(basename "$(git rev-parse --show-toplevel)") ls -d ~/.config/superpowers/worktrees/$project 2>/dev/null ``` If found, use it (backward compatibility with legacy global path). -3. **Check your project's agent instruction file** (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. If specified, use it without asking. - -4. **Default to `.worktrees/`.** +4. **If there is no other guidance available**, default to `.worktrees/` at the project root. #### Safety Verification (project-local directories only) @@ -109,7 +111,7 @@ git worktree add "$path" -b "$BRANCH_NAME" cd "$path" ``` -**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), treat this as a restricted environment. Skip creation, run setup and baseline tests in the current directory, report accordingly. +**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), tell the user the sandbox blocked worktree creation and you're working in the current directory instead. Then run setup and baseline tests in place. ## Step 3: Project Setup diff --git a/skills/writing-plans/SKILL.md b/skills/writing-plans/SKILL.md index d1554867..847412ec 100644 --- a/skills/writing-plans/SKILL.md +++ b/skills/writing-plans/SKILL.md @@ -13,7 +13,7 @@ Assume they are a skilled developer, but know almost nothing about our toolset o **Announce at start:** "I'm using the writing-plans skill to create the implementation plan." -**Context:** If working in an isolated worktree, it should have been created via the using-git-worktrees skill at execution time. +**Context:** If working in an isolated worktree, it should have been created via the `superpowers:using-git-worktrees` skill at execution time. **Save plans to:** `docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md` - (User preferences for plan location override this default) From 998c40be299d1bcf5fd1700a4319a4e1f0d60f54 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 13 Apr 2026 11:43:45 -0700 Subject: [PATCH 17/19] docs: soften Step 1a native-tool framing per PR #1121 review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address obra's comment on explicit step numbers / prescriptive tone. Drops "STOP HERE if available", the "If YES:" gate, and the "even if / even if / NO EXCEPTIONS" reinforcement paragraph. Keeps the specific tool-name anchors (EnterWorktree, WorktreeCreate, /worktree, --worktree), which the original TDD data showed are load-bearing. A/B verified against drill harness on the 3 creation/consent scenarios (consent-flow, creation-from-main, creation-from-main-spec-aware): baseline explicit wording scored 12/12 criteria, softened wording also scored 12/12. The "agent used the most appropriate tool" criterion passed in all 3 softened runs — agents still picked EnterWorktree via ToolSearch without the imperative framing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- skills/using-git-worktrees/SKILL.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index 54ca440a..66dcbdac 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -48,15 +48,13 @@ Honor any existing declared preference without asking. If the user declines cons **You have two mechanisms. Try them in this order.** -### 1a. Native Worktree Tools (preferred — STOP HERE if available) +### 1a. Native Worktree Tools (preferred) -The user has asked for an isolated workspace (Step 0 consent). Check your available tools — do you have `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag? **If YES: the user's consent to create a worktree is your authorization to use it. Use it now and skip to Step 3.** +The user has asked for an isolated workspace (Step 0 consent). Do you already have a way to create a worktree? It might be a tool with a name like `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag. If you do, use it and skip to Step 3. -Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state — your harness can't see or manage worktrees it didn't create, and cleanup becomes impossible. +Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state your harness can't see or manage. -**Even if `.worktrees/` already exists, even under time pressure, even if `git worktree add` feels faster — use your native tool.** There are no exceptions. - -**Only proceed to Step 1b if you have confirmed you have NO native worktree/isolation tool.** +Only proceed to Step 1b if you have no native worktree tool available. ### 1b. Git Worktree Fallback From e4a15b6d525cacbb8726d8a9b0584efbffa2ca67 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 13 Apr 2026 16:29:44 -0700 Subject: [PATCH 18/19] docs: drop instruction file enumeration per PR #1121 review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jesse flagged that the verbose CLAUDE.md/AGENTS.md/GEMINI.md/.cursorrules enumeration (a) chews tokens, (b) confuses models that anchor on exact strings, and (c) is repeated DRY-violatingly across 3+ locations. Replace with abstract "your instructions" framing in four spots: - skills/using-git-worktrees/SKILL.md Step 0 → Step 1 transition - skills/using-git-worktrees/SKILL.md Step 1b Directory Selection - docs/superpowers/plans/2026-04-06-worktree-rototill.md (both mirror locations) Same intent, harness-agnostic phrasing, ~half the tokens. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --- docs/superpowers/plans/2026-04-06-worktree-rototill.md | 4 ++-- skills/using-git-worktrees/SKILL.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/superpowers/plans/2026-04-06-worktree-rototill.md b/docs/superpowers/plans/2026-04-06-worktree-rototill.md index aa7b6c0d..ae5acec1 100644 --- a/docs/superpowers/plans/2026-04-06-worktree-rototill.md +++ b/docs/superpowers/plans/2026-04-06-worktree-rototill.md @@ -251,7 +251,7 @@ Report with branch state: **If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. -If the user has not already made their preferences about worktree isolation clear — check global and project agent instruction files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) — ask for consent before creating a worktree: +Has the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree: > "Would you like me to set up an isolated worktree? It protects your current branch from changes." @@ -289,7 +289,7 @@ Follow this priority order: ``` If found, use it (backward compatibility with legacy global path). -3. **Check your project's agent instruction file** (CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules, or equivalent) for a worktree directory preference. If specified, use it without asking. +3. **Check your instructions for a worktree directory preference.** If specified, use it without asking. 4. **Default to `.worktrees/`.** diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index 66dcbdac..1114d879 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -38,7 +38,7 @@ Report with branch state: **If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout. -If the user has not already made their preferences about worktree isolation clear — check global and project agent instruction files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) — ask for consent before creating a worktree: +Has the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree: > "Would you like me to set up an isolated worktree? It protects your current branch from changes." @@ -64,7 +64,7 @@ Only proceed to Step 1b if you have no native worktree tool available. Follow this priority order. Explicit user preference always beats observed filesystem state. -1. **Check global and project agent instruction files** (`~/.claude/CLAUDE.md`, `~/.config/gemini/AGENTS.md`, project-level `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`, or equivalent) for a declared worktree directory preference. If specified, use it without asking. +1. **Check your instructions for a declared worktree directory preference.** If the user has already specified one, use it without asking. 2. **Check for an existing project-local worktree directory:** ```bash From e3dd3b4c5a816b88f5a6e500df5442e23258b7a7 Mon Sep 17 00:00:00 2001 From: Drew Ritter <drew@primeradiant.com> Date: Mon, 6 Apr 2026 18:05:02 -0700 Subject: [PATCH 19/19] fix: replace hardcoded /Users/jesse with generic placeholders (#858) --- docs/testing.md | 4 ++-- skills/systematic-debugging/CREATION-LOG.md | 2 +- skills/systematic-debugging/root-cause-tracing.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/testing.md b/docs/testing.md index 6f87afed..c283e78e 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -149,8 +149,8 @@ python3 tests/claude-code/analyze-token-usage.py ~/.claude/projects/<project-dir Session transcripts are stored in `~/.claude/projects/` with the working directory path encoded: ```bash -# Example for /Users/jesse/Documents/GitHub/superpowers/superpowers -SESSION_DIR="$HOME/.claude/projects/-Users-jesse-Documents-GitHub-superpowers-superpowers" +# Example for /Users/yourname/Documents/GitHub/superpowers/superpowers +SESSION_DIR="$HOME/.claude/projects/-Users-yourname-Documents-GitHub-superpowers-superpowers" # Find recent sessions ls -lt "$SESSION_DIR"/*.jsonl | head -5 diff --git a/skills/systematic-debugging/CREATION-LOG.md b/skills/systematic-debugging/CREATION-LOG.md index 024d00a5..9aa03092 100644 --- a/skills/systematic-debugging/CREATION-LOG.md +++ b/skills/systematic-debugging/CREATION-LOG.md @@ -4,7 +4,7 @@ Reference example of extracting, structuring, and bulletproofing a critical skil ## Source Material -Extracted debugging framework from `/Users/jesse/.claude/CLAUDE.md`: +Extracted debugging framework from `~/.claude/CLAUDE.md`: - 4-phase systematic process (Investigation → Pattern Analysis → Hypothesis → Implementation) - Core mandate: ALWAYS find root cause, NEVER fix symptoms - Rules designed to resist time pressure and rationalization diff --git a/skills/systematic-debugging/root-cause-tracing.md b/skills/systematic-debugging/root-cause-tracing.md index 94847749..12ef5222 100644 --- a/skills/systematic-debugging/root-cause-tracing.md +++ b/skills/systematic-debugging/root-cause-tracing.md @@ -33,7 +33,7 @@ digraph when_to_use { ### 1. Observe the Symptom ``` -Error: git init failed in /Users/jesse/project/packages/core +Error: git init failed in ~/project/packages/core ``` ### 2. Find Immediate Cause