# Action Worktrees

> Use when fanning several tickets into parallel branches and git worktrees, with related tickets grouped together.

- Skill: `tony/action-worktrees` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tony/action-worktrees`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tony/action-worktrees/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tony (https://skillmd.com/u/tony)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tony/action-worktrees

---


# this skill

Fan several tickets out into branches and worktrees. This command
owns exactly three things: **discovery** (which tickets),
**grouping** (which tickets share a branch), and **fan-out**
(parallel subagents or a sequential loop). Everything per-unit —
ticket resolution detail, branch naming, worktree creation,
implementation, gates, commits, the exit axis — is
the `action-worktree` skill's procedure, followed by reference, never
restated here.

This skill is invoked by name, never routed to on the model’s initiative: it creates
worktrees and branches, modifies files, and creates commits, so it
must be user-explicit, not router-inferred.

## Core thesis

N tickets rarely need N decisions — they need one plan and N
executions. The plural command's value is the plan: the right ticket
set, the right grouping (1:1 by default, shared branches only on
clear overlap), and a fan-out that parallelizes the safe part
(implementation inside isolated worktrees) while serializing the
unsafe part (mutation of shared git state).

Three disciplines:

1. **Delegate, don't duplicate.** The per-unit procedure lives in
   the `action-worktree` skill and the shared
   references — this file never paraphrases it. If the two files ever
   disagree, `worktree.md` wins; if `worktree.md` cannot be read at
   runtime, stop and say so — never reconstruct its procedure from
   memory.
2. **Group by evidence, confirm at the gate.** Default 1:1
   ticket-to-branch; propose a group only when tickets clearly
   overlap; every grouping is confirmed at the plan gate.
3. **Shared git state mutates only in the main loop** (see The Iron
   Rule).

## The Iron Rule

```
SHARED GIT STATE MUTATES ONLY IN THE MAIN LOOP
```

`git worktree add` / `remove`, branch creation, and any stash or
index operation on the shared repository happen **serially, in the
main loop**, before or after fan-out — never inside parallel units.
A parallel unit touches only files inside its own worktree and
commits only on its own branch. The tickets themselves stay
read-only throughout, per ticket-detection.md § The read-only
invariant — discovery queries included.

| Rationalization | Reality |
|---|---|
| "Each subagent can create its own worktree — it's faster" | `git worktree add` writes shared `.git` state (refs, the worktree registry); concurrent adds race. Creation costs seconds; untangling a corrupted registry costs the afternoon. |
| "Two small units can share a worktree" | A worktree serves one branch. Two units in one tree overwrite each other's diffs and commit each other's files. |
| "Stash the main checkout so units start clean" | The main checkout's uncommitted work belongs to the user, and worktrees already isolate units from it. If a stash is ever genuinely needed, it happens in the main loop with the user's consent — never from a unit. |

**Red flags — STOP:** a `git worktree` or `git stash` command inside
a subagent prompt; two units whose worktree paths collide; a unit
whose branch name matches another unit's.

## `$ARGUMENTS` contract

Non-flag text: any number of ticket references (IDs, URLs, `#123`).
Empty → Phase 1 discovers candidates and asks.

| Flag | Default | Effect |
|---|---|---|
| `--groups="a b; c"` | off | Explicit grouping: semicolon-separated groups, whitespace-separated tickets within a group. Skips overlap proposals; still confirmed at the plan gate. |
| `--sequential` | off | Force sequential execution even where subagents are available. |
| `--local` / `--temp` | `--local` | Placement axis, forwarded to every unit (see the `action-worktree` skill). |
| `--push` / `--pr` / `--setup-only` | commit only | Exit axis, forwarded to every unit (see the `action-worktree` skill). |

Placement and exit flags apply uniformly to every unit; there is no
per-unit override — run the `action-worktree` skill separately for a unit
that needs different axes.

## Phase 0: Situational awareness

As the `action-worktree` skill Phase 0 (Situational awareness) — conventions
files, the five gate
buckets and CI split per
`references/verification-gates.md`, ticket
tooling inventory, trunk and remote detection — plus plural-specific
checks:

1. Confirm `git worktree` is usable and there is disk headroom for N
   checkouts.
2. Note any setup a fresh checkout needs before gates can run
   (dependency install, codegen) — every unit must be able to
   verify.
3. Detect subagent support (Task tool or host equivalent); without
   it, plan for sequential main-loop execution.
4. More than 4 units → flag the fan-out size for explicit
   confirmation at the plan gate; a dozen worktrees is rarely what
   anyone wants.

## Phase 1: Ticket discovery

Resolve the ticket set:

1. **Explicit references in `$ARGUMENTS`** — resolve each per
   ticket-detection.md (detection source ladder; read-only fetch of
   title, description, acceptance criteria, branch-name field).
2. **Empty → mine the conversation** — tickets under discussion, a
   pasted list, a triage the user just agreed to.
3. **Still empty → query, read-only** — the tracker reached by the
   detection ladder: assigned-to-me or current-cycle issues via
   tracker MCP reads, or:

```
gh issue list --assignee @me
```

   Present the candidates via `ask-user-choice` (multi-select) —
   never auto-select a whole backlog.

## Phase 2: Grouping

Default: **1:1** — one ticket, one branch, one worktree.

Propose a group (several tickets, one branch) only on clear overlap
evidence:

- The tickets name the same component, files, or surface.
- One ticket's acceptance criteria cannot be met without another's
  change.
- The tracker marks them as sub-issues or duplicates of one story.

`--groups` replaces proposals with the user's own grouping. Grouped
units are crosscutting branches: naming skips the ticket-system rung
and proposes a theme slug (ticket-detection.md § Branch-name
precedence ladder), and every ticket's ID rides in the unit's
commits and PR per ticket-detection.md § Server-side linking. Every
grouping — proposed or explicit — is confirmed at the Phase 3 plan
gate.

## Phase 3: Orchestration plan

Enter plan mode if the host supports it (Claude Code:
`EnterPlanMode`; Cursor / Codex / Gemini: `/plan` or `Shift+Tab`) and
present:

1. The unit table: unit → ticket(s) → branch name (with its ladder
   rung) → worktree path → exit axis.
2. Grouping rationale, one line per proposed group (or "1:1
   throughout").
3. Execution mode: parallel (one subagent per unit) or sequential,
   and why (host support, `--sequential`).
4. Discovered gate commands and the local-vs-CI split (shared by all
   units).
5. The serialization boundary: worktree/branch creation in the main
   loop; implement → gates → commit → exit per unit.

Wait for approval, then exit plan mode. This gate also stands in for
each unit's own plan gate (the `action-worktree` skill Phase 2, Orchestration
plan): units run non-interactively and must not re-prompt. If plan mode is
unavailable, present the plan inline and proceed on confirmation. In
a non-interactive run, record the plan in the report and proceed
with **1:1 grouping only** — never apply inferred groups without a
human at the gate.

## Phase 4: Fan-out

1. **Serialize setup (main loop).** For each unit in plan order,
   perform the `action-worktree` skill Phase 3 (Worktree & branch) exactly as
   written there — start point, idempotency ladder, collision halt,
   primer assembly. One unit at a time; never a parallel
   `git worktree add`. With `--setup-only`, all units stop here.
2. **Delegate the work.** For each unit, hand the executor — a
   subagent (Task) where supported, the main loop otherwise — the
   unit's parameters (tickets and primer content, branch, worktree
   path, exit axis, resolved gate commands) plus the per-unit
   procedure: the `action-worktree` skill Phases 4–5 (Implement; Gates &
   commit) and its Iron Rule, read from
   the `action-worktree` skill and quoted to the
   executor — not paraphrased from memory — with this standing
   instruction: *work inside your assigned worktree only; never run
   `git fetch`, `git stash`, or `git worktree` subcommands; never
   touch paths outside your worktree.*
3. **Contain failures.** A unit that cannot reach green exits with a
   failure note (the `action-worktree` skill Phase 5, Gates & commit — red
   path): it never blocks other units, and its worktree stays in
   place for inspection.
4. **Serialize the exit axis.** Remote operations are excluded from
   subagent scope: after the units report, run each green unit's
   the `action-worktree` skill Phase 6 (Exit axis — push, PR) one unit at a
   time in the main loop. In sequential degradation, Phase 6 folds
   into each unit's turn instead — nothing is concurrent there.
5. **Serialize teardown decisions.** No worktree is removed in this
   phase; removal is offered in the closing panel and executed in
   the main loop.

## Output contract

1. Hero block (1–4 lines): `✓ N units done, M blocked` + execution
   mode + exit axis.
2. `## Units` — one row per unit: ticket(s) → branch → worktree path
   → created/resumed → commits landed → gate status → exit taken.
3. `## Grouping` — the final grouping and its rationale (or "1:1").
4. `## Verification` — shared gate commands, per-unit results
   summarized, the local-vs-CI split, deferred work named.
5. `## Blocked` — failed units with the failure verbatim and the
   worktree path to inspect. Omit when none.
6. End with an `ask-user-choice` panel (skip when already in plan
   mode): push all green units / open PRs for green units / retry
   blocked units / remove finished worktrees / stop. In a
   non-interactive run, record the question and options in the
   report instead of asking, and default to stopping with all
   worktrees kept.


## Portability notes

- `ask-user-choice` — present the listed options and wait for the user to pick one. Hosts with a structured multiple-choice tool (Claude Code's `AskUserQuestion`) should use it; otherwise print a numbered list and wait for a numbered reply. Never proceed on an assumed answer.
- `$ARGUMENTS` — the text the user passed when invoking this skill. If your host does not substitute it, read it as the user's request in the current turn, and ask when there is none.
- Bundled files — every relative path in this skill points at a file shipped inside this skill directory. Read them from here, not from the host's plugin tree.

