claude-code-dynamic-workflows

star 0

Use when a task is too big for one context — broad audits, multi-file migrations, multi-source research, or parallel multi-dimension review — and you want to fan out and orchestrate many subagents deterministically with the Workflow tool (requires ultracode / explicit opt-in).

ucsandman By ucsandman schedule Updated 6/8/2026

name: claude-code-dynamic-workflows description: Use when a task is too big for one context — broad audits, multi-file migrations, multi-source research, or parallel multi-dimension review — and you want to fan out and orchestrate many subagents deterministically with the Workflow tool (requires ultracode / explicit opt-in). user-invocable: true

Claude Code Dynamic Workflows

The Workflow tool runs a deterministic JavaScript orchestration script that fans out subagents. You write the control flow (loops, conditionals, fan-out); the script spawns agents, collects structured results, and returns a synthesis. It runs in the background and notifies you on completion.

Reach for this when the structure of the work — not just its size — needs to be encoded: cover a wide surface in parallel, get independent perspectives before committing, or take on a job one context can't hold.

When to use (signals)

  • A migration, rename, or codemod across many files → discover sites, then pipeline a transform+verify over each.
  • A broad audit / review across dimensions (bugs, security, perf, tests) → fan out finders, then adversarially verify each finding.
  • Multi-source research → parallel searches by different angle → deep-read → synthesize with citations.
  • Understand a large subsystem → parallel readers over modules → one structured map.
  • Anything where you'd otherwise serially grind through 10+ near-identical subtasks.

If it fits in one focused pass, don't reach for a workflow — use a single subagent or just do it.

Opt-in gate (important)

The Workflow tool only fires when the user has explicitly opted into multi-agent orchestration: the ultracode effort/keyword is on, the user asked for a workflow / fan-out in their own words, or a skill's instructions tell you to call it. It can spawn dozens of agents and spend a lot of tokens, so do not invoke it for tasks the user didn't scope to that scale. When unsure, describe the workflow and rough cost and ask first.

Anatomy of a script

Every script starts with a pure-literal meta block, then a body using the hooks:

export const meta = {
  name: 'review-changes',
  description: 'Review changed files across dimensions, verify each finding',
  phases: [{ title: 'Review' }, { title: 'Verify' }],
}

const DIMENSIONS = [{ key: 'bugs', prompt: '...' }, { key: 'perf', prompt: '...' }]

const results = await pipeline(
  DIMENSIONS,
  d => agent(d.prompt, { label: `review:${d.key}`, phase: 'Review', schema: FINDINGS }),
  review => parallel(review.findings.map(f => () =>
    agent(`Adversarially verify: ${f.title}`, { phase: 'Verify', schema: VERDICT })
      .then(v => ({ ...f, verdict: v })))),
)
return { confirmed: results.flat().filter(Boolean).filter(f => f.verdict?.isReal) }

Hooks

  • agent(prompt, opts?) — spawn one subagent. With schema (JSON Schema) it returns a validated object (the agent is forced to emit structured output); without, it returns its final text. Opts: label, phase, schema, model, isolation: 'worktree', agentType (e.g. 'Explore', 'claude-code-guide', a custom agent). Returns null if the agent dies/skips — .filter(Boolean).
  • pipeline(items, stage1, stage2, ...)the default. Each item flows through all stages independently, NO barrier between stages (item A can be in stage 3 while B is still in stage 1). Wall-clock = slowest single chain. Each stage gets (prevResult, originalItem, index).
  • parallel(thunks) — run thunks concurrently and await all (a barrier). Use only when stage N genuinely needs ALL of stage N-1 (dedup/merge across the full set, early-exit on zero, cross-item comparison). A thunk that throws resolves to null.
  • phase(title) / log(msg) — progress grouping + a narrator line for the user.
  • workflow(name|{scriptPath}, args) — run another workflow inline (nesting is one level only).
  • budget{ total, spent(), remaining() }: the turn's token target (or total: null). Gate dynamic loops on budget.total && budget.remaining() > N.
  • args — the value you passed as the tool's args (pass real JSON, not a stringified blob).

Pick pipeline, not a barrier

Default to pipeline(). A parallel() barrier between stages is justified ONLY when stage N needs cross-item context from all of N-1. "I need to flatten/map/filter first" is NOT a reason — do that inside a stage: pipeline(items, stageA, r => transform([r]).flat(), stageB). A barrier where the slowest item is 3x the fastest wastes the fast items' idle time.

Quality patterns (compose freely)

  • Adversarial verify — spawn N independent skeptics per finding, each prompted to refute; kill the finding if a majority refute. Stops plausible-but-wrong results.
  • Perspective-diverse verify — give each verifier a distinct lens (correctness / security / repro) instead of N identical ones.
  • Loop-until-dry — for unknown-size discovery, keep spawning finders until K consecutive rounds surface nothing new (dedup against everything seen, not just confirmed).
  • Judge panel — generate N independent attempts from different angles, score with parallel judges, synthesize from the winner.
  • Completeness critic — a final agent that asks "what's missing — a modality not run, a claim unverified?"
  • No silent caps — if you bound coverage (top-N, no retry, sampling), log() what was dropped.

Mechanics & limits

  • Concurrency cap is min(16, cores - 2) per workflow; excess queues. Lifetime cap 1000 agents; ≤4096 items per parallel/pipeline call.
  • Scripts are plain JS (no TypeScript types). Date.now() / Math.random() / argless new Date() are unavailable (they break resume) — pass timestamps via args, vary by index for randomness.
  • Subagents return raw data, not human-facing prose. Use schema for anything structured.
  • Iterate by editing the persisted script file and re-invoking with {scriptPath}. Resume a paused/edited run with {scriptPath, resumeFromRunId} — unchanged agent() calls return cached results instantly.
  • Right-size: omit model to inherit the session model (usually correct); only override when a different tier clearly fits.

Don't

  • Don't fan out for work that fits one focused pass.
  • Don't use a barrier where a pipeline works (latency tax).
  • Don't run it without the opt-in gate above.
  • Don't poll a background workflow — you're notified when it completes.

For the orchestration primitive (one subagent at a time, model-driven control flow), see claude-code-subagents. For long-running async single tasks, see claude-code-background-agents.

Install via CLI
npx skills add https://github.com/ucsandman/claude-code-capability-primer --skill claude-code-dynamic-workflows
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator