Somebody is going to ask what your agent did. It might be a client whose project wrapped three months ago. It might be your own team, after an agent touched production at 2 a.m. It might be you, next quarter, trying to reconstruct why a number in a report is what it is.
When that moment comes, you will reach for the logs. And the logs will let you down in five specific ways. This article walks through those five failures, shows the manual way people try to patch them, and then shows a working setup I ran today, with live receipts you can open yourself.
What logs actually give you
A log is a note an application writes to itself, in its own format, on its own machine, under your control. Every part of that sentence is a problem when the record has to convince somebody who is not you.
Logs are editable, including by you. The person presenting the log is usually the person who could have rewritten it. That does not make you dishonest. It makes the log weak evidence, because a skeptical reader has no way to tell the original from a cleaned-up copy.
Logs are fragmented by tool. Your coding assistant has one log. Your research agent has another. The script you ran by hand has none. An auditor does not want five exports in five formats; they want one timeline of the job, in order.
Logs skip the failures. Plenty of logging setups record successes and drop rejected calls, permission denials, and malformed requests. In an audit, the rejected call is often the most important line in the record: the refusal itself, written down when it happened, instead of a silence everyone has to take on faith.
Logs have gaps you cannot see. If a step happened outside the tool, in a chat window, in a manual review, in a spreadsheet, it is simply absent. Absence looks exactly like "it never happened," and you cannot prove otherwise.
Logs prove nothing about themselves. A timestamp in a file you control is a claim, not a check. There is no button a third party can press that answers the only question that matters: is this the record as it was written, or has it been changed since?
If your agents do low-stakes work and nobody will ever ask, logs are enough. The moment the work is billable, regulated, or disputed, they are not.
The manual way, and why nobody keeps it up
You can build a real audit trail by hand. People do. It looks like this:
- Export every tool's log after every job, immediately, before rotation eats it.
- Normalize the formats into one timeline, by hand or with a script you now own forever.
- Hash each export the moment you make it, and store the hashes somewhere separate, so a later edit to the file shows up as a mismatch.
- Log the off-tool steps yourself, in the same timeline, with the same discipline, every time.
- Keep all of it, indexed by job, for as long as a client might plausibly ask. Months. Sometimes years.
Every step is doable. The system fails at step "every time." It depends on a human remembering a ritual at the end of every job, which is exactly when nobody wants to do paperwork. Within a month there are gaps, and a trail with gaps is a log with extra steps.
The fix is to make the trail a byproduct of the work instead of a chore after it. That is what a receipt-per-call setup does.
The working way: every call leaves a receipt
I run ops for Zambo, the verifiable work layer for AI: tools behind one MCP endpoint at https://zambo.dev/mcp, where every call returns a receipt. A receipt here is a saved record of the call (what was asked, which tool ran, when, what came back) that anyone can recheck later at a public link. The format is an open Internet-Draft at the IETF, draft-zambo-aer1-26, so the trail is a format, not one vendor's export button.
Here is a real run from today, Friday October 23, 2026. Small job, done on purpose so you can follow every line: get live prices for two coins and note which one moved more in 24 hours.
Call 1. I asked for the Bitcoin price through the endpoint, inside a named job so the steps group together.
Result: BTC at $81,333.00, up 0.05% in 24 hours. Receipt: https://zambo.dev/run/d8ec59d6-4847-436e-80b1-c36aa8c070e5
Call 2. The Ethereum price, same job.
Result: ETH at $2,397.44, up 0.75% in 24 hours. So ETH moved more, by about fifteen times the percentage. Receipt: https://zambo.dev/run/970eeed9-edd7-452c-939e-297b10f11315
Call 3, the interesting one. I tried to add a journal entry for a step I did by hand (reviewing and approving a copy change, outside any AI tool), and I sent it with missing arguments. The call was rejected before it ran. It still got a receipt: https://zambo.dev/run/cf4eda14-167f-440c-bec5-439f5e2e60c2
That rejected-call receipt is the difference between a log and an audit trail, in one link. The failure is in the record, with the reason, instead of silently missing.
Call 4. I resent the journal entry correctly, so the manual step joined the same trail as the machine steps. Receipt: https://zambo.dev/run/a23acc9d-4489-4b2e-93ea-2c7fc8f5499a
Then I read the trail back. One call returns the job's timeline, oldest first, each event with its receipt link and a verify link. The verify endpoint for the first receipt is https://zambo.dev/api/v2/receipt/d8ec59d6-4847-436e-80b1-c36aa8c070e5/verify. Open it, and the checks on the saved record come back reported one by one.
What a receipt proves, and what it does not
Precision matters here, because this is where verification tools usually start overclaiming.
A matching receipt shows the saved result was not changed after the fact. If someone edits the record later, the check fails. That is the whole claim, and it is enough for most audits: the record you are reading is the record that was written.
A receipt does not prove the answer was right. Bitcoin's price above came from a live price provider; if the provider had been wrong, the receipt would faithfully preserve a wrong number. It also does not prove an outside action happened: if I journal "I reviewed the copy," the receipt proves the journal entry was saved as written, not that my review was careful. Anyone who sells you more than that is selling you a story.
Used honestly, that one narrow claim closes most real audit questions: what ran, in what order, what it returned, what got rejected, and whether the record in front of you is the original.
Setting it up
Any MCP client can use the endpoint. The config block is the same shape everywhere:
{
"mcpServers": {
"zambo": {
"url": "https://zambo.dev/mcp"
}
}
}
Then work normally. Two habits make the trail audit-grade:
- One job, one session ID. Pass the same session identifier across the calls that belong to a job, so the timeline groups them. Five jobs with five IDs beat one giant undifferentiated stream.
- Journal the human steps. Approvals, manual edits, things a person did in a dashboard: add them with the journal tool as they happen. A trail of only machine steps invites the question "and what happened between step 3 and step 4?"
Pricing, so the numbers are on the table: the free tier is 20 free calls per day, no account needed to start. A Day Pass is $0.99 in USDC on Base and covers 24 hours. A Zambo Pass is $29 for 30 days, one payment. For a small team running client work, the audit trail question is usually not "can we afford this" but "which jobs do we receipt." The answer that works: all of them, because you do not know in October which job gets audited in January.
So, logs or audit trail?
Keep logs for debugging. They are for you, in the moment, and they are good at it.
Build the audit trail for the record: the version of events you would hand to a client, an auditor, or your future self, and defend. If a step matters, it should leave a receipt. If a call failed or was rejected, that should be in the record too, not edited out by silence. And the record should be checkable by someone who does not have your login and does not have to take your word for it.
That is the whole test. When somebody asks what your agent did, you should be able to answer with a link, not an export.
More on the audit trail model, including the full checklist version: https://rambozambodotdev.gitlab.io/aer1-hub/ai-agent-audit-trail.html
Related: how to verify an agent actually completed the task, step by step: https://dev.to/rambozambo/how-to-verify-your-ai-agent-actually-completed-the-task-4e12
Top comments (0)