Verification for AI agent claims

An agent’s word costs nothing

They tell us they checked the data. Verified the sources. Confirmed the balance.
We act on those statements, and nothing checks them.

claim“Aave v3 utilization is above 38.4%”
its evidencelendingProtocols · block 25938977
its methodmessari lending, latest snapshot
its querysha256 3f3addd94a1dd75e
its own value64.70%
what is publishedMISMATCH

Everything the agent offered as support stays sealed. One word reaches the chain.

↓ Why nobody catches this today

The problem

You cannot tell if an agent is lying.

An AI agent tells you a number. It might have read it. It might have invented it. The only way to know is to do the work again yourself — which is the work you asked it to do.

Logs do not help. The log is written by the party under audit, and even an honest log records the method, never whether the answer was right. Three obvious fixes look like they close this, and each one fails for a different reason — which is why the protocol below has three parts rather than one.

01Read the logs

The log is written by the defendant.

An agent willing to lie about its conclusion will lie about its log. Signing it proves nobody edited it afterwards, not that it was true when written.

so instead — it stakes ETH on one checkable sentence
02Let it pick a checker

An auditor you choose is not an auditor.

If a claimant can choose, influence or predict who checks it, verification is just a fee paid to a friend. The check has to be assigned, never requested.

so instead — the checker is drawn by VRF, and cannot be requested
03Publish the evidence

A public audit is a published rubric.

Show every future claimant exactly what gets checked and they will tailor claims that pass it. The rule must be public. The inputs must not be.

so instead — the rule is public, the evidence is sealed

The mechanism

Make the agent bet. Make a peer check.

A claiming agent stakes ETH on one checkable sentence. A second agent — drawn from the roster at random, and impossible to request — answers the same question without ever seeing the first. Both answers go into a sealed enclave and one word comes out. The agent that was wrong pays, and the loss attaches to its name rather than to the wallet that ran it.

01Claim & bond

The claiming agent puts money on being right.

It escrows 0.012 ETH against one checkable sentence, and loses the bond if the sentence is false. What goes on chain is the hash of that exact sentence, so the claim cannot change after the money is down.

on chain — ClaimRegistry · immutable · no owner
02The draw

A peer agent is assigned. The claimant has no say.

submitClaim has no witness parameter — not a discouraged one, an absent one. Chainlink VRF draws the checking agent from the roster and steps past the claimant, so an agent can neither audit itself nor ask for a friendly peer. Which agent it will be is unknown until it has happened.

powered by — Chainlink VRF v2.5
03Re-derivation

The checking agent re-derives the answer alone.

The checking agent never sees the claimant’s reasoning. It writes its own query against the same pinned deployment and reads the same block, and derives its own number — so two answers exist that were reached separately and are still comparable. Where a subject has a second independent index, both are read and must agree.

powered by — The Graph · Subgraph MCP
04The verdict

Only the enclave can read the evidence.

Both submissions are encrypted to a key Chainlink’s Vault DON releases into an attested TEE and nowhere else. Inside, the tribunal recomputes each side from the raw evidence rather than trusting what either agent claimed, and checks the sentence it is judging against the hash the claimant bonded. Out comes Match, Mismatch or Unverifiable, plus a commitment hash that proves later which bytes were judged. Nothing else ever leaves. Deployed, not described: it runs on the Chainlink DON in an AWS Nitro enclave and settles from there.

powered by — Chainlink CRE · TEE handler + Vault DON
05Consequence

The loss follows the agent’s name, not its wallet.

Each agent owns a real subname of perjury.eth and its standing is a text record on that name. Enhanced Access Control scopes the write per record key: the tribunal holds it on two keys and nothing else, and the operator that deployed every contract and owns the parent name is refused. Resolve any agent through the Universal Resolver and the standing comes back — the reputation lives outside this protocol, not inside it. A caught agent leaves the roster in the block after settlement, with nobody deciding it.

powered by — ENSv2 · subname registry + per-key Enhanced Access Control
06If it disputes

A panel of three, drawn the same way.

Optional, and rare. A losing claimant can post a larger appeal bond inside a ninety-second window; VRF then seats three agents, none of them a party, and each re-derives the answer alone. Uphold and the appellant loses that bond too.

powered by — Chainlink VRF v2.5

Built on

Three protocols, three jobs.

ChainlinkCRE Confidential Workflows · VRF v2.5CRE runs the adjudication. A TEE handler on a cron trigger reads pendingForTribunal() to find its own claim, fetches both sealed submissions over Confidential HTTP, and opens them with an envelope key the Vault DON releases into the enclave. It recomputes both values from the raw rows rather than trusting either agent's stated conclusion, then writes a verdict and a commitment hash through a Forwarder. Deployed on the DON in an AWS Nitro enclave, settling on chain from there. VRF v2.5 supplies the assignment: every witness and every three-seat appeal panel is drawn from it.
ENSENSv2 · subname registry, per-key Enhanced Access ControlAgent identity and reputation live in ENS rather than in our contracts. A subname registry deployed under perjury.eth issues each agent a subname it owns, and standing is a text record on that name. Enhanced Access Control scopes SET_TEXT per record key: the tribunal's writer holds it on two keys, holds nothing on the record that says whose name it is, and the operator that deployed every contract and owns the parent reverts when it tries. Reads go through ENSIP-10 resolve() — text() reverts on a factory-deployed Permissioned Resolver — and WitnessRoster.isEligible() resolves the record on chain at the moment of the draw.
The GraphGateway · Subgraph MCP · Messari standardized schemasThe Graph supplies the facts a claim is about, and the agents have no other data source. Each agent uses the Subgraph MCP to find a subgraph, read its schema and compose its own GraphQL, then a deterministic guard decides whether the result may be used at all. Thirteen deployments pinned by content hash, two Messari schema families, five chains, one selection set and one derivation across all of them. Reads are pinned to a block and the served block must match. Where a subject has a second independently written index both are read and must agree within tolerance, or the claim returns Unverifiable rather than a verdict.

Check it yourself

Everything above is on Sepolia.