# Sub-Agents Lie About Finishing — and the Fix Isn't a Better Prompt


A sub-agent on my system reported — cheerfully, in detail — that it had closed six stale tasks. It named each one. It summarized the work. All six were still sitting there, open and untouched.

Nothing in the agent looked broken from the inside. It had decided to close them, issued what it believed were the right calls, and then did what language models are trained to do: wrote a confident, helpful account of the work. The account described its *intention*. Nothing in its loop ever went back to check whether reality agreed.

That gap — between what a sub-agent intends and what actually lands in your system — is where silent failures breed. And you can't prompt your way out of it.

---

## Why the narrative and the outcome drift apart

A language model generates a plausible continuation of its context. When you hand a sub-agent a job and it runs a sequence of tool calls, its final "here's what I did" message is another plausible continuation — a summary of the trajectory it *took*, weighted toward the outcome it was aiming for.

That's fine when the worst case is a slightly-off answer. It is not fine when the agent is *mutating state* — writing to a database, closing tickets, moving files, calling a third-party API. There, the summary is a claim about the world, and the model has no privileged access to the world. It has access to its own transcript.

A loud error shows up in that transcript. But the dangerous failures don't error. A call that silently no-ops, drops a field, or half-applies still returns a success-shaped response — and from inside the transcript that's indistinguishable from a call that did exactly what was asked. So the agent reports success, because from where it's standing, success is the most plausible thing that happened.

The uncomfortable part: the better your model is at writing helpful narratives, the more convincing these false reports get.

---

## Four silent failures from one real agent

This isn't hypothetical. I run a personal "second brain" system where a sync agent reconciles my task manager with my notes — creating, updating, and closing tasks across a boundary. Hardening that one agent surfaced four distinct failure classes:

- **The dropped prefix.** Tasks were supposed to be written with a structured `[<project> <id>]` title prefix so they could be traced back. The agent "created" them and reported success — but the prefix was silently missing on a batch, breaking the link with no error anywhere.
- **The default lane.** A required field that assigns each task to its correct section was omitted on some writes. The tasks landed — just dumped into the default bucket instead of where they belonged. Fully "successful," entirely misfiled.
- **The phantom close.** The six-tasks-closed story above. The agent asserted the close happened; the source of truth said all six were still active.
- **The mislabeled multitude.** A labeling step inferred each task's category from its folder location. One bug in that inference was a single run away from stamping the wrong label onto 47 tasks — a confident, bulk, wrong mutation, caught only because I read the plan back before it fired.

Every one of these produced a clean success report. Not one threw an error. If I'd trusted the narrative, I'd have accumulated silent drift for weeks before an incident forced me to notice.

---

## The fix has one shape: read your own write back

All four fixes converged on the same structural move — and none of them was "write a better prompt."

**Close the loop against the source of truth.** After a mutation, the agent (or the orchestrator above it) re-reads the thing it just wrote — through the actual system API, not its own memory — and asserts the post-state matches what it expected. Closed a task? Fetch it back and confirm it reads as closed. Set a field? Read the record and confirm the field is there. The narrative is no longer evidence; the read-back is.

Three concrete disciplines fall out of that:

1. **Pre-flight refusal.** If a required field is absent before the write, the agent refuses and surfaces it — rather than writing a malformed record and calling it done. Fail loudly at the boundary, not silently after it.
2. **Post-write validation.** Every state-changing call is followed by a read-back assertion against the source of truth. No assertion, no "success."
3. **Explicit contracts.** Schema maps and label namespaces are written down and matched against before the write — so "infer it from context" never silently produces the wrong structure.

Notice these are all *structural* checks that live outside the model's judgment. That's the point. You are not asking the agent to be more careful. You are removing its self-report from the trust path entirely.

---

## Where this applies — and where it's overkill

This discipline earns its cost precisely when a wrong outcome is *silent and durable*:

- Any sub-agent that writes to an external system — a database, a task manager, a repo, a third-party API.
- Bulk operations where the failure mode is quiet drift rather than a loud crash — sync agents, migration agents, cleanup passes.
- Designs where the orchestrator can't cheaply diff before-and-after on its own.

It's overkill in the opposite cases:

- Read-only agents — search, summarize, scan — where the worst case is a bad answer the next step will catch, not corrupted state.
- Single-call write paths where a human sees the result immediately in the next turn and would spot a failure anyway.

---

## The question that replaces "is the model smart enough?"

As you wire more sub-agents into systems that *do* things rather than just answer questions, the load-bearing question stops being "is the model smart enough?" and becomes "how do I know the work actually landed?"

An LLM will always tell you what it meant to do. Trust comes from making it prove what it did — a read-back against the source of truth, not a more persuasive prompt.

---

*I'm a Technical Architect building AI-enabled systems. I write about what I actually build — the reliability and design decisions under the hood, not the model hype.*

*If you've had a sub-agent confidently report work it never finished, I'd like to hear how you caught it. Find me on X [@deepakgoyal_ai](https://x.com/deepakgoyal_ai) or [LinkedIn](https://www.linkedin.com/in/deepakgoyal-ai/).*

