Agent Actions Need Receipts
Agent Actions Need Receipts
Twice this month, our own build logs taught us the same lesson from different directions.
First: we spent days believing a piece of our publishing pipeline was untested, because the verification run that proved it worked had been recorded only inside the artifact it verified. Nothing wrote it to a log anyone reads. The work was done; the record didn’t exist; so operationally, the work didn’t exist. We made decisions on stale information for two days.
Second, the mirror image: we discovered our deploy scripts had been shipping content to production for weeks without appending a single line anywhere. Every deploy had happened. None of them had recorded happening. When we later needed to know what was live and when it got there, the honest answer was: unknown by construction.
Neither of these involved an AI agent misbehaving. They involved something more basic, and more embarrassing for a team building an agent-native operating system to admit: actions without records. We’re telling the story anyway, because the lesson generalizes to every team wiring agents into real systems this year, and most of them are about to learn it the way we did.
An action without a record is a rumor
Here’s the uncomfortable property of side effects: they don’t testify. A file got written, an email got sent, a deploy went out, and unless something wrote a durable record at the moment it happened, the only evidence is the world itself, which you’d have to go inspect, if you even knew to look.
Humans paper over this constantly. We remember what we did. We recognize our own work when we see it. A human operator asked “did the deploy go out?” has a memory to consult.
An agent doesn’t get that courtesy, and neither does anyone supervising one. When an agent performs a hundred actions a day, “what happened?” is answerable only from records. If the records are partial, your knowledge is partial in ways you can’t detect, because missing records look exactly like nothing happened. That’s the trap: an incomplete audit trail doesn’t feel incomplete. It feels like a quiet day.
Why this gets worse with agents, specifically
Traditional software has this problem too, which is why audit trails and logging discipline are decades old. But agents sharpen it in three ways.
Agents act on inference. A script does what it was told; if you have the script, you mostly know what it did. An agent decides what to do from context, which means you cannot reconstruct its actions from its instructions. The record of what it actually did is the only source of truth about what it did.
Agents span systems. A single agent task might touch the filesystem, two APIs, an email account, and a calendar. Each of those systems keeps its own partial logs in its own format with its own retention. Nobody’s logs tell the whole story, and stitching them after an incident is archaeology.
Agents run when you’re not looking. The whole point is delegation. But delegation without records is abdication: if you weren’t watching and nothing wrote it down, the action is unsupervised in the strongest sense, unreviewable even in hindsight.
Put those together and the audit trail stops being a compliance artifact and becomes the substrate of trust. You can only extend an agent more authority if you can review what it did with the authority it had. No receipts, no review; no review, no earned trust; no earned trust, and you’re stuck supervising forever, which was the thing delegation was supposed to end.
Receipts are a systems property, not a habit
The tempting fix is discipline: tell the agent to log what it does. We’ve written before about why instructions are not controls — an instruction to log is exactly as reliable as everything else that depends on a model choosing to comply, and the failure mode is silent.
The reliable version puts the receipt where the action is. If every consequential action flows through one mediating layer, that layer can write the record as a side effect of performing the action, not as a separate step that might be skipped. The action and its receipt become one event. Nothing downstream has to remember; nothing has to be trusted to confess. This is the same architectural instinct behind inspectability by default: properties you care about should be produced by the structure of the system, not by the good behavior of its parts.
And receipts change what “done” means. We’ve argued that completion needs verification — an agent saying “completed” is a claim, not a fact. Records are what make verification cheap: checking a claim against a ledger is fast; checking it against the world is an investigation. Our two build-log incidents were both, at bottom, verification failures caused by ledger failures. The information existed. It just wasn’t anywhere a checker would look.
The standard we now hold ourselves to
Out of those two incidents came a rule we’ve adopted internally, and it’s blunt: a verification recorded only inside the artifact it verifies is not a record, and a deploy that doesn’t append to the ledger didn’t happen. Best-effort, never able to fail the action it records, written at the moment of the action, in the place where questions get asked.
We’re in alpha, and honesty about rough edges is part of the deal: we got this wrong in our own operations while designing a system whose thesis is that it should be impossible to get wrong. That’s not a contradiction; it’s the motivation. Every hour we spent reconstructing what our own scripts had done was an hour spent living in the world we’re building MagenticOS to end — a world where the answer to “what happened on this machine?” is a shrug and some grep.
The machine should know what happened on it. Every consequential action, one ledger, receipts by construction. If you’re wiring agents into systems that matter, don’t wait for your own two incidents. Decide now that actions without records don’t count as actions.