本文へ移動
cccskills
無料GitHub で公開

swarm-dispatch

Execute a swarm plan wave by wave with filesystem isolation via git worktrees. For each wave, main context decides the scenario recipe + implementation contract for every task, then spawns one swarm-worker per task in parallel. Each worker executes its recipe and reports JSON status. Worktree merge-audit verifies write-set discipline before changes land on main. Aborts remaining waves on any audit or task failure.

インストール方法を見る

含まれるファイル(5)

  • SKILL.md14.3 KB
  • parse_worker_result.mjs3.0 KB
  • swarm_merge.mjs6.6 KB
  • swarm_wave_audit.mjs4.2 KB
  • worktree-safety.mjs1.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

swarm-dispatch — wave runner with worktree isolation

Invoked after /swarm-plan + /approve-swarm. The architecture is the user's principle made concrete:

Main context decides. Workers execute.

Per task, before dispatch, you (main context) produce two recipes:

  1. The scenario recipe — exactly which failing tests the worker should write.
  2. The implementation contract — exactly which source files the worker may touch and what behavior they must implement.

The worker's prompt contains both recipes verbatim. The worker invokes Skill(scenario) then Skill(implement) and reports JSON. It makes no design decisions.

Isolation modes

Read project.json → swarm.isolation (default "auto"):

  • "auto" → choose worktree if the project root is inside a git repo (git rev-parse --is-inside-work-tree succeeds), else shared.
  • "worktree" → require a git repo; bail if absent.
  • "shared" → never use worktrees; rely on swarm_boundary_guard for runtime enforcement.

Default path is worktree. The rest of this document describes that mode. The shared fallback is at the end.

Worktree mode = single-wave only (D1). The worktree base commit is chosen by the Agent tool's isolation:"worktree", not by baseline (observed forking from a stale ref on the first real swarm run), and swarm_merge.mjs applies wave output without committing — so a multi-wave worktree plan's wave-N+1 worktrees branch from a base lacking wave-N output. Baseline cannot fix this, only refuse it. Before dispatch, call assertWorktreeWaveSafety({isolation, waves, baselineRef, worktreeBase}) from .claude/skills/swarm-dispatch/worktree-safety.mjs (worktreeBase = git -C <wt> merge-base HEAD <wt-HEAD> once a worktree exists). On ok:false (multi-wave under worktree, or baseline_ref ≠ the worktree's real merge-base), abort and steer the plan to shared isolation — do not run the wave. Multi-wave plans belong in shared mode.

Prereqs (worktree mode)

Verify in order, abort on any failure:

  1. .claude/state/swarm/<slug>.json exists, has status: "planned", and a non-null waves array.
  2. .claude/state/swarm_approvals/<slug>.approval exists and begins with APPROVED.
  3. .claude/state/swarm/active_wave.json does not already exist (stale/racing dispatch — ask before clobbering).
  4. git rev-parse --is-inside-work-tree succeeds at the project root.
  5. Working tree is clean (git status --porcelain empty) if project.json → swarm.refuse_dirty_tree is true (default).

Record the baseline: git rev-parse HEAD → this SHA is the reference every worktree will be compared against at merge time.

Per-wave loop

For each wave in plan.waves, in order:

1. Decide the recipes (main context)

For every task in the wave, produce:

  • Scenario recipe — list of failing tests to write. Each: name, covers, assertion, fixtures. Plus out-of-scope list and test target paths.
  • Implementation contract — failing_tests (the paths the scenario step will produce), write_set (from the plan), behavior contract (the spec's §Behavior excerpts for the task's ACs, plus §Design data model + contracts), project conventions (from project.json).
  • Style anchors — 1–2 existing test files and 1–2 existing source files in the touched modules so the worker matches the project's idioms.

This is where the heavy thinking lives. Do it before dispatch — once a worker is running, the recipe cannot be changed.

2. Park the harness, then raise the barrier

Park first. Write .claude/state/harness_state as {state: "parked", slug, reason: "swarm wave <n> in flight"}. This dispatch owns the session until the wave resolves, and harness_continuation's Path A would otherwise re-fire the loop into a phase whose predecessor is still running — the marker is present by definition, because the wave runs inside an armed loop.

Park is a declaration, not a detector. Nothing infers that workers are running; this skill says so, and says when it stops. Clearing it is step 7's job and is unconditional — see Unparking below.

Then write .claude/state/swarm/active_wave.json:

{
  "slug": "<slug>",
  "wave": <n>,
  "isolation": "worktree",
  "baseline_ref": "<HEAD SHA>",
  "started_at": <epoch>,
  "write_sets": [
    {"task_id": "T-001", "files": [...]},
    {"task_id": "T-003", "files": [...]}
  ]
}

In worktree mode this file is consumed by swarm_merge.mjs (which reads baseline_ref). swarm_boundary_guard is dormant — writes happen inside worktrees that don't contain active_wave.json.

3. Update plan status

Set each wave task's status to "running" inside .claude/state/swarm/<slug>.json.

4. Dispatch the wave

One message, N parallel Agent calls — one per task. Each uses:

  • subagent_type: "swarm-worker"
  • isolation: "worktree"
  • run_in_background: true

Worker prompt template (self-contained — the worker has no memory of this conversation):

You are executing swarm task <T-XXX> from plan <slug>, in your own isolated
git worktree. Your write_set is the ONLY set of files you may modify.

# Task metadata
- task_id: <T-XXX>
- slug: <slug>
- ACs covered: <AC list>
- Component: <component id>

# Spec excerpt (behavior contract)
<paste §Behavior sequences for this task's ACs + §Design data-model/contract
 rows the task touches. Keep under ~200 lines.>

# Scenario recipe — what tests to write
out-of-scope: [<scenarios explicitly NOT to write>]
test target paths: <test file paths>
style anchors: <1-2 existing test files>

scenarios:
- name: test_when_X_then_Y
  covers: AC-001
  assertion: "<one plain sentence>"
  fixtures: [<paths/factories>]
- name: test_when_A_then_B
  covers: AC-002
  assertion: "..."
  fixtures: [...]
- ...

# Implementation contract
write_set (STRICT — anywhere else fails the merge audit):
- <file 1>
- <file 2>
- ...

read_set (advisory):
- <file 1>
- ...

style anchors: <1-2 existing source files>
project conventions:
  test.cmd: <...>
  lint.cmd: <...>
  tdd.test_globs: <...>

# Your job
1. Invoke Skill(scenario) with the scenario recipe + test target paths.
2. If all expected tests are RED, invoke Skill(implement) with the failing test
   paths, the write_set, the behavior contract above, and the project
   conventions. During the RALPH loop run ONLY your own test file
   (node --test <your test target paths>), never the full suite — sibling
   workers run concurrently and a full-suite run races the
   live-objtemplate-rebuild-races landmine; the full suite runs at /integrate.
3. You SHALL complete BOTH step 1 (scenario) and step 2 (implement) before
   reporting. Do not emit a final message until the JSON status line; a
   scenario-only stop is status:failed.
4. Report JSON on your final line per the swarm protocol:
   {"task_id": "<T-XXX>", "status": "done" | "failed",
    "files_touched": [...], "note": "<one short line>"}

The swarm-worker agent's body already knows the protocol. The prompt contains the recipes; the worker executes them.

5. Wait

Do not respond to the user until every task in the wave has completed. Each Agent return gives you the worktree path (if the worker made changes) and the JSON summary line.

5.5 Classify each worker result (D4)

For every worker return, run parseWorkerResult(<final message text>) from .claude/skills/swarm-dispatch/parse_worker_result.mjs (or the CLI parse_worker_result.mjs <result-file>). A worker is complete only when its final non-empty line is a valid {task_id,status:"done"} JSON line. A missing/garbled line, trailing prose after the JSON, or status:"failed" → incomplete: do NOT treat the task as done. Route it to resume-if-possible (re-dispatch / SendMessage where available) else main-context completion from the worker's RED tests. This closes the first-run gap where workers rested after scenario and were silently passed.

6. Per-task merge-audit

For each completed task:

.claude/skills/swarm-dispatch/swarm_merge.mjs \
  .claude/state/swarm/<slug>.json \
  <task-id> \
  <worktree-path>

Outcomes:

  • Exit 0: audit passed, patch applied to main, worktree removed. Update task status: "done".
  • Exit 1: audit failed OR git apply failed. Worktree preserved for inspection. Update task status: "failed" with a note naming the offending file(s).
  • No worktree path returned (worker made no changes): the harness auto-cleans the empty worktree. Mark task per the worker's self-reported JSON.

7. Clear the barrier and unpark

Delete .claude/state/swarm/active_wave.json.

Unparking. Rewrite harness_state back to {state: "continue", slug, reason: "<n> waves done; next: <phase>"} when the plan continues, or to {state: "yielded", slug, reason: "<one sentence>"} when the wave failed and the human must look. Do this on every exit from a wave — success, task failure, audit failure, and an aborted prereq after step 2 ran — so a park never outlives the thing that set it.

If the session dies mid-wave the park stays on disk. That is the correct residue and the reason park beats a background registry: the human returns, types /harness, and preflight rearms. The failure mode is one command, not a loop that spins or a hook silenced with no signal.

8. Decide the wave's fate

  • Every task done → advance to the next wave.
  • Any task failed (worker-reported OR audit failure) → set plan status: "failed", stop, surface the failed task(s) with their note and (for audit failures) the preserved worktree path.

After the last wave

  1. Set plan status: "complete".
  2. Record the Phase-6 completion marker. Append the canonical Phase-6 phase-name "tdd" to workflow.json → completed (alongside the swarm phases already there). The swarm path IS Phase 6 (6a/6b/6c), but track_guard resolves the tdd ordering slot by completed-membership; recording "tdd" is the SOP companion to hooks/lib/track-order.mjs → phaseSatisfied (which also accepts a completed swarm-dispatch) — belt-and-suspenders so downstream phases (/security etc.) are never false-blocked whether or not the guard fix is present.
  3. Run /integrate on the full codebase — per-wave success is necessary but not sufficient; cross-component integration must be re-verified.
  4. If /integrate passes: tell the user "Swarm <slug> complete. <N> tasks across <M> waves. Next: /document."

Shared-mode fallback

When isolation is "shared":

  • No worktrees. Each Agent call uses isolation omitted or "none".
  • active_wave.json carries isolation: "shared" and the union of write_sets (no baseline_ref). At wave start, also record pre_wave_changed — the set of already-changed paths (git status --porcelain) before the wave runs — so the post-wave audit attributes only this wave's changes.
  • swarm_boundary_guard is the runtime enforcer: writes in enforced paths must be in the union of active write_sets, else denied. But the guard exempts .claude/ (D2 blind spot) — so for baseline self-dev under .claude/skills/** it enforces nothing.
  • Post-wave diff-audit (D2). After each shared wave completes, run swarm_wave_audit.mjs <plan-path> <wave-index>. It diffs the wave's actual changes (current git status minus pre_wave_changed) against the union write_set directly — not via the guard's exempt list — so .claude/skills/** drift IS caught. Exit 1 (a path outside the union) → treat the wave as failed: stop, surface the offending paths, do not advance. This is the shared-mode analogue of worktree mode's per-task merge-audit.
  • Cross-task bleed within a wave (two tasks in the same wave writing each other's files) remains a known limitation — the audit catches out-of-union drift, not intra-union misattribution.
  • After each wave: run the post-wave audit, then clear active_wave.json, unpark the harness (step 7), update per-task status from the worker's self-reported JSON (classified via §5.5, D4).

Use shared mode deliberately — it trades real safety (physical isolation) for runtime permissiveness. Worktree mode is preferred whenever git is available.

Failure recovery

  • Unpark before surfacing. A failed wave still leaves the harness parked unless step 7 ran. Write harness_state as yielded with the failure reason so the human is notified and /harness is not needed to get their attention.
  • Plan stays in "failed" state for user inspection.
  • In worktree mode, failed tasks' worktrees are preserved. The user can cd in, read the worker's changes, and either:
    • Manually finish + commit to main, then mark the task done in the plan.
    • Drop the worktree (git worktree remove --force <path>) and re-plan.
  • In shared mode, partial writes may have landed on main. git status shows them; revert or keep as appropriate.
  • Never auto-retry a failed task. Failures warrant human attention.

Constraints

  • Recipes are decided before dispatch. Once a worker is running, you cannot change its recipe. Plan with that in mind.
  • run_in_background: true is mandatory on every Agent call inside a wave. Foreground calls would serialize the wave.
  • isolation: "worktree" is mandatory in worktree mode. Without it, the merge-audit guarantee collapses.
  • One message, N parallel Agent calls. Sequential issuance defeats parallelism.
  • subagent_type is always swarm-worker. No per-stack variants — stack-specific skill loading is handled by the worker template's {{SKILLS}} token at /init-project time, not by spawning different agents.
  • Never touch source files from this skill. This orchestrator only reads and updates .claude/state/. File edits happen inside workers; merges happen via swarm_merge.mjs.
  • active_wave.json lingering after abnormal termination is recoverable: delete it, inspect per-task status, re-dispatch the first incomplete wave.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

archive

無料

Phase 10.5 — move the slug's workflow artifacts (intake, scout, research, spec, approvals, swarm state, security reports, rendered diagrams) to docs/archive/<YYYY-MM-DD>/<slug>/. Runs before /commit so the committed tree is clean of work-in-flight files. workflow.json stays live and gets archived as the first step of /commit.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

Drift check between the baseline implementation on disk and the claims in `docs/init/seed.md` + cross-references in CLAUDE.md, README.md, and the rendered docs site. Verifies hook/agent/skill/command names + counts, settings.json wiring, project.json key presence, .mcp.json servers, vendored license files, and helper script presence. Exit 0 PASS / 1 FAIL — suitable for CI. Read-only; safe to invoke any time.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

PM-mode brainstorm helper. Captures the requirement via Socratic dialogue before any entry phase (`/intake`, `/spec`, `/tdd`) drafts its artifact. Stage 0 skip-check, Stage 1 gap-analysis, Stage 2 probe-loop, Stage 3 confirm-and-persist. Output lives at `docs/brief/<slug>.md`. Never proposes solutions — Stage 2 dialogue discipline is structurally enforced via `discipline.mjs`.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

brd

無料

Draft a Business Requirements Document (BRD) for cross-functional or stakeholder-heavy work that needs more structure than an intake. Use after `/intake` when the request spans multiple systems/teams, carries regulatory weight, or needs formal sign-off. Output lives at `docs/brd/<slug>.md`.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

chore

無料

Workflow track for tasks that need no TDD — documentation edits, governance count bumps, vendored-skill content updates, configuration tweaks, formatting, typo fixes, dependency bumps where no project code changes. Skips `/scenario` and `/implement` (no failing test to drive) and runs the work directly. `archive`, `memory-sync`, `/grant-commit`, and `/commit` remain mandatory. `verify`, `simplify`, `integrate`, and `document` are conditional — required when the diff hits one of the listed triggers, optional otherwise. `verify` is skipped only when the diff is pure-docs/prose AND `project.json → test.kind` is `behavior` (absent/invalid `test.kind` → `structural` → verify runs). Chore is a stripped-down pipeline, not a bypass; never silently skip a conditional phase whose triggers apply.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

Analyze a codebase and recommend Claude Code automations (hooks, subagents, skills, plugins, MCP servers). Use when user asks for automation recommendations, wants to optimize their Claude Code setup, mentions improving Claude Code workflows, asks how to first set up Claude Code for a project, or wants to know what Claude Code features they should use.

日本語の概要は準備中です。原文の説明を表示しています。

friedbotstudio/baseline142026年9月9日 更新

friedbotstudio のスキルをすべて見る

このスキルの問題を報告する