An OpenChainGraph artifact already carries a hash any reader can recompute. This page walks the layer above that hash: the W3C Data Integrity proof that lets a named key vouch for the whole artifact, the checks that test one, and the revocation status list that tells a verifier when a key has since been retired. Everything described as running today was read against the repository at commit 9fd3e4c51 on 5 October 2026.
Three steps: what a signature adds to a recomputed hash, what the proof object carries, and how to check one in your browser.
Every artifact carries an execution_hash: a SHA-256 over its inputs and outputs under one canonicalization rule. Recomputing it catches any edit to the bytes, which makes the artifact tamper-evident. What the hash cannot say is who answers for the content. The standard's proof-binding section (SPEC.md §16) adds an optional W3C Data Integrity proof at audit_signature.proof: a named key vouches for the artifact exactly as published.
The proof is holder-chosen and defaults to off. Signing links a run to a key and a key is an identity, so a tool that offers signing says so before it signs; an artifact with no proof stays fully conformant, because the standard treats the proof as an addition rather than a requirement.
Explain what audit_signature.proof adds beyond a recomputed execution_hash, and name the W3C cryptosuite the OpenChainGraph standard requires for that proof.
A conforming proof sets six members, and every one of them has a job. The signature itself covers the whole artifact with the proof removed, canonicalized by the same JCS code (RFC 8785) that the artifact hash uses, so one canonicalizer serves the whole estate. Ed25519 signs the SHA-256 of the proof options followed by the SHA-256 of that document, which means the signature transitively covers execution_hash.
| Member | What it holds |
|---|---|
| type | DataIntegrityProof, the W3C Data Integrity proof type |
| cryptosuite | eddsa-jcs-2022, the W3C EdDSA Data Integrity cryptosuite, a W3C Recommendation since May 2025 |
| proofPurpose | assertionMethod: the key asserts what the artifact says |
| verificationMethod | a did:key URL that resolves to the signing Ed25519 public key |
| created | the ISO-8601 instant the proof was made, supplied by the caller so the pipeline stays deterministic |
| proofValue | the signature bytes in multibase form, always starting with z |
One proof may become several. audit_signature.proof can be an array: parallel members mean independent signers vouched for the same artifact, and an endorsement is a proof whose previousProof names the proofs it approves. A verifier walks the set in dependency order and trusts the last signature only once everything it depends on has verified. The shared kernel implements both shapes in its verifyProofs function, and the worker-side copy of that kernel behaves identically.
An artifact carries two proofs in audit_signature.proof and one names the other in previousProof. Describe the order a conforming verifier verifies them in and what makes the set fail.
Verification is offline and reproducible. Recompute execution_hash from the inputs and outputs. Verify proofValue against the key named by verificationMethod over the same canonical input. Either check failing fails the verification, and both together are the whole test. The Artifact Verifier runs these paths in the browser: paste an artifact to recompute its hash, generate a keypair, sign a record with it, and review a bundle whose records the accountability gate checks proof by proof.
The same proof pipeline signs on the server side of the estate: the scheduled receipt workers import the shared kernel and sign their receipts with an ephemeral did:key minted per receipt, so no long-lived signing key accumulates value in the worker. Because the browser bundle, the compute kernel and the worker all run the same pipeline, a proof verifies identically in all three places.
Open the Artifact Verifier at ainumbers.co/chaingraph/verify.html, generate a keypair, sign a synthetic human-accountability record with it, and list the checks the bundle review runs over audit_signature.proof.
Where the signing key lives, the post-quantum second proof that rides the same pipeline, and the status list that records a retirement.
A did:key is enough for self-contained signing from one browser session, and it is the only shape a fully client-side tool can use, since client HTML must never carry a private key. A stable institutional publisher anchors to did:web over its own domain instead and signs server-side with the key held in an HSM or KMS. In every signing path the reasoning model stays away from the key material: a deterministic gate performs the signature beside the non-deterministic reasoner, which is why a proof attests the artifact rather than the model run.
| Key home | Who it fits |
|---|---|
| did:key | self-contained signing from one browser session, the only shape a fully client-side tool can hold |
| did:web | an institutional publisher anchoring the key to its own domain and signing server-side |
| ocg:signing_keys | the catalog field where a long-lived signer key should be published, so a verifier resolves it without contacting the signer |
The publication field ships today and waits for its first tenant: on 5 October 2026 all 48 dataset entries in chaingraph.json carried an ocg:signing_keys array and every one of them was empty. The spec's advisory sentence about logging long-lived keys to a transparency log is exactly that, advisory: it builds nothing yet and adds no gate.
Read https://ainumbers.co/chaingraph/chaingraph.json and report how many dcat:dataset entries carry a non-empty ocg:signing_keys array.
The spec's post-quantum section extends whole-artifact signing with a hybrid pair: two Data Integrity proofs over the same canonical bytes, the classical Ed25519 proof plus a second proof signed by ML-DSA (FIPS 204). Both ride the existing proof array, so the shape is the same proof set the standard already allows: no new envelope, no new hash, and chaingraph_version stays at 0.4.0. A verifier declares a policy (require the classical proof, require the post-quantum proof, or require both) and each proof verifies independently under its own cryptosuite.
The pipeline is live in the shared proof module, which signs and verifies ML-DSA proofs beside the Ed25519 ones, and the worker-side copy of that module carries the same code. No browser tool offers a hybrid signature yet. The proofs name their algorithm by the registered RFC 9964 identifier ML-DSA-65 while the W3C cryptosuite name for ML-DSA is still unregistered, which is the reserved-extension posture the spec itself prescribes.
Name the three verifier policies a hybrid proof set can satisfy and state what each policy requires to verify.
The spec's revocation section (SPEC.md §REVOKE-1) gives a receipt or a key a way to advertise its status through a W3C BitstringStatusList. A status entry lives under audit_signature carrying three things: the status list URL, an index into that list, and the entry type BitstringStatusListEntry. The entry is excluded from the artifact hash, so attaching one never moves execution_hash. To check it, a verifier expands the list's bitstring and reads the bit at the index: a set bit means revoked, and revocation overrides signature validity, so a receipt whose key was retired reads as unverified for that purpose even with a valid signature. No status entry at all means no signal was published, which is not evidence that the key is good.
The check side runs today. The estate's Revocation-Status Verifier reads a status entry of exactly this shape in the browser, takes the referenced status list as pasted input so its zero-egress posture holds and nothing is fetched, and answers revoked, flagged, or no published signal. The publish side has not started: no live artifact carries a status entry and no service serves a status list, so the entries this tool reads arrive when a publisher adopts the mechanism.
A receipt carries a BitstringStatusListEntry at index 1721 and the referenced status list has that bit set. State the verification outcome and explain why the valid Ed25519 signature on the receipt does not change it.