A decision tool produces artifacts. Each artifact carries a fingerprint of its inputs and outputs, and each one can cite the fingerprints of the artifacts it consumed. The result is a verifiable provenance chain that any agent or auditor can re-check with nothing more than a hash function. This page walks the standard from that first idea to time anchoring. The version of record is v0.8.13, and the matching normative text lives in the technical specification.
Four short steps before any standard vocabulary. A hash, a school project, a cheat attempt and a loan application carry the whole picture.
OpenChainGraph is built on a concept called cryptographic hashing. A hash is a digital fingerprint for any piece of data: a document, a number, a decision. Feed any data into a hash function and it produces a fixed string. The standard uses SHA-256, and the fingerprint is always 64 characters.
One changed letter rewrites all 64 characters of the fingerprint
Type anything below. The 64-character fingerprint recomputes with every keystroke. Change a single character, even one space, and the entire output transforms.
Run SHA-256 on "Apple" a million times in a million different countries and you always get the same hash. This property is called determinism.
One character difference flips the entire 64-character output. Any tampering, even changing a single digit in a decision output, is immediately detectable.
Given only the hash you cannot work backward to the original data. A fingerprint is not encryption. The only verification is to re-run the hash yourself.
The avalanche effect is intentional. Two inputs that differ by one character produce hashes with zero characters in common, which is what makes tampering impossible to miss.
Before the math and the JSON, here is the same idea with something you already know.
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. Change even one word afterwards and the machine produces a completely different code. In OpenChainGraph a decision tool runs a calculation and SHA-256 hashes its inputs and outputs. That hash is the fingerprint, the execution_hash.
Your teammate writes the next section. At the top of her section she writes: "This builds on Roger's section, fingerprint: a3f9…". Her work is now linked to yours by your fingerprint. If anyone later swaps in a different version of your section, her reference no longer matches and the tamper is caught at once. In OpenChainGraph, Tool B lists Tool A's execution_hash in its chain.parent_hashes array. The link is the hash itself; a file name or a URL would not detect the swap.
The teacher takes your section, re-runs it through the fingerprint machine, and checks whether the code matches what your teammate wrote. She then does the same for your teammate's section. She never calls you and never emails you. The math is the proof. In OpenChainGraph, any agent or auditor re-hashes {policy_parameters, output_payload} and compares the result with the stored execution_hash. A match means verified, and no trusted authority is required.
A student from a different school cites your group's project in her own work. She knows neither your teacher nor your systems, yet she can verify the fingerprints herself because the fingerprint standard is public and open. Her citation creates a three-link chain across two schools with no phone calls asking anyone to confirm versions. In OpenChainGraph this is cross-vendor chaining: two organizations that have never met form a verifiable provenance chain by following the same open specification.
x-chaingraph capabilityThe whole point of the fingerprint system is that nothing can be changed in secret. When a bad actor tweaks one number inside an artifact, even a tiny edit, the chain reports it.
A tampered artifact breaks every citation downstream of it
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, with no investigation needed.
There is no central authority to bribe or fool. The math runs locally on any verifier's machine. A bad actor cannot quietly edit a credit score, a risk rating or a loan decision: any change breaks every downstream link in the chain.
Four separate tools make four separate decisions, and each one cites the hash of the one before it. Six months later a regulator audits the loan by re-running SHA-256 on each artifact in order, left to right.
Each decision cites the hash of the one before it and the audit re-checks the whole line
Pulls your payment history. Emits a score of 712 and an execution_hash. This is depth: 0, the starting point.
Takes the credit score artifact as input. Cites its hash in parent_hashes. Decides you can afford $850/month repayments.
Cites both the credit and affordability artifacts. Assigns a risk band of Low. depth: 2, two links back to the origin.
risk_controlCites the risk model artifact. Approves the loan at 6.4% APR. depth: 3, the full chain of decisions is now locked in.
loan_decisionThe auditor re-runs SHA-256 on each artifact, in order. Every hash matches, so nobody 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 appeals to trust.
Twenty stages from the artifact envelope through Compute Binding and Export Profiles to proofs of correct execution. Each stage adds one layer, and each carries a chip linking the matching normative section.
Every conformant tool takes structured inputs (policy_parameters), runs a deterministic computation, and produces outputs (output_payload). It wraps inputs and outputs together into a JSON envelope and runs SHA-256 over the combined package. That hash, the execution_hash, is stamped onto the artifact before it is sent anywhere.
SPEC §1Live Hash VerifierTechnical spec
Same inputs always produce identical outputs. No timestamps and no random numbers inside the hash preimage: those would make the hash different every second and break reproducibility.
A JSON object wrapping the inputs (policy_parameters) and outputs (output_payload) together. Adding the execution_hash turns it into a verifiable record.
SHA-256 computed over {"policy_parameters":…, "output_payload":…} with keys sorted alphabetically. Any party can re-run this exact procedure to verify the hash independently.
For example risk_control, liquidity_mandate or credit_assessment. A category label that tells downstream tools and agents what kind of decision this artifact represents.
{
"@context": "https://ainumbers.co/chaingraph/context/v0.3/context.jsonld",
"chaingraph_version": "0.4.0",
"buildType": "https://ainumbers.co/chaingraph/context/v0.2#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": {…}
}
}Only the two preimage fields enter the hash. Everything else annotates the artifact without changing its fingerprint, which is why fields added in later versions never break old verifiers.
When Tool B consumes the output of Tool A, it copies Tool A's execution_hash into its own chain.parent_hashes array. That single act creates a cryptographically linked chain. Tool C can cite both A and B. The result is a directed acyclic graph, a family tree of decisions in which every connection is a hash reference that can be verified independently.
A named chain of steps like this is a workflow in reader-facing terms. Package a workflow with a signed manifest, declared inputs, sample data and review gates, and it becomes a pack ready to run in Helm.
SPEC §1SPEC §0.1Live SandboxChain Builder
Depth 0. The starting point. This artifact has no parents and was built from raw inputs only. In the loan scene above the credit score tool is depth 0.
Depth 1. One link back. This artifact consumed a depth-0 artifact. The affordability tool is depth 1.
Depth 2. Two links back. Its parents are themselves derived from original sources. The risk model cites the credit and affordability artifacts, so it sits at depth 2.
Depth 3. Three links back. The loan approval cites the risk model, so verifying it fully means tracing three steps to the root. Depth is the length of the longest path from any root, so branches are never double-counted.
Tool: the callable unit itself, either a browser page like the work-mandate compiler or the identical computation exposed as an MCP-callable tool that an agent calls directly. SPEC §21 references it as tool_id. Same computation, two doors in.
Node: a tool registered in the Graph Index, viewed as one vertex of the citation graph. It exists once registered, whether or not any chain's step list places it; a chain's steps[] entry is one way a node picks up citation edges rather than what makes it a node (SPEC §0.1). The network-topology tools under Guides use "node" for a DLT network participant, an unrelated meaning.
Chain: the named, ordered list of steps itself, a chaingraph.json chains[] entry. The Escalation SLA / Supervised-Autonomy Receipt chain, for example, places the work-mandate compiler (art-274-compile-work-mandate) as its first node, feeding the agentic-AI risk classifier as its second.
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 and no certificate authority are involved; trust comes from reproducibility, and you can verify it yourself in your own browser.
A conformant tool exposes a tools/call MCP endpoint. An AI assistant such as Claude or 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 the demo above ran "Apple" through SHA-256. When the numbers match, the artifact is genuine.
SPEC §7Live Hash VerifierLive Sandbox
One MCP round-trip out and an independent re-hash back
The agent sends policy_parameters and receives the full artifact envelope. It modifies nothing: the server declares readOnlyHint: true, so nothing on the server changes from the call.
Given an artifact, the server re-runs the same SHA-256 procedure and returns match or mismatch. Agents call this on every artifact before trusting it, the way you would double-check a bank balance.
Given a goal or chain name, returns the ordered list of tools to call with the parent_hashes wiring done. It is the agent's recipe: the exact order of steps, nothing left to guess.
A published JSON document listing all tools, their mandate_type, and which tools consume which outputs. Agents read it first to plan a chain before calling anything, the way you read 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, because the hash is the contract.
SPEC §7Integration GuideLegacy vs OCG
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, and no authority is 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.
Encode {"elementId": value, …} as base64url and append it as a URL hash fragment: tool.html#in=<token>. Add &run=1 to auto-execute. The fragment is never sent to a server; it lives only in the browser. Agents hand off a pre-configured tool URL to a user with one click.
Composer pages load tools in <iframe> elements and drive them via window.postMessage. Three message types: AIN_PREFILL fills inputs, AIN_RUN triggers execution, AIN_COLLECT retrieves the output Policy Mandate. Same-origin only; cross-origin composers cannot drive tools.
Tools with 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 instead of URL. The execution_hash field in the mandate closes the provenance loop.
All three channels decode client-side. URL hash fragments are not included in HTTP requests. postMessage is same-origin only. Policy Mandate JSON never leaves the browser tab. Bridge dispatches input and change events after filling so reactive tool UIs update correctly.
Full explainer: AIN Bridge Explainer
v0.2 adds a @context URL to every artifact. That one 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 was used, making the provenance machine-auditable end to end.
W3C PROV-DM GuidebuildType / SLSA Guide
A single URL (https://ainumbers.co/chaingraph/context/v0.3/context.jsonld) maps all OpenChainGraph field names to W3C standard vocabulary. Any JSON-LD processor understands the artifact automatically.
parent_hashes maps to prov:wasDerivedFrom, the standard W3C term for an entity 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, then UTF-8, then 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 has not changed. Authenticity is a separate question: 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 with an invalid signature means the content is intact but the signer is wrong.
The upgrade turns audit_signature into a structured object: payloadType (MIME type), payload (base64url), and a signatures array with keyid and sig per signer.
An optional WebCrypto 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.
Integrity means the content is unchanged (hash check). Authenticity means it came from the right key (signature check). Both can pass, both can fail, or either can fail alone. Always verify both separately.
The keyid in each signature entry identifies which public key was used. Verifiers look up the public key by keyid to confirm the signature, which enables 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, with no instrumentation code required.
| Span / Tool | Trace ids | Duration |
|---|---|---|
| Credit Score (depth 0) | traceId: 3f9a… · spanId: 3f9a… | 48 ms |
| Affordability (depth 1) | parentSpan: 3f9a… · spanId: 7c2b… | 62 ms |
| Risk Model (depth 2) | parentSpan: 7c2b… · spanId: a1d9… | 55 ms |
| Loan Approval (depth 3) | parentSpan: a1d9… · spanId: 8e5a… | 38 ms |
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
The first 8 bytes (16 hex characters) of execution_hash become the span ID. The mapping is deterministic: the same artifact always maps to the same spanId, with no random IDs and no coordination.
The first 8 bytes of parent_hashes[0] become the parentSpanId, pointing at the parent artifact's span. This is what creates the waterfall indentation in Datadog, Jaeger and Honeycomb.
The root artifact's execution_hash (depth 0, no parents) becomes the traceId for the entire chain. Every artifact in the chain shares it, grouping the run into one coherent trace.
artifactToOtelSpan() is a pure function: it takes an artifact and returns an OTel span object. No SDK, no agents, no code changes to existing tools. Export the span to any OTel-compatible backend and decision chains become observable.
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 are not payment tools carry no profile: a VaR engine or DORA classifier has nothing ISO 20022-shaped to declare.
OpenChainGraph aligns with ISO 20022 vocabulary without claiming to be a registered ISO 20022 message. The profile maps common financial fields to ISO 20022 business element names so banks, PSPs and regulators can read artifacts without a custom adapter, using vocabulary they already know.
Applying the profile means adding a second entry to the @context array: the existing OCG context plus iso20022-context.jsonld. No other field changes, and the preimage is unaffected, so a v0.1 verifier produces an identical hash.
Currency (ISO 4217), country (ISO 3166), BIC/SWIFT (ISO 9362), and LEI (ISO 17442) code sets are adopted by reference, the same external code lists ISO 20022 payments already use. No new registries; no proprietary enumerations.
Only fields with a direct ISO 20022 counterpart are mapped: amount, currency, debtor, creditor, lei, bicfi, settlement_date, remittance_information. Risk scores, model outputs and compliance flags are not 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 the 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.
SPEC §9Ed25519 / did:key Guide
A did:key:z6Mk… URI encodes the raw Ed25519 public key in multicodec plus base58btc form. It resolves without a registry: anyone can derive the public key from the DID alone. It replaces an opaque hex fingerprint with a standardized W3C DID identifier.
A 20-character alphanumeric code issued by the Global LEI System (GLEIF). Banks, PSPs and supervisors already consume LEIs. It optionally binds an OpenChainGraph vendor, and their signing key, to a legal entity that regulators can look up directly.
The same LEI can appear in publisher.lei (who signed this artifact) and in debtor.lei / creditor.lei (party to this payment). One identifier serves the provenance signing layer and the ISO 20022 financial payload layer.
publisher.lei and the keyid form describe who produced the artifact rather than what decision was made. Neither enters the execution_hash preimage: a verifier written for v0.1 computes identical hashes on v0.3 artifacts carrying 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 is 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 a human reads to understand what a tool does and when to use it. OKF concept documents are knowledge and never decision artifacts: they MUST NOT carry an execution_hash.
OKF concept documents explain what a tool means, its intent, when to use it, and how its output feeds downstream decisions. An agent reads OKF before choosing tools; a human reads it to understand what is in the catalog. It is the annotation layer rather than the execution map.
The DCAT catalog (chaingraph.json) tells an agent which tools exist, which tools feed which, and which MCP endpoint to call. OKF sits on top of it as the meaning layer, separate by design.
The 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.
An OKF concept document MUST NOT carry an execution_hash or an audit_signature. It is knowledge rather than 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 published at a dereferenceable URI and declared with dct:conformsTo, beyond being named by an opaque string token. The semantic_profile token (for example "iso20022:pacs.008-subset") is retained as a registered alias pointing at the URI through 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, and all prior artifacts remain valid.
SPEC §11Profile Conformance Guide
Conformance is declared as dct:conformsTo: ["https://ainumbers.co/chaingraph/profiles/iso20022/pacs008-subset.jsonld"]. The profile URI resolves to a PROF prof:Profile resource listing schema and guidance.
The semantic_profile string token (for example "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.
A payment node gets iso20022:pacs.008-subset. A party-only node gets iso20022:party-identification. 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, and this design avoids it.
dct:conformsTo, @context and semantic_profile all sit outside the execution_hash preimage (sorted-key SHA-256 over {policy_parameters, output_payload}). Backward compatibility holds by construction.
v0.4 introduces Compute Binding: a registered kernel (pure ESM exporting compute(), buildArtifact() and 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, with no browser delegation, no user interaction and no waiting for a page to load. The new compute_mode: "server" envelope field tells every downstream consumer how the hash was computed, and it is excluded from the hash preimage, so all prior artifacts remain valid.
SPEC §12Integration GuideTry it live: run a workflow
A v0.4 kernel exports three things: 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. Kernels are registered in kernels/index.mjs and vendored into data/ at build time.
The envelope carries 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 discover it before calling. compute_mode: "auto" lets the Worker decide.
Before v0.4, a tool call returned a delegation URL the agent had to open in a browser, which required a JS runtime and user interaction. v0.4 collapses this to one MCP tools/call: the agent sends parameters and receives a complete signed artifact. The spec calls this agent-native execution.
§12.4 keeps the Worker kernel in a stateless context. No PII is logged and no computation telemetry is emitted. The boundary matches the MCP contract's readOnlyHint: true: sensitive policy_parameters never leave the call and response envelope.
v0.4 defines the chaingraph_export umbrella: xlsx, pdf, csv and xbrl renderings generated from a verified artifact, with chaingraph_export:vc added in v0.4.1 (the next panel). The 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, and the execution_hash travels intact into every output as embedded metadata. Regulatory XBRL submissions use the xbrl_taxonomy parameter (for example "eba-corep-own-funds") to select the filing profile.
SPEC §13Export Profiles GuideTry it live: run a workflow
Four profiles ship in v0.4: xlsx (a three-sheet analyst workbook: Decision, Summary, Provenance), pdf (signed printable render), csv (tabular data extract) and xbrl (machine-readable regulatory submission). Each is generated from output_payload after the execution_hash is already fixed.
The agent calls export_artifact(artifact, format, xbrl_taxonomy?). The tool generates the rendering on demand and returns it, changing nothing on the server. Nodes advertise it through export_capability in chaingraph.json so agents can discover it before calling.
The 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. Existing artifacts remain valid with no re-hashing. The export is the last mile rather than the source of truth.
Pass xbrl_taxonomy: "eba-corep-own-funds" for a bank capital COREP filing. The XBRL instance document embeds execution_hash as a named fact, so regulators can trace every submitted number back to the verified artifact that produced it, with no spreadsheet chain of custody.
v0.4.1 adds a fifth export profile: chaingraph_export:vc. Where xlsx, pdf, csv and xbrl 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 is required and it is 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. The credential is a view and carries no VC proof; the next panel covers the signed form.
SPEC §13SPEC §13.11Try it live: export a verified artifact
A structural re-expression of any OCG artifact into VC format always exists, so the profile is universally available. Unlike xlsx or xbrl it is domain-independent and needs no export_capability declaration.
The VC type array contains "VerifiableCredential" and "OpenChainGraphCredential". The id is urn:ocg:artifact:<bare-execution-hash>: deterministic, with no UUID and no clock. The same artifact always maps to the same credential URI.
The anchor re-states the canonical execution_hash, digestMethod and a verify_url inside the VC envelope. It is a structured pointer rather than a VC proof suite, and it routes any downstream consumer back to the original verification path.
Like every §13 export, the VC mints no new execution_hash and adds no W3C Data Integrity proof. The envelope and chaingraph_version are unchanged. For a secured VC, add a proof through Proof Binding (next panel).
v0.5 adds Proof Binding. The execution_hash proved that content has not changed since it was produced; it did not prove, at the artifact level, who produced it. 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, which erodes 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, and only spec_version advances to 0.5.0.
SPEC §16Try it live: art-04 attestationTry it live: verify a hash
The proof lives at audit_signature.proof: at the artifact root the frozen v0.4 schema sets additionalProperties:false, and inside signatures[] the DSSE/in-toto meaning is retained. A signed v0.5 artifact still validates under the v0.4 schema.
The cryptosuite uses the same cgCanon JCS canonicalizer from kernels/_hash.mjs as §4, so no second canonicalization path exists. proofValue is "z" + base58btc(Ed25519.sign(key, hashData)), multibase-encoded. Shared kernels/_proof.mjs produces it: the browser inlines it and the Worker imports it, with byte-identical output.
The secured document is the full artifact minus 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, with one key pair carrying two guarantees.
Ephemeral or client-side signing uses did:key, self-describing with no registry. Institutional issuers SHOULD use did:web anchored to their domain, with the key held in an HSM or KMS and signing performed server-side through the §12 Compute path on the 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 every other caller stays anonymous by default.Every artifact carries two fields that panel 5 could only name. mandate_id is a UUID v4 assigned at run time, 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 or ERROR) and message. A valid execution_hash alongside flags with severity ERROR is a coherent state: 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.
UUID v4 assigned at execution time. It uniquely identifies this specific run of this tool, and ops teams use it for support lookup, audit queries and recall. It does not enter the hash preimage: the same inputs always produce the same hash regardless of when they run.
An array of flag objects shaped {code, severity, message}, with severity levels INFO, WARN and ERROR. A valid hash plus an ERROR flag is fully valid: the content is intact and the business logic raised a warning, and these are independent properties.
The OTel mapping (§6) converts compliance_flags into span status.code: any flag with severity: ERROR sets status.code = ERROR. INFO and WARN flags leave status at OK. Compliance exceptions become visible in Datadog, Jaeger and any OTel-compatible trace viewer.
compliance_flags and mandate_id sit outside the hash preimage; only policy_parameters and output_payload are hashed. A tool can raise a WARN or ERROR flag without changing the verifiable hash of its decision inputs and outputs.
Panel 11 covered what the signature does. This panel covers how the key is born, where it lives, how verification finds it and how it gets rotated. The lifecycle is: Generate (crypto.subtle.generateKey in the browser, or Node's crypto.generateKeyPairSync server-side), Publish (export the public key as hex, derive the did:key, add it to chaingraph.json under ocg:signing_keys), Sign (kernels/_proof.mjs or the 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, and old artifacts signed under the prior key remain permanently verifiable through the prior entry.
crypto.subtle.generateKey({name:"Ed25519"}, true, ["sign","verify"]) produces a CryptoKeyPair. Export the public key as raw bytes, encode as hex, then derive the did:key (multicodec 0xed01 prefix plus base58btc). Never export the private key bytes outside a secure context.
Add the public key to the tool's Graph Index entry: ocg:signing_keys: [{keyid:"did:key:z6Mk…", valid_from:"2025-01-01"}]. Any verifier that fetches chaingraph.json from the tool's endpoint can derive the public key from the did:key and verify anything signed with it.
For in-toto, sign the base64url-encoded artifact body (the PAE envelope). For Proof Binding, sign the JCS-canonicalized document via kernels/_proof.mjs. Both use crypto.subtle.sign("Ed25519", privateKey, data). The output is 64 bytes, encoded into the artifact.
Add a new key entry with today's valid_from, and set valid_until on the old entry if desired. Verifiers MUST use the key whose valid_from and valid_until bracket the artifact's created_at timestamp. Rotation is additive, so old artifacts stay verifiable permanently.
Panel 7 showed an agent calling a tool, and panel 8 showed cross-vendor chains. Neither answered how the agent knows 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 through L4) signals implementation completeness, and dcat:accessService plus ocg:mcp_tool_name give the callable address. The Graph Index is what makes OCG an orchestration protocol beyond a hash format.
SPEC §7Try it live: run a workflow
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 it once to understand the full tool landscape.
ocg:consumes names the upstream tools this node reads artifacts from; ocg:feeds names the downstream tools that can consume its output. Together they form a directed acyclic graph that agents traverse to order calls and find parallelizable branches.
L1: canonical artifact plus hash. L2: plus PROV-DM context and buildType. L3: plus in-toto signature and OTel mapping. L4: plus profile conformance, compute binding and export profiles. An agent can filter the DAG to plan high-assurance paths through L3+ nodes.
dcat:accessService.endpointURL plus ocg:mcp_tool_name give the agent everything needed to call the tool: the MCP server URL and the tools/call name. No out-of-band configuration; the Graph Index is the service directory.
| Node | mandate | Level | Feeds |
|---|---|---|---|
| FX Desk | mandate:fx_rate | L4 | Risk Score, Liquidity |
| Risk Score | mandate:risk_assessment | L3 | Loan Approver |
| Liquidity | mandate:liquidity_check | L3 | Loan Approver |
| Loan Approver | mandate:credit_decision | L4 | Audit Export |
| Audit Export | mandate:regulatory_report | L2 | none |
Reading the table as a graph, the agent sees that Risk Score and Liquidity can run in parallel, that both must finish before the Loan Approver, and that an L2-only path reaches the Audit Export. Planning happens before the first call.
Every previous stage showed that execution_hash proves an output follows from its inputs. 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: the artifact kernel_digest equals the Graph Index compute_images[].image_id and equals the digest recomputed from the published source file. Any mismatch fails the binding. The §17.2 caveat states it plainly: this is an advisory claim rather than a cryptographic proof of execution, because a dishonest server could record the right digest while running different code. That is what §18 solves.
_buildid.mjs reads the kernel file, normalises all line endings to LF, and runs WebCrypto SHA-256 over the UTF-8 bytes. The result, sha256:<hex>, is stored at audit_signature.build_identity.kernel_digest. Deterministic: the same source always gives the same digest regardless of OS or runtime.
Each live node in chaingraph.json SHOULD publish its kernel digest in compute_images[]: compute_images: [{system:"sha256-source", image_id:"sha256:…", valid_from:"…"}]. This is the second leg of the three-way cross-check, the public and independently verifiable record of which kernel a node claims to run.
The verifier compares (1) artifact.build_identity.kernel_digest, (2) chaingraph.json compute_images[].image_id, and (3) the digest recomputed from the published source file. All three must match. A tampered artifact, a stale Graph Index or a modified source fails the binding immediately.
§17 cannot prevent a dishonest server from recording the correct digest while running different code. It strengthens tamper-evidence (the digest is inside the §16 secured set when both apply) and makes forgery auditable, but it does not prove the named kernel produced the output. §18 exists for that.
§17 pins which kernel was claimed; §18 makes the claim 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 re-running the kernel and optionally without revealing those inputs at all. This is OCG's analogue of Trusted Compute Units (arXiv:2504.15717), and it is software-only: no TEE, no hardware enclave, no blockchain anchor. The system is agnostic (risc0, sp1, jolt); groth16-bn254 (256 bytes, uncompressed BN254 A, B, C) is recommended. STARK seal verification is delegated to the named system's vetted verifier, exactly as §4 delegates SHA-256 to WebCrypto and §16 delegates Ed25519; for the recommended Groth16 format OCG ships its own self-contained BN254 pairing check (§18.1). Proving is off-band: it requires a Rust toolchain and heavy compute, and it MUST NOT be claimed to run in the browser or the Worker. Default-off.
SPEC §18Deep dive: how the reference deployment reached full coveragearXiv:2504.15717Try it live: verify a hash
{type:"ZkVmReceipt", system:"risc0"|"sp1"|"jolt", receiptFormat:"groth16-bn254"|"stark", imageId:"sha256:…", seal:"<base64>", journal:{output:…}}. It 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 the §17 kernel_digest this gives a two-layer program identity check: source digest (advisory) plus zkVM guest identity (cryptographic).
The receipt's journal.output MUST equal the artifact's output_payload. The verifier checks this binding directly, with no re-execution. If the journal matches and the seal verifies, the verifier holds cryptographic assurance that this program produced this output.
When inputs are confidential, policy_parameters carries commitments or hashes instead of cleartext. §4 recompute then becomes unavailable to third parties and the receipt is the sole verification path. A tool in this mode MUST surface that to users. Like §16, default-off.
L1 is the §4 execution_hash: tamper-evidence, with the verifier re-running under cleartext inputs. L2 is the §16 Proof Binding: authenticated attestation, where a named key vouches for the whole artifact. L3 is the §18 Compute-Integrity Proof: a succinct proof of correct execution, checked from a receipt with no re-run and optionally no revealed inputs. They compose: a §18 receipt MAY itself be covered by a §16 proof. Proving stays off-band and MUST NOT be claimed to run in the browser or the Worker.
A rulebook nobody checks is a wish list. Most specifications are prose: they say a conformant tool should do this and must not do that, and everyone hopes implementers read carefully. OpenChainGraph takes a stricter stance, and it is the reason the earlier panels can be trusted.
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 a test that either passes or does not. A rule with no gate is outside the standard: if nothing can fail when the rule is broken, the rule is decoration.
SPEC §15The receipt-conformance corpus, explainedTry it live: run a workflow
Each normative rule points at a real check. "The hash preimage is built exactly one way" is a gate that re-derives the hash and fails if a tool used any other recipe.
One check reads the rule-to-gate matrix and fails the build if any numbered rule has no gate attached. Nobody can quietly add a rule and forget to enforce it, and nobody can delete a gate and leave the rule stranded.
If a proposed rule cannot be expressed as something a machine can check, it does not enter the standard as a MUST. It stays advice. That keeps the normative core small, precise and resistant to fakery.
You do not audit a vendor's good intentions. The standard ships with its own enforcement, so a green build obeyed every rule, and a build that broke a rule never reached anyone.
preimage. One canonical way to build the hash input. The gate re-computes every published hash and rejects any tool that shortcut the recipe.
coverage. The meta-gate: every numbered rule in the standard maps to a named check. A rule with no check fails the whole build.
page parity. The friendly spec page you read cannot drift from the written standard. If the page shows a section the standard does not define, the build stops.
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 it carries one or more independent timestamp receipts. Each binding names a timestamp authority, carries the hash that was sent, and embeds the signed response. The authority never sees your file, only the hex digest.
SPEC §20Try it live: anchor a document
You send 32 bytes and receive a signed RFC 3161 receipt with no account required
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.
The authority's signed timestamp proves the hash existed before the receipt was issued. Combined with the artifact's execution_hash you hold proof of both the computation's content and the moment it occurred.
A DER receipt verifies with 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.
Anchor the terminal node's artifact and the full provenance graph is covered. Every prior node's hash sits in parent_hashes, so the timestamp receipt anchors the whole chain by transitivity.
rfc3161-tst. Certificate-backed timestamp. DigiCert, Sectigo, Sigstore TSA, FreeTSA or GitHub TSA. DER-encoded TimeStampToken, confirmed immediately, verifiable with openssl ts -verify and the issuing CA's root certificate, which the standard pins.
opentimestamps. Bitcoin-anchored proof. The hash is batched into a Bitcoin transaction by the OTS calendar network, with no fee and no wallet. The proof is pending for a few hours after stamping; once confirmed the block timestamp is the permanent evidence.
To anchor an OCG artifact, drop it on the Anchor page at anchor.ainumbers.co. The page reads the execution_hash field directly, with 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.
The standard polices itself through gates, anchors its artifacts in time, and answers the questions that come up every time someone meets it for the first time.
These 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. OpenChainGraph has no coin and no network to join. There is also no shared ledger that strangers must agree on: each tool runs on its own and stamps its result with a fingerprint, and you trust that result by redoing the math yourself.
The OpenChainGraph and Blockchains page shows where the two designs overlap and where they differ, in three short animations. For the technical comparison with blockchains, Git and supply-chain attestations, see "Isn't this basically a blockchain?" further down.
A chain is the named, ordered list of steps defined in chaingraph.json. SPEC §21 calls it a chains[] entry: {name, steps: [{tool_id, ...}]}. That is the noun. In plain language people also call a chain a workflow; when this page says run a workflow it means run a chain.
Running a chain is what produces the fingerprint trail: each step copies the prior step's execution_hash into its own parent_hashes, so decisions link into a tamper-evident line you can trace end to end. That trail is what a chain produces when it runs, beyond what a chain is.
A node is a tool registered in the Graph Index, viewed as one vertex of the citation graph. It exists once registered, whether or not any chain's step list places it. Being placed in a chain's step list is one way a node picks up citation edges rather than what makes it a node (SPEC §0.1).
Some tools on this site, the DLT and permissioned-network topology tools under Guides, also use "node" for a network participant. That is a different concept from the one on this page, so do not carry the meaning across.
Close, with a distinction. A tool is the callable unit itself, either a browser page or the identical computation exposed as an MCP-callable tool (tool_id in SPEC §21). A node is that tool viewed as a vertex in the citation graph once it is registered in the Graph Index; chain placement is one way it picks up edges rather than a requirement for being a node.
Ask for a tool by name and you get one page or one MCP call. Ask about a node and you are asking about its place in the citation graph, which may or may not include a chain's step list.
Three audiences read 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 trusting 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 label on each panel marks the natural entry point for each reader, so you can skim to your level and go deeper only where you need to.
The similarity is real: both designs use hash pointers to link records into a graph. A blockchain adds distributed consensus, a network of nodes that must agree on one shared, append-only ledger. OpenChainGraph has no such network. Each vendor runs its own tool and publishes its own artifact, and nothing needs mining or validating.
The closer analogy is Git's object model, a directed acyclic graph of content-addressed objects where you trust a record by recomputing its hash yourself. Another is in-toto and SLSA supply-chain attestations, which hash an artifact and sign it so anyone can verify it independently. OpenChainGraph applies that pattern to financial decision artifacts instead of software build artifacts. The OpenChainGraph and Blockchains page animates the comparison and shows where the two meet, such as timestamps anchored in Bitcoin.
Old hashes remain permanently valid for the inputs and outputs they were computed over; the hash does not expire. 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 and different execution_hash. That is correct behavior: it is 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, which makes model changes auditable by design.
Yes. MCP is an optional integration layer. The core of OpenChainGraph is 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 transport: a REST API, a message queue, a file drop, an email attachment or a direct database write all work.
MCP becomes relevant for cross-vendor chaining (panel 8) when you want agents to autonomously discover, call and chain tools from a chaingraph.json Graph Index. Before that, 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 are 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 competes with the other.
The SPEC carries the status "NORMATIVE, Single Source of Truth" and is at version 0.8.13, with the hash construction, the artifact envelope and the verification procedure stable and implementable today: the reference implementation exists and runs under gates. What matures on a slower clock is the ecosystem: most MCP tool catalogs are still young, most vendors do not yet emit structured JSON artifacts at all, and cross-vendor chaining needs two parties who both follow the spec.
The recommended posture: implement the artifact envelope now, in any tool that produces decisions your team or your 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 going mainstream, MCP tool catalogs proliferating, regulators asking for machine-verifiable decision trails), you will already be producing conformant artifacts. Standards that arrive late to adoption cycles rarely win.
They serve different layers. 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 is designed for auditors, regulators and downstream tools that need to verify a decision independently. 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, packaging 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 for traceability; the mandate itself is not hashed. Mandates are ephemeral transit containers and artifacts are the permanent record. If they conflict, the artifact wins.
The export does not carry a hash of itself, but it embeds the original execution_hash as metadata, and that is 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. The mismatch is the tamper signal.
For high-stakes auditing, go back to the canonical JSON artifact (beyond the xlsx), re-run verify_execution_hash, and confirm the output_payload matches what the exported file shows. The export is a rendering for humans; the artifact is what is 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 has not changed since v0.1: SHA-256 over the RFC 8785 canonical serialization of {policy_parameters, output_payload} with keys sorted. 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, beyond what was hashed. A verifier that ignores the field entirely still computes an identical hash. 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 domain-agnostic. The mandate_type field is a free string: 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 (panel 13) and the LEI / did:key identity model (panel 14) are optional addenda for payment tool vendors; they do not affect the core hash preimage and are not required for conformance. The fintech examples in this explainer reflect where the spec authors work rather than a constraint on who can implement it. If your tool takes structured inputs, runs a deterministic computation and produces outputs someone might later need to audit or dispute, OpenChainGraph applies.
They are fully independent. §12 addresses where computation runs (server or browser); §13 addresses 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 and 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 envelope signals that the emitting tool understands the v0.4 schema; it does not imply both features are implemented.
No. Proof Binding is default-off, and inputs (policy_parameters) remain PII-free under 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 rather than 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, so no second canonicalization path exists. The two mechanisms co-exist in the same audit_signature object, are independent, and serve different verifier ecosystems: in-toto and Sigstore consumers use signatures[]; W3C VC and Data Integrity verifiers use proof. Both are optional, and a fully signed v0.5 artifact carries both.