OpenChainGraph · Explainer 14 steps and 3 live examples

From one number in a browser tab to an agent that carries proof across workflows and blockchains

Each step on this page adds one idea to the step before it. A person uses a page. The rule inside the page becomes a kernel, the kernel becomes a node, and each answer gets a hash that anyone holding the inputs can recompute. Agents reach that same kernel from a link, from inside the browser, or over the network. Nodes are ordered into workflows, and the evidence around an answer grows as a signature, a kernel identity, a zkVM receipt and outside timestamps are added. By the last step, a single prompt sends an agent through several workflows and across two blockchains, and anyone can check what it brings back with public tools.

Presenter mode shows one step per screen. Arrow keys move, A toggles autoplay, Esc exits.
Every hash, verdict and timestamp below comes from a live run against the public surfaces on 26 September 2026 (UTC), with synthetic inputs. The ten runs are bound into one session receipt whose root three independent timestamp authorities signed; step 18 lets you download it and check it yourself.
Part one · Baby steps

Each step adds one idea

Each step names one term, animates it, and ends with the prompt an agent can send once that step exists. From step 2 to step 8 the example is a single node, art-591, which recovers the address that signed an EIP-712 digest, the same check a merchant runs on an agent's x402 payment authorization.

1
Step 1 · Tool

A page a person uses

A tool is a single HTML page with a form, its math written inline, and a result panel. Once loaded, it computes in the tab without calling a server or storing anything. The Agentic Checkout Protocol Selector, for example, asks for a merchant platform, buyer type, order value and agent-traffic appetite, then ranks checkout protocols.

a person ainumbers.co/tools/495-agentic-checkout-protocol-selector.html Agentic Checkout Protocol Selector Merchant Platform Primary Buyer Type Average Order Value Agent-Traffic Appetite Run protocol_rank merchant_risk_profile 0 requests after loadcomputes in the tab .policy.jsonPolicy Mandate export built for peopleagents prefill it by link (step 5)

Tools are built for people; an agent reaches one by handing you a link that fills the form (step 5). A workflow can include a tool as a human step: tool 495 is the first step of the agentic-commerce-checkout workflow, marked for a person to run. A tool that sets policy exports a Policy Mandate, the JSON file that carries one tool's result into the next.

Who asks at this stepno agent yet
You, at the keyboard: open the page, fill the fields, press Run.
tools/495-agentic-checkout-protocol-selector.htmlrunFn runProtocolSelectorPolicy Mandate export
2
Step 2 · Kernel

The rule moves into a pure function

A kernel is the page's rule in a module of its own: compute(policy_parameters) returns output_payload and reads only its inputs. That purity lets the same file run in a browser tab, on a Cloudflare Worker and inside a zkVM with identical results.

a page's inline math chaingraph/kernels/art-591-x402-signer- recovery-verifier.kernel.mjs export function compute(pp) export async function buildArtifact(pp) export const meta pure: reads only its inputs browser tabsha256:4dfa2047…5ab7 Cloudflare Workersha256:4dfa2047…5ab7 zkVM guest (RISC Zero)sha256:4dfa2047…5ab7 the Worker and the zkVM guest run the file the browser runs

Every kernel lives at chaingraph/kernels/<tool_id>.kernel.mjs and exports compute, buildArtifact and meta (SPEC §12). The x402 signer-recovery kernel is the running example through step 8. Its source digest, sha256:4dfa2047d3aeebb35c0825fa07d54d487c7b254d0ad031e2d0c360a3736b5ab7, is how each surface names the exact bytes it ran (step 11).

Who asks at this stepa developer
import { compute } from './kernels/art-591-x402-signer-recovery-verifier.kernel.mjs'
compute({ digest, r, s, yParity, claimedFrom })
// { verdict: 'SIGNER_RECOVERED', recovered_signer: '0x7e5f…5bdf', recovered_signer_matches_claimed_from: true, ... }
art-591 kernelSPEC §12 Compute Binding
3
Step 3 · Node

A node gives the kernel a public identity

A node is a kernel registered in the Graph Index, chaingraph.json (SPEC §7): a tool_id, an agent-facing name, declared inputs, a page, and digests that pin its code. art-591 was one of 663 live nodes on 26 September 2026.

Graph Index chaingraph.json one catalog, downloadable by anyone: it is the registry art-591-x402-signer-recovery-verifier mcp_nameverify_x402_signer_recovery inputsdigest, r, s, v or yParity, chainId, claimedFrom kernelsha256:4dfa2047d3ae…5ab7source digest zk imagesha256:a1a0bc89b5b1…7bc6RISC Zero guest receiptgroth16-bn254, 256-byte seal pagechaingraph/art-591-x402-signer-recovery-verifier.html tool: for people only node: for people and agents

The Graph Index is a DCAT catalog. A tool serves people; a node serves people and agents at once, with one kernel behind its page, its MCP tool and, on pages like art-591, a WebMCP registration. Nodes also declare consumes and feeds edges, so an agent can plan which nodes fit together before it runs anything.

Prompt at this stepfind
Find the AINumbers tool that recovers the signer of an EIP-712 digest, and list its inputs.
find_tool returns verify_x402_signer_recovery (art-591): digest, r, s, v or yParity, chainId, claimedFrom.
art-591SPEC §7 Graph Indexfind_tool
4
Step 4 · Execution hash

Bind the answer to its exact inputs

Every run emits an execution_hash: SHA-256 over the canonical JSON (RFC 8785) of exactly {policy_parameters, output_payload}. Anyone holding the inputs can recompute it. Change the last character of the signature's s value and the recovered signer changes, the match fails, and the hash changes completely.

policy_parameters "claimedFrom": "0x7e5f…5bdf" "digest": "0x6948b98d…f1b7" "r": "0x2a7b2516…b457" "s": "0x36c25d04…73bf" "yParity": 1 output_payload "verdict": "SIGNER_RECOVERED" "recovered_signer": "0x7e5f…5bdf" "…matches_claimed_from": true JCS, RFC 8785sorted keys, no whitespaceone canonicalizer: _hash.mjs SHA-256 execution_hash888dd6a8…5859 one character changed "s": "0x36c25d04…73be" was …73bf recovered_signer 0x4296…7c8bmatches_claimed_from: false 35e66b8f…ffcb

This is the base of the staircase: anyone with the inputs and a SHA-256 implementation can recompute the hash (SPEC §4). Canonical JSON removes differences in key order and whitespace, and every value is covered, so dropping one output field fails verification. verify_execution_hash on the MCP server does the recomputation for any caller.

Prompt at this stepcall and check
Call verify_x402_signer_recovery with these fields and give me the execution_hash. Then change the last character of s and show me what moves.
Live: 888dd6a85969a6437a7e064ebdd601b515ed88c5021bddd24e16751b873f5859, SIGNER_RECOVERED. With s ending …73be: signer 0x4296e368…7c8b, match false, 35e66b8f27f2164efc291a6da4b963e7eeb0fdd4babae125c34bfb77ebd0ffcb.
SPEC §4 Execution hashchaingraph/kernels/_hash.mjsverify_execution_hash
5
Step 5 · AIN Bridge and deep links

Links and frames that fill a page inside the browser

AIN Bridge is a small script inside nearly every tool page. It accepts inputs from a #in= URL fragment, which the browser keeps to itself, from a dropped Policy Mandate file, or from postMessage sent by a same-origin parent frame. Node pages carry a sibling deep link, #p=v1, that gzips the inputs; adding &run=1 computes on load.

tools/495-….html#in=eyJtZXJjaGFu…&run=1 fragment stays in the browser .policy.jsondropped into intake runner page (parent frame) ain:prefill → ← ain:prefilled ain:run → ← ain:ran ain:getMandate → ← ain:mandate origin checked on every message tool page AIN Bridge v1.0 values set with .value only,then the page's own run function node pages art-591-….html #p=v1.<gzip JSON>&run=1 same rule: the fragment stays in the browser 0 requests while computing

Workflow runner pages use the message channel to drive each step in an iframe: prefill it, run it and collect its mandate. The bridge sets values through .value and .checked and calls the one run function the page declares, so a link reaches the declared fields and that function alone.

Prompt at this stephand the human a link
Give me a link that opens the art-591 page with these inputs filled in and runs it on load.
https://ainumbers.co/chaingraph/art-591-x402-signer-recovery-verifier.html#p=v1.H4sIAAAAAAAACh3MyU1DMRAA0F58_gfPZntSAGdamMWDIhEh_eRAhOgdkVfA-2l5_dj3R7u0_j2Ul-tKKrKsCkzemsMGDuLMrNSdkxGhQGcP4drUYQKGF_hsRztfEdp0FBhYCCun2IZJEKGiBBvBpYuZ7K5SSDZs9xlMypXkLP_R_RXRCJTsnCaFS4gGL5_bkMFscWxxoFXay5EyXMiGDg10hEle7WjPdzuvj2e7wNHi0663nW_n1-3Vzy3FItgVbCigpGSFT1-BQ7Sjkopntd8_kkjKYigBAAA&run=1
AIN Bridge explainerworkflow runner pagesOCG deep link #p=v1
6
Step 6 · WebMCP

The page tells the browser's agent what it can do

With WebMCP the page registers its own tool with the browser: registerTool({ name: 'verify_x402_signer_recovery', inputSchema, execute }). A browser-resident agent calls it and the page computes in the tab. In our run, the page's registered function made 0 network requests and produced sha256:1bc5c975…7a64.

ainumbers.co/chaingraph/art-591-x402-signer-recovery-verifier.html browser agent digest r s yParity claimedFrom registered with the browser name: verify_x402_signer_recovery inputSchema: 8 declared fields execute(params) fills the form, runs annotations: readOnlyHint true page computes sha256:1bc5c975…7a64 network fonts at page load 0 requests during the call In public testing in Chrome origin trial in Chrome 149 to 156; 472 pages here carry the trial token art-591 registers one tool workflow pages register plan_chain, assemble_session_receipt and apply_delegation_bundle

Chrome is testing WebMCP in public through an origin trial in Chrome 149 to 156, and Chrome 157 is the tentative milestone for turning it on by default. On 26 September 2026 the trial token was on 472 pages of this site, art-591 and 359 workflow pages among them, so those Chrome versions expose the tools to a browser agent without a flag. The art-591 page registers in wrapper mode: the agent's arguments fill the page's own form and the page's own run function computes, so the hash matches the page's deep link exactly.

A local-first agent setup of the kind Vitalik Buterin describes in My self-sovereign / local / private / secure LLM setup (April 2026) keeps inference and files on the user's machine and sandboxes its tools, and it still cannot show a third party what the agent decided or computed. The Work Mandate states what the agent was allowed to do. The execution receipt proves what it did. Both verify offline, so the audit trail outlives the machine it ran on.

Prompt at this stepin the tab
You are in my browser on the art-591 page. Use the tool this page registers to check this signature. Do not send anything off the page, and tell me how many network requests the call made.
Live, calling the page's registered execute() directly: SIGNER_RECOVERED, sha256:1bc5c97543161d5dda51016b24d3c1e0f3792beb50244105f405432adf1c7a64, 0 requests during the call.
WebMCP field notesscripts/gen-webmcp-registrations.mjsThe gap this closes
7
Step 7 · MCP

The same tool runs one network hop away

The MCP server at mcp.ainumbers.co runs the same kernel on a Cloudflare Worker. Send it the parameters the page used and it returns the same hash, sha256:1bc5c975…7a64, together with the digest of the kernel it ran. Whether an agent arrives by link, through the browser or over the network, the kernel and the hash are the same.

any MCP clientanywhere JSON-RPC tools/call verify_x402_signer_recovery { policy_parameters: { … } } mcp.ainumbers.co/mcp Cloudflare Worker, streamable HTTP, no key same kernel sha256:4dfa2047…5ab7 one tool per node, plus utilities artifact returned execution_hash 1bc5c975…7a64 build_identity.kernel_digest sha256:4dfa2047…5ab7 compute_proof_ready: deferred page, through WebMCP1bc5c975…7a64 = worker, through MCP1bc5c975…7a64 equal A lean call without the page's empty fields gets the same verdict and the hash 888dd6a8…5859, because its bytes differ.

The page fills every declared field, empty strings included, while a lean call leaves them out, so the two preimages and their hashes differ even though the verdict agrees; the hash commits to the exact bytes. The server lists one tool per node, a set of pilot widgets, and utility tools such as find_chain, run_chain, verify_execution_hash and build_session_receipt. For new inputs it attaches the kernel identity at once and marks the zk receipt as deferred (step 13).

Prompt at this stepcross-check two doors
Call verify_x402_signer_recovery on https://mcp.ainumbers.co/mcp with the exact parameters the page used, and compare its execution_hash with the page's, character by character.
Live: worker 1bc5c97543161d5dda51016b24d3c1e0f3792beb50244105f405432adf1c7a64 = page. Kernel digest sha256:4dfa2047…5ab7 on both.
MCP docsmcp.ainumbers.co/mcpSPEC §24 surface parity
8
Step 8 · Workflow

A workflow runs nodes in order and links them by hash

A workflow is an ordered list of nodes in the Graph Index. The standard calls it a chain (SPEC §21), which is why the tool that runs one is run_chain; on this page, chain means a blockchain. The x402-spend-evidence workflow recomputes the EIP-712 digest (art-590), recovers the signer (art-591), then checks the domain, nonce and validity window (art-592). run_chain threads each step's execution hash into the next step's parent_hashes and returns one composite hash over the steps that ran.

inputs: from the caller inputs: from the caller inputs: from the caller art-590EIP-712 digest recompute DIGEST_COMPUTED cf3e29af…3c0f parent_hashes h art-591ECDSA signer recovery SIGNER_RECOVERED 888dd6a8…5859 parent_hashes h art-592domain, nonce, window PASS 2b67271e…9517 composite_execution_hash ad46564c00bd402b0e6e5c930187d192…211b each step passes its hash forward; the composite covers every step that ran, in order

Each step reads its own inputs from the caller or from the workflow's fixture, and the record shows what each step decided and in which order. Gates can route a run forward, end it, or escalate it to a person (SPEC §21.4 and §22.8). On 26 September 2026 the Graph Index held 370 workflows, 67 of them with gates. A composite hash can be cited as a parent hash by a step in another workflow, which is how an agent carries a receipt from one workflow into the next.

Prompt at this stepone call, three steps
Run the x402-spend-evidence workflow on this authorization with run_chain, and give me each step's verdict and execution_hash plus the composite.
Live: art-590 cf3e29af…3c0f, art-591 888dd6a8…5859, art-592 2b67271e…9517 PASS, composite ad46564c00bd402b0e6e5c930187d19236149d75d84cd4b40529bb2bdf84211b.
workflow x402-spend-evidenceSPEC §21 Chain Executionrun_chain
9
Step 9 · Helm pack

A workflow compiled to run on your own machine

A workflow can run on the public server through run_chain, or it can be compiled into a Helm pack: a control-plane manifest (SPEC §26) listing its trigger, its nodes with their kernel digests, its gates and its actions. helmd, a daemon that listens on your own machine, runs the pack.

workflow agent-commerce-conformance compile ocg-control-plane@1 pack trigger nodes[ kernel_id, kernel_digest ] connectors gates actions workflow_manifest_digest same kernel digests as the public server run_chain on mcp.ainumbers.co, the public worker returns a composite receipt and ledger link helmd 127.0.0.1:4173/mcp, loopback only workflow.describe, workflow.dry_run, workflow.run, artifact.verify evidence.export needs a person's consent ticket from the Helm UI the public server and helmd run the same kernels for the same workflow

helmd listens on 127.0.0.1 and exposes eight MCP tools. An agent can describe, dry-run, run and verify a pack, and exporting evidence waits for a person to mint a consent ticket in the Helm UI. Helm is in beta, and its packs run on bundled sample data. On the public server, suite_howto serves workflow recipes that walk an agent through a workflow step by step.

Prompt at this steplocal control plane
On my local Helm daemon, find the agent commerce conformance workflow, list its nodes, gates and manifest digest, and dry-run it. Do not export evidence.
HelmSPEC §26 Control Plane Profileworkflow recipes
10
Step 10 · Signature

Who vouches for the artifact

A signature adds who stands behind an artifact. OpenChainGraph uses W3C Data Integrity eddsa-jcs-2022 over the whole artifact, keyed by a did:key (SPEC §16). In Example 2 a principal's key signs a Work Mandate, and a copy edited after signing is refused with mandate_bad_signature.

work mandate mandate_type: work_mandate scope.chains: agent-commerce-conformance escalation-sla-supervised-… validity: 2026-09-25 to 2026-10-25 principal: did:key:z6MkhU7i…u2T4 execution_hash 2266ce3efbb34154…5f73 principal key eddsa-jcs-2022 verifier (run_chain does this first) 1 resolve the did:key to an Ed25519 public key 2 SHA-256(JCS proof options) + SHA-256(JCS document) 3 verify the signature over those 64 bytes proofValue z3qwKgvT7MmVLd9X…uLVxd signature valid: steps may run scope edited after signing mandate_bad_signature: the run stops before step 1

Signing is optional and done by whoever holds a key, here the mandate's principal. Node results from the public server carry a hash and a kernel identity, and its credential tool generates a fresh key for each call. Several parties can sign one artifact as a proof set, an endorsement can sign over an earlier signature (SPEC §16.5), and a hybrid post-quantum profile adds ML-DSA (§PQC-1).

Prompt at this stepcheck who
Before you act on this mandate, verify its eddsa-jcs-2022 signature and tell me which did:key signed it and whether that is the principal it names.
SPEC §16 Proof Bindingchaingraph/kernels/_proof.mjsEd25519 signing guide
11
Step 11 · Kernel identity

The artifact names the code that ran

Every artifact the server returns names the kernel it ran: build_identity.kernel_digest is SHA-256 over the kernel's source (SPEC §17). A verifier checks that three values agree: the artifact's digest, the node's published compute_images entry, and a digest recomputed from the source. For art-591 all three read sha256:4dfa2047…5ab7.

artifact.audit_signature.build_identity.kernel_digestsha256:4dfa2047d3aeebb35c0825fa…5ab7 Graph Index: compute_images, system sha256-sourcesha256:4dfa2047d3aeebb35c0825fa…5ab7 recomputed: SHA-256 of the kernel source, LF-normalizedsha256:4dfa2047d3aeebb35c0825fa…5ab7 = an advisory claim (§17.2) A server could name one kernel and run another; a verifier who recomputes from the source would catch the swap. steps 12 and 13 prove it with a zkVM receipt

A mismatch among the three values fails the binding. On its own this is an advisory claim (SPEC §17.2): a server could name one kernel and run another, which the zkVM receipt in steps 12 and 13 rules out. Each digest is published with a valid_from date, so a kernel change shows up as a new digest.

Prompt at this stepwhich code
Which exact kernel produced this result? Compare the kernel_digest in the artifact with art-591's sha256-source entry in https://ainumbers.co/chaingraph/chaingraph.json.
SPEC §17 Kernel Identity Bindingkernels/_buildid.mjs
12
Step 12 · RISC Zero zkVM

Run the kernel inside a zkVM

To prove execution, the same kernel source runs inside RISC Zero's zkVM: a QuickJS JavaScript engine compiled into a RISC-V (RV32IM) guest that takes the kernel as data. The guest commits a journal holding the kernel digest and the output, and the receipt is bound to the guest program's ImageID, sha256:a1a0bc89…7bc6, one universal guest shared by nearly every node.

kernel sourcepassed in as data policy_parametersthe node's published fixture RISC Zero zkVM one universal guest RISC-V RV32IM core QuickJS engine art-591 kernel source ImageID sha256:a1a0bc89b5b1…7bc6 journal (public) chaingraph_version: 0.4.0 kernel_digest: sha256:4dfa… output: { verdict, … } output must equal output_payload STARK receipt bound to the ImageID large; step 13 shrinks it proved offline on a GPU

Proving is heavy, so it runs offline on a GPU (SPEC §18.2), and every surface verifies. Because the guest interprets the kernel source as data, one ImageID serves almost every node, and the journal's kernel_digest ties the receipt to the exact source from step 11. The journal's output must equal the artifact's output_payload, so the proof speaks about this particular answer.

Prompt at this stepshow the receipt
Show me art-591's zkVM receipt from the Graph Index: the system, the ImageID it pins, and the kernel digest in its journal. Does the journal's output match the node's published fixture output?
SPEC §18 Compute-Integrity ProofzkVM compute integrityrisc0
13
Step 13 · Groth16

Shrink the proof to 256 bytes and check it anywhere

RISC Zero wraps its STARK into a Groth16 SNARK over the BN254 curve: a 256-byte seal. OpenChainGraph ships its own verifier, verifySeal, which rebuilds the claim from the ImageID and journal and runs the pairing check in about a tenth of a second in a browser or a Worker. On 26 September 2026 every live node carried one, 663 of 663.

STARK receipt wrap A64 B B128 B C64 B Groth16 over BN254: 256 bytes verifySeal(imageId, journal, seal) 1 rebuild the claim digest from ImageID + journal 2 derive the Groth16 public inputs 3 check the pairing against the published key e(A, B) = e(α, β) · e(L, γ) · e(C, δ) valid, in about 0.1 s runs in a browser, a Worker or a CLI zero dependencies, vendored BN254 math chaingraph/kernels/_computeproof.mjs A stored receipt covers the node's published fixture run; a new run gets its own receipt when someone proves it offline.

A stored receipt proves that the node's kernel ran on its published fixture, and it is renewed by an offline re-prove when the inputs or the kernel change; until then a new run reads compute_proof_ready: deferred, as ours did. A freshness check flags receipts whose journal names an earlier kernel digest. The verifier handles RISC Zero receipts, and the SPEC names SP1 as another system that emits the same seal format.

Prompt at this stepverify without re-running
Verify art-591's Groth16 seal against its ImageID and journal with the published verifier, without re-running the kernel. Then tell me whether my own run today is covered by that receipt.
The seal verifies for the node's fixture run. A new run is covered once someone proves it offline; until then its artifact says compute_proof_ready: deferred.
SPEC §18.1 VerificationverifySealGroth16 page
14
Step 14 · Session receipt and anchors

Bind a session and let outside authorities timestamp it

build_session_receipt folds any number of execution hashes into one Merkle root. anchor.ainumbers.co then asks independent timestamp authorities to sign that root as RFC 3161 tokens; OpenTimestamps and a witness-cosigned Sigsum log are supported too (SPEC §20). The tokens verify offline against pinned roots, with no AINumbers server involved.

ten live runs on this page ad46… a7a6… 4242… 2266… c548… 7519… ef76… 3ef8… f5a9… e89f… session_receipt_root7bc2980bc7d8…c26b Sigstore TSA2026-09-26 02:48:56Z DigiCert2026-09-26 02:48:56Z FreeTSA2026-09-26 02:48:57Z

An anchor fixes when a value existed; steps 4 to 13 establish what the value means. The ledger at ledger.ainumbers.co replays hashes, signatures, kernel identity and gate decisions in the browser from a URL fragment, and the anchor page verifies timestamp tokens the same way, so both checks run on the reader's own machine.

Prompt at this stepbind and timestamp
Bundle every execution hash from this session into one receipt with build_session_receipt, then timestamp the root with anchor_hash on https://anchor.ainumbers.co/mcp using the sigstore, digicert and freetsa authorities, and verify the tokens.
Live: root sha256:7bc2980bc7d8a719166804e9bd9e553f767d9dd2fd3f96c1ac9b14cbd669c26b, three RFC 3161 tokens, all valid. Details and download at step 18.
SPEC §20 Anchor Bindinganchor.ainumbers.coEvidence Estate explainer
Part two · The top of the staircase

Three prompts that climb every step at once

Each example below gives a copy-paste prompt for any agent that can reach the public MCP server or a browser tab, the live answers it produced, and an animation of what happened. They cross two kinds of boundary: workflows that hand receipts to one another, and blockchains, each of which a signature is bound to.

15
Example 1 · One authorization across two blockchains

An agent's USDC authorization is valid on exactly one chain

EIP-3009 lets an agent pay with a signed transfer authorization, and x402 uses it for HTTP payments. EIP-712 folds the chain id and the token contract into the digest the agent signs, so a signature made for USDC on Base cannot be replayed on Ethereum. The x402-spend-evidence workflow checks both halves, and the results below are from live runs.

agenttest key 1 authorization for Base from 0x7e5f…5bdf (the signer) to 0xFFcf…09f2 value 1000000 = 1 USDC nonce 0x…2a domain 8453 + USDC 0x8335…2913 digest 0x6948b98d…f1b7 authorization for Ethereum same fields, same signer domain 1 + USDC 0xA0b8…eB48 digest 0x9207db39…25a0 new digest, new signature Base · chainId 8453 Ethereum · chainId 1 590 591 592 PASS compositead46564c…211bdomain chain + contract match replayed 590 591 592 REFUSE domain chain + contract mismatcha7a6588b…0269 590 591 592 PASS composite42420965…575e changing only the domain changes the digest, so each signature works on one chain
RunDomain check (art-592)Composite execution hashVerify
Signed for Base, checked on BasePASSad46564c00bd402b0e6e5c930187d19236149d75d84cd4b40529bb2bdf84211bledger
Same signature replayed on EthereumREFUSE chain + contract mismatcha7a6588be0ebbb9d74430c09c1e40021f9f5ac98e3608c8e373daaec912b0269ledger
Signed for Ethereum, checked on EthereumPASS424209654e4c3106de219067251a739f023c7c65ef259b32cac649b1d933575eledger

The signer is the public test key 1 (address 0x7e5f4552091a69125d5dfcb7b8c2659029395bdf), and the recovered signer equals the authorization's from. The workflow produces evidence about the authorization; moving the funds and enforcing nonce uniqueness happen in the USDC contract at settlement. Each ledger link carries the whole run in its URL fragment and re-checks it in your browser.

Prompt
You are checking an agent's USDC payment authorization before a merchant accepts it. Use the MCP server at https://mcp.ainumbers.co/mcp (streamable HTTP, no key). All data is synthetic: the signer is the public test key 1.

1. Call run_chain with chain "x402-spend-evidence", compute "server", and these inputs:
{"art-590-x402-eip712-digest-recomputer":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","from":"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf","to":"0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f2","value":1000000,"validAfter":0,"validBefore":2000000000,"nonce":"0x000000000000000000000000000000000000000000000000000000000000002a"},
 "art-591-x402-signer-recovery-verifier":{"digest":"0x6948b98d3f3adffc2d4e9d6a62634dddfd9ed74221f1970c54fe301712cbf1b7","r":"0x2a7b25162f218d75ae1731cc95931e21b505aa5e095f23a6ae07c4394fd3b457","s":"0x36c25d04da5f28533648b7ea241aa84ce5b138f90fb23dcb53a6969c2b2173bf","yParity":1,"claimedFrom":"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"},
 "art-592-x402-domain-nonce-window-checker":{"expected_chain_id":8453,"expected_verifying_contract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","validAfter":0,"validBefore":2000000000,"now_unix":1790000000,"nonce":"0x000000000000000000000000000000000000000000000000000000000000002a","nonce_already_used":false}}
   Report each step's verdict and execution_hash, the composite_execution_hash and the ledger_url.
2. Someone replays the same signed authorization on Ethereum mainnet. Run the workflow again, changing only art-592's expected_chain_id to 1 and expected_verifying_contract to 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48. Report the verdict and explain why it changed.
3. Recompute the digest with chainId 1 and the mainnet USDC contract, and explain why the Base signature cannot be reused for it.
4. Call build_session_receipt over the two composite hashes, in order, and give me the root.
Live answers: Base run PASS, composite ad46564c…211b. Replay REFUSE (DOMAIN_CHAIN_MISMATCH, DOMAIN_CONTRACT_MISMATCH), composite a7a6588b…0269. Mainnet digest 0x9207db39…25a0. Session root sha256:af031f811510abae28aae56785dde54a66b1730a25966723c72b5c6abc4e21ef.
art-590 · art-591 · art-592EIP-712 · EIP-3009 · x402workflow page
16
Example 2 · Agent under a signed Work Mandate

A receipt that proves which policy was in force

A principal signs a Work Mandate that scopes what an agent may run (SPEC §22). run_chain verifies the signature, then folds the mandate hash into every step, so the receipt proves which policy governed the run. When a gate trips, the run halts and opens a record that a person must close.

principal Work Mandate scope: 2 chains valid to 2026-10-25 did:key:z6MkhU7i…u2T4 mandate_hash 2266ce3efbb3…5f73 agent run_chainsignature ok agent-commerce-conformance art-01 art-12 art-03 art-30 gold dot: mandate_hash folded into the stepwithout mandate e51f3c23…8bb6with mandate c5486c05…5eb6 escalation-sla-supervised-autonomy-receipt art-274 art-67 gategrade F: escalate art-236skipped open escalation recordrecord_hash b5f9ce94…d3bacarries mandate_hash 2266ce3e… closes it tampered copy scope edited after signing mandate_bad_signature stops before step 1 The record hash excludes the wall-clock time, so two identical escalations hash identically.
RunStatusComposite or record hashVerify
agent-commerce-conformance, no mandate4 of 4 rane51f3c239b0e4395f5baa5d1f1088eca22852be4521b198089ea3a4356428bb6
same workflow under the mandate4 of 4 ran every step hash changedc5486c0547530fc9542360f73a53f3149d0df9e25abff01071d653088f975eb6ledger
escalation-sla-supervised-autonomy-receipt under the mandateescalated at art-67, art-236 skipped7519b7d687df882f191cb5580ca7f9df93fc1b60bb2d2e56978290d7ad8b3e46
record b5f9ce9472b0de3df9f2bfe2e071910af7ad12163e4b77c73ba3ceadd4abd3ba
ledger
mandate edited after signingmandate_bad_signaturestopped before step 1

The mandate is synthetic: a key generated for this run signed it, scoped to the two workflows above and valid from 25 September to 25 October 2026. Closing the open record takes a signed decision through the anchor server's create_signature_envelope and verify_escalation_closure tools. These runs exercise signature verification and the hash binding.

Prompt
You act for a treasury team under a signed OpenChainGraph Work Mandate. Prove the mandate governed every step, and show what happens when a case leaves the automated path. Use https://mcp.ainumbers.co/mcp. The mandate below is synthetic (a throwaway key signed it) and is valid until 25 October 2026.

MANDATE = {"chaingraph_version":"0.4.0","mandate_type":"work_mandate","tool_id":"work-mandate","generated_at":"2026-09-25T12:00:00Z","policy_parameters":{},"output_payload":{"mandate_type":"work_mandate","scope":{"tool_ids":[],"chains":["agent-commerce-conformance","escalation-sla-supervised-autonomy-receipt"]},"conditions":[],"escalation_triggers":[],"validity":{"not_before":"2026-09-25T00:00:00Z","not_after":"2026-10-25T00:00:00Z"},"principal":{"id":"did:key:z6MkhU7ioaZXvWTnV5eQPCfEuwyX6JMM3roPpgBf3XcDu2T4"}},"execution_hash":"2266ce3efbb34154345acda9018a1955b7a187b310849721b9f02fafcf3e5f73","audit_signature":{"proof":{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:key:z6MkhU7ioaZXvWTnV5eQPCfEuwyX6JMM3roPpgBf3XcDu2T4","proofPurpose":"assertionMethod","created":"2026-09-25T12:00:00Z","proofValue":"z3qwKgvT7MmVLd9XDD4fSnUorXhhq9sruyTvoEwTe4qgzTv6LV7b4Q3JYPduYQ6VeF6rdEL4FixBCHV7tBJZuLVxd"}}}

1. Call run_chain with chain "agent-commerce-conformance", compute "server", and mandate MANDATE. Report each step's execution_hash and the composite. Run it again without the mandate and explain why every hash differs.
2. Call run_chain with chain "escalation-sla-supervised-autonomy-receipt", compute "server", and the same mandate. Report the status, which gate fired, which step was skipped, and the escalation record's record_hash, and confirm the record carries the mandate hash.
3. Change one character inside MANDATE's scope and call run_chain again. Quote the error.
Live answers: with mandate c5486c05…5eb6, without e51f3c23…8bb6. Escalated at art-67 (overall_grade F), art-236 skipped_by_escalation, record_hash b5f9ce94…d3ba with mandate_hash 2266ce3e…5f73. Tampered: mandate_bad_signature.
SPEC §22 Work Mandatesart-01 · art-12 · art-03 · art-30art-274 · art-67 · art-236Mandate Loop explainer
17
Example 3 · Data that stays in the tab

A regulatory check where only hashes cross the boundary

Four EMIR Refit checks, UTI completeness, UPI validity, lifecycle action and reporting readiness, run inside their own pages from fragment links. The trade fields stay in the browser; only four hashes leave, to be bound into a receipt and timestamped. Each page's hash equals the kernel's hash for the same inputs.

your browser tab: the trade fields stay here art-154 UTI completenessuti_complete: trueshared_on_time: true, lag 16 hef76f68f…92b5 art-155 UPI validityupi_valid: trueasset class IR, consistent3ef8679a…7ea1 art-157 lifecycle actionaction_legal: trueNew after nonef5a96705…5205 art-158 reporting readinessready: true, grade A5 of 5 dimensionse89f8f61…5cc8 build_session_receiptreceives the four hashesroot dc2244cae7bb…b167 three timestampauthorities inputs stay in the tab network during each run: the font stylesheet at page load, and nothing after it
Node (in-page, from a fragment link)ResultExecution hash (page = kernel)
art-154 check_emir_uti_completenessuti_completeef76f68fe520581b62ead2423822022b70d71d0dbd69445e9bde8226260892b5
art-155 validate_emir_upiupi_valid3ef8679a7817268f7df888891874caf57a037f39547eb69604590ff8d7c77ea1
art-157 validate_emir_lifecycle_eventaction_legalf5a9670511d044f8ae1f180c39d75c66fa84f6944157791befb523b7044e5205
art-158 run_emir_reporting_fitready, grade Ae89f8f61eb15ddbbd19553c0abb28869c8ed53e46d100228ec171c21f05c5cc8

A third party re-verifies one of these results from its disclosed inputs. For data that stays private, SPEC §25 defines a profile in which a zkVM receipt over committed inputs becomes the verification path; these four nodes use the standard hash. Each page ships its own synthetic sample, and those are the inputs used here.

Prompt
You are a trade-reporting agent working inside my browser. The trade fields must not leave this tab. All values are the pages' own synthetic samples.

1. Open each link below. Each carries its inputs in the URL fragment, which the browser never sends to a server, and computes on load:
https://ainumbers.co/chaingraph/art-154-emir-uti-completeness-checker.html#p=v1.H4sIAAAAAAAACk3NsQrCMBQF0H95c4ab5yNts3XoIDQoakG6hEBDzRIkpqCI_y5uzmc4b9pqIkvTZQ_o4dq74zgwWCDcQZOiNeZYQk159fdQ6ossuX44w_DM-iCnmafGdYYU1RKW6LecnmR1o2UnbQuo3-Aft1Di8ocCI8DnC0SuYMyAAAAA&run=1
https://ainumbers.co/chaingraph/art-155-emir-upi-validator.html#p=v1.H4sIAAAAAAAACqtWKi3IVLJScvHy9TUIizD3iDRxVNJRSiwuTi2JT85JLC5WslLyDFLSUcrMKy4pKs1NzSuJL6ksSAULByvVAgC_AoEMQQAAAA&run=1
https://ainumbers.co/chaingraph/art-157-emir-lifecycle-event-validator.html#p=v1.H4sIAAAAAAAACqtWSkwuyczPiy-pLEhVslLySy1X0lEqKMrML4ovLkksAYnl5eelKtUCAJia9okqAAAA&run=1
https://ainumbers.co/chaingraph/art-158-emir-reporting-readiness-diagnostic.html#p=v1.H4sIAAAAAAAACkXKOwoCQQwA0LtMbbFM6WVCyGbXQEwkH0HEu4uKWr93H5I-l2VOoC6_csDqxuNY0XwYfRFI7yCxHchtk72D1x-XQJ4wXpqKcOb6UjC5kahgiRuUKwcaMeT_qGxMN1IGpPcitwrX_ITHE--iBo6dAAAA&run=1
2. From each page, read the execution hash it produced, and confirm in DevTools that no request left the tab after the page loaded.
3. Send only the four hashes (bare hex, without the sha256: prefix), never the inputs, to build_session_receipt on https://mcp.ainumbers.co/mcp, in the order above, and return the root.
4. Timestamp that root with anchor_hash on https://anchor.ainumbers.co/mcp using the sigstore, digicert and freetsa authorities, and return the three timestamps.
Live answers: the four hashes in the table, zero requests carrying inputs, session root sha256:dc2244cae7bb9e1edf5e6b2ca3fc4dbdd45e3a5bb48a5538a08e3dba4b00b167. Step 4 creates a real public timestamp each time it runs.
art-154 · art-155 · art-157 · art-158EMIR RefitSPEC §25 Private-Input Profile
18
Receipt for this page

Three timestamp authorities signed one root over ten live runs

The ten runs in the three examples (three x402 composites, the mandate, two mandated runs, four EMIR hashes) are bound into one session receipt, root sha256:7bc2980b…c26b, and three independent timestamp authorities signed that root within one second of each other.

Example 1: x402ad46… a7a6… 4242… Example 2: mandate2266… c548… 7519… Example 3: EMIRef76… 3ef8… f5a9… e89f… session_receipt_root (10 leaves)7bc2980bc7d8a719…c26b Sigstore TSA 02:48:56Zserial 00cb1d26…7d803a DigiCert 02:48:56Zserial 00b6271d…348191 FreeTSA 02:48:57Zserial 08773b2a
AuthoritygenTime (UTC, 26 Sep 2026)SerialPolicy OIDChain valid until
Sigstore TSA (OpenSSF)02:48:5600cb1d269d4efb1f2374f5f2672c9bdf02ff7d803a1.3.6.1.4.1.57264.22035-04-06
DigiCert Timestamp Authority02:48:5600b6271da38ff8ad6f4d04f5573f3481912.16.840.1.114412.7.12031-11-09
FreeTSA02:48:5708773b2a1.2.3.4.12040-02-02

The download holds the session receipt (its ten leaves, in order, with their tool ids) and the three RFC 3161 responses, base64-encoded, with their signer certificate chains. To check a token yourself, decode a response to a .tsr file and run openssl ts -verify -in digicert.tsr -digest 7bc2980bc7d8a719166804e9bd9e553f767d9dd2fd3f96c1ac9b14cbd669c26b -CAfile <that authority's root>, or call verify_anchor_binding on the anchor server. To check the root itself, call build_session_receipt with the ten hashes in order and compare.

build_session_receiptanchor_hash · verify_anchor_bindingRFC 3161
Part three · Where this sits

Related work and how to check this page

19
Related work · Trusted Compute Units by Castillo et al. at IEEE ICBC 2025

TCU and OpenChainGraph share a goal and choose different trust roots

Trusted Compute Units frame chained verifiable computation as one abstraction over heterogeneous backends, TEEs and zkVMs, with an on-chain program registry. OpenChainGraph shares the goal and uses the zkVM half. It makes three different choices: software and cryptography only, a published catalog as the registry, and a base layer that anyone can verify by recomputing.

Trusted Compute Units proof-carrying: verify the upstream proof inside OpenChainGraph hash-linked: cite the upstream hash and verify outside unit 1logicprove π1TEE or zkVM unit 2verify π1logicprove π2 unit 3 (sink)verify π2logicprove π3 Program Registry (smart contract, EVM)ImageIDs, verification keys, attestation reportsthe sink proof is verified on-chain; it covers the pipeline node 1kernelh1 node 2kernelh2, parent h1 node 3kernelh3, parent h2 any verifier, any steprecompute the hash, or check the 256-byte seal Graph Index (published JSON) + timestamp anchorskernel digests and ImageIDs in a downloadable catalogchecked in a browser, Worker or CLI; anchors add time
DimensionTrusted Compute UnitsOpenChainGraph
UnitA containerized service: an application component exposing compute and proof retrieval, and a verifiable-computation component that checks external inputs, runs the logic, and commits to internal inputs.A node: one pure kernel plus a declared contract, reachable as a page and an MCP tool, and on some pages as a WebMCP tool, all running the same source.
BackendsHeterogeneous by design: TEEs (evaluated with AWS Nitro Enclaves) and zkVMs (evaluated with RISC Zero).Software and cryptography only. RISC Zero receipts today, through one universal QuickJS guest; the spec is system-agnostic.
RegistryA smart-contract program registry on an EVM chain holding unit ids, verification keys or ImageIDs, and attestation reports.The Graph Index, a published and downloadable catalog, carrying kernel source digests and ImageIDs per node.
ChainingProof-carrying: each downstream unit verifies its upstream proofs inside its own computation, so a consumer checks only the last output.Hash-linked: each step cites its predecessor's hash in parent_hashes, and a verifier checks each receipt on its own. Composing the receipts into one proof is an open direction.
Confidential inputsKept inside the TEE or zkVM, with commitments to internal inputs.Optional: SPEC §25 private-input profile (commitments, the receipt becomes the only verification path); Example 3's pattern keeps data in the browser.
Base layerEvery unit attests or proves.Recompute-to-verify works from the inputs alone; signatures, kernel identity and zk receipts add strength on top.
Where verification runsOn-chain for sink computations, so downstream applications can react automatically.In a browser, a Worker or a CLI; external timestamp authorities are optional.

The two designs meet at composition. A TCU verifies upstream proofs inside the downstream computation, and RISC Zero can verify one receipt inside another guest, so a single Groth16 seal could cover a whole multi-workflow agent run while OpenChainGraph keeps its recompute base layer. That is an open direction for OpenChainGraph. The mapping above is our reading of the paper (arXiv:2504.15717).

arXiv:2504.15717SPEC §18 cites TCU as the analogueOCG paper, related work
20
Check it yourself

Four checks cover every hash and timestamp here

Every hash, seal and timestamp above can be re-derived with public tools, most of them inside a browser tab. These four checks run from a single hash up to the timestamps on the page's receipt.

Recompute a hashverify_execution_hashor the kernel plus _hash.mjs Replay a workflowledger.ainumbers.co/#a=…the run travels in the fragment Verify a sealverifySeal(imageId, journal, seal)from _computeproof.mjs Verify timestampsopenssl ts -verifyor verify_anchor_binding
  1. Recompute a hash. Call verify_execution_hash on https://mcp.ainumbers.co/mcp with an artifact's policy_parameters and output_payload, or run the kernel from the repository and hash the result with chaingraph/kernels/_hash.mjs.
  2. Replay a workflow. Open any ledger link in Example 1 or Example 2; the run travels in the URL fragment, and the ledger re-checks each step in your browser.
  3. Verify a Groth16 seal. Take a node's compute_proof from chaingraph.json and run verifySeal from chaingraph/kernels/_computeproof.mjs against its ImageID and journal.
  4. Verify the timestamps. Download the receipt at step 18, then run openssl ts -verify for each token, or call verify_anchor_binding on https://anchor.ainumbers.co/mcp.

All content on this page is static and processed locally in your browser. No data is transmitted. Do not enter real personal data into any OpenChainGraph tool. Use synthetic or anonymised inputs only.