agentleFS
dork-labsdork-labs/dorkos/.claude/skills/orchestrating-parallel-work/SKILL.md

orchestrating-parallel-work

Skill11 starsChanged 49 days agoMITView on GitHub

Orchestrates parallel execution of AI agents with dependency analysis, batch scheduling, and the playbook for landing many branches at once. Use when coordinating multiple concurrent tasks, optimizing task ordering, sequencing batches of code changes into waves, landing parallel branches through review and merge, or rebasing a branch that fell behind other in-flight work.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 8 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Keep batches to 3-5 agents.

    line 82
  2. Distinctive:

    Before dispatching anything, annotate every batch with the collision classes it touches — the directories, shared primitives, user-visible …

    line 115
  3. Distinctive:

    Same-domain sweeps travel together: All the copy edits in one wave, all the layout fixes in another.

    line 123
  4. Distinctive:

    Same-surface tickets land as one PR or a strict sequence: When two or more tickets touch one component family or surface, batch them into a …

    line 130
  5. Distinctive:

    Check load-sensitivity before debugging a red test: Before spending a cycle on it, check the tells: it passes in isolation but fails in the …

    line 168
  6. Very specific:

    Format as the last step before every push: Run the formatter over the full changed set (git diff --name-only origin/main...HEAD) …

    line 189
  7. Distinctive:

    Rebase deliberately: When a branch falls behind, resolve to both intents — the incoming change and yours — rather than picking a side by …

    line 212
  8. Distinctive:

    Read each result for reported failures or blockers before starting dependent work

    line 312
  9. Distinctive:

    Keep users informed: say what you launched and why ("Launched 3 agents: client hooks, SSE research, server routes"), then summarize each …

    line 329

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Orchestrating Parallel Work

Overview

This skill provides patterns for coordinating parallel subagent execution in Claude Code workflows. Apply these patterns when tasks can run simultaneously without interdependencies — parallel fan-out saves wall-clock time and keeps large intermediate output out of the main context.

When to Use

  • Launching multiple research or exploration agents
  • Implementing features with independent subtasks
  • Running diagnostics that check multiple layers
  • Processing batch operations with dependency graphs
  • Any workflow where "wait for A, then start B" isn't required

Key Mechanics

The Agent tool spawns a subagent with its own isolated context:

  • Parallel launch: to run agents concurrently, send multiple Agent calls in a single message. Each call takes description, prompt, and subagent_type.
  • Results: the agent's final message comes back as the tool result. It is not shown to the user — relay what matters.
  • Background mode: run_in_background: true returns immediately; the main conversation continues and completion arrives as an automatic task notification. No polling API exists — you are re-invoked when the agent finishes.
  • Follow-ups: SendMessage (addressed by the agent's ID or name) continues a previously spawned agent with its context intact. A fresh Agent call starts from zero.
  • Isolation: isolation: "worktree" gives an agent its own git worktree — required when parallel agents mutate tracked files.

Decision Logic

Should I Parallelize?

  1. Are tasks independent? → If no, use sequential
  2. Will each task take >30 seconds? → If no, sequential might be faster
  3. Do agents need each other's output? → If yes, use batched approach
  4. Will agents edit the same files? → If yes, must be sequential (or isolated worktrees)

Choosing the Pattern

SituationPattern
2-5 independent research/analysis tasksParallel Fan-Out
Many tasks with known dependenciesDependency-Aware Batching
Long-running work alongside interactive workBackground Agents + Notify

Core Patterns

Pattern 1: Parallel Fan-Out

For 2-5 independent tasks that don't share state. Launch all agents in one message; their results come back together.

# One message, three Agent calls — they run concurrently
Agent(description: "Survey client hooks", prompt: "...", subagent_type: "Explore")
Agent(description: "Research SSE reconnect", prompt: "...", subagent_type: "research-expert")
Agent(description: "Map server routes", prompt: "...", subagent_type: "Explore")

# Each tool result is that agent's final report — synthesize them

Give each agent a self-contained prompt (it cannot see the conversation) and tell it exactly what shape of answer to return.

Pattern 2: Dependency-Aware Batching

For tasks with dependencies where some can still run in parallel. Group tasks into batches by their dependency edges; each batch is a parallel fan-out, and the next batch starts only after the previous one's results are in.

batches = analyze_dependencies(tasks)
# e.g., [[1,2,3], [4,5], [6,7,8]] — 3 batches

for batch in batches:
  # Launch every task in the batch as Agent calls in ONE message
  # Wait for all results (they arrive as the tool results)
  # Check each result for failure before starting the next batch

Rules for building batches:

  • A task joins a batch only when everything it's blocked by is in an earlier batch
  • Tasks touching the same files never share a batch (or get isolation: "worktree")
  • Keep batches to 3-5 agents; split bigger groups

Pattern 3: Background Agents + Notify

For heavy work that shouldn't block the conversation.

# Returns immediately with an agent ID
Agent(
  description: "Deep audit of session storage",
  prompt: "...",
  subagent_type: "general-purpose",
  run_in_background: true
)

# Keep working — validation, prep, user conversation.
# A task notification re-invokes you when the agent completes.
# Use SendMessage with the agent's ID/name for follow-up questions
# without losing its accumulated context.

Note: the /flow engine's DECOMPOSE/EXECUTE stages apply these batching patterns, but flow lives in the external marketplace plugin (dork-labs/marketplace, plugins/flow/), not this repo.

Landing Parallel Batches

The patterns above cover fan-out. When the parallel work is code that has to reach main, fan-out is the easy half: the branches then have to survive each other, review, and the merge queue. This playbook is what a 20-batch programme of concurrent branches taught (167 findings, 2026-09); it assumes a repo where every change lands via PR.

Sequence batches by collision class

Before dispatching anything, annotate every batch with the collision classes it touches — the directories, shared primitives, user-visible strings, and config files it will edit — and order the waves from that annotation, not from priority:

  • Foundation first. Shared primitives, design tokens, and other code many batches build on go in an early wave, so later batches build on the new version instead of racing it.
  • Same-domain sweeps travel together. All the copy edits in one wave, all the layout fixes in another. Their conflicts are then resolved once, between siblings that know about each other, rather than repeatedly against strangers.
  • Dependents after their dependency. A batch that consumes another batch's output waits for it, exactly as in Pattern 2.
  • File moves and renames last. A move collides with every branch that has the file open, and it is the one change that cannot be rebased cheaply.
  • Same-surface tickets land as one PR or a strict sequence. When two or more tickets touch one component family or surface, batch them into a single PR, or cut the second branch from the first's final merged SHA rather than its in-flight tip — a same-surface stack rebased later always costs more than sequencing up front.
  • Cap concurrency. The 2026-09 programme held at four live worktrees; past that, rebasing cost more than the parallelism bought. Pick a ceiling from your own machine and orchestrator, and hold it.

The per-batch chain

Each batch runs the same chain, and no step is optional:

  1. Worktree from origin/main, one per batch (isolation: "worktree", or an explicit worktree the agent is told to work in). Never two agents in one checkout. The base rule, the port model, and the cleanup protocol belong to the working-in-worktrees skill (/worktree:create); this playbook adds nothing to them.
  2. Implement with a self-contained brief: the task list verbatim, the verification commands, and the constraint that the agent touches nothing outside its batch.
  3. Verify locally — targeted tests for every package touched plus every test that renders a changed component, typecheck and lint per package, and for UI work, drive the real surface rather than trusting the unit tests.
  4. Adversarial review before the PR opens. A separate agent reviews the branch against the repo's review rubric — in this repo REVIEW.md — and the brief names the failure modes to hunt (REVIEW.md → "Failure modes worth hunting by name"). A generic "review this branch" finds nothing; the named shapes found roughly forty-five real defects pre-PR. The implementer fixes; the reviewer re-verifies its own findings rather than accepting the fix report.
  5. Finalize — fragment, labels, push, PR. The mechanics (when a changelog fragment is owed, what skip-changelog / review:light / review:deep mean, review-before-open ordering, and how auto-merge behaves) belong to the creating-pull-requests skill. What this playbook adds is below.

Landing rules

  • Check load-sensitivity before debugging a red test. Before spending a cycle on it, check the tells: it passes in isolation but fails in the full run; the assertion is about timing, throughput, or sample counts rather than behavior; the failure text names milliseconds, wall-clock boundaries, or "expected N samples"; the file is in the known flake family (harness atomic-write AP-10's sample-throughput guard, MIN_SAMPLES fixed at 200; RoomLiveLane's wall-clock boundaries; agent-activity's teardown timing; palette-scope-chips, DOR-1502). A load-starved guard refusing to conclude is not a defect in your branch — re-run once before spending a cycle, and if it repeats, it belongs to the test's owner, not your PR.
  • A commit either isn't user-facing, or fills its own stub. A commit that is genuinely not user-facing — a review-nit fold, a refactor, a CI tweak — takes a chore( or ci( subject, so the populator mints no stub at all. A user-facing commit curates its seeded stub in the same commit that creates it (rewrite the bullet for a human, delete the seeded comment) rather than leaving it for CI to catch; if a curated fragment for the batch already exists, fold the stub's covers: line into it byte-for-byte — matching the commit subject exactly, since a missing ticket suffix breaks coverage — and delete the stub. Five PRs failed the fragment-present gate this way in one week (#1510, #1567, #1581, #1618, #1700). Mechanics: creating-pull-requests skill and changelog/README.md#seeded-fragments.
  • Format as the last step before every push. Run the formatter over the full changed set (git diff --name-only origin/main...HEAD) immediately before pushing, and again after any hand-resolved conflict. In this repo the pre-push hook now checks that same set and prints the exact pnpm exec prettier --write <files> line (scripts/pre-push-format-check.sh, DOR-1839) — it deliberately never writes, so running the formatter yourself is still the only thing that fixes it, and doing it first is how you skip the refusal. A worktree with no node_modules fails that hook; install before you push rather than reaching for --no-verify.
  • Verify the merge is armed or queued; never assume either way. How auto-merge behaves — that a new commit drops the armed state on every push, that the strategy flag belongs to the queue, that arming follows review — is the creating-pull-requests skill's, and it is the one to read. The parallel-specific delta is the check: after arming, confirm one of two things is true — the PR reports an auto-merge request, or it appears in the merge queue. A queued PR reports no auto-merge request, so the first field alone answers wrongly. A zero exit proves nothing, and the request silently no-ops while mergeability is unknown. In this repo a janitor (merge-tail.yml) also arms finished PRs on a 10-minute tick, so the population that actually strands is the one it skips by design — unresolved review threads, any check pending, failing or cancelled, a hold/wip/blocked label, a conflicting tree, unknown mergeability (scripts/should-arm-automerge.sh names each reason). Straight off a push, most PRs are in that set.
  • Rebase deliberately. When a branch falls behind, resolve to both intents — the incoming change and yours — rather than picking a side by reflex; when one side deleted what the other edited, the deletion wins, and the edit's intent gets re-applied elsewhere if it still matters. Then run the full suite (pnpm test -- --run here — the pre-push hook runs affected-only, and a bare vitest full run skips the per-package env turbo sets up), because semantic conflicts carry no markers and nothing else will tell you that your renamed string broke another branch's assertion. A conflicting PR runs no CI at all, so after resolving, re-push and re-request the review that never ran. When the fallen-behind branch is a stacked PR rebasing onto its own now-merged predecessor, take the predecessor's merged state as the base and re-apply the stacked change on top rather than resolving hunk-by-hunk — treat each component and its test as one indivisible unit, because a mixed-side resolution produces a green suite asserting a contract the code no longer implements.
  • Test-merge before trusting two in-flight branches together. Once your branch is in the merge queue this is structurally handled — the queue builds and tests your PR on top of main plus everything ahead of it. Before that, do it by hand from the branch:

    git merge --no-commit --no-ff origin/main   # or the other branch's ref
    pnpm test -- --run                          # the full suite, on the combined tree
    git merge --abort                           # throw the trial merge away

Rolling dispatch, load-aware

Waves are a scheduling model, not a batching requirement. Prefer rolling dispatch: when one batch lands, top the pool back up to its ceiling rather than waiting for a whole wave to drain. Two conditions on that:

  • Check machine load before topping up. Other agents and the operator's own dev servers share the machine; an over-subscribed machine starves hooks and turns green work red. If load is high, hold the slot.
  • Reuse veterans for repeat rebases. Continue the agent that already owns a branch (SendMessage) instead of spawning a fresh one — it holds the conflict history a new agent would have to rediscover.
  • Give push-capable agents foreground-only instructions. An agent that backgrounds a long command and then waits for a notification stalls indefinitely; tell it to run gates in the foreground.
  • Never stop a process you did not start, and never by name — see the process rule in AGENTS.md.

Close-out discipline

  • Keep a follow-ups ledger during the run. Anything deferred, out of scope, or larger than its batch gets written down the moment it is found, with enough context to act on later.
  • File the ledger before declaring the programme done. An unfiled follow-up is a lost one; every entry becomes a real tracker issue with its evidence.
  • Remove a worktree only once its content is provably on main. "The PR was green" is not proof, and neither is "it merged" on its own — a squash rewrites history, so the test is that the PR merged and the branch tip is still the commit that merged (anything pushed after the merge is not in main). In this repo /worktree:prune and scripts/should-reap-worktree.sh make exactly that decision; use them rather than eyeballing it, and never remove a worktree holding uncommitted or unpushed work.

Non-normative: this playbook is written against the Agent tool so it works in any harness that can spawn a subagent — and runs the same way sequentially, one batch at a time, in a harness that spawns none. A session orchestrator that can drive several sessions at once parallelizes the same method without changing any of it.

Worktrees vs Subagents

They solve different isolation problems and compose: a subagent with isolation: "worktree" gets a throwaway worktree for collision-free parallel edits.

ScenarioWorktreeSubagent
Different branchesYesNo
Full build isolationYesNo
Mutating files in a shared checkoutYesNo
Long-running dev server neededYesNo
Same branch, parallel readsNoYes
Quick analysis or researchNoYes
Shared mutable state is fineN/AYes (sequential)

Rule of thumb: worktrees give process-level isolation for code work; subagents give an isolated context for reads, research and analysis on the same tree. The worktree decision rule, mechanics, port model and cleanup safety live in the working-in-worktrees skill and AGENTS.md → Worktrees.

An agent that stops mid-work on a context error was handed too much: split the task, give the aspects to separate agents, and pass only the context each one needs.

Agent Selection Guide

Task TypeRecommended Agent
Codebase explorationExplore
Web researchresearch-expert
React/frontendreact-tanstack-expert
TypeScript issuestypescript-expert
Code reviewcode-reviewer
Bulk read-and-summarizecontext-isolator
General implementationgeneral-purpose
File searchcode-search

Error Handling

Agents report their own outcome in their final message — treat it as a claim, not proof:

  • Read each result for reported failures or blockers before starting dependent work
  • For implementation agents, verify with the VCS diff (git status / git diff), never the report alone
  • On failure: retry with a sharper prompt, continue without the result, or stop and ask the user if the task is critical

Anti-Patterns to Avoid

  1. Sequential launches for independent work — separate messages serialize; batch Agent calls in one message
  2. Duplicating delegated work — once a search/task is delegated, don't also run it yourself; wait for the result
  3. Shared file edits — don't let parallel agents edit the same file without worktree isolation
  4. Too many agents — batch in groups of 3-5, not 20 at once
  5. Re-spawning instead of continuing — use SendMessage for follow-ups; a new Agent call loses the prior context
  6. Trusting success reports — check the diff or output evidence
  7. Vague output asks — tell each agent the exact format to report back in
  8. Parallelizing chatty work — work that needs rapid back-and-forth with the person stays in one thread

Progress Display

Keep users informed: say what you launched and why ("Launched 3 agents: client hooks, SSE research, server routes"), then summarize each result as it lands and what you concluded from it.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.