execute-batch-parallel
Skill0 starsChanged 6 months agoMITView on GitHub
Execute one "chat" from an Implementation Strategy by fanning out one scoped sub-agent per Ready story IN PARALLEL, then reconciling the board once on the main thread. Use when the user invokes /tandem:execute-batch-parallel with a chat id (e.g. CHAT-02), or asks to run a batch of independent stories concurrently. Operates as Dev/QA hat. Refuses to fan out unless the batch is provably file-disjoint (pm:batch-check, ADR-0075) and every story is DoR-ready — otherwise falls back to serial execute-batch. This command DOES change story status.
In this repository32 other files it gives its agents.
- _00-Project-Management/CLAUDE.mdCLAUDE.md
- autopilotSkill
- close-out-storySkill
- close-phaseSkill
- coreSkill
- critiqueSkill
- curate-toolkitSkill
- documentSkill
- draft-epicSkill
- draft-okrsSkill
- draft-prdSkill
- execute-batchSkill
- execute-storySkill
- execution-strategistSkill
- fill-claude-mdSkill
- installSkill
- modeSkill
- monthly-retroSkill
- path-scope-exampleSkill
- peer-reviewSkill
- plan-driftSkill
- refine-backlogSkill
- reflectSkill
- run-testplanSkill
- session-startSkill
- split-into-featuresSkill
- split-into-storiesSkill
- start-phaseSkill
- triage-backlogSkill
- updateSkill
- weekly-monitorSkill
- write-outcomesSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Use Read / Glob; treat missing files as "not present", never throw.
- Very specific: line 46
DoR precheck: Every story in the chat must be status: ready.
- Very specific: line 49
Disjoint-file precondition (
pm:batch-check, ADR-0075): Run the static batch-check over the batch's stories: - Very specific: line 59
Only a provably disjoint batch (exit 0) may run in parallel.
- Distinctive: line 86
Every dispatched prompt is built from this template — the *exclusions are load-bearing*:
- Distinctive: line 121
After all sub-agents return, the main thread alone folds the handoffs onto the board in one ordered pass.
- Very specific: line 131
Collect: every story's structured handoff (from Step 3).
- Very specific: line 161
Per-story commit checkpoint: Commit each finalised story (STORY-NN.M.PP — <imperative>) so a crashed batch leaves completed stories …
- Distinctive: line 204
After reconciliation completes, append the chat-level retro ledger line (SOP §14.1) — from the main thread, never from a lane.
- Distinctive: line 239
When every chat in the phase is executed, close the phase (retrospective + gated merge).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Tandem: execute-batch-parallel (Dev/QA hat)
Operate as Dev/QA hat in a fresh chat. This is the concurrent sibling of
execute-batch: where execute-batch runs a chat's stories one-at-a-time, execute-batch-parallel
fans out one sub-agent per story so a batch of independent stories clears in a single chat,
then folds every result back onto the board in one serialised reconciliation pass on the main
thread.
It is built against the settled concurrency model in ADR-0075 — sub-agents-with-merge under a
disjoint-file precondition, main thread as sole writer of serialised state. It composes the
existing per-story skills (execute-story, run-testplan, close-out-story); it does not
re-implement their logic, and it never relaxes the kit's gate contract (status enum, atomic
flip, ADR-on-the-spot, BUG-on-defect).
Default is still serial. Parallel fan-out is opt-in and earned by precise metadata. If a batch cannot be proven file-disjoint, this skill refuses and the operator runs the serial
execute-batchinstead. A batch that cannot be proven safe is treated exactly like an unsafe one.
Inputs needed
- A chat id — e.g.
CHAT-02. If the user didn't supply one, ask, or list the chats in the latest strategy. - The strategy — default to the latest
_00-Project-Management/41-Reports/EXECUTION-STRATEGY-*.json. Fall back to the paired.mdreport if the JSON is absent. The user may name a specific file.
Load into context
Use Read / Glob; treat missing files as "not present", never throw.
- The named chat from the latest
EXECUTION-STRATEGY-*.json: itsstories(withreadyflags),lanes,verifycommand,sub_agents, andexecutedflag. - Each story + its paired testplan under
32-Stories/+33-Testplans/. - SOP —
90-Standards/SOP.md(DoR/DoD, status enum, WIP limits §5, parallel-vs-serial rule). - ADR-0075 — the concurrency model this skill obeys.
Step 1 — Safety gate (refuse BEFORE any fan-out)
The gate runs before a single sub-agent is dispatched. All of the following must pass; on any
failure, do not fan out — report the failing item and fall back to serial execute-batch:
- DoR precheck. Every story in the chat must be
status: ready. If any story isready: falsein the strategy or notreadyin its frontmatter, refuse and name the unready story — it isunsafeto start. (The operator runs/tandem:refine-backlogfirst.) Disjoint-file precondition (
pm:batch-check, ADR-0075). Run the static batch-check over the batch's stories:node _00-Project-Management/93-Scripts/batch-check.js STORY-A STORY-B STORY-CIt compares every pair's
files_touched:. ACONFLICT(two stories write the same file, or a file under another's directory) or anyUNKNOWN(directory×directory, or empty/absentfiles_touched:— cannot prove disjoint) is a hard stop: the batch is not fanned out. Only a provably disjoint batch (exit 0) may run in parallel.UNKNOWNnever silently passes. Fail closed: any non-zero exit — a conflict, an unknown, or a batch-check script error — blocks fan-out and falls back to serialexecute-batch; the gate never reads a crash as "safe".
The refusal path precedes the fan-out: the skill computes the gate, and only a clean gate unlocks Step 2.
Step 2 — Fan-out: one scoped sub-agent per story
On a safe batch, dispatch one sub-agent per story, concurrently (a single message with one
Agent call per story so they run in parallel). Each sub-agent is tightly scoped to its own
story and is structurally unable to corrupt shared state:
- Scope = one story only. The sub-agent's prompt contains only that story file, its paired
testplan, and that story's ACs. It implements that story's ACs (using the chat's resolved
sub-agent discipline for that story, e.g.
mcp-developer/build-engineer), runs its testplan TCs, and records AC pass/fail — and nothing about any sibling story. - Board files are FORBIDDEN. The sub-agent prompt explicitly says never MONITOR / ACTIVE: the
sub-agent must not read or write
MONITOR.md/ACTIVE.md, and must not create ADR/BUG files or claim an ADR/BUG number. Sub-agents never write serialised state — that is the main thread's job alone (ADR-0075 single-writer). A sub-agent that thinks it needs an ADR/BUG proposes the body in its handoff; it does not number or file it. - No cross-story coordination. Because the batch is provably file-disjoint, the sub-agents work in the shared tree with no content collision; they do not need to talk to each other.
Sub-agent prompt template (the safety boundary)
Every dispatched prompt is built from this template — the exclusions are load-bearing:
You are implementing exactly ONE story: STORY-NN.M.PP.
Inputs (the ONLY files you own): <story path>, <paired testplan path>.
Write ONLY the files listed in this story's files_touched: <files_touched list>.
Do: implement each AC; run every testplan TC's Command; record PASS/FAIL per TC and per AC.
Do NOT touch MONITOR.md or ACTIVE.md (forbidden);
do NOT create or number any ADR-*/BUG-* file; do NOT edit any sibling story.
If the work requires touching ANY file outside files_touched, STOP and report it in the
handoff — do not create or edit it (an undeclared write breaks the disjoint-file guarantee).
Return: the structured handoff described below — raw data, not prose for a human.Step 3 — Structured handoff (sub-agents return data, not board writes)
Each sub-agent returns a structured handoff that the main thread later reconciles (the reconciliation pass itself is defined in the next section). Returning data — rather than writing shared state — is what keeps fan-out race-free. The handoff shape per story:
story_id— the story it worked.status_flip_proposal— proposed terminal status (done, orin-progressif a DoD/TC failed) plus thecompleted_atit would stamp. The main thread, not the sub-agent, applies the flip.ac_verification_log— each AC with PASS/FAIL and the evidence (the TC command output).testplan_results— each TC id → PASS/FAIL (+ the failing output if any).proposed_adrs— zero or more draft ADR bodies (title + content) for non-obvious decisions, un-numbered (the main thread assigns the sequentialADR-NNNN).proposed_bugs— zero or more draft BUG bodies for any TC failure / defect, un-numbered (the main thread assigns the sequentialBUG-YYYYMMDD-NN).files_changed— the files the sub-agent actually wrote (for the reconciliation commit).
The main thread collects every story's handoff and applies them in one ordered pass (next section).
Step 4 — Reconciliation (single-writer, serialised)
After all sub-agents return, the main thread alone folds the handoffs onto the board in one ordered pass. Sub-agents proposed; the main thread disposes. This is the single-writer contract of ADR-0075 — there is exactly one writer of serialised state, so nothing races.
Reconciliation order (deterministic — apply in this exact order)
Process the collected handoffs in deterministic story order (the chat's listed order), and within that, in these stages — first collect, then number, then flip, then write the board, then commit:
- Collect every story's structured handoff (from Step 3). Partition into succeeded (proposes
done, all ACs/TCs PASS) and failed (any AC/TC FAIL or DoD gap). - Assign sequential IDs (main-thread-only). For every
proposed_adr/proposed_bugbody, the main thread computes the next free number at write time by globbing the existingADR-*/BUG-*files — never a number pre-assigned during fan-out — so two stories can never collide on the sameADR-NNNN/BUG-YYYYMMDD-NN. Numbers are allocated in story order, then the files are written by the main thread. Run the per-story DoD gate, then apply atomic status flips. A story only flips to
doneonce its Definition-of-Done gate passes — the main thread runs the same DoD checksclose-out-storywould (AC verification against the handoff'sac_verification_log+ testplan PASS + the R14 AI-code review for that story's diff). Only the board write (stage 4) is batched to once; the DoD gate still runs per story. For each story that passes, flipready → done(the story wasreadyon the board through fan-out — the in-progress work happened inside its sub-agent), setting bothstarted_atandcompleted_atin a single edit (atomic — status + both timestamps together, never half-flipped, never adonestory with an emptystarted_at). This matches ADR-0077'sready → in-progress → donelifecycle, collapsed into one atomic write at reconciliation. For each failed story (DoD gap, TC FAIL, or no usable handoff), see partial-failure handling below.Per-item retro ledger line — run it here, once per flip. Because this stage re-implements the close-out gate rather than delegating to it, the item-level ledger line would otherwise never be written on the parallel path, and the level would be silently empty for every fanned-out batch. So: for each item that flips to
done, runclose-out-storystep 5's capture command verbatim, substituting that item's values. Do not restate the command here — it is defined in exactly one place on purpose (SOP §14.1), and a second copy is precisely the drift that rule exists to prevent. This is a side-effect, not a gate: it never blocks a flip.- Write the board once —
MONITOR.md+ACTIVE.md. A single (once)MONITOR+ACTIVEwrite covers the whole batch — one revision-history block for every shipped story, one ACTIVE update — not once per story. Only this board write is batched; the per-story DoD gate in stage 3 is not. Single writer + single write = no interleaving. - Per-story commit checkpoint. Commit each finalised story (
STORY-NN.M.PP — <imperative>) so a crashed batch leaves completed stories committed anddone(retained fromexecute-batch).
Partial-failure handling (honest reporting)
A batch where some sub-agents fail must not abort the successful ones:
- A failed story is flipped
ready → in-progress(setstarted_at, leavecompleted_atempty) and leftin-progress(recoverable — never half-flipped, never silentlydone), with a one-line note of why; its proposed BUG body is filed (numbered by the main thread). - A story whose sub-agent returned nothing or a garbled handoff (crash, timeout, or a terminal API error after retries) is treated exactly like a failed story — never silently dropped: left recoverable and named in the shipped-vs-not split below, so the operator always sees it.
- The succeeded stories still finalise to
doneand commit — the failure of one does not roll back the others. - The run reports the split: which stories shipped vs which did not, plus the chat id to resume. Honest partial success beats an all-or-nothing abort.
Two batches back-to-back must not double-count MONITOR's shipped totals — the count blocks are regenerated by
pm:monitorfrom frontmatter (the source of truth), not incremented by hand.
Step 5 — Guardrails (WIP limit + DoR refusal)
Batch mode must never quietly break the kit's own gate contract. Two guardrails sit on top of the safety gate (Step 1):
- DoR refusal (hard stop). The skill will not start a batch if any story has unmet DoR — it
refuses and names the failing story and the specific missing DoR item (e.g. "STORY-17.1.09
— no paired testplan"). An unready story is never fanned out; the operator runs
/tandem:refine-backlogon it first. (This is the Step 1 DoR precheck, restated as a guardrail: refuse, don't degrade.) - WIP-limit interaction (preserve, do not raise — ADR-0077). Batch-parallel preserves the SOP
§5
in-progressWIP limit (max 2) unchanged — it does not raise the limit. This is safe at any fan-out width because fan-out consumes zero WIP slots: sub-agents work in isolation and never flip board status, so stories stayreadyuntil the serialised reconciliation flips them one at a time (boardin-progress≤ 1 during the pass). The only WIP risk is failed stories leftin-progress; to honour the cap, at most §5-limit (2) failed stories stayin-progress; any excess failures are setblocked(recoverable, with a note). Batch width is bounded by the soft batch-size limit (ADR-0026), and a batch beyond that bound queues — distinct from the WIP cap. See SOP §5 + ADR-0077.
Retro capture
After reconciliation completes, append the chat-level retro ledger line (SOP §14.1) — from the main thread, never from a lane. Always exits 0, never blocks the chat; skip silently if the script is absent.
node _00-Project-Management/93-Scripts/retro-capture.js --level chat --id <CHAT-NN> --phase <EPIC-NN> [--stories <n>] [--halts <n>] [--lanes parallel] [--wall-clock-s <n>] [--dispatch-overhead-s <n>] [--fallback-fired|--no-fallback-fired] [--friction "…"] [--artefact-gap <ID>] [--kit-signal "…"]--lanes parallel— the one field that distinguishes this command's line fromexecute-batch's, and the whole point of capturing it: it is what lets the rollup compare the two lane strategies.--fallback-firedwhen the ADR-0081 nesting wall forced the orchestrator to run a chat itself in the main thread instead of dispatching it.--dispatch-overhead-scovers fan-out and the serialised reconciliation, which is where this command's overhead actually lives.- Sub-agents write no ledger lines. Lanes never flip board status, and capture follows the same single-writer rule as reconciliation.
- This section covers the chat level only. The per-item lines are written during reconciliation stage 3, one per flip — see Step 4. Both come from the main thread.
Output rules
- Status changes are THIS command's job (it is not dry-run — that's
execution-strategist). - Per-story commit messages:
STORY-NN.M.PP — <imperative>(applied by the main thread in reconciliation, not by the sub-agents).
Relationship to subagent-per-batch (sequential-across-phase)
This skill's fan-out is the parallel-within-batch axis (concurrent lanes, disjoint-file safety) — distinct from, and composable with, the sequential-across-phase subagent-per-batch pattern in SOP §18, which chains whole chats one at a time across a phase.
Next command
Next: /tandem:close-phase
When every chat in the phase is executed, close the phase (retrospective + gated merge). Do
not hand a finished batch to run-testplan — the lanes above already ran every story's
testplan inside the fan-out; re-running them after the batch does each step twice.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

