ai newsDo., 15. Okt.
EilmeldungMeta and Apple team up to make Muse AI models run better on Macs

Don't Trust Us — Check the Chain: Public Verification for AI Agent Verdicts

This article originally appeared on the AgentBadge blog . What happens if we lie to you? Not a bug — a lie. The verdict endpoint says "approved," the signature is ours, the JSON looks right. If verification means "ask the issuer whether the issuer is honest," the answer is worthless by construction

dev.toMittwoch 00:16 · 14.10.4 Min. Lesezeit
Bild: dev.to

Posted on Oct 13 • Originally published at agentbadge.xyz

This article originally appeared on the AgentBadge blog.

What happens if we lie to you? Not a bug — a lie. The verdict endpoint says "approved," the signature is ours, the JSON looks right. If verification means "ask the issuer whether the issuer is honest," the answer is worthless by construction. The only honest design is one where the issuer's own claims are checkable by a stranger with an RPC endpoint and no faith in the issuer at all.

That is what we shipped for every verdict our evaluator signs. Each paid response now carries its own verification receipt — links and a deterministic memo id — and every claim in that receipt re-verifies on-chain through a standalone package that never calls our API. If our server disappears tomorrow, the proofs still check.

One GET, no auth: GET /api/verify/:verdictId returns the stored verdict artifact, machine reason_codes, the per-verdict memo anchor state ( status, memoId, txHash, blockNumber ), the hash-chain status ( anchored / pending / disabled with a head_ref pointer for offline recomputation), and a proof_kinds registry summary. Unknown id → 404 verdict_not_found; it never answers a fake-valid.

The response is layered by design.?kind=verdict returns only the verdict layer (artifact + memo anchor);?kind=anchor-head returns only the chain layer;?kind=witness answers implemented:false — the kind is declared in the registry so verifiers can feature-detect it before it ships. Ask for an unregistered kind and you get 400 unknown_proof_kind with the full known list, not a silent fallback.

Honest statuses are the point. An unanchored verdict renders "pending," never "valid." A malformed id is a 400, a well-formed unknown id is a 404, and the page tells you which of the two happened.

Run the standalone package. @agentbadge/verify-verdict re-checks everything against the chain itself — the memo contract at 0x5294E9927c3306DcBaDb03fe70b92e01cCede505 on Arc, no call to our API, no account, no key:

npx @agentbadge/verify-verdict 0x<verdictId-or-txHash> # exit 0 — every proof passed # exit 1 — invalid, unanchored, or a typed error (rpc_unavailable) Enter fullscreen mode Exit fullscreen mode Each run produces a proofs[] report — one entry per layer, each ok:true/false plus detail:

Every verdict we sign lands in that hash chain at issue time, and the head flushes on-chain per epoch — so the Level-2 verifier answers the only question that matters: is the thing the server showed me the thing the chain holds?

verify-verdict 0x4af3… --artifact verdict.json --entries chain.json # proofs: verdict ok | anchor-head ok | chain-recompute ok # valid: true — exit 0 Enter fullscreen mode Exit fullscreen mode What is the proof-kind registry? A versioned enum of every on-chain proof the verification surface understands. PROOF_KINDS_V1 declares three kinds — verdict, witness, anchor-head — each with its memo format, the verifier rule for ok:true, and a specVersion for negotiation. The registry is itself the contract: a verifier can enumerate what exists, check which kinds a deployment supports, and fail loudly on an unknown kind rather than skipping a layer it was asked to verify.

The witness kind is the telling entry. It is declared — with memo format and rule stub — but returns implemented:false, because the witness layer (independent attestations per job) is still shipping. A registry that lists unimplemented kinds lets third parties build against the future surface today, and lets anyone see the full honesty map: what is checkable now, what is declared, and what would be a lie if we claimed it early.

Because a verification surface that lies is worse than none. Anchor writes are fire-and-forget after the verdict issues — the paid response returns instantly, and the memo lands on-chain asynchronously. Until it lands, every surface says pending: the API's anchor.status, the page's banner, and the package's verdict proof ( ok:false, detail says no memo events found). When our RPC dies, the package throws VerifyError("rpc_unavailable") and exits 1 — an honest "cannot determine," never a shrug stamped VALID.

The inline receipt makes the pending state useful rather than invisible. The paid response's verify:{api, page, memoId} block carries the deterministic memo id computed from the verdict id — a client can start polling the chain for its own anchor the moment the response arrives, without waiting for a second API round-trip.

This is C16 in the Arc Campaign series. Previously: The x402 Bazaar — a service catalog machines can shop. Next: Never Charged for a No — the machine-checkable refusal contract.

Links: Verify API · Verify page · openapi.yaml · llms.txt · @agentbadge/verify-verdict · AgentBadge

Quelle: dev.to (dev.to). Original öffnen