# Squad Batch Run

> Run multiple squad tasks end-to-end in Rolling Wave order — refine each task based on the prior card's actual implementation, then implement, then verify, then refine the next. Use for epic-level batch execution. --big-bang flag disables rolling wave for simple independent tasks.

- Skill: `steloit/squad-batch-run` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add steloit/squad-batch-run`
- Raw SKILL.md: https://api.skillmd.com/api/skills/steloit/squad-batch-run/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- License: MIT
- Author: steloit (https://skillmd.com/u/steloit)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/steloit/squad-batch-run

---


# Squad Batch Run

> Safety principles: read `../squad/principles.md` — **mandatory, not optional.**

Execute several squad tasks as one orchestrated batch using **Rolling Wave Planning** by default.

Default loop per task:
```
refine(N) → implement(N) → verify(N) → refine(N+1) → implement(N+1) → ...
```

This skill is an orchestrator, not a shortcut. Every implement step hands off to `squad-run`. Every refine step hands off to `squad-refine`.

## Codex Invocation Rule

When running inside Codex, if a dedicated Skill tool is not available, invoke the inner runners by issuing slash command text directly:

- `$squad-run <ID>` / `$squad-run <ID> --auto`
- `$squad-refine <ID>`

Treat these as the Codex-native equivalent of `Skill(skill="squad-run", ...)` and `Skill(skill="squad-refine", ...)`.
Do not re-implement either pipeline manually when this command path is available.

---

## Commands

### `/squad-batch-run <selector> [--auto] [--big-bang]`

Run all tasks matching the selector in dependency order. A `<selector>` is an explicit display-id list (`<KEY>-42 <KEY>-43`) and/or composable `--status` / `--tag` / `--phase` / `--epic <EPIC-ID>` filters (see **Inputs**).

- **Default (Rolling Wave)**: refine(N) → implement(N) → verify(N) → repeat. L2/L3 tasks pause at review checkpoints for user confirmation.
- **`--auto`**: auto-approve all review checkpoints inside `squad-run`. Refine and Verify always run.
- **`--big-bang`**: skip rolling wave — implement tasks directly without pre-refine or verify steps. Use only when tasks are fully refined upfront and independent.

### `/squad-batch-run resume <start-ID> [--auto]`

Resume a stopped batch from the given task ID. Skips all tasks before `<start-ID>`. Resumes with the same mode (rolling wave unless `--big-bang` was set).

---

## Inputs

Task ids are **opaque per-project display strings** (`<KEY>-<seq>`, e.g. `<KEY>-42`) — never positional integers. Select tasks **declaratively**:

- **Explicit id list** — `--tasks "<KEY>-42 <KEY>-43"` (space- or comma-separated). Deduped in first-seen order; resolves current-or-former-key aliases server-side.
- **Composable filters** (AND together) — narrow whichever base is chosen:
  - `--status <todo,impl,...>` — one or more statuses.
  - `--tag <auth,billing>` — match any of the given tags.
  - `--phase <N>` — the `phase:N` tag.
  - `--epic <EPIC-ID>` — expand to that epic's children via the relationships API.
- At least one selector source is required. With only filters (no `--tasks`/`--epic`), the whole board is the base.
- **Numeric ranges are rejected.** Legacy positional selectors (a numeric range `<n>-<m>` / `<n>~<m>`, reverse ranges, or a bare numeric) raise an error pointing at this syntax — per-project display ids make positional ranges meaningless.
- Read `../squad/shared.md` before any API call.
- Invoke `squad-run` and `squad-refine` for each task via the Skill tool when available.
- In Codex environments without the Skill tool, invoke via `$squad-run ...` / `$squad-refine ...` directly.
- Do not emulate or re-implement either pipeline.

## Resources

- Use `scripts/plan_batch.py` to normalize selectors, fetch task metadata, and produce phase-ordered candidates.
- Read `references/parallel-rules.md` when deciding whether tasks are safe to run in parallel.

## Metadata Hints

**Dependencies are structural**, read from the relationships API — NOT text-parsed from descriptions
(the `Depends on:` convention is retired; see `../squad/shared.md` → **Task Relationships & Epics**):

- `GET /api/task/:id/relationships` → `.blocked_by` (the deps that must be `done` (or `cancelled`) first)

Other strong signals still come from task descriptions:

- `Parallel-safe: yes` / `Parallel-safe: no`
- `Touches: browse-data, header-nav`

Fall back to conservative inference from phase, tags, title, and description when hints are absent.

---

## Workflow

### 0. Pre-flight checks

```bash
api GET /board?summary=true > /dev/null   # non-zero exit (auth/transport) → stop
```

- If the board is unreachable: report the error (api.py prints it on stderr; check auth) and stop.
- If `plan_batch.py` fails: report error and stop.

### 1. Resolve project

Read the project name from `.squadrc` (`SQUAD_PROJECT=`) — see `squad/shared.md` for the full resolution (it sources the `api()` wrapper and reads `SQUAD_ORG` env → `.squadrc`; `api.py` owns the PAT internally).

**Observation gate-seam.** Resolve the consent gate ONCE for the whole batch and cache it, so any post-Verify steering emit (step 6C) is consent-gated and best-effort (see `squad/shared.md` → **Abstraction Rubric**):

```bash
python3 ../squad/scripts/observe.py gate >/dev/null 2>&1; OBSERVE_OK=$?   # 0 = emit, non-zero = skip
```

### 2. Plan

**SQUAD_ORG export contract:** `plan_batch.py` reads `SQUAD_ORG` from the **env only** (it does not parse `.squadrc`). Resolve `.squadrc` and `export SQUAD_ORG` before launching it (the shared.md resolution already sets `SQUAD_ORG`) — it selects the tenant via the `/api/orgs/<org>/` path. `plan_batch.py` resolves its own auth + base URL the same way `api.py` does (env `SQUAD_AUTH_TOKEN` / `SQUAD_BASE_URL` > `~/.squad/*`), so no token need be passed on the command line.

```bash
export SQUAD_ORG   # exported from the shared.md resolution (env → .squadrc); selects the tenant via the org path
# Explicit id list, and/or composable --status / --tag / --phase / --epic filters:
python3 scripts/plan_batch.py --project "$PROJECT" --tasks "<KEY>-42 <KEY>-43"
python3 scripts/plan_batch.py --project "$PROJECT" --epic "<EPIC-ID>" --status todo
```

### 3. Read plan

Read the returned task list and proposed groups.

### 4. Validate ordering

- Respect `phase:N` tags when present; prefer phase order over user order if they conflict.
- **Epics are containers, not runnable**: skip any `card_type:'epic'` card with a note (e.g. `⚠ #520 skipped — epic container, run its children`). Epics never enter the runnable set.
- **Non-todo tasks**: skip with a warning line (e.g. `⚠ #502 skipped — status is impl`). If all tasks skipped, stop and report.
- `resume <start-ID>`: skip tasks before that ID silently.

### 5. Decide execution mode per group

- Default: sequential.
- Parallel only if **all** of these are true:
  - Same phase or no phase tag
  - No `blocks` relationship edge between tasks in the group (`.blocked_by` / `.blocking` from the relationships API)
  - Titles/tags/descriptions point to distinct modules or surfaces
  - Failure in one would not invalidate another's work
- If any doubt remains, stay sequential.
- **Rolling wave + parallel**: run refine steps for a parallel group concurrently, then implement concurrently. Verify sequentially.

### 6. Execute — Rolling Wave Loop (default)

For each task N in order:

```
A. Refine(N)
   - Skill(skill="squad-refine", args="<ID>")  [Codex: $squad-refine <ID>]
   - squad-refine auto-detects the prior card via the relationships API (`.blocked_by`) or asks one question.
   - Reads N-1's implementation_notes + actual codebase to ground N's requirements spec.
   - First task in the batch (no prior card): regular user interview.

   Card split check (before invoking squad-refine):
   - If scope exceeds limits (AC > 5, files > 5, multi-layer), split first:
     1. Create sub-cards via squad API
     2. Declare any blocks dependency between sub-cards via `POST /api/task/:id/relationships {to, type:"blocks"}` (NOT a `Depends on:` text line; 409 on a cycle is surfaced, no pre-check)
     3. Replace N in execution order with N-a, N-b, N-c
     4. Report split to user, continue automatically

B. Implement(N)
   - Invoke squad-run (level-aware, see Inner Task Contract)

C. Verify(N)
   - Check actual implementation: git diff, created/modified files, test results
   - Record an activity event: api POST /task/$ID/activity --json '{actor:"Orchestrator", model:"system", message:"Verified: [confirmed interface/schema]"}'
   - Note anything that will affect N+1's refinement scope

→ Move to N+1
```

**Loop exceptions:**
- Split triggered during Refine → insert sub-cards, continue
- Circuit breaker or blocker during Implement → stop, report resume point
- Unexpected design change during Verify → queue a re-refine for downstream tasks (writes a new spec; never patch their `description`); report to user. Also emit ONE abstracted `user_steering` event for the deviation (consent-gated by the cached `OBSERVE_OK`, best-effort; enums per `squad/shared.md` → **Abstraction Rubric**, the batch-run post-Verify row):
  ```bash
  [ "$OBSERVE_OK" = 0 ] && python3 ../squad/scripts/observe.py emit "$ID" --modality corrective \
    --valence negative --target scope --severity major --attributability violated_constraint \
    --comment "verify found a design deviation" || true
  ```

### 6b. Execute — Big Bang mode (`--big-bang`)

Invoke `squad-run` directly per task. No refine or verify steps.
Use only when all tasks were fully refined before the batch started.

**Sequential**: invoke for each task in order.

**Parallel**: invoke for all tasks in the group concurrently.
- Claude: multiple Skill tool calls in one message.
- Codex: multiple `$squad-run ...` only if runtime supports concurrent execution; otherwise sequential.

After parallel group:
```bash
git status --porcelain
git diff --check
```
If conflict markers found: stop, report which tasks conflicted.

After each task or group: re-read task status from API before continuing.

### 7. Stop conditions

- Requirement ambiguity requiring user input
- Repeated review/test failure (circuit breaker inside `squad-run`)
- Conflicting code changes between parallel tasks
- Task exits normal path and needs a product decision
- Parallel group partial failure: wait for in-progress tasks to finish, then stop. Report succeeded vs. failed.

### 8. Early stop summary

- Completed task IDs
- Current blocker and which task caused it
- Resume point: `Resume with: /squad-batch-run resume <next-ID>`

### 9. Completion summary

- Completed IDs in order
- Whether any groups were parallelized
- Key interfaces/schemas confirmed during verify steps (useful for next epic)
- Resulting commits

### 10. Coach (batch-level friction review)

After the completion summary, dispatch the **Coach** at the **batch level** per `../squad/shared.md` → **Coach Dispatch** — judging the batch loop itself (the per-task Coach already fired inside each `squad-run`). batch-run has no model block of its own, so resolve `MODEL_PROVIDER` + the `read_model` / `read_effort` helpers per `../squad/shared.md` → **Model Resolution** first, then pass its batch framing:
- `skill_name` = `squad-batch-run`
- `source_task` = the first batch ID completed this run
- `run_summary` = `"squad-batch-run completed a batch of tasks in rolling-wave order."`
- `trajectory` = batch loop record: completed IDs in order, parallelization decisions, verify-step notes
- `friction_signals` = ordering reworks / stale-assumption refines / stop-condition trips; `none` if clean

---

## Execution Notes

- Be conservative. This skill is for throughput, not shortcuts.
- Never implement a task freehand and patch squad state afterward — drive every task through `squad-run`.
- Treat shared routes, server loaders, types, and top-level navigation as dependency hotspots — keep sequential.
- Re-check the worktree between tasks.
- Only parallelize when the batch planner can justify it in one sentence.
- Rolling wave adds refine+verify overhead per task, but prevents rework from stale assumptions — net faster for epics with inter-task dependencies.

---

## Inner Task Contract

### Refine invocation

```
Skill(skill="squad-refine", args="<ID>")   # Claude
$squad-refine <ID>                          # Codex fallback
```

squad-refine handles prior context detection internally. No extra args needed.

### Implement invocation (level-aware)

| Level | Claude default | Claude `--auto` | Codex default | Codex `--auto` |
|-------|---------------|-----------------|---------------|----------------|
| L1 | `Skill("squad-run", "<ID> --auto")` | same | `$squad-run <ID> --auto` | same |
| L2 | `Skill("squad-run", "<ID>")` | `Skill("squad-run", "<ID> --auto")` | `$squad-run <ID>` | `$squad-run <ID> --auto` |
| L3 | `Skill("squad-run", "<ID>")` | `Skill("squad-run", "<ID> --auto")` | `$squad-run <ID>` | `$squad-run <ID> --auto` |

In default mode, L2/L3 tasks pause for user confirmation at review checkpoints.

### Result verification

```bash
STATUS=$(api GET /task/$ID?fields=status -q status)
```

| Status | Interpretation | Action |
|--------|---------------|--------|
| `done` | Completed successfully | Continue to Verify, then next task |
| `todo`, `plan`, `impl` | Circuit breaker or rejection | Stop batch, report blocker |
| `plan_review`, `impl_review` | Review pending (unexpected in `--auto`) | Stop batch, report |

### Rules

- Never re-implement `squad-run` or `squad-refine`. Always invoke via Skill tool or Codex `$` command fallback.
- Never skip Refine in rolling wave mode — prior implementation context may change scope.
- If a task blocks, status check surfaces it — stop and report exact resume task.
- For parallel groups, issue multiple invocations in a single message.

---

## Output Style

Start with the resolved plan:
- Ordered task list, proposed grouping, mode (Rolling Wave or Big Bang), one-line reason per group, skipped tasks

During execution:
```
Refine  #201 — scope locked (prior: POST /api/items interface confirmed)
Impl    #201 — done (commit: a1b2c3)
Verify  #201 — confirmed: items table schema, POST /api/items → {id, name}
Refine  #202 — scope updated: builds on items table from #201
Impl    #202 — done (commit: d4e5f6)
Verify  #202 — confirmed: ItemCard component at src/components/ItemCard.tsx
...
```

End with batch summary and resume point if stopped early.

