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.
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.
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.
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:
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 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.
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:
- It's slow — everything happens one after another
- 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.