Every subagent said "done." The catalog was still broken.
When you hand work to an agent, "done" means the agent stopped. It does not mean the work is right. Most multi-agent setups let the worker decide when its own task is finished, then ask another model to read the worker's summary and agree. That is two opinions and zero evidence.
The fix is a Done Check: before the orchestrator delegates a task, it writes a small, machine-checkable test for that task. The check runs against the real system, not the worker's report. Only the check can mark the task done.
Quick use case
Situation. An e-commerce operations team migrates 1,800 product listings to a new catalog schema. An orchestrator splits the work into batches of 50 and hands each batch to a subagent. Each subagent maps old fields to new ones, writes the listings, and returns a summary. A reviewer agent reads each summary and marks the batch complete.
What broke. Thirty-six batches came back green. Every summary said something like "Migrated 50 listings, all fields mapped." The reviewer agreed with every one. Two days after launch, customer service started getting orders for shirts with no size. About 340 listings had an empty size field, because one old format stored sizes inside the variant title, and the subagents skipped what they could not parse. Nothing lied on purpose. The summaries described what each worker tried, not what landed in the catalog.
The reviewer checked the words. Nobody checked the data.
The fix (Done Check).
- Write the check first. Before delegating a batch, the orchestrator writes its check: every listing ID in the batch exists in the new catalog, and size, color, price, and stock are filled in for every variant.
- Check real state. The check queries the new catalog directly. It never reads the subagent's summary.
- Workers cannot mark done. A subagent can only report "submitted." The batch moves to done when the check passes.
- Fail with specifics. A failed check returns the exact listing IDs and fields that are missing, and the batch goes back to a worker with that list attached.
- Count the leftovers. Anything a worker skipped must be listed as skipped, and the check fails if the skipped count plus the migrated count does not equal the batch size.
Same model, same batches. On the rerun, the check failed 9 batches in the first hour, named the 340 listings, and the fix was a parsing rule plus one more pass.
Why "the agent said done" is not evidence
An agent's sense of completion comes from its own context. It ran its steps, hit no errors it noticed, and wrote a confident summary. Silent skips, partial writes, and a tool that returned success without doing anything all look fine from the inside.
Adding a second model to review the summary does not fix this. It reads the same story and finds it reasonable. I learned this the hard way with 18 subagents on one sprint board: each one finished, each one undid someone else's work, and the QA agent signed off on all of it. Review needs something the worker does not control, and the cheapest thing a worker does not control is the actual state of the system.
The Done Check (four layers)
1. Written at delegation time
The check is part of the task, not an afterthought. If the orchestrator cannot write a check for a task, the task is too vague to delegate. Split it until each piece has a check. This one rule improves planning more than any prompt tweak.
2. Run against the system of record
Query the database, call the API, run the test suite, diff the file. Read-only, deterministic code where possible. A model can help write the check, but the check itself should be boring code that gives the same answer twice. Same idea as the Boundary Contract: hard rules live outside the model.
3. Only the check closes the task
Status moves through submitted, checking, then done or returned. No agent, including the orchestrator, can skip the check. A pass carries proof with it: which check ran, what it queried, and the counts it saw. That record goes in the trace and in the Handoff Note for whoever picks up next.
4. Failures are work orders
A failed check returns a precise list, not a vibe. "Listings 4411, 4417, and 4502 are missing size" is a task a worker can finish. Cap the number of returns per task, and after the cap, route it to a person. Pair it with a Run Budget so a stuck task cannot loop forever.
How this maps to what you already have
- 5-layer agent stack. Done Checks live in Orchestration and write their results to Traces.
- Receipt Gate. A receipt proves a write happened once. A Done Check proves the result is correct.
- Blast Radius. The radius limits how much a run can change. The check confirms what it changed is right.
- Ship Gate. Add one line: no multi-agent workflow ships unless every delegated task type has a check that reads real state.
A test you can run this week
Pick one workflow where an agent hands work to another agent, or where an agent marks its own tasks complete. Look at the last 20 tasks it called done.
Ask two questions: (1) For each one, could a piece of code have confirmed it without reading the agent's summary? (2) Did anything actually run that code before the task was marked done?
If the first answer is no, the tasks are too vague to delegate. If the second is no, you are trusting a summary. Write the check before the next delegation, not after the next incident.
Closing
Agents are good at doing work and bad at grading it. Write the check when you delegate, run it against the real system, let only the check mark a task done, and send failures back as specific lists. You do not need a smarter reviewer. You need a reviewer that looks at the data.
I'm Wasim Sheikh, AI Architect. I build systems teams trust and organizations depend on: not demos, not proofs of concept, production.
Follow for practical AI architecture that ships.
Connect on LinkedIn: Wasim Sheikh · Site: sheikhwasim.com · Notes: Wasim Sheikh on Substack · X: @anciwasim
Related: Blast Radius · Run Budget · Perfect Sprint Board · Handoff Note · Shadow Path · Receipt Gate · Boundary Contract · Golden Trace · Ship Gate · 5-Layer Agent Stack