wgm CLI reference: swarm.sh

August 20, 2026 · View on GitHub

scripts/swarm.sh fans the Ralph loop out across parallel streams, each isolated in its own git worktree on its own branch so they never collide. Each stream runs scripts/loop.sh build. When the streams finish, you review and merge the branches yourself.

Note: This is parallelism across tasks. It is distinct from the role swarm — the twelve role-specialized subagents described in subagents, which is parallelism across reviewer roles within one task.

Syntax

WGM_SKILL_ROOT="${WGM_SKILL_ROOT:-$HOME/.agents/skills/wgm}"
"$WGM_SKILL_ROOT/scripts/swarm.sh" --tasks FILE [FLAGS] -- AGENT_ARGV...
"$WGM_SKILL_ROOT/scripts/swarm.sh" -n COUNT     [FLAGS] -- AGENT_ARGV...

Run the installed skill path from the target project's root. A checkout-local ./scripts/swarm.sh also works when you are developing wgm itself.

Before you begin

  • The project must be a git repository with an IMPLEMENTATION_PLAN.md in the root or .wgm/. Run /wgm plan first if you do not have one.
  • Configure an agent, either with $WGM_AGENT or as argv after --.
  • Partition your work into disjoint slices. This is not optional advice — see Partitioning rules.

Flags

FlagDefaultDescription
--tasks FILEOne stream per non-empty, non-# line. Each line becomes that stream's --request scope.
-n, --count NRun N identical streams. Ignored when --tasks is given. Useful for racing or diversity.
--max-iterations N0Per-stream iteration cap. 0 runs until each stream self-stops.
--prefix NAMEwgm/swarmBranch and worktree name prefix.
--worktree-dir DIR.wgm/worktreesBase directory for the worktrees. Gitignored by wgm.
--cleanupoffRemove the worktree directories when done. Branches are kept for merging.
--dry-runoffPrint the plan; create no worktrees and run nothing.
-h, --helpShow usage.

Everything after -- is forwarded verbatim to each stream's loop.sh. Streams always run with --commit, so each branch carries its work.

Partitioning rules

These are defaults that materially affect whether a swarm succeeds.

RuleWhy it matters
Give every stream a disjoint, non-overlapping file setDisjoint lanes make consolidation an octopus merge with zero conflicts. Overlapping lanes risk something worse than a conflict: one lane silently reverting a sibling's edits.
Size the swarm to your host's concurrency cap, and treat the remainder as backfillHosts cap concurrent background agents. N lanes does not mean N simultaneous agents; queued lanes should start as running lanes go idle.
Prefer a full-shell agent for lanes with nested-path deliverablesA constrained file-writer that cannot create intermediate directories does not fail loudly. It flattens paths, hides content in bootstrap scripts, and stops committing.
Run the consolidation gate after mergingCross-link integrity and UTF-8 double-encoding are defects no single lane can see. scripts/check-docs.sh catches both.

Lane safety

Each lane's request is pinned to its absolute worktree path and expected branch, and the lane refuses to run if the guard finds it anywhere else.

Caution: This guard exists because of a real failure. In a 32-lane run, several lanes executed git from the parent checkout on a later turn and one advanced local main. If this happens to you, never repair it by discarding commits — preserve reachability first (keep the accidental commits on the intended branch plus an explicit recovery branch), then restore the intended checkout.

Telemetry output

After the streams finish, swarm.sh prints a == swarm telemetry == block. It reports three clocks that must never be conflated:

MetricMeaningHonest label
wall time (parent)Parent elapsed, frozen at the ready-to-test gateExact
lane time (allocated)Sum of lane lifetimesCapacity upper bound — includes parked time
agent time (active)Sum of per-turn durations from the lanes' ledgersMeasured lower bound
parked timeAllocated minus activeReal capacity, but not work
peak concurrencyMost lanes alive at any one instantExact
critical pathThe longest single laneExact
lifecycle effectivenessactive ÷ wallOperational heuristic
implementation parallelismallocated ÷ longest laneOperational heuristic

Caution: Never call parked-lane lifetime "agent-hours." A lane alive between turns still burns lifetime, so summing lifetimes and dividing by wall time produces a flattering number that is not work done. Both ratios are operational heuristics from one run — not billing data, and not a causal speedup claim. See Telemetry.

Per-lane ledgers are written to .wgm/metrics/PREFIX-N.tsv in the parent worktree, so the summary survives --cleanup removing the lane's worktree.

Merging and cleanup

To merge a stream's work:

git merge wgm/swarm/1

To drop a stream you do not want:

git worktree remove .wgm/worktrees/wgm-swarm-1
git branch -D wgm/swarm/1

To clear one leftover worktree and branch:

git worktree remove --force .wgm/worktrees/wgm-swarm-1
git branch -D wgm/swarm/1

For the wgm source checkout, make clean-worktrees remains a convenience wrapper around this target-project-independent Git cleanup.

After every run

swarm.sh always consolidates each stream's .wgm/memories.md back into the invoking worktree, then hands the result to scripts/harvest-hive.sh. That dispatch is unconditional and safe to ignore: the courier owns every consent and anonymization decision itself, and a harvest hiccup never fails the swarm. See Self-improvement.

After each lane exits, swarm.sh verifies the artifact rather than trusting the process status: status=ok, commits=0 is converted to a hard failure. Read the corresponding .wgm/swarm-logs/ entry, fix the agent's write/tool permission or task scope, and rerun before merging any branch.

Exit codes

CodeMeaning
0Every stream finished successfully.
1One or more streams failed (see .wgm/swarm-logs/*.log), a lane produced zero commits, or no streams started.
2Misconfiguration: not a git repository, bad flag, missing --tasks file, or no agent configured.

What to do next