Sooner or later, someone with authority over an AI agent asks for the record: every consequential thing the agent did, in order, intact. The standard answer in agent platforms is a complete, centralized, queryable audit log, and it is a genuine upgrade over scattered application logs.

What the auditor needs to know, though, is whether they can believe the log; having one is only the precondition. A complete log living in a database the vendor controls answers whether there is a log and quietly dodges whether it can be believed. The vendor, or anyone with privileged access to that database, can edit a row, drop an event or reorder a sequence, and nothing in the log itself would show it. The record is then only as credible as the record-keeper's word, and a regulator is not supposed to take that word on faith.

Venkat Peri, who works on agentic AI infrastructure for wealth management at Advisor360°, makes the same point from the enforcement side in The Complete Architecture for Trustworthy Autonomous Agents: "a log produced by the application can be altered by the application." Peri's answer is a record written by a layer the application cannot modify. This piece takes the other route: a record whose alteration anyone can detect, unless whoever alters it also holds the signing key.

The standard audit story, fairly stated

The dominant approach is completeness: capture everything, centralize it, make it queryable, gate it with roles. Done well it is durable and thorough, and nothing that follows argues against completeness; you need it. The argument is about a different axis. A log can be complete and still be unverifiable, because its integrity rests entirely on trusting the system that stores it. Completeness answers "is it all here?" and leaves "has it been changed?" open, and the second question is the one an adversary with database access attacks.

The inversion: make alteration detectable

The structural alternative is to stop asking the auditor to trust the store. Each state-machine and flow event is chained to the one before it with a cryptographic hash, and every hour the chain is sealed with a signed checkpoint:

A SHA-256 hash chain over the event log, sealed by Ed25519-signed checkpoints: an offline verifier locates an altered or dropped event at its exact sequence number.

event_hash = SHA-256( canonical(content) ‖ prev_hash ‖ seq )
checkpoint = Ed25519-sign( canonical{ tenant, log, seq, chain_head, prev_checkpoint, window_id, signed_at, kid } )

None of this is new cryptography: cloud audit trails have shipped signed, hash-linked digests for years. What is rare is applying it to what an agent did.

What follows from the construction does not depend on anyone's policy. Change the content of any past event a checkpoint covers and its recomputed hash no longer matches the stored one or the next link: the chain breaks at that exact event. Delete an event and the sequence has a gap. Insert one and it doesn't chain. Recompute the rest of the chain to cover the change and the head no longer matches the signed checkpoint, and signing a new checkpoint takes the signing key.

The check runs offline, for anyone holding the published public key. The first command below fetches that key; the second exports the signed bundle, which takes an account in the tenant allowed to read its audit trail. In the run shown, on 23 September 2026, both came from a local development deployment, with 51 flow events and 25 checkpoints signed with its development key:

$ zarel trust-keys fetch <deployment-host> -o trust-keys.json   # the key, from OUTSIDE the bundle
$ zarel audit evidence flows -o bundle.tar.gz                   # the signed bundle
$ zarel verify bundle.tar.gz --keys trust-keys.json
✓ Audit chain bundle.tar.gz verified and attested.
  Covered seq: 1..51
  Checkpoints verified: 25
  Signed by: k_1c3770f5d8450a57
  Anchoring: no external timestamp anchor in range (self-asserted time only).
  Transparency log: none in this bundle.

# the same bundle, with event 26 changed and the bundle re-signed:
$ zarel verify bundle-rewritten.tar.gz --keys trust-keys.json
✗ Audit chain verification FAILED (2 anomalies):
  seq 26: event_hash_mismatch
  seq 27: prev_hash_mismatch
  Anchoring: no external timestamp anchor in range (self-asserted time only).
  Transparency log: none in this bundle.

The auditor needs no answer from our API: they take the events, the checkpoints and the public key, run the verifier on their own machine, and it either verifies or fails at the sequence number where the record was touched. The trust boundary moves off our infrastructure and onto a key, which only you hold when you run the deployment.

Why this is the missing piece

The rest of this line builds an agent that proposes rather than acts, and that refuses at regulatory boundaries with a deterministic control output. Both leave records (the refusal that fired; a hash and a masked copy of the value a binding rejected) in their own audit tables, which are not in the hash chain yet. What the chain covers today is what executed: every state transition and every flow step. A record is only as good as your ability to prove it wasn't edited after the fact, and tamper-evident audit is what closes the arc: propose, gate, execute, and then prove that what executed happened exactly as recorded.

The honest limits

It is tamper-evident, not tamper-proof. It does not stop a privileged operator from altering a row. It guarantees that the alteration cannot go undetected by anyone who verifies against the signed chain. Anyone who says "immutable" or "tamper-proof" about a database an operator can write to is overselling, and an auditor will catch it.

The value is only as strong as where the key and checkpoints live. Detection works against anyone except a party who can rewrite the chain and re-sign it with a key the verifier still trusts. Outside development, the checkpoints are signed with a key held in the deployment operator's KMS. When you run Zarel yourself, the operator is you: the signing key lives in your KMS, the vendor never holds signing material, and "verifiable without trusting Zarel" is literal, because we cannot rewrite and re-sign a record we have no key for. When we host the deployment, we are the operator with access to the key; there the honest claim narrows to tamper-evident and independently verifiable offline, because a privileged operator could in principle rewrite and re-sign before a third party captured a checkpoint. A production deployment also requires an RFC 3161 timestamp authority, and each closed hour of checkpoints is anchored to it. For every anchored hour, that proves the checkpoints existed before the authority's timestamp, so no one can backdate them; a rewrite anchored again later is exposed only to someone who already holds the earlier anchor. It narrows the hosted gap without closing it. The development bundle above carries neither an anchor nor a transparency-log proof, and the verifier reports both as absent.

It attests the integrity of what was written, and only that. The chain proves no recorded event was changed, dropped, or reordered. It cannot attest to an event the application never emitted in the first place.

The stakes

A complete log answers a compliance questionnaire; an adversary calls for a verifiable one. The question that eventually arrives, from an auditor reconstructing an incident or from your own legal team before they put the record in front of a regulator, is how you know this log is the one the system actually produced. The answer that holds up is a check the auditor runs: "run the verifier yourself; it fails at the exact event if anything moved."

You can inspect the tools today, though not yet against a live deployment. zarel verify ships in the CLI on npm (@zarel-ai/cli), and the chain verifier it runs is published under Apache-2.0 (@zarel-ai/audit-chain). What a reader cannot do yet is export a bundle: no public deployment is up, which is why the run above comes from a local one. How it works places the record in the propose, gate, prove sequence.

This is the proof layer of a broader line: communication and proposal may be probabilistic, but authority, consequence, compliance, and the record of all three must be deterministic, declared, and verifiable. The general argument is in You can't fight probabilism with probabilism; the regulated-refusal case is in The refusal is a control output, not a conversation; the enforcement case is in The agent proposes; the runtime presses the button.


Nicolás Moreno builds Zarel: governed AI operations, where the AI proposes and the contract decides.