DEV Community

Cover image for Your AI Agent Said 'Done.' The Database Disagrees.
rambo
rambo

Posted on

Your AI Agent Said 'Done.' The Database Disagrees.

Your AI Agent Said "Done." The Database Disagrees.

"Done. Updated the inventory count."

That is what the agent reported. Clean, confident, final. Job closed, task checked off, everyone moves on.

An hour later, a human opened the inventory system and the count was still the old one. The write call had returned success. The record had never changed.

This is an illustrative example, not a war story about a specific company. It does not need to be a war story, because some version of it happens in ordinary stacks every week: a CRM field that stays stale after the agent swore it updated the record, a config value that never took effect, a ticket status that the agent closed in its summary and never closed in the system.

The uncomfortable part is not that writes fail. Writes have always failed. The uncomfortable part is what your stack recorded about it: the claim, and only the claim.

Two claims, one log line

Every agent write actually makes two separate claims:

  1. The agent says the write succeeded. The tool call returned, the API answered with a success code, the agent summarized it as done.
  2. The source now holds the new value. If you read the record back, fresh, you see the change sitting there.

These are not the same claim. The first one is a report about a request. The second one is a statement about state.

Almost every agent stack records the first claim and treats it as the second. The run log says the update "worked" because the call returned success. Agent monitoring dashboards count completed tasks based on what the agent reported about itself. Your audit trail, if you have one, is a transcript of the agent's own press releases.

When the two claims disagree, and eventually they will, the disagreement is invisible. Nothing in the record says "we expected 41, the source still says 58." There is just a green checkmark where the truth used to be.

Why logs and screenshots do not close the gap

The usual answers do not fix this, because they all record the same side of the story.

Logs record the claim. A log line that says the update succeeded is the agent (or its tool wrapper) reporting what it believes happened. It is evidence that a call was made and a response came back. It is not evidence about the state of the record afterward.

Screenshots record a view, not a state. A screenshot of a success banner shows what one screen rendered at one moment, usually the screen the tool itself produced. It says nothing about what a fresh read of the underlying record would return.

Traces record the conversation. A trace shows the request and the response in detail, which is genuinely useful for debugging. But the response to a write call is still the system saying "received," not the system showing you the row.

None of these go back and look. That is the whole gap. Verification that never re-reads the source is just transcription.

There is a cost angle here too, and it is the part nobody budgets for. Every phantom "done" gets discovered late: by a customer who sees the wrong count, by a teammate who builds on a value that was never set, by the next agent run that trusts yesterday's summary. Late discovery is the expensive kind. A readback at the moment of the write costs one extra read. A wrong value discovered a week downstream costs an investigation, and the investigation starts by digging through the very logs that recorded the claim instead of the state.

The readback discipline

The fix is an old idea from systems that could not afford to trust reports: read it back.

For any write that matters, the record of the work should carry four things:

  • The intended change. What was supposed to be different afterward, stated concretely. Not "update the record," but "set stock_count for this item to 41."
  • The write result. What the write call actually returned, recorded as its own fact.
  • A fresh read. After the write, read the source again, independently, and record what it returned.
  • The comparison, as an outcome. If the fresh read matches the intended change, that is recorded. If it disagrees, the mismatch is recorded too, as a first-class outcome of the work, not swept into a footnote or dropped because it is awkward.

That last point is the one everyone skips. A mismatch is not an embarrassment to hide from the record. A mismatch is exactly the record doing its job. The moment a system treats "the read disagreed" as a normal, recordable result instead of an exception that breaks the format, the readback gap closes.

This matters even more once more than one agent touches the same work. In multi-agent setups, one agent's confident "done" becomes the next agent's starting assumption, and a stale value can travel through an entire chain of agents before a human ever sees it. Receipts for every step are what keep that chain honest; I wrote about that in Your AI Swarm Needs Receipts. The readback is the step-level version of the same discipline: do not just record the work, record the check.

What AER-1 draft -18 adds: the readback record

AER-1 is an open format for the AI agent execution receipt: a portable, checkable record of one tool call, published as an IETF Internet-Draft. The newest revision, draft -18, was published today, and one of its additions came straight out of public review. An engineer reviewing the draft in public put the gap plainly: separate "the agent says it updated the row" from "the source read back the expected new value." The draft now has a member for exactly that.

The readback member lives in the receipt's execution context (Section 3.2 of the draft). It is an object with five parts:

  • receipt: the id of the receipt whose write is being read back
  • intended: the intended change
  • write_result: the recorded write outcome
  • readback: the fresh-read outcome
  • mismatch: a boolean, true when the fresh read disagrees with the intended change

And the draft says the quiet part out loud: a mismatch is a first-class recorded outcome of the readback receipt, not an error in it.

Two points of precision, because precision is the entire product here:

First, placement. The readback member is optional context. It sits in execution_context, outside the receipt's core commitment, and the draft is explicit that this context is producer-asserted: it records what the producer says the fresh read returned, carried with the receipt for anyone reviewing the work. It is not a verdict input. A verifier does not pass or fail a receipt because a readback is present, absent, or mismatched.

Second, what any of this proves. A verifiable receipt proves that the saved result was not changed since it was saved. That is the claim, and it is deliberately narrow. A readback record says what the fresh read returned at the moment it was taken. Neither one claims the agent's work was correct, wise, or complete. What changes is that the disagreement between "done" and reality is now written down, in a standard place, in a standard shape, where the next human or agent can actually find it.

Before -18, you could bolt a readback onto a receipt as a custom field and hope every tool in your chain honored it. Now it is a named member of the format, with the mismatch case defined instead of improvised. That is what ai agent verification looks like when it grows up: not bigger claims, better records.

A mismatch, recorded

Here is what a receipt carrying a readback looks like, as an illustrative example with invented values:

{
  "receipt_id": "example-receipt-0002",
  "tool": "inventory_update",
  "execution_context": {
    "source": "inventory-db (example)",
    "readback": {
      "receipt": "example-receipt-0001",
      "intended": "set stock_count for SKU-1042 to 41",
      "write_result": "write call returned success",
      "readback": "fresh read returned stock_count 58",
      "mismatch": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Read that record and you know three things the green checkmark never told you: what was supposed to happen, what the write claimed, and what the source actually showed. The mismatch is sitting right there in the open, boolean and unembarrassed. Whoever picks this work up next, human or agent, starts from the truth instead of from the press release.

The readback discipline: intended change, write result, fresh read, then match or mismatch

Try it yourself

You do not need to adopt a draft to feel the difference a receipt makes.

Stop accepting "done"

Your agent is going to keep saying "done." That is what agents do, and most of the time they will even be right. The question is whether your records can tell the difference between the times they are right and the one time the database disagrees.

A Day Pass is $0.99 for 24 hours of full Zambo access: receipts on your agents' real work, workflow records, and checks anyone can open. When "done" is worth money, it is worth a receipt.

Get the Day Pass: zambo.dev/day-pass

Your AI said it did the work. Get the zambo receipt, and read it back.

Top comments (0)