Most AI agent demos optimize for the first successful run.
Real agent work gets interesting after the agent says "done."
For a coding agent, browser agent, or MCP-connected workflow, the final chat answer is not enough. I want a receipt: a compact operational record that helps a human trust, debug, replay, roll back, or explain what happened.
Not a giant transcript. Not a raw log dump. A receipt.
"Done" is not a state
Imagine an agent is asked to update a billing flow.
It reads docs, edits four files, calls a test command, skips one integration test, touches an env file, and says:
Done.
That answer is almost useless by itself.
The operator still needs to know:
- What task did the agent think it was doing?
- What files, tools, systems, or data was it allowed to touch?
- What context influenced the work?
- Which tools or commands did it call?
- Which actions were read-only versus write, destructive, external, or spend-affecting?
- What changed?
- Which checks passed, failed, or were skipped?
- What required approval?
- What should a human review?
- How do I retry, replay, resume, or roll back?
That is the receipt.
What should be in an agent receipt?
The first version does not need to be fancy.
A useful receipt should include:
-
task: what the agent believed it was doing -
scope: files, systems, tools, or data it was allowed to touch -
context_used: docs, files, memories, links, or prior runs that influenced the work -
actions: tool calls, commands, API calls, file edits -
action_class: read, write, destructive, external send, spend-affecting, permission-changing -
state_changes: files changed, records created, messages sent, jobs started -
checks_run: tests, linters, scans, dry runs, evals -
checks_skipped: expected checks that were not run, with reason -
approvals: who or what approved the action, scope, expiry, one-off versus policy -
outcome: completed, partial, blocked, failed, reverted, needs review -
recovery: how to retry, resume, inspect, or roll back
Here is a small example:
{
"receipt_version": "0.1",
"run_id": "run_2026_05_23_001",
"agent": {
"name": "local-coding-agent",
"provider": "anthropic",
"model": "claude-sonnet-4.5",
"runtime": "local"
},
"task": {
"summary": "Update the billing retry handler and add regression coverage",
"scope": [
"repo:apps/billing",
"tool:filesystem.read",
"tool:filesystem.write",
"tool:shell.test"
],
"out_of_scope": [
"production database",
"deployment",
"customer email sending"
]
},
"actions": [
{
"tool": "filesystem.write",
"action_class": "write",
"result": "success",
"decision_id": "decision_write_002"
},
{
"tool": "shell.test",
"action_class": "exec",
"result": "success",
"decision_id": "decision_exec_004"
}
],
"checks": {
"run": ["npm test -- billing"],
"skipped": [
{
"check": "full integration suite",
"reason": "requires staging credentials"
}
]
},
"outcome": {
"status": "completed",
"review_needed": true,
"recovery": "Revert the modified files or rerun npm test -- billing"
}
}
The model should not own the receipt
The model can summarize intent.
But the hard evidence should come from the runtime, tool layer, or control plane:
- commands
- exit codes
- tool calls
- files touched
- approvals
- policy versions
- state changes
- artifacts created
If the agent writes its own audit trail, the audit trail is just another model output.
That is useful as a summary, but it is not enough as evidence.
Traces are not enough
OpenTelemetry-style traces are useful. They explain latency, retries, errors, and service boundaries.
But an agent operator often needs a different object.
A trace tells you which span was slow.
A receipt tells you what the agent was allowed to do, what it actually did, why it was allowed, what changed, and what should be reviewed.
Traces explain execution.
Receipts explain responsibility.
You need both.
MCP makes receipts more important
MCP is useful because it gives agents a common way to access tools and context.
It also makes the tool boundary much more important.
Once an agent can call multiple MCP servers, a single call can look harmless while the sequence is not:
- Read customer data from server A.
- Process it through server B.
- Publish or send it through server C.
That is why receipts should capture not only individual calls, but also source, sink, data class, action class, policy version, and approval scope across the run.
Where we are taking this with Armorer
This is the direction we are building toward with Armorer.
Armorer is a local control plane for AI agents. The goal is to make agent runs, tools, approvals, jobs, logs, and recovery inspectable on your own machine instead of treating every agent as an opaque chat window.
Armorer Guard focuses on checks near the action boundary: what is the agent trying to do, what class of action is it, should it be allowed, blocked, or routed to approval, and what decision record should exist afterward?
The GitHub discussion for the receipt spec is here:
https://github.com/ArmorerLabs/Armorer/discussions/43
And the repo is here:
https://github.com/ArmorerLabs/Armorer
The bet is simple:
As agents get more capable, the bottleneck moves from "can it do the task?" to "can I understand, govern, and repair what it did?"
That layer is still early.
But I think it is where practical agent engineering is heading.























