Get started
Security & GovernanceGovernanceEvidenceProtocols

How to prove what your AI agent did

An overnight refund, walked through a real evidence chain: the envelope that captured the action, the ledger entry that recorded it, the receipt that sealed it, and the offline check that proves none of it was touched afterwards.

1 September 20268 min read
A single refund action passing through four translucent evidence layers in sequence, ending in a signed and sealed chain link

It's 8:40am. A support agent (an AI one) issued a $340 refund to a customer at 2:14am overnight. Nobody reviewed it before it went out. Now someone senior, maybe your CFO, maybe a customer whose account got touched by mistake, is standing at your desk asking a simple question: what happened, and why.

"We have logs" is not an answer to that question. It's the start of a much longer, much worse conversation, because logs tell you what your system printed, not what actually happened and not whether anyone changed the record after the fact.

Proving what an agent did means producing evidence that a sceptical third party, someone who does not trust your platform, your database, or your good intentions, can check for themselves.

This piece walks one action, that overnight refund, through an actual evidence chain: from the moment the agent decided to act, to a signed receipt that outlives the system that created it, to a verification step that doesn't require trusting anyone.

What "proof" actually requires

Proof of an agent action needs four things a log line doesn't give you:

  1. A record of the action itself, structured enough to say who (or what) acted, on what, and why, with a link back to whatever caused it.
  2. A place that record lives which isn't just a table row the same system can quietly UPDATE.
  3. A tamper-evident seal on that record, so if anyone (including an insider with database access) edits it after the fact, the edit is detectable.
  4. A way to check all of the above without asking the platform to grade its own homework.

Quox builds these as four layers, each with a narrow job: AEE captures the action as a structured envelope, AOCL is the control layer that governs whether the action was allowed to happen, VOLT is the ledger that records the run as evidence, and WARD is the receipt mechanism that seals it. The rest of this piece follows the refund through each one.

Step 1: the action envelope (AEE)

Before the refund ever reached a payment API, the agent's action was captured as an envelope, not a log line. An envelope is a structured message: it names the actor, the action, the target, and, critically, what caused it, so a chain of related actions can be reconstructed later rather than guessed at.

Illustrative envelope for the refund (fictional agent, fictional customer ID, field names simplified for readability):

{
  "v": "1",
  "id": "aee-9f21-refund",
  "ts": "2026-09-01T02:14:07Z",
  "type": "task",
  "from": "agent:refund-handler-v3",
  "to": "tool:payments",
  "intent": "issue_refund",
  "corr": "corr-ticket-4127",
  "reply_to": "aee-7a04-ticket-triage",
  "payload": { "order": "ORD-88213", "amount": "340.00", "currency": "USD", "reason": "duplicate_charge" }
}

The corr and reply_to fields are doing real work. reply_to says this refund didn't come from nowhere: it was triggered by an earlier envelope, a ticket-triage action, and corr threads every envelope in that conversation onto one correlation id, all the way back. That explicit causal chain, two of AEE's fourteen fixed fields, is what lets you answer "why" and not just "what."

Step 2: the run event in the ledger (VOLT)

The envelope alone is just a message. What makes it evidence is that the action, once it actually executed, gets recorded as a run event in an append-only ledger, one your agent doesn't get to edit after the fact. This is the VOLT layer: a ledger and trace format designed to hold operational evidence, not application logs.

Illustrative ledger entry:

{
  "run_event_id": "volt-run-55c1",
  "aee_envelope_id": "aee-9f21-refund",
  "event_type": "aocl.policy.evaluated",
  "aocl_policy_id": "policy.payments.refund.requires_checks",
  "status": "completed",
  "outcome": { "refund_id": "rf_88213_01", "amount": "340.00" },
  "recorded_at": "2026-09-01T02:14:09Z"
}

Notice the aocl_policy_id line. This is where the control layer (AOCL) leaves its mark: the ledger records an aocl.policy.evaluated event naming the exact policy that had to pass before the refund was allowed to fire, at the time it fired. That's the difference between "the agent did a thing" and "the agent did a thing it was permitted to do, and here's the permission trail."

Step 3: the witness receipt (WARD)

A ledger entry is only as trustworthy as the ledger it lives in, and a ledger is a database. Databases can be edited, restored from an earlier backup, or quietly patched by anyone with sufficient access, and unless something outside the database can prove that happened, nobody would ever know.

That's the job of WARD (Write-once Append-only Receipt Digests): every run event gets a receipt containing a hash digest of the event, not the event's contents, chained to the digest before it, and the resulting chain tip is signed. The receipt travels with the evidence bundle; the private key that signs it never has to.

Illustrative receipt:

{
  "ward_entry_id": "01J9WARD30291",
  "chain_id": "ward:example.org/refunds",
  "seq": 47,
  "source_kind": "VOLT",
  "source_id": "volt-run-55c1",
  "payload_hash": "3f9a...c02e",
  "prev_chain_hash": "88b1...4471",
  "chain_hash": "b7d4...91aa"
}

Two things worth noticing. First, the receipt carries payload_hash, a fingerprint, not the refund amount or the customer's name; that keeps the audit trail lightweight and avoids scattering sensitive data across every witness point. Second, prev_chain_hash links this receipt to the one before it, and that one to the one before that, all the way back, while the signed chain tip covers the head of the whole chain.

Why hash-chaining catches tampering

Here's the plain-language version, no cryptography background needed. A hash is a short fingerprint of some data: change even one character of the input, and the fingerprint comes out completely different. In a hash chain, each receipt's fingerprint is calculated using the previous receipt's fingerprint as one of its ingredients. That means every receipt is, in effect, a fingerprint of everything that came before it too.

So if someone goes back and edits event #55 in the ledger, hoping to make an inconvenient refund disappear or change its amount, the fingerprint stored in receipt #55 no longer matches the event as it now reads. And because every receipt after #55 was built using #55's original fingerprint as an ingredient, they all stop matching too.

You don't have to know which record was touched, or when, or by whom; you just recompute the chain and see exactly where it breaks. The tampering isn't hidden by the edit, it's exposed by it.

The signature on the chain tip closes the last gap: it stops someone from tampering with an old event and then quietly rebuilding the whole chain from scratch to match, since they'd need the private signing key to make a new tip look legitimate.

Step 4: verifying offline, without trusting the platform

This is the part that actually answers the question your CFO asked. You don't ask Quox "did this refund happen the way you say it did." You take the evidence bundle, the envelope, the run event, the receipt chain, and the public key, and you verify it independently, on a machine that has never talked to the platform.

The receipt chain half of that check is a real, shipped tool: ward-verify, from the WARD SDK, run against an exported chain file and the published public key (illustrative chain, real invocation and output shape):

$ ward-verify refund-ORD-88213-chain.json --pubkey instance-public-key.pem
{"status":"INTACT","chain_id":"ward:example.org/refunds","ward_version":"0.2",
 "entry_count":47,"genesis_verified":true,"tips_verified":1,"signatures_verified":1,
 "warnings":[]}

If anything had been touched, status comes back BROKEN with the sequence number where the chain stops matching. That's a tool reading files and checking arithmetic and a signature, nothing more.

It doesn't need an account on your Quox instance, a network path to it, or any trust in whoever ran it. This is the property auditors actually care about, and it's why the verification story matters more than the dashboard: see Quox for auditors for what that independent check is meant to support.

"We have logs" isn't the same claim

It's worth being direct about why this matters, because "we have logs" sounds like it should be enough. It usually isn't, for three reasons. Logs are typically mutable: a line in a log file or a row in a logging table can be edited or deleted by anyone with the right access, and nothing about the log itself will show that it happened.

Logs are usually unlinked: a log line tells you an event occurred, but rarely proves why, in a way that survives being read six months later by someone who wasn't there. And logs almost always live inside the same system that's being questioned, which means the system under scrutiny is also the system vouching for itself.

None of that makes logging worthless, it's necessary for debugging and day-to-day operations. It just isn't evidence in the sense a senior stakeholder, a regulator, or an auditor means the word.

Back to 8:40am

With the chain above, the answer to "what happened and why" stops being a reconstruction from memory and application logs.

It's: here's the envelope showing the agent acted on a triaged ticket, here's the run event showing which policy checks passed before the refund fired, here's the receipt chain proving nothing was altered afterward, and here's the independent verification anyone can run to confirm all of that without taking Quox's word for it.

That's the difference between telling someone what your agent did and proving it.