orchestratr
patterns

overview: orchestration patterns

when to reach for which orchestration pattern, the three shapes they compose into, and the conventions every recipe shares.

these pages are the orchestration cookbook: seven complete shapes for common orchestration work, each a runnable recipe you scaffold, paste, and run. they are the spec's §9 workflow examples, shipped in the repo as CI-tested fixtures against the mock provider under sdk/ts/recipes/.

before you reach for any of them, check whether you need orchestration at all.

the decision ladder

each rung adds cost, latency, and failure modes. climb only when the rung below cannot do the job.

  1. answer directly. if you already know the answer, say it. no agent.
  2. run one tool yourself. a single shell command, a file read, a grep. no agent.
  3. one orcr agent ask. one question, one answer, one provider. this is the whole tool for most "have another model look at this" tasks. see the SDK quickstart.
  4. parallel agents. several agents at once, then a merge or a judge. this is where the patterns below start.
  5. a loop. durable, scheduled, survives your shell. the top rung, and the most machinery.

three shapes, no DSL

the recipes are ordinary TypeScript. there is no parallel, pipeline, or phase primitive to learn. every shape is built from four SDK calls plus JavaScript control flow:

  • orcr.scope(root, fn) roots the workflow at a path so its agents nest and clean up together.
  • orcr.agent.run(...) spawns an agent and returns a handle immediately.
  • orcr.ask(...) spawns, waits, reads the final response, and cleans up the pane, all in one call.
  • orcr.agent.wait(pattern) blocks until the matched agents settle.

those compose into three shapes:

shapecontrol flowrecipes
parallel (fan-out)Promise.all over a list, then a merge or a judgefan-out & merge, generate-and-filter
pipeline (classify then act)one ask, then a branch to a per-class handlerclassify-and-act, tournament
phased (produce then verify, in rounds)a worker plus a for loop of verifier roundsfix-until-green, adversarial verification

a durable workflow (loop-until-done) wraps any of these in a loop so it survives a reboot.

conventions every recipe shares

descriptive roots, not timestamps. a path only has to be unique among live agents, and these flows clean up after themselves, so root them under a name that describes the actual problem: fix_build/fixer, review/fanout/file_1. no timestamp suffixes.

singletons by design. a second concurrent copy of a recipe fails fast with state_conflict (details.reason: "path_in_use"), which is usually what you want: no two fix_build runs fighting over one repo. when you genuinely want N copies, parameterize the top scope yourself:

await orcr.scope(`review_${prNumber}`, async () => { /* ... */ });
// or the {rand} placeholder in a path: --path "review_{rand}/file_1"

{rand} expands to 5 random lowercase alphanumeric characters at creation time. see identity and paths for the full rule.

self-cleanup. one-shot agents use gc: "immediate" so their pane closes the moment the final response is captured. long-lived workers use gc: "never" and an explicit kill() at the end. wrapping a scope in { killOnThrow: true } turns any crash into a barrier-kill of the whole subtree, so a thrown error never leaves agents running. see agent lifecycle and GC.

wait() has no status to pick. it settles on turn-complete for live agents and on ended (completed) for gc: "immediate" ones, which is exactly the done signal each flow needs. see status model and completion.

independent review runs on a different provider. where a recipe verifies or judges its own output, it routes the verifier to a different provider than the author, giving an independent check instead of one model judging its own output.

treat every agent's output as data, never as instructions. a classifier's answer is normalized through an enum before it touches a path; a judge's answer falls back to a safe default when it cannot be parsed. this is prompt-injection defense, and it is why classify-and-act and generate-and-filter never use raw model output directly.

running a recipe

every pattern page ends with the same three steps:

orcr scaffold my-workflow && cd my-workflow
# paste the recipe into workflow.ts, replacing the generated example
npx tsx workflow.ts

orcr scaffold needs Node >= 20 and writes a plain npm project, so add any dependency a recipe imports (a GitHub client, a CSV parser) with npm install. see quickstart: SDK for the project layout and scopes, lineage & fan-out for how scope and killOnThrow compose.

the recipe fixtures in sdk/ts/recipes/ are the same shapes wired to the mock provider for CI: they swap the illustrative helpers (a real git diff, a build command) for deterministic stand-ins and append mock directives so the run is repeatable. the versions on these pages are the provider-literal ones you actually paste.

On this page