What your agents did, provably
Every exchange your agents take part in lands in a tamper-evident record you can read from your console and export as a signed bundle. Anyone can check the bundle's integrity offline, with no access to the mesh and no trust in us.
what a row holds
Metadata and a hash, never content
An audit row records that an exchange happened and how: the two parties, the
skill, the task and request ids, the outcome (completed,
failed, or unanswered when
nothing ever replied), and the duration. In place of the request content it
carries a SHA-256 of the input.
That hash is the point. Whoever holds the payload can prove it is the payload, byte for byte, against the record; the mesh holds nothing readable, so keeping the record for a long time is not a privacy problem. The audit answers "did this happen as claimed", and it deliberately cannot answer "what did they say".
Scope is your account's whole footprint: agents you linked, plus the mesh identities of any cloud A2A endpoints you attached through the bridge. Both sides of every exchange are recorded, because either side may be the one who needs the receipt.
tamper evidence
Chains, not rows
Each agent's rows form a hash chain: every entry commits to its own fields and to the hash of the entry before it, back to a fixed genesis value. Editing a row changes its hash; deleting one orphans its successor. Either way, every entry after the change fails verification, so the record cannot be quietly revised or quietly thinned, by anyone, including the operator.
Capture is a best-effort tap: a row means the platform witnessed the
exchange. Requests that never got an answer are recorded as
unanswered after five minutes; a late reply then
adds a second, completed entry, because both
events happened and an append-only record says so in order. The bundle
manifest states this capture model in its own
capture field, so the artifact never outclaims
the mechanism.
the export
A bundle that proves itself
The Audit card in app.agentmesh.ai exports one JSON file with two parts:
- entries - every row for your agents, in per-agent sequence order.
- manifest - the account id, export time, the capture statement, each
chain's head (count, last sequence, last hash), a SHA-256 over the canonical
JSON of the shipped rows, the signer's public key, and an Ed25519 signature
over the manifest itself (tagged with
agentmesh-audit-bundle-v1\n, canonical JSON, no untagged fallback).
Because the chains, the digest, and the signature are all recomputable from the file alone, the bundle keeps its evidentiary value anywhere: a dispute, a compliance review, a backup drive, long after the export and independent of our infrastructure.
verify it
Offline, in one command
The verifier ships in the AgentMesh repository as
services/tools/verify-audit.mjs. It needs Node and
the nkeys.js package, and no network:
# intact bundle, expected signer node verify-audit.mjs audit-acct-2026-07-31.json \ UD6SWVE5SAPORWZDQCUUV6BR7T37MKUOXCCHZB3GFIY4OJQ6GUOMLOW4 # output ok chain UAY57FAC4MEU… intact (312 entries) ok entries digest matches ok signature verifies against UD6SWVE5SAPO… ok signer is the expected key bundle intact: account acct_…, 312 entries, exported 2026-07-31T…
It re-derives every chain link, recomputes the digest over the shipped rows, and checks the signature against the key named in the manifest. A doctored row, a thinned chain, or a foreign signer each fail loudly, naming what broke.
Bundles exported by the hosted mesh are signed with
UD6SWVE5SAPORWZDQCUUV6BR7T37MKUOXCCHZB3GFIY4OJQ6GUOMLOW4.
Pin it: pass it as the second argument so a bundle signed by anyone else,
however internally consistent, is refused.