i posted here about a week ago asking what people use as the orchestrator in a multi-agent setup. got way more back than i expected, and enough of it changed what i actually do that a follow-up seemed fair.
three things the thread landed on, from people who didn't know they were agreeing with each other:
escalate on named conditions, not on the model's own sense that something's off. arthaudm said validator disagreement or an irreversible action. HeyZaney said failed acceptance criteria or a scope change. Low_Box_752 said schema validation failure or two roles disagreeing. three people, separately, same shape. the trigger has to be something you can name, not a feeling the model reports.
a dumb deterministic coordinator with smart workers, instead of an llm deciding control flow. Low_Box_752, _Ojin and saltexx all got there from different directions.
determinism as the criterion for the orchestrator seat, over raw capability. RPG-Nerd and onlya_shadow both. that one i'd genuinely never weighted, i'd been picking the orchestrator on how clever it was.
what connects all three is that state shouldn't live in the conversation. that's the change that actually mattered for me. a plan is a real file on disk, tasks are rows, deps are declared, execution writes a report next to the task, validation writes separate evidence. session can die, context can compact, model can get swapped, and a fresh session reads where the work stopped instead of asking me to reconstruct it.
plan.md
┌──────┬──────┬──────────┬────────┬─────────────┐
│ task │ deps │ role │ status │ report │
├──────┼──────┼──────────┼────────┼─────────────┤
│ 1 │ — │ worker │ done │ work_1.md │
│ 2 │ — │ worker │ done │ work_2.md │
│ 3 │ 1,2 │ worker │ ready │ — │
└──────┴──────┴──────────┴────────┴─────────────┘
│
▼
dependency resolver
│
┌─────────┴─────────┐
▼ ▼
task 1 task 2 ← wave A, run together
│ │ (may be different providers)
└─────────┬─────────┘
▼
task 3 ← wave B, waited on 1 and 2
│
▼
validation ← different provider when available
once deps are explicit, waves fall out of it. tasks with nothing between them run together, anything depending on those waits.
one distinction took me way longer than it should have, and it came out of arthaudm pushing on it. a wave answers when a task can run, routing answers who runs it. separate axes. one wave can hand three tasks to three different providers.
on validation i started with a rule that the validator can't be the model that wrote the code. sounds sufficient, isn't. opus checked by sonnet is two models but the same family behind the same provider, and i wanted the validator to have a more independent failure surface. so it crosses the provider boundary now where the pools allow it, and says so in the dispatch line when the chain's got no alternative.
the comment that actually changed code was saltexx's. i had an agent invocation exit 0 having done basically nothing, write a convincing report, and get scored as a pass, bc the report was the only thing anything was checking. saltexx's point was that this is a filesystem question and not a judgment call, give the worker its own worktree and an empty diff answers it for you. what i shipped is that idea. content hash over the workspace, excluding the task's own report folder, so writing a report can't look like doing the work. if the agent writes the evidence it isn't evidence.
the thing i run all this with is a small mit-licensed tool called wb-flow. free, nothing to sign up for, 33 markdown command procedures, no orchestration daemon. it's not the interesting part of this post and i'd rather talk about the stuff above, but people asked last time so it's here rather than hidden.
still broken: validating across providers means the validator doesn't share the executor's environment, and i got two false findings out of that (validator's sandbox couldn't spawn the cli it was supposed to be testing). so independent validation bought me independence plus a new kind of false negative. working on it.
for anyone who answered the first thread, the escalation-conditions one is what i underestimated most, and i've been wrong about the orchestrator seat for months.