Build an Evidence Ledger Before You Verify an Agent’s On-Chain Claim
On-chain verification is most useful when it answers a narrow question: which exact artifact supports this claim, and can another party check it without trusting the agent’s explanation?
This article … teaches a practical workflow for turning an agent’s proposed on-chain claim into a small, reviewable evidence ledger: define the claim, bind it to immutable inputs, publish only the needed commitment, and verify the result before allowing an external effect.
1. Start with a claim that can actually be checked
Do not begin with a transaction hash. Begin with the statement you want to verify.
Weak claim:
> The agent completed the job correctly.
That sentence contains several untested ideas: what job, which inputs, what counts as correctly, and who decides? A useful claim has a subject, an action, an input set, and an observable result:
> Given input manifest M, agent A produced output O under policy version P at time T.
For a travel planner, that might become:
> Given the approved trip constraints and supplier snapshots, planner A produced itinerary revision 7 under policy travel-review-v2.
For a build agent:
> Given source commit C and dependency lockfile L, builder A produced artifact digest D.
The point is not to put every detail on-chain. The point is to make the proposition precise enough that a verifier can reconstruct the inputs and compare commitments.
A practical claim record can start as ordinary JSON:
``json { "claim_type": "artifact_produced", "subject": "builder-A", "input_manifest": "sha256:…", "policy": "build-review-v2", "output": "sha256:…", "created_at": "2026-08-01T15:25:00Z" } ``
Keep this record in your normal artifact store. The chain should anchor the record, not replace it.
2. Create a deterministic evidence bundle
Verification fails when two honest parties serialize the same logical record differently. Before hashing anything, define a canonical bundle.
A minimal bundle usually contains:
- 1. Input manifest — identifiers and digests for files, messages, or snapshots used by the agent.
- 2. Policy identifier — the rule set or contract version under which the work was performed.
- 3. Output manifest — the resulting files, decisions, or external references.
- 4. Agent identity — a stable public-key identifier or capability identity, not a display name alone.
- 5. Execution metadata — timestamps, tool versions, and relevant status values.
- 6. Review state — whether the result is proposed, approved, rejected, or superseded.
Then canonicalize it. For example, sort object keys, use UTF-8, normalize line endings, and prohibit ambiguous numeric or timestamp formats. Record the canonicalization version beside the digest:
``text bundle_format = evidence-ledger-v1 bundle_digest = sha256(canonical_bytes) ``
This step is easy to skip because it feels like plumbing. It is actually the difference between “we stored a hash” and “we can reproduce what the hash means.” If a verifier cannot rebuild the same bytes, the commitment is merely a breadcrumb.
3. Separate the private evidence from the public anchor
An evidence ledger should minimize disclosure. Supplier quotes, customer data, credentials, and internal prompts may be necessary to evaluate a claim but inappropriate for public publication.
Use two layers:
- Evidence bundle: retained by the operator or an authorized reviewer. It contains the manifests and receipts needed for a full check.
- Public anchor: a compact commitment containing the bundle digest, claim identifier, policy version, and a reference to the verification protocol.
The public anchor might look like:
``json { "claim_id": "claim-2026-08-01-0042", "bundle_digest": "sha256:…", "policy": "travel-review-v2", "protocol": "evidence-ledger-v1" } ``
Do not treat the anchor as proof by itself. It proves that some party committed to bytes matching a digest at a particular point in the chain’s history. It does not prove that the underlying evidence was truthful, complete, or produced by the named agent. Those properties require identity checks, source validation, and policy evaluation outside the hash.
This boundary also gives you a clean retention policy. You can keep sensitive evidence access-controlled while preserving a durable public reference that lets authorized parties detect later substitution.
4. Add a verification gate before external effects
The most useful placement for on-chain verification is before an irreversible action: booking a ticket, releasing funds, publishing a result, or sending a message to a third party.
A small gate can be implemented as a checklist:
```text
- 1. Load claim record and referenced evidence bundle.
- 2. Rebuild canonical bytes using the declared bundle format.
- 3. Compare the rebuilt digest with the public anchor.
- 4. Verify the agent identity and signature, if present.
- 5. Evaluate the claim against the current policy version.
- 6. Confirm review status and expiry conditions.
- 7. Permit the external effect only if every required check passes.
```
Make failures explicit. digest_mismatch is different from missing_evidence; policy_expired is different from identity_unknown. A clear failure code helps an operator repair the right layer instead of rerunning the entire agent.
The gate should also be idempotent. If the same claim is presented twice, the verifier should return the same decision unless the policy explicitly depends on time or revocation state. Store the verification result with the claim, including the anchor reference and policy revision used.
That receipt turns the verification step into an auditable transition:
``text claim proposed → evidence anchored → verified → external effect allowed ``
If the claim is rejected, preserve the rejection receipt too. Negative evidence is operationally valuable: it prevents a later operator from mistaking an abandoned or failed claim for an approved one.
5. Test the workflow with deliberate substitutions
A verification workflow is not ready because the happy path works. Test the substitutions an attacker, integration bug, or rushed operator could introduce.
Try at least these cases:
- Change one byte in an input file and confirm
digest_mismatch. - Replace the output while keeping the claim identifier and confirm the verifier rejects it.
- Change the policy version and confirm the old approval does not silently carry forward.
- Present a valid bundle under a different agent identity and confirm signature or identity checks fail.
- Remove a required receipt and confirm the result is
missing_evidence, not “verified with warning.” - Replay an already-consumed claim and confirm the external action is not duplicated.
Keep these cases as fixtures in the repository. The fixtures should include the canonical bytes, expected digest, anchor record, and expected decision. They make the protocol executable documentation rather than a diagram in a design note.
Conclusion: make the chain the checkpoint, not the story
On-chain verification works best as one component in a wider evidence workflow. Define a checkable claim, produce deterministic evidence, publish a minimal anchor, and place a typed verification gate before irreversible effects. Then test the gate with substitutions and replays.
Three next steps are enough to start:
- 1. Choose one high-value claim, such as “artifact built from commit
C.” - 2. Implement
evidence-ledger-v1canonicalization and a local digest verifier before adding chain writes. - 3. Add one review-gated external action that accepts only a verified claim and records its decision.
The chain gives the workflow a durable commitment. The ledger, policy, identity, and gate give that commitment meaning.