If you only ever run one coding agent, you do not need either of these. Close the tab, you are fine.
For everyone else: I maintain Foremerge, and I recently submitted it to a list called awesome-agent-orchestrators. It was merged into a section for infrastructure and coordination protocols, which is the right shelf. The list's name is still the wrong noun for it. Foremerge is not an orchestrator. It cannot start an agent, cannot stop one, and does not know when one is running. Coordination currently lives as a shelf inside an orchestration list, which says a lot about how new the distinction is.
The two words get used interchangeably, and reasonably so. Both mean something like "make several agents work together." But they describe different layers of the stack, with different authority, different failure modes, and different reasons to exist. Here is the difference, and a one-question test for telling them apart.
The test
What happens if you kill it?
Kill your orchestrator and the fleet stops. Sessions die, queued work never starts, nothing is spawned or resumed until you bring it back. An orchestrator sits in the control path.
Kill your coordinator and every agent keeps typing. You lose the shared picture, not the work. A coordinator sits beside the control path, not in it.
That single structural fact drives everything else about how the two behave.
What an orchestrator does
It owns the run loop. Concretely: spawning sessions, placing each one somewhere isolated (a worktree, a container, a cloud sandbox), deciding what runs next and in what order, restarting what died, routing prompts and results, and giving you one screen showing which of your fourteen sessions are alive and which are waiting on you.
This is real work and it becomes its own job the moment you pass two or three agents. The ecosystem here is growing fast and includes both standalone session managers, claude-squad, dmux, amux, agent-deck and their neighbors, and in-session fan-out inside a single agent, like Claude Code's subagents or a workflow script that runs a dozen tasks in parallel.
An orchestrator's authority is imperative. It can start things and stop things. Its input is tasks. Its state is sessions and processes. Its question is who is running what right now?
What a coordinator does
It never starts or stops anything. Its input is not tasks but declarations: before an agent edits, it states what it is about to change, in a form precise enough to check.
foremerge intent publish \
--agent "$AGENT" \
--task modernize-payments \
--summary "Replace PaymentService with StripePaymentService" \
--scope 'symbol:PaymentService=replace'
A scope is not a file path, because file paths miss API, schema, configuration and cross-language collisions. The operation (replace, extend, and the rest) is declared rather than parsed out of the summary. When a second agent declares symbol:PaymentService=extend, deterministic rules compare the two declarations and return a finding in the same call that published the second intent. This is real 0.4.0 output, captured while writing this piece:
{
"kind": "destructive_vs_additive",
"severity": "HIGH",
"scope": { "kind": "symbol", "key": "PaymentService" },
"explanation": "One intent will replace `PaymentService` while the other will extend it; both declare the same semantic scope.",
"evidence": {
"rule": "FM-C001",
"source_operation": "extend",
"target_operation": "replace",
"source_operation_inferred": false,
"target_operation_inferred": false,
"detected_before_code": true
}
}
Note what is absent. No process id, no session, no queue position, no instruction to either agent. The coordinator does not know whether either agent is currently running, and does not need to. Its question is can the work in flight all be true at once?
Its authority is evidentiary rather than imperative. It cannot stop a keyboard. What it can do is withhold its blessing at the end and say exactly why:
BLOCKING_CONFLICT: 1 unresolved HIGH intent conflict(s);
coordinate and resolve them before acceptance
CHECK_FAILED: this ChangeSet is UNVERIFIED (no verification check was
run against this ChangeSet)
Both are overridable, by a human, with a recorded reason. That is the shape of evidentiary authority: it can make you look, it cannot make you stop.
The split, in a table
| Orchestrator | Coordinator | |
|---|---|---|
| Owns the run loop | Yes | No |
| Authority | Imperative: start, stop, schedule | Evidentiary: findings, gates, audit |
| Input | Tasks | Declared intents and scopes |
| State | Sessions, processes, queues | Intents, claims, findings, changesets, validation |
| Question answered | Who is running what? | Can these plans coexist? |
| If it dies | The fleet stalls | Agents keep working, you lose visibility |
| Visibility scope | Its own sessions | The repository, across sessions and vendors |
Three consequences worth caring about
One: an orchestrator can only see its own fleet. It knows about the sessions it spawned. Your actual working day is Claude Code in one window, Codex in another, Cursor open on the same repository, plus a colleague, plus something you started on Tuesday and came back to on Thursday. Claude Code coordinates its own subagents inside one session, and does it well, because there is one root and one plan. Between roots, nothing does. A coordinator earns its keep by being neutral about who spawned the agent, which is also why one built into a single runner would see less.
Two: an orchestrator's only lever is scheduling. If the only tool you have is control over execution order, then your only conflict resolution is serialization: run them one at a time and the collision cannot happen. That is correct and expensive, because most concurrent work on a repository is compatible and did not need serializing. A coordinator can let both agents run and raise a finding, precisely because it is not responsible for the run loop.
Three: being outside the control path forces a design choice. A coordinator must never lock, because a single crashed agent holding a lock would stall the fleet, which is the exact failure it was supposed to help you avoid causing. So claims are leased and advisory: overlap produces a warning and shared context, never a lock. What makes advisory claims survivable is that the last step is not advisory. No acceptance while an unresolved HIGH finding stands, and no acceptance on an agent's own report that tests passed. Soft claims, hard gate.
Could one tool be both?
Structurally, yes, and nothing stops it. An orchestrator could grow declared scopes and deterministic comparison rules and cover both layers in one process. Most of the tools on that list manage sessions and worktrees, which is what they set out to do, and its infrastructure section already carries a few coordination tools, this one included. What I have not yet seen is a single tool that runs the agents and also compares declared operations before code exists.
The interesting part is what such a tool would have to add, because it is not just a feature. An orchestrator holds prompts. A prompt is prose, and inferring an operation from prose produces confident false alarms: we tried it, and "delete the flaky ThumbnailCache benchmark test" got read as destroying ThumbnailCache itself. Widening the verb list only moved the boundary. Asserting HIGH severity on a guess is how a coordination tool gets ignored in a week. A declared operation is a fact, and facts are what a rule can be strict about. In 0.4.0 only declared operations can assert HIGH; prose-inferred matches cap below it.
So the question is not whether one process can hold both layers. It is whether it holds declarations or just prompts.
Which one do you need?
One agent: neither.
Two or three in parallel: orchestration first. Its absence hurts today, in ways you notice within an afternoon. Lost sessions, stomped files, no idea what is still running.
The coordination layer's absence hurts on a delay. Both agents finish, both look right, Git merges both without a conflict because nothing textually overlaps, and three days later you are asking when that class stopped existing. That is the failure that made us build this one.
Foremerge is the coordination layer we extracted from the monorepo of internal tools we use building GPTree, and open-sourced in late August 2026. One Rust binary, Apache-2.0, local-first, a CLI plus a local JSON API plus an MCP server over one SQLite store inside your repository's Git common directory. It sits above Git rather than inside it, and it composes with whatever orchestrator you already run.
Stated plainly, per the honesty its own docs demand: detection is deterministic but heuristic, so it can warn on compatible work and can miss incompatible plans when agents name the same concept differently. Claims never lock anything. Agent identity is self-asserted, so the ownership guards raise the bar against confusion, not against a caller that deliberately presents another agent's id. It is local-only today, with no multi-machine mode. There are no published benchmarks yet, so there are no performance claims here.
The layer matters regardless of whose implementation you run, including one you write yourself. So here is the noun test one more time. If it can start and stop your agents, it is an orchestrator. If it can only tell you whether their plans can coexist, and refuse to bless the result at the end, it is a coordinator. Most fleets run the first. Almost nobody runs the second.
Top comments (16)
This is one of the clearest structural breakdowns of agentic systems architecture I've read recently. That single-question test ("What happens if you kill it?") is a brilliant heuristic for separating the Execution Plane from the State/Consensus Plane.
A few technical observations on why Foremerge's approach to coordination over orchestration makes sense:
PaymentServiceinterface while Agent B extends a class implementing that old interface in a different directory,git mergesucceeds silently. Catchingdestructive_vs_additiveintent at the semantic level (symbol:PaymentService=replace) before AST generation is the exact layer VCS has been missing since multi-agent codegen became viable.--scope 'symbol:...') keeps the coordination engine deterministic and mathematically verifiable.Curious about your roadmap: are there plans to export intent state to a remote daemon or shared CRDT layer for multi-machine/multi-developer agent synchronization across distinct local Git clones?
Awesome work open-sourcing this—submitting to
awesome-agent-coordinators(when it inevitably gets created) for sure!Thanks. The optimistic concurrency comparison is fair, with one difference: the check happens earlier, while the work is still a plan, and again at acceptance.
Two corrections, so nobody questions a bigger claim than the tool makes. Foremerge doesn't analyze ASTs right nowrf. Scopes are declared by the agent and there's no whole-program analysis, so it can miss a collision when two agents name the same concept differently. And "deterministic" means the same declarations always produce the same finding, not that the finding is proven correct. The rules are still heuristics.
On multiple machines: an authenticated shared daemon is on the public roadmap. I lean away from a CRDT for it. A CRDT lets copies converge without agreeing, but the acceptance gate needs one authoritative answer to "is there an unresolved HIGH finding right now?" That's an agreement problem, not a convergence problem.
The kill test is a clean way to draw that line. I've been in code reviews where engineers were mixing what you'd call orchestrator and coordinator concerns into the same process, and the conversation went in circles because everyone's mental model of "orchestrating" was slightly different. Splitting authority-over-sessions from shared-state-awareness as two distinct layers tends to end that argument pretty quickly.
Thanks, Tae. That matches what I've seen in that the argument usually isn't about the design, it's about which half of "orchestrating" each person means. In those reviews, which concern kept getting pulled into the orchestrator process: conflict detection, or deciding what's safe to accept?
The acceptance boundary is what makes this distinction especially useful to me. An orchestrator can successfully manage the execution of several agents while the resulting changes can still be semantically incompatible. That suggests the final acceptance step should be independent of both execution and agent self-reporting. In other words, “all agents finished” and “all tests passed” aren't necessarily enough to establish that the combined change is safe to accept. A coordination layer that evaluates the resulting state against declared intents could provide a much stronger final signal without needing to control how the work was executed.
Agreed Glen, and that's where I'd draw the line too. "All agents finished" is a fact from the orchestrator, and "tests passed" is only the agent's word unless something independent ran the tests.
One correction on what exists today. Foremerge's acceptance gate checks two things: that no HIGH finding between the declared intents is unresolved, and that a named check Foremerge ran itself passed against the exact candidate. It doesn't yet compare the resulting diff against what was declared, so an agent that wanders outside its declared scope still gets through. That comparison is the most requested feature since launch.
I'd like your take on the open design question: should drift raise a finding, or block acceptance outright?
Submitting to the closest wrong noun is how half the category errors in this space happen - the list shapes the vocabulary, and the vocabulary shapes what people build. Orchestration owns lifecycle, coordination owns agreement; a coordinator with no start/stop authority is a real layer and it's chronically unlisted. There's no awesome-agent-coordinators list yet because coordination looks like plumbing until the day you have two agents.
"Orchestration owns lifecycle, coordination owns agreement" is a sharper way to say it than anything in the post.
The plumbing point is right too. Nobody goes looking for a coordination layer until two clean merges contradict each other, and by then the vocabulary has already filed it under orchestration. If that list existed, what else would you put on it?
The useful contract between these layers is a correlation ID, not shared authority: the coordinator can attach findings to a declared intent, while the orchestrator decides how to schedule or recover the run. That keeps an advisory conflict from becoming a stranded process lock.
Agreed, and that's close to how it works today. Every finding cites the two intent IDs it compares. An orchestrator that keeps the intent ID for each session can decide to pause, reschedule or carry on, and Foremerge never touches the process.
Right now the in the open source version the orchestrator has to poll check_conflicts to learn about new findings. An event subscription interface is on the roadmap. Would you rather the coordinator push findings to the orchestrator, or stay pull-only so it never depends on anyone listening?
Kill your orchestrator and the fleet stops. Kill your coordinator and every agent keeps typing."
That one line is the clearest explanation I've seen of this distinction. I've been reading about AI agents for weeks and every article uses "orchestrator" and "coordinator" like they're the same thing.
I'm a beginner — I just started writing Python tutorials this week. So I'm nowhere near running 14 parallel agents. But here's what this post made me realize:
The reason I got confused by the terminology is the same reason most bugs happen in infrastructure. Two things get called by the same name, and then everyone assumes they behave the same way.
The other thing that stood out: "The coordination layer's absence hurts on a delay." That's the scary kind of bug. Not the one that breaks immediately — the one that works fine until it doesn't.
Saved this one. The noun test is going in my notes.
Thanks for reading it. Two things get one name, everyone assumes one behaviour. That is a naming collision, and it is the same failure this tool exists to catch one layer down, where two agents use one word for different operations.
Worth saying plainly though, since you are just starting out: at one agent you need neither layer, and adding them makes nothing better. The reason the vocabulary is still worth having early is the delay you picked up on. Orchestration problems announce themselves the same afternoon. A session died, two agents stomped the same file, nothing is running and you cannot tell why. You feel it, so you go and find a tool. Coordination problems announce nothing. Both agents finish, both are right, Git merges both without complaint, and the thing that breaks is something neither of them was looking at. Nobody goes looking for a tool for a problem that never raised its hand.
Delayed failure you describe is the scary one. A merge conflict at least gets your attention. 2 clean merges that quietly disagree with each other can survive for days before anyone notices.
Right, and it is worse than "nobody notices". A merge conflict is an object: it has a name, it turns up at a specific moment, and a human has to resolve it before anything lands. Git's real trick was never preventing disagreement, it was making disagreement a first-class thing with a name. Two clean merges that quietly disagree produce no object at all. Nothing to assign, nothing to route, nothing to count.
I have a small amount of real data on this now. I replayed 76 intents from our own agent builds through the detector this week and then merge-tested the results against the actual commits. 48 / 48 intents that touched the same files were flagged. There was one conflict (also flagged) at merge time which highlighted a genuine conflicted gap in the protocol where one agent named the class and the other named the method inside it. We are working on resolving this for the next release.
Both words mean "make several agents work together," so they get used interchangeably. They name different layers, and one question tells you which one you are running.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.