Decision tools produce artifacts. Artifacts carry a fingerprint of their inputs and outputs. Each artifact can cite the fingerprints of the artifacts it consumed, forming a verifiable, tamper-evident provenance chain. v0.2 adds W3C PROV-DM semantic context, buildType URI, in-toto envelopes, Ed25519 signing, and OpenTelemetry span mapping. v0.3 adds ISO 20022 payload alignment, LEI & did:key party identity, and an OKF companion bundle. v0.3.1 formalizes profile conformance via dereferenceable dct:conformsTo URIs. v0.4 adds Compute Binding (gpu:false kernels run server-side in a single MCP round-trip) and Export Profiles (chaingraph_export generates xlsx, pdf, csv, xbrl, and vc renderings downstream of a fixed execution_hash). v0.5 adds Proof Binding (§16): an optional W3C Data Integrity proof (eddsa-jcs-2022) at audit_signature.proof that turns the artifact from tamper-evidence into authenticated attestation, default-off, holder-chosen, backward-compatible. v0.6 adds Kernel Identity Binding (§17): audit_signature.build_identity.kernel_digest, SHA-256 over the LF-normalised kernel source, cross-checked three ways against the Graph Index compute_images[], closing the gap that execution_hash proves some logic ran but not which. v0.6 also adds Compute-Integrity Proof (§18): an optional zkVM receipt (audit_signature.compute_proof, groth16-bn254 recommended) that turns the §4 hash from re-execute-to-verify into a succinct proof of correct execution, optionally without revealing inputs, software-only, no TEE, no chain. Any agent, anywhere, can re-run the math to confirm any link. No trusted authority required.
OpenChainGraph is built on a concept called cryptographic hashing. Before diving into stages, you need to understand this one idea. Think of a hash as a digital fingerprint for any piece of data, a document, a number, a decision. Feed any data into a hash function (we use SHA-256) and it spits out a unique 64-character string.
Type anything below. Watch the 64-character fingerprint recompute with every keystroke. Then change a single character, even one space, and see the entire output transform.
Changing one letter, just the capital A to lowercase, completely changed all 64 characters of the fingerprint. That's the key property: even the tiniest change produces a totally different hash. There's no "slightly different", it's all or nothing.
Before the math and the JSON, here's the same idea explained with something you already know. Click each step to expand it.
You finish your history essay. Before handing it in, the teacher runs your paper through a machine that produces a unique 64-character code, your paper's fingerprint. If you change even one word after that, the machine produces a completely different code.
In OpenChainGraph: a decision tool runs a calculation and SHA-256 hashes its inputs + outputs. That hash is the fingerprint, the execution_hash.
Your teammate writes the next section of the group project. At the top of her section, she writes: "This builds on Roger's section, fingerprint: a3f9…". Now her work is linked to yours by your fingerprint code.
If anyone later tries to swap in a different version of your section, her fingerprint reference will no longer match, the tamper is caught instantly.
In OpenChainGraph: Tool B lists Tool A's execution_hash in its chain.parent_hashes array. The link is the hash, not a file name, not a URL.
The teacher takes your section, re-runs it through the fingerprint machine, and checks: does the code match what your teammate wrote at the top of her section? If yes, your section is authentic, unmodified.
She then does the same for your teammate's section. She doesn't need to call you, email you, or trust any middleman. The math is the proof.
In OpenChainGraph: any agent or auditor re-hashes {policy_parameters, output_payload} and compares it to the stored execution_hash. Match = verified. No trusted authority required.
Now a student from a completely different school wants to cite your group's project in her own work. She doesn't know your teacher, your school, or your systems, but she can still verify the fingerprints herself. The fingerprint standard is public and open.
She cites your teammate's fingerprint in her bibliography. Now there's a three-link chain spanning two schools, zero phone calls, zero emails asking "can you confirm this is the right version?"
In OpenChainGraph: this is cross-vendor chaining. Two organizations that have never met can form a verifiable provenance chain by both following the same open hash specification.
x-chaingraph capabilityReplace "history essay" with a credit risk score. Replace "teacher" with a bank regulator. Replace "student from another school" with a fintech vendor. The protocol is identical, and that's the point. OpenChainGraph is just the fingerprint standard, applied to financial decisions.
The whole point of the fingerprint system is that you can't secretly change anything. Press the red button below to watch what happens when a bad actor tweaks just one number inside an artifact, even a tiny edit.
Changing even one byte of an artifact produces a completely different SHA-256 hash. Every downstream artifact that cited the old hash now holds a broken reference. The mismatch is instant and obvious, no investigation needed.
There's no central authority to bribe or fool. The math runs locally on any verifier's machine. A bad actor can't quietly edit a credit score, a risk rating, or a loan decision, any change detonates every downstream link in the chain.
Four separate tools make four separate decisions, each one citing the hash of the one before it. Six months later, a regulator audits the loan. Watch the chain light up as each hash is verified, left to right, step by step.
execution_hash. This is depth: 0, the starting point.parent_hashes. Decides you can afford $850/month repayments.The auditor re-runs SHA-256 on each artifact, in order. Every hash matches. That means no one altered the credit score, the affordability calculation, the risk rating, or the final decision between the day the loan was approved and today. The chain is the audit trail: no spreadsheets, no emails, no "trust me."
Every conformant tool takes structured inputs (policy_parameters), runs a deterministic computation, and produces outputs (output_payload). It then wraps inputs + outputs together into a JSON envelope and runs SHA-256 over the combined package. That hash, called the execution_hash, gets stamped onto the artifact before it's sent anywhere.
policy_parameters) and outputs (output_payload) together. Adding the execution_hash turns it into a verifiable record.{"policy_parameters":…, "output_payload":…} with keys sorted alphabetically. Any party can re-run this exact procedure to verify the hash independently.risk_control, liquidity_mandate, credit_assessment. Think of it like a category label, it tells downstream tools and agents what kind of decision this artifact represents.{
"@context": "https://ocg.postoaklabs.com/ns/v0.5",
"chaingraph_version": "0.4.0",
"buildType": "WebCryptoSHA256",
"chain_depth": 2,
"parent_hashes": ["sha256:3f9a…"],
"policy_parameters": { "loan_amount": 45000, "rate": 6.4 },
"output_payload": { "decision": "APPROVED", "score": 712 },
"mandate_id": "urn:uuid:a1b2c3d4…",
"compliance_flags": [],
"audit_signature": {
"execution_hash": "sha256:8e5a…",
"signatures": […],
"proof": {…}
}
}When Tool B consumes the output of Tool A, it copies Tool A's execution_hash into its own chain.parent_hashes array. This single act creates a cryptographically linked chain. Tool C can cite both A and B. The result is a directed acyclic graph (DAG), like a family tree of decisions, where every connection is a hash reference that can be independently verified.
A named chain of steps like this is a workflow. Package a workflow with a signed manifest, declared inputs, sample data, and any review gates, and it becomes a pack — a workflow ready to run in Helm.
An auditor can pick any node in the chain, re-run the tool with the recorded policy_parameters, recompute the SHA-256 hash, and compare. A hash mismatch means the artifact was altered or the tool is non-deterministic. No signer, no certificate authority, trust comes from reproducibility. You can verify it yourself in your own browser.
A conformant tool exposes a tools/call MCP endpoint. An AI assistant, Claude, ChatGPT, or any MCP-compatible agent, can call emit_artifact, receive the envelope, then call verify_execution_hash to confirm integrity. The agent never needs to trust the server. It runs the SHA-256 check itself, the same way you ran "Apple" through SHA-256 in the pre-stage above. If the numbers match, the artifact is genuine.
policy_parameters and receives the full artifact envelope. It never modifies anything, the server declares readOnlyHint: true, meaning nothing on the server changes from this call.parent_hashes wiring. This is the agent's recipe, like a cooking recipe that tells you exactly what order to do things.mandate_type, and which tools consume which outputs. Agents read this first to plan a chain before calling anything, like reading a menu before ordering.When two vendors both publish the x-chaingraph A2A capability extension, an orchestrating agent can chain artifacts across them. An OCS constraint solution can cite an ApexLogics credit assessment as a parent. An AINumbers compliance verdict can cite either. Every link is verified through each vendor's own verify_execution_hash. No vendor needs to trust another, the hash is the contract.
Once two suites are L4 with x-chaingraph, their artifacts can chain, and any third party can independently verify the entire provenance graph without asking either vendor. That cross-suite auditability is why OpenChainGraph is a standard rather than an internal convention. The math is the trust. No authority needed.
OCG defines the artifact format and the hash. AIN Bridge is how AINumbers tools actually receive inputs from agents, composers, and prior tool outputs, entirely in the browser, with no server round-trips and no storage writes. Every tool in the suite carries a small Bridge script that listens on three channels and fills form inputs the moment the page loads.
{"elementId": value, …} as base64url and append as a URL hash fragment: tool.html#in=<token>. Add &run=1 to auto-execute. The hash is never sent to a server, it lives only in the browser. Agents use this to hand off a pre-configured tool URL to a user with one click.<iframe> elements and drive them via window.postMessage. Three message types: AIN_PREFILL (fill inputs), AIN_RUN (trigger execution), AIN_COLLECT (retrieve the output Policy Mandate). Same-origin only, cross-origin composers cannot drive tools.intake: true render a drop zone. Drag, choose, or paste a .policy.json from any prior tool. Bridge validates mandate_id, tool_id, and payload, then maps payload keys to matching element IDs, the same mechanism as prefill, driven by mandate rather than URL. The execution_hash field in the mandate closes the OCG provenance loop.input and change events after filling so reactive tool UIs update correctly.v0.2 adds a @context URL to every artifact. This single field makes OpenChainGraph artifacts interpretable by any W3C-compliant provenance tool. Field names like tool_id map to standardized PROV-DM terms, so a DORA audit system, a prov:Entity processor, and a DCAT catalog can all consume the same artifact without a custom adapter. A buildType URI declares exactly which hash construction algorithm was used, making the provenance machine-auditable end to end.
buildType tag appears below the artifact node.https://ainumbers.co/chaingraph/context/v0.3) that maps all OpenChainGraph field names to W3C standard vocabulary. Any JSON-LD processor understands the artifact automatically.parent_hashes maps to this PROV-DM property, the standard W3C term for "this entity was derived from another entity." Auditors using any PROV-aware tool see the chain automatically.https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256 declares the exact construction: sorted-key JSON → UTF-8 → WebCrypto SHA-256. No ambiguity about what was hashed or how.chaingraph.json is expressible as a dcat:Catalog with each tool as a dcat:Dataset. Any data catalog portal can index an OpenChainGraph suite without a custom connector.The execution_hash proves integrity: the content hasn't changed. But it doesn't prove authenticity: who produced it. v0.2 upgrades audit_signature from a bare string to a structured in-toto ITE-6 attestation envelope, {payloadType, payload, signatures[{keyid, sig}]}. An optional Ed25519 key (RFC 8032, via WebCrypto) signs over the execution_hash. These are two independent checks: a valid hash but invalid signature means the content is intact but the signer is wrong.
audit_signature from a free-form string to a structured object: payloadType (MIME type), payload (base64url), and a signatures array with keyid and sig per signer.Ed25519 key pair signs over the execution_hash bytes. Small (32-byte keys, 64-byte signatures), fast, and natively available in modern browsers via crypto.subtle.keyid in each signature entry identifies which public key was used. Verifiers look up the public key by keyid to confirm the signature, enabling key rotation without re-signing old artifacts.v0.2 defines a deterministic mapping from OpenChainGraph artifacts to OpenTelemetry spans. The first 8 bytes of an artifact's execution_hash become its spanId. The first 8 bytes of parent_hashes[0] become the parentSpanId. The root artifact's execution_hash becomes the traceId for the whole chain. Run artifactToOtelSpan() on any artifact and it drops into Datadog, Jaeger, or Honeycomb as a waterfall trace, no instrumentation code required.
artifactToOtelSpan(). Right: the resulting OTel waterfall, each bar indented by depth, showing spanId and parentSpanId labels.execution_hash become this artifact's OTel span ID. Deterministic, same artifact always maps to the same spanId. No random IDs, no coordination required.parent_hashes[0] become the parentSpanId, pointing to the parent artifact's span. This is what creates the waterfall indentation in Datadog / Jaeger / Honeycomb.execution_hash (depth: 0, no parents) becomes the traceId for the entire chain. Every artifact in the chain shares this traceId, grouping them into one coherent trace.ⓘ spanId = first 16 hex chars of execution_hash · parentSpanId = first 16 hex chars of parent_hashes[0] · traceId = root artifact execution_hash · status.code = ERROR if any compliance_flag has severity:ERROR
v0.3 gives the financial payload a semantic standard to complement the provenance envelope's W3C PROV-DM alignment. The ISO 20022 semantic profile is an optional JSON-LD overlay, a second @context entry, that maps amount, currency, party, and agent fields to ISO 20022 business elements. It never touches the execution_hash preimage (§2 is unchanged). Tools that aren't payment tools carry no profile: a VaR engine or DORA classifier has nothing ISO 20022-shaped to declare.
@context array: the existing OCG context plus the new iso20022-context.jsonld. No other field changes. The execution_hash preimage is unaffected, a v0.1 verifier produces an identical hash.amount, currency, debtor, creditor, lei, bicfi, settlement_date, remittance_information. Risk scores, model outputs, compliance flags, none of those are profiled.v0.3 formalizes two optional identity anchors. A did:key identifier, a self-describing, multicodec-prefixed base58btc encoding of the Ed25519 public key, is the recommended form for keyid in the signature envelope. An ISO 17442 Legal Entity Identifier (LEI) optionally binds the publisher (and signing key) to a regulator-grade legal-entity anchor. Together they bridge the signing layer (§6) and the ISO 20022 payload layer (§8): the same LEI can identify both the tool vendor and a debtor or creditor in a payment artifact.
did:key:z6Mk… URI encodes the raw Ed25519 public key in multicodec + base58btc form. It's resolvable without a registry, anyone can derive the public key from the DID alone. Replaces an opaque hex fingerprint with a standardized W3C DID identifier.publisher.lei (who signed this artifact) and debtor.lei / creditor.lei (party to this payment). One identifier serves both the provenance signing layer and the ISO 20022 financial payload layer.publisher.lei and the keyid form describe who produced the artifact, not what decision was made. Neither enters the execution_hash preimage, a verifier correct for v0.1 computes identical hashes on v0.3 artifacts with full party identity.v0.3 publishes an Open Knowledge Format (OKF) companion bundle auto-generated from chaingraph.json: one markdown concept file per Graph Index node. It's the narrative complement to the DCAT catalog, DCAT is what an agent reads to plan a chain before calling anything; OKF is what an agent (or human) reads to understand what a tool does and when to use it. Crucially, OKF concept documents are knowledge, never decision artifacts, they MUST NOT carry an execution_hash.
chaingraph.json) tells an agent which tools exist, which tools feed which, and which MCP endpoint to call. It's the execution map. OKF sits on top of it as the meaning layer, separate by design.ocg:consumes and ocg:feeds edges in the DCAT catalog become markdown hyperlinks between concept documents, reproducing the graph structure in a human-readable form. One concept file per live node; regenerated on every index change.execution_hash or audit_signature. It is knowledge, not a decision. Nothing in the OpenChainGraph verification path depends on OKF, the bundle is generated, swappable, and purely informational.v0.3.1 makes semantic profile conformance machine-resolvable using W3C PROF and Content Negotiation by Profile. A profile is now published at a dereferenceable URI and declared with dct:conformsTo, not just named by an opaque string token. The semantic_profile token (e.g. "iso20022:pacs.008-subset") is retained as a registered alias pointing to the URI via a token↔URI registry. Every node declares only what it truthfully conforms to, a VaR engine carries no ISO 20022 profile. The hash preimage is unchanged; all prior artifacts remain valid.
dct:conformsTo: ["https://ainumbers.co/chaingraph/profiles/iso20022/pacs008-subset.jsonld"]. Any verifier can fetch it. The profile URI resolves to a PROF prof:Profile resource listing schema and guidance.semantic_profile string token (e.g. "iso20022:pacs.008-subset") is retained as a registered alias. The authoritative token↔URI map is published at profiles/registry.json. Existing v0.3 artifacts remain valid with no changes required.iso20022:pacs.008-subset. A party-only node gets the new iso20022:party-identification profile. A VaR engine or DORA classifier gets no ISO 20022 profile. Forcing a payment profile onto a non-payment node would be a false conformance claim, this design avoids it.dct:conformsTo, @context, and semantic_profile are all outside the execution_hash preimage (sorted-key SHA-256 over {policy_parameters, output_payload}). Backward compatibility is complete and mathematical, not just claimed.v0.4 introduces Compute Binding: a registered kernel (pure ESM, exports compute(), buildArtifact(), meta) runs directly on the Cloudflare Worker for nodes where gpu:false. An AI agent sends policy_parameters in a single tools/call and receives a complete, fully-hashed v0.4 artifact in one round-trip, no browser delegation, no user interaction, no waiting for a page to load. The new compute_mode: "server" envelope field tells every downstream consumer how the hash was computed. It is excluded from the hash preimage, so all prior artifacts remain valid.
compute(params) runs the calculation server-side; buildArtifact(params, output) assembles the OCG envelope with execution_hash; meta declares the kernel name and tool version. Registered in kernels/index.mjs and vendored into data/ at build time.compute_mode: "server" when the Worker ran the kernel, excluded from the hash preimage. The compute_capability field in chaingraph.json advertises which nodes support server-side compute, so agents can discover it before calling. compute_mode: "auto" lets the Worker decide.tools/call: the agent sends parameters and receives a complete, signed artifact. No browser. No wait. The spec calls this agent-native execution.readOnlyHint: true. Sensitive policy_parameters never leave the MCP call/response envelope.v0.4 defines the chaingraph_export umbrella: xlsx, pdf, csv, xbrl, and vc renderings generated from a verified artifact. v0.4.1 adds chaingraph_export:vc (W3C Verifiable Credentials 2.0) as a base profile available on every node, covered in Stage 14. The key invariant: exports are produced downstream of execution_hash and are excluded from the hash preimage. The cryptographic anchor is fixed before any export runs. The export_artifact MCP tool (readOnlyHint: true) takes an artifact and a format and returns a deterministic rendering, the execution_hash travels intact into every output as embedded metadata. Regulatory XBRL submissions use the xbrl_taxonomy parameter (e.g. "eba-corep-own-funds") to select the filing profile.
xlsx (three-sheet analyst workbook: Decision / Summary / Provenance), pdf (signed printable render), csv (tabular data extract), xbrl (machine-readable regulatory submission). Each is generated from output_payload after the execution_hash is already fixed.export_artifact(artifact, format, xbrl_taxonomy?). The tool generates the rendering on demand and returns it, nothing on the server changes. Advertised via export_capability in chaingraph.json nodes so agents can discover it before calling.chaingraph_export field and all export outputs are outside the hash preimage. The hash is computed over {policy_parameters, output_payload} only, as in every prior version. All existing artifacts remain valid with no re-hashing required. The export is the last mile, not the source of truth.xbrl_taxonomy: "eba-corep-own-funds" for a bank capital COREP filing. The XBRL instance document embeds execution_hash as a named fact, regulators can trace every submitted number back to the verified artifact that produced it, with no spreadsheet chain-of-custody required.v0.4.1 adds a fifth export profile: chaingraph_export:vc. Unlike xlsx/pdf/csv/xbrl, which target human reviewers and regulatory filings, the VC profile targets agents and counterparties that already speak W3C Verifiable Credentials 2.0. It renders any verified artifact as an OpenChainGraphCredential (application/vc+json). It is a base profile: no export_capability declaration required, available on every node. The ocg:hashAnchor field re-states the canonical execution_hash inside the VC envelope so downstream consumers can always route verification back to the canonical JSON. Key distinction: this is a view, not a secured credential, it carries no VC proof. For a signed, secured artifact, see Stage 15.
execution_hash travels into the credential envelope as ocg:hashAnchor. The VC is a lossless structural re-expression. Hash preimage unchanged; chaingraph_version stays "0.4.0".export_capability.type array contains "VerifiableCredential" and "OpenChainGraphCredential". The id is urn:ocg:artifact:<bare-execution-hash>, deterministic, no UUID or clock. Same artifact always maps to the same credential URI.execution_hash, digestMethod, and a verify_url inside the VC envelope. Not a VC proof suite, a structured pointer that routes any downstream consumer back to the original verification path.execution_hash and adds no W3C Data Integrity proof. The envelope and chaingraph_version are unchanged. For a secured VC, add a proof via Stage 15 (Proof Binding).v0.5 adds the final layer: Proof Binding. Until now, execution_hash proved integrity, the content hasn't changed since it was produced. But it didn't prove who produced it at the artifact level. v0.5 adds an OPTIONAL W3C Data Integrity proof (eddsa-jcs-2022) at audit_signature.proof. Because execution_hash sits inside the secured document, one signature transitively secures both the §4 hash anchor and the full artifact envelope. The mechanism is default-off: signing makes the run linkable to a key, eroding the zero-PII anonymous posture. Tools MUST surface that opting in de-anonymizes the run. The hash preimage is unchanged; unsigned artifacts are byte-identical to v0.4.1; only spec_version advances to 0.5.0.
audit_signature.proof, not at artifact root (additionalProperties:false in frozen v0.4 schema) and not inside signatures[] (which retains its DSSE/in-toto meaning). A signed v0.5 artifact still validates under the v0.4 schema.cgCanon JCS canonicalizer from kernels/_hash.mjs as §4, no second canonicalization path. proofValue is "z" + base58btc(Ed25519.sign(key, hashData)), multibase-encoded. Produced by shared kernels/_proof.mjs; browser inlines it, Worker imports it, byte-identical output.proof. Because execution_hash sits inside the secured document, a whole-artifact signature transitively secures both the §4 hash anchor and all other artifact fields, one key pair, two guarantees.did:key, self-describing, no registry. Institutional issuers SHOULD use did:web anchored to their domain, key held in HSM/KMS, signing performed server-side via the §12 Compute path (same Worker).zero_pii_verified guarantee still holds for inputs; only the identity of the signer is revealed. Proof Binding MUST default OFF and MUST NOT be auto-applied. A tool may offer signing as an opt-in for institutional issuers wanting auditor-grade attestation while preserving anonymous-by-default behavior for all other callers.
Every artifact carries two fields that Stage 1 didn't have space to unpack. mandate_id is a UUID v4 assigned at run time, it's the "ticket number" for this specific execution, used by ops teams for support queries and audit lookup. compliance_flags[] is the structured exception layer: an array of flag objects with code, severity (INFO / WARN / ERROR), and message. A valid execution_hash and one or more compliance_flags with severity ERROR are not contradictory, integrity and business-logic warnings are fully independent. The OTel mapping converts compliance_flags into span status.code: any ERROR flag produces status.code = ERROR on the span.
{code, severity, message}. Severity levels: INFO, WARN, ERROR. A valid hash + ERROR flag is fully valid, the content is intact AND the business logic raised a warning. These are independent properties.compliance_flags into span status.code: any flag with severity: ERROR sets status.code = ERROR on the span. INFO and WARN flags leave status at OK. This makes compliance exceptions visible in Datadog, Jaeger, and any OTel-compatible trace viewer.compliance_flags and mandate_id are outside the hash preimage, only policy_parameters and output_payload are hashed. This means a tool can raise a WARN or ERROR flag without changing the verifiable hash of its decision inputs and outputs.Stage 6 covered what the signature does. This stage covers how the key is born, where it lives, how verification finds it, and how it gets rotated. The full lifecycle is four steps: Generate (crypto.subtle.generateKey in the browser, or Node's crypto.generateKeyPairSync server-side), Publish (export the public key as hex → did:key → add to chaingraph.json under ocg:signing_keys), Sign (the kernels/_proof.mjs or in-toto envelope signer produces the signature bytes), Verify (any verifier imports the public key from the Graph Index and calls crypto.subtle.verify). Rotation adds a new entry with a valid_from date, old artifacts signed under the prior key remain permanently verifiable using the prior entry.
crypto.subtle.generateKey({name:"Ed25519"}, true, ["sign","verify"]) produces a CryptoKeyPair. Export public key as raw bytes → hex string → derive did:key (multicodec 0xed01 prefix + base58btc). Never export the private key bytes outside a secure context.ocg:signing_keys: [{keyid:"did:key:z6Mk…", valid_from:"2025-01-01"}]. Any verifier that fetches chaingraph.json from the tool's endpoint can now derive the public key from the did:key and verify any artifact signed with it.kernels/_proof.mjs. Both use crypto.subtle.sign("Ed25519", privateKey, data). Output: 64 bytes → encoded in the artifact.valid_from. Set valid_until on the old entry if desired. Verifiers MUST use the key whose valid_from/valid_until bracket the artifact's created_at timestamp. Old artifacts remain verifiable permanently, rotation is additive, not destructive.Stage 3 showed an agent calling a tool. Stage 4 showed cross-vendor chains. But neither answered: how does the agent know which tools to call, in what order, before making any calls? The answer is the chaingraph.json Graph Index, a DCAT 3.0 catalog that every node publishes at its well-known URL. It declares ocg:consumes (what this node depends on) and ocg:feeds (what this node can produce input for), forming a dependency DAG. Agents read the full graph before calling anything, plan the optimal execution path, and avoid invalid partial chains. ocg:conformance_level (L1–L4) signals implementation completeness. dcat:accessService + ocg:mcp_tool_name give the callable address. The Graph Index is what makes OCG an orchestration protocol, not just a hash format.
chaingraph.json is a DCAT 3.0 dcat:Catalog published at the tool's well-known URL. Each tool is a dcat:Dataset entry with mandate_type, compute_capability, export_capability, dct:title, and ocg:mcp_tool_name. Agents fetch this once to understand the full tool landscape.ocg:consumes: this node reads artifacts from these upstream tools. ocg:feeds: this node's output can be consumed by these downstream tools. Together they form a directed acyclic graph, agents traverse it to determine which tool calls must precede others and which can be parallelized.dcat:accessService.endpointURL + ocg:mcp_tool_name give the agent everything it needs to call the tool: the MCP server URL and the tools/call tool name. No out-of-band configuration required, the Graph Index is the service directory.Every previous stage has shown that execution_hash proves "this output follows from these inputs". But it says nothing about which code performed the computation. A dishonest server could substitute a different kernel, one with backdoors, different rounding, or different regulatory logic, while still producing a valid hash over its outputs. v0.6 closes this gap with Kernel Identity Binding (§17): the artifact MAY record a kernel_digest, a SHA-256 over the LF-normalised kernel source bytes, at audit_signature.build_identity. A verifier performs a three-way cross-check: artifact kernel_digest == Graph Index compute_images[].image_id == digest recomputed from the published source file. Any mismatch fails the binding. Important caveat (§17.2): this is an advisory claim, not a cryptographic proof of execution, a dishonest server could still record the right digest while running different code. That is what §18 solves.
_buildid.mjs (LF-normalised, WebCrypto SHA-256). The digest travels into the artifact at audit_signature.build_identity.kernel_digest AND into the Graph Index compute_images[]. The verifier pulls both and checks three-way equality. The tamper button swaps the kernel, watch all three values diverge and the binding fail._buildid.mjs reads the kernel file, normalises all line endings to LF, and runs WebCrypto SHA-256 over the UTF-8 bytes. Result: sha256:<hex>. Stored at audit_signature.build_identity.kernel_digest. Deterministic: same source always → same digest regardless of OS or runtime.chaingraph.json SHOULD publish its kernel digest: compute_images: [{system:"sha256-source", image_id:"sha256:…", valid_from:"…"}]. This is the second leg of the three-way cross-check, the public, independently verifiable record of which kernel a node claims to run.artifact.build_identity.kernel_digest == (2) chaingraph.json compute_images[].image_id == (3) recomputed digest from the published source file. All three must match. Any mismatch, tampered artifact, stale Graph Index, or modified source, fails the binding immediately.§17 pins which kernel was claimed. §18 makes it cryptographic. An artifact MAY attach an optional zkVM receipt at audit_signature.compute_proof: a zero-knowledge proof that this specific program (identified by imageId) produced this specific output (recorded in journal) from some inputs, without the verifier having to re-run the kernel, and optionally without revealing those inputs at all. This is OCG's analogue of Trusted Compute Units (arXiv:2504.15717), but software-only: no TEE, no hardware enclave, no blockchain anchor. The system is agnostic (risc0, sp1, jolt…); groth16-bn254 (~200 bytes) is recommended. Seal verification is delegated to the named system's vetted verifier, exactly as §4 delegates SHA-256 to WebCrypto and §16 delegates Ed25519. Proving is off-band: it requires a Rust toolchain and heavy compute; it MUST NOT be claimed to run in the browser or Worker. Default-off.
{type:"ZkVmReceipt", system:"risc0"|"sp1"|"jolt", receiptFormat:"groth16-bn254"|"stark", imageId:"sha256:…", seal:"<base64>", journal:{output:…}}. Lives at audit_signature.compute_proof, hash-excluded, under the tolerant audit_signature object. A v0.6 artifact still validates under the frozen v0.4 schema.imageId in the receipt MUST match compute_images[].image_id in the Graph Index node entry, the published claim of which program the node runs. Together with §17 kernel_digest, this gives a two-layer program identity check: source digest (advisory) + zkVM guest identity (cryptographic).journal.output MUST equal the artifact's output_payload. The verifier checks this binding directly, no re-execution. If the journal matches and the seal verifies, the verifier has cryptographic assurance that this program produced this output.policy_parameters carries commitments/hashes instead of cleartext. §4 recompute is then unavailable to third parties. The receipt becomes the sole verification path. A tool in this mode MUST surface that to users. Like §16, default-off.L1, §4 execution_hash: tamper-evidence; verifier must re-run with cleartext inputs. L2, §16 Proof Binding: authenticated attestation; a named key vouches for the whole artifact. L3, §18 Compute-Integrity Proof: succinct proof of correct execution; verifier checks a receipt without re-running, optionally without seeing inputs. They compose: a §18 receipt MAY itself be covered by a §16 proof. Proving is off-band, MUST NOT be claimed to run in the browser or Worker.
A rulebook nobody checks is just a wish list. Most specifications are written as prose: they say a conformant tool should do this and must not do that, and then everyone hopes implementers read carefully and behave. OpenChainGraph takes a stricter stance, and it is the reason you can trust everything on the pages before this one.
The rule is simple: every sentence in the standard that says MUST has to name a script that fails the build the moment the rule is broken. Conformance is not a promise a vendor makes. It is a test that either passes or does not.
A few of the gates a build has to pass before anything ships:
This is what "conformance-by-construction" means. You do not audit a vendor's good intentions. The standard ships with its own enforcement, so a build that is green is a build that obeyed every rule, and a build that broke a rule never reached anyone.
An artifact's execution_hash proves what a tool computed. It does not prove when. Section 20 closes that gap by defining the anchor_bindings array, which sits outside the hash scope so an artifact's integrity proof is unchanged while carrying one or more independent timestamp receipts.
Each binding names a timestamp authority, carries the hash that was sent, and embeds the signed response. The timestamp authority never sees your file, only the hex digest.
anchor_bindings sits outside the execution_hash preimage. Adding it after the fact does not change the hash — §4 verification passes on the same artifact before and after anchoring. The two checks are fully independent.execution_hash, you have proof of both the computation's content and the moment it occurred.openssl ts -verify and the issuing CA's root certificate. No network call, no account, no expiry. The receipt is self-contained evidence that survives any server going offline.parent_hashes, so the timestamp receipt anchors the whole chain by transitivity.Supported binding types in §20:
openssl ts -verify and the issuing CA's root certificate, which the standard pins.To anchor an OCG artifact, drop it on the Anchor page at anchor.ainumbers.co. The page reads the execution_hash field directly — no re-hashing of the raw file — and emits the artifact with anchor_bindings appended per §20. The anchor_document_integrity MCP tool exposes the same operation for use inside multi-step workflows.
Fifteen questions that come up every time someone meets OpenChainGraph for the first time, covering the plain-language basics, the core standard, the v0.4 additions, v0.5 Proof Binding, and the AIN Bridge integration layer.
No. There is no network to join, no coin, no miners, and no shared ledger that strangers have to agree on. Each tool runs on its own and stamps its result with a fingerprint. Trust comes from re-doing the math yourself, not from a crowd voting on what is true.
If you want the longer, more technical comparison to blockchains, Git, and supply-chain attestations, see the "Isn't this basically a blockchain?" question further down.
Two different things share the word, so it is worth separating them. The "chain" in the name refers to the way one result cites the fingerprint of the result it used, so decisions link into a tamper-evident line you can trace end to end. That is the mechanism.
Separately, when several tools are wired together to run as one repeatable, multi-step process, we call that a workflow in plain language. So a "workflow" is a named recipe you can run, and the "chain" is the fingerprint trail it leaves behind. When this page says run a workflow, it means the runnable recipe; when it says the chain, it means the linked trail of hashes.
Three audiences, reading the same page from different doors. A compliance officer or auditor gets a decision trail that proves what ran and that nothing was altered after the fact, without having to trust a vendor's word. An engineer gets a small, precise standard with real gates and one canonical way to build a hash. An AI agent gets tools it can discover, call, and verify on its own over MCP.
The Beginner, Practitioner, and Advanced badge on each stage marks the natural entry point for each reader, so you can skim to your level and go deeper only where you need to.
The surface similarity is real, both use hash pointers to link data objects into a DAG. But the resemblance ends there. A blockchain requires distributed consensus: a network of nodes that must agree on a shared, append-only ledger. OpenChainGraph has none of that. Each vendor runs their own tool and publishes their own artifact. There is no shared ledger, no mining, no validators, no network to join.
The closer analogy is Git's object model, a directed acyclic graph of content-addressed objects where trust comes from recomputing the hash yourself, not from a consensus mechanism. Or in-toto / SLSA supply chain attestations: hash the artifact, sign it, let anyone verify it independently. OpenChainGraph applies that pattern to financial decision artifacts instead of software build artifacts.
Old hashes remain permanently valid for the inputs and outputs they were computed over, the hash doesn't "expire." But if a tool changes its computation logic (say, a risk model update) and you re-run the same policy_parameters, the new output_payload will differ, producing a new, different execution_hash. That's correct behavior, it's a different decision.
The recommended practice is to version your tools explicitly: tool_version: "1.2.0" inside the artifact envelope. A downstream tool that cites an artifact from v1.1.0 is permanently linked to that exact version's output. Auditors can distinguish "the credit model on 14 March 2026" from "the updated model on 1 April 2026" by comparing the parent hashes. Version drift is a feature, not a bug, it makes model changes auditable by design.
Yes, MCP is an optional integration layer, not a requirement. The core of OpenChainGraph is just a JSON envelope and a SHA-256 hash function. Any tool that emits a JSON artifact with execution_hash and chain.parent_hashes is conformant, regardless of how that artifact is transported, REST API, message queue, file drop, email attachment, or a direct database write.
MCP becomes relevant in Stage 4 (cross-vendor chaining) when you want agents to autonomously discover, call, and chain tools from a chaingraph.json Graph Index. For teams that aren't there yet, the value is simpler: tamper-evident audit trails across your existing pipeline, with no new infrastructure. Add MCP when you're ready, the artifacts are already compatible.
Those standards govern payment execution, the mechanics of how an AI agent authorizes and settles a transaction. OpenChainGraph governs decision provenance, the verifiable record of why a decision (including a payment decision) was made, what inputs drove it, and which prior decisions it depended on.
They're complementary layers of the same stack. An AP2-conformant agentic mandate might cite an OpenChainGraph artifact as its authorization evidence: "This payment was authorized because the liquidity stress tool (hash: a3f9…) determined headroom was sufficient, which itself cited the FX hedge optimizer (hash: 7c2b…)." The payment rails handle settlement; OpenChainGraph handles the audit trail upstream of it. Neither standard competes with the other.
The DRAFT label is a candid characterization of ecosystem readiness, not technical readiness. The hash construction, the artifact envelope, and the verification procedure are stable and implementable today, the reference implementation exists and works. What isn't ready is the ecosystem: most MCP tool catalogs don't yet exist, most vendors don't yet emit structured JSON artifacts at all, and cross-vendor chaining requires two parties who both follow the spec.
The recommended posture: implement the artifact envelope now in any tool that produces decisions your team (or regulators) will need to audit later. The lift is small, one SHA-256 call and a JSON wrapper. When the ecosystem catches up, agentic payment stacks go mainstream, MCP tool catalogs proliferate, regulators start asking for machine-verifiable decision trails, you'll already be producing conformant artifacts. Standards that arrive late to adoption cycles rarely win.
They serve different layers of the stack. An OCG artifact is the canonical provenance record, the tamper-evident envelope whose execution_hash is the SHA-256 of {policy_parameters, output_payload}. It's designed for auditors, regulators, and downstream tools that need to independently verify a decision. The artifact is the source of truth.
A Policy Mandate (.policy.json) is a browser-side handoff format. AIN Bridge produces one when a tool finishes, it packages the tool's inputs and key outputs into a file the user can drop into the next tool's intake zone. The execution_hash field in the mandate is inherited from the artifact; it's there for traceability, not for the mandate itself to be hashed. Mandates are ephemeral transit containers. Artifacts are the permanent record. If they conflict, the artifact wins.
The export itself doesn't carry a hash of the export, but it embeds the original execution_hash as metadata. That's enough to anchor it. If someone alters the numbers in the Excel file, the execution_hash in the Provenance sheet no longer matches what you get when you re-run the tool with the recorded policy_parameters and verify the output. The mismatch is the tamper signal.
For high-stakes auditing, the correct workflow is: go back to the canonical JSON artifact (not the xlsx), re-run verify_execution_hash, confirm the output_payload matches what the exported file shows. The export is a rendering for humans. The artifact is the thing that's actually tamper-evident. This is the three-layer model: provenance-out (canonical JSON) → knowledge-in (OKF) → rendered-for-review (exports). Only the first layer is in the verification chain.
No, compute_mode is completely outside the hash preimage. The hash computation hasn't changed since v0.1: SHA-256 over the RFC 8785 canonical serialization of {policy_parameters, output_payload} with keys sorted. It doesn't matter whether a server ran the kernel, a browser ran the tool, or someone computed the artifact by hand. The math is the same.
What compute_mode: "server" tells you is how the tool was executed, not what was hashed. A verifier that ignores the field entirely will still compute an identical hash. This is intentional: every v0.4 field outside the preimage is strictly informational, it annotates the artifact without affecting its verifiability. A v0.1 verifier from 2025 produces the same result on a v0.4 artifact from 2026.
No. The core spec is entirely domain-agnostic. The mandate_type field is a free string, you can use "diagnostic_result", "routing_decision", "eligibility_check", or anything else. The hash construction, the chain model, the MCP integration layer, and Compute Binding work identically regardless of domain.
The ISO 20022 semantic profile (Stage 8) and the LEI / did:key identity model (Stage 9) are optional addenda for payment tool vendors, they don't affect the core hash preimage and aren't required for conformance. The fintech examples throughout this explainer reflect where the spec authors work, not a constraint on who can implement it. If your tool takes structured inputs, runs a deterministic computation, and produces outputs that someone might later need to audit or dispute, OpenChainGraph is applicable.
They're fully independent. §12 and §13 address different integration points, §12 is about where computation runs (server vs. browser); §13 is about how verified results are rendered for human consumption. You can ship a gpu:false server-side kernel without ever implementing export_artifact, and you can implement the xlsx/pdf/xbrl export profiles for browser-computed tools without touching Compute Binding.
Capability discovery in chaingraph.json is per-node: compute_capability: "server" and export_capability: ["xlsx","pdf"] are separate fields. An agent calling list_ainumbers_tools sees exactly which capabilities each node advertises and routes accordingly. The chaingraph_version: "v0.4" field in the artifact envelope just signals that the emitting tool understands the v0.4 schema, it doesn't imply both features are implemented.
No — Proof Binding is default-off, and inputs (policy_parameters) remain PII-free by the standard zero-egress contract. What changes is that the signer’s key identity becomes linkable to the run. The artifact itself carries no personal data. Tools that offer signing MUST clearly communicate that opting in de-anonymizes at the key level — not the payload level.
The zero_pii_verified semantics are unchanged. If you sign with a did:key generated fresh for each session and never published, the run remains practically unlinkable. If you sign with an institutional did:web anchored to your domain, the signer becomes publicly known — which is exactly the point for regulated institutions seeking auditor-grade attestation.
signatures[] (§4, v0.2) is a DSSE/in-toto envelope — it signs over a payload field that is a base64url encoding of the artifact without audit_signature. It is the v0.2 signing mechanism, optimized for in-toto and Sigstore toolchain compatibility.
proof (§16, v0.5) is a W3C Data Integrity proof using the eddsa-jcs-2022 cryptosuite. It signs over the whole artifact minus proof itself, using the same JCS canonicalizer as the §4 hash construction — no second canonicalization path. The two mechanisms co-exist in the same audit_signature object, are independent, and serve different verifier ecosystems: in-toto/Sigstore consumers use signatures[]; W3C VC / Data Integrity verifiers use proof. Both are optional. A maximally signed v0.5 artifact carries both.