OpenChainGraph · Receipt conformance

How receipt conformance works

A receipt built to the OpenChainGraph envelope carries an execution_hash. This page explains the public corpus that pins that hash to a formula, the standalone verifier that checks it with zero AINumbers code, and the kit a third party uses to submit its own kernel's vector. Written for implementers of the standard outside AINumbers and for auditors who need to check the format without trusting the vendor.

Foundation

What conformance means here

Conformance is a statement about a format, and it is deliberately narrow: a stated input and output pair hashes to the stated execution_hash under the formula below. That is the whole claim. It does not say a kernel's business logic is correct. It says nothing about a proof attached at compute_proof or audit_signature.proof, and it makes no claim about AINumbers' live service. Those are separate, larger questions with their own evidence surfaces.

The corpus and the verifier behind this page were extracted from the normative specification so that a party with no interest in AINumbers code can check the receipt format independently. Every vector in the corpus is a real pair produced by a real, shipped decision kernel, named in the manifest's source field. None are hand-invented.

The formula

The formula and its four checks

Every OpenChainGraph receipt carries an execution_hash, and the hash has exactly one definition:

execution_hash = SHA-256( JCS-canonicalize( { policy_parameters, output_payload } ) )

Only the receipt's own policy_parameters and output_payload enter the hash. Canonicalization recursively sorts every object's keys by Unicode code point, keeps array order unchanged, and serializes with minimal whitespace; for the practical JSON subset the vectors use (finite numbers, no integers past 253) this reproduces RFC 8785 output exactly. The SHA-256 runs over the UTF-8 bytes of that canonical string, rendered as lowercase hex.

vectors/inputs/<id>.input.jsonpolicy_parameters vectors/outputs/<id>.output.jsonoutput_payload check 1 + 2 · byte hashes match the manifest check 3 · canonicalized JSON matches per side check 4 · SHA-256 over canonicalized preimage{ policy_parameters, output_payload } execution_hash equals the manifest, lowercase hexany mismatch names the vector and exits nonzero
The middle check isolates canonicalizer disagreements from hashing bugs before either side touches the preimage
witnessocg-conformance/verify.py runs all four checks per vector in pure Python standard library, with no dependencies, no network access, and no AINumbers code. Exit 0 means every vector passed; exit 1 names the vector and the check that failed.
enforcementThe same four checks run as a Node gate in the site's preflight suite (scripts/check-conformance-vectors.mjs), over the one canonicalizer every AINumbers kernel uses, so a corpus that fails verify.py cannot merge.
Portability

The same hash from any language

PractitionerRFC 8785 (JCS)

Any implementation in any language that sorts keys, serializes to minimal-whitespace JSON, and runs SHA-256 over the UTF-8 bytes will reproduce the same execution_hash for the same input pair. On 2026-09-21 the corpus was cross-checked between two independent implementations: the site's JavaScript canonicalizer and verify.py's Python canonicalizer reproduce identical canonical hashes on every vector, including a float-heavy one where a naive Python float rendering would disagree with ECMAScript.

Number rendering
Where implementations diverge
Python's default float rendering and ECMAScript's differ on values like 0.000001. JCS mandates the ECMAScript production, so a conforming Python canonicalizer must special-case it; verify.py ships that logic and the corpus exercises it.
Prior art
A corpus for adjacent formats exists
A JCS conformance vector corpus for adjacent agentic-payment receipt formats is public (cross-validated across eight language implementations). This corpus covers only the OpenChainGraph receipt envelope, which that corpus does not.
Worked example

A worked vector

PractitionerThe manifest

One entry from vectors/manifest.json, verbatim as of September 2026. A conforming implementation reproduces the final hash from the two files and nothing else.

idart-47-arc-cctp-transfer
inputvectors/inputs/art-47-arc-cctp-transfer.input.json
input bytes sha25605ae0eea37329e5b7ff4d857394534b6d568bc850675821fcd1fd66cadc19dd2
input canonical sha25606a6f2c7d0c0ecf6ce474c3124978b43198a8c20c63939f7492766421bf63e7a
expected outputvectors/outputs/art-47-arc-cctp-transfer.output.json
output bytes sha256ce59989a4a25c536f33e34faeb2d0c4d0fe7e684ac848b89a4f2c7af0539f857
output canonical sha2568e711258c838449efbeb1e1c462c6ff32e5d745f0d03fd346998c2b27b22b881
expected execution_hashsha256:41166a1b759d2c53a44b4540bf4d8240f1fced2b54b5bc0b37e2c1d14796dc7e
sourcederived from chaingraph/kernels/art-47-arc-cctp-transfer.kernel.mjs, a real shipped kernel

The two canonical hashes exist so a new implementation can agree on canonicalization before touching hashing: if your canonicalizer disagrees at check 3, your hasher is not yet implicated.

Re-run

Run the verifier yourself

Beginnerzero dependencies
fresh clonegithub.com/PostOakLabs/ainumbers python3 verify.pypure standard libraryno network, no install 9/9 · exit 0the format conforms mismatch · exit 1vector and check named
The site's own preflight gate runs the same corpus and the same four checks; your exit code should match CI's for the same commit
git clone https://github.com/PostOakLabs/ainumbers
cd ainumbers
python3 ocg-conformance/verify.py            # 9/9 vectors, exit 0
python3 ocg-conformance/verify.py --quiet    # summary line only

Provenance is a separate, complementary check: node ocg-conformance/derive-vector.mjs <id> --check re-runs the named kernel on its recorded input and proves the committed pair against the result. The manifest was last regenerated on 2026-09-22, when the art-09 and art-34 vectors were re-derived after a kernel field-name fix had left them stale.

Third-party submissions

Submitting your own kernel's vector

A party that is not AINumbers submits its own kernel's conformance vector as one pull request that touches a single new directory, ocg-conformance/third-party/<your-slug>/: a submitter.json (display name, contact URL, verified GitHub identity, a reverse-DNS namespace derived from it), a manifest.json carrying the same four hash fields the house corpus uses, and the input/output pair itself. Reverse-DNS naming means two submitters can name a kernel identically without colliding. Both schemas ship in the kit, together with example-submitter/, a hand-authored worked example under GitHub's octocat demo account that round-trips end to end.

Every submission carries a machine-readable conformance witness and a trust disclaimer pinned by JSON Schema as a const, so it cannot be paraphrased or dropped:

Conformance-suite-pass is not a correctness guarantee, not an endorsement, and not an audit. AINumbers verifies formats; it does not verify facts.

Validate before you open the pull request: node ocg-conformance/third-party/validate-submission.mjs your-slug checks both schemas, the namespace binding, and every vector's hashes, recomputed through the same canonicalizer the estate's kernels use. Submissions are reviewed as ordinary pull requests today; the auto-check workflow and the generated roster row for submissions are specified in the kit's README as follow-up rows and have not been built yet, which is also why each shipped witness carries status: pending.

One directory per submitter
Submissions can never conflict
Two submissions from different parties touch disjoint directory trees, so neither PR can collide with the other and neither submitter's files can be edited by another's PR.
No runtime role
A passing check registers nothing
A passing vector never adds a kernel to chaingraph.json, never makes it callable through MCP, and never grants it any runtime role. It adds one public line: this hash claim checked out.
Status

Who is conformant today

The conformance roster keeps the dated list of implementations and their gate-suite results, run and quoted rather than asserted. The house corpus currently stands at nine vectors, all passing; the roster records AINumbers' own §15 gate-suite results against the same specification.

Sources: RFC 8785, JSON Canonicalization Scheme 1.0, IETF, July 2020. ocg-conformance/README.md and ocg-conformance/third-party/README.md in the public repository, accessed September 2026. Hash values quoted verbatim from vectors/manifest.json version 1.1.0. All statements on this page are as of September 2026.