Skip to content

VDI: Verifiable Decision Infrastructure Protocol

Version: 1.0.0 Status: Draft Authors: QuantZK

Abstract

VDI defines a standard format for cryptographically verifiable decision attestations. A Decision Attestation is a self-contained, portable artifact that proves a decision was made correctly, following defined constraints, by authorized actors, using valid inputs, without revealing the decision logic, input data, or internal state.

Verification requires only the attestation object and a verifier library. No server, no API, no trust in the attestation issuer is required.

0. Cryptographic model (non-normative)

VDI security arguments assume a probabilistic polynomial-time (PPT) adversary with full visibility into attestation and receipt artifacts, verifier code, and network traffic, control over decision inputs, and adaptive interaction with proving/verification interfaces. For signatures, the adversary is in the chosen-message setting (EUF-CMA). Curves referenced as BN128 in this document may also be referred to as BN254 in some tooling/literature.

0.1 Adversary capabilities and limits

Adversary capabilities in scope:

  • Construct arbitrary attestation objects (well-formed or malformed) and submit them to verifiers.
  • Modify/tamper with attestation payloads in transit.
  • Attempt to produce accepting proofs without a satisfying witness.
  • Replay old attestations or receipts.
  • Attempt manifest/pipeline substitution.
  • Exploit key or setup compromise if such compromise occurs.

Adversary limits (assumptions):

  • Ed25519 signatures are existentially unforgeable (EUF-CMA).
  • Groth16 soundness/knowledge-soundness holds for the instantiated circuits.
  • SHA-256 and Poseidon resist preimage, second-preimage, and collision attacks at the intended security level.
  • For invalid decisions (relative to the encoded relation), no valid witness exists unless constraint encoding is wrong.

0.2 Enforcement soundness statement

Let $R_M$ be the relation induced by manifest-constrained circuit $M$, and let $x$ denote verifier-visible statement data (including pipeline hash, manifest hash, verification-key binding, and public signals). For any security parameter $\lambda$ and any PPT adversary $\mathcal{A}$, if $\mathcal{A}$ outputs $(x,\pi,\sigma)$ such that verification accepts (proof check, key-integrity check, and signature/binding checks pass), then there exists a witness $w$ such that $R_M(x,w)=1$, except with probability negligible in $\lambda$.

Proof sketch: Groth16 knowledge soundness implies acceptance corresponds to knowledge of a witness for the compiled relation. With correct constraint encoding (equivalently, circuit construction relative to intended policy semantics) plus manifest/pipeline/key/signature binding checks, witness existence implies compliance with encoded constraints. Therefore invalid decisions are unprovable except with probability negligible in $\lambda$.

Reduction-style interpretation: Any adversary that achieves non-negligible success in this enforcement setting can be transformed into an adversary that breaks either Groth16 knowledge soundness (accepting proof without satisfying witness) or Ed25519 EUF-CMA/binding assumptions (successful payload-signature substitution), contradicting the assumptions above.

0.3 Trusted setup assumption

When Groth16 is used, security depends on at least one honest participant in the setup ceremony destroying toxic waste.

0.4 Formal example ($x,w,C_M$)

Let $C_M$ be the compiled constraints for manifest $M$, and define $R_M(x,w)=1 \iff C_M(x,w)$ is satisfied.

  • $x$ (public statement): pipeline hash, manifest hash, decision commitment, and policy parameters.
  • $w$ (private witness): sensitive attributes and execution-trace values.

Valid case: if there exists $w$ with $C_M(x,w)=1$, completeness implies a proof $\pi$ exists such that Verify(vk, x, pi) = 1.

Invalid case: if for fixed $x$ there is no $w$ with $C_M(x,w)=1$, then no PPT adversary can produce accepting $\pi$ except with probability negligible in $\lambda$.

0.5 Security game view (enforcement unforgeability)

Define game $\mathsf{Game}_{\mathrm{enf}}^\mathcal{A}(\lambda)$:

  1. Challenger samples setup/keys at security parameter $\lambda$ and publishes verifier-visible parameters.
  2. Adversary $\mathcal{A}$ obtains adaptive access to allowed interfaces (including chosen-message signature queries where applicable).
  3. $\mathcal{A}$ outputs candidate $(x,\pi,\sigma)$.
  4. $\mathcal{A}$ wins iff verification accepts and there is no witness $w$ such that $R_M(x,w)=1$.

Define advantage $\mathrm{Adv}{\mathrm{enf}}^\mathcal{A}(\lambda)=\Pr[\mathsf{Game}{\mathrm{enf}}^\mathcal{A}(\lambda)=1]$. Security claim: $\mathrm{Adv}_{\mathrm{enf}}^\mathcal{A}(\lambda)$ is negligible in $\lambda$ for all PPT $\mathcal{A}$.

0.6 Normative proof backend modes

VDI has one attestation envelope but multiple proving relations. Implementations and documentation MUST use these exact mode identifiers:

ModeCanonical meaningPrimary APIs / circuits
causalzk-cp relation over DAG/path necessity (causalProof)default attest() path in @quantzk/attest, VDI prover + zk-cp/build/causalProof*
enforced-policypolicy constraints encoded directly in named Circom policy circuitsPolicyProver, attestEnforcedPolicy(), protocol/build/{fairLending,hipaaAccess,euAiAct,soc2Access}
compliancecertificate/scoring relation for compliance attestationComplianceCertificateProver, protocol/build/complianceCertificate

Alternate labels for these modes SHOULD NOT be used in normative docs or API surfaces to avoid semantic drift.

1. Decision Attestation Object

The atomic unit of VDI. A JSON object with exactly these fields:

json
{
  "vdi_version": "1.0.0",
  "type": "decision_attestation_v1",
  "attestation_id": "vdi:att:0x<32-byte-hex>",
  "pipeline": {
    "id": "vdi:pipeline:0x<16-byte-hex>",
    "hash": "0x<32-byte-hex>",
    "name": "ACME Bank Lending",
    "version": "1.0.0"
  },
  "policy": {
    "manifest_hash": "0x<32-byte-hex>",
    "constraint_count": 3,
    "authority": {
      "type": "self_attested|legal_review|standards_body|audit_firm",
      "name": "Covington & Burling LLP",
      "reference": "Opinion #2026-AI-FL-014",
      "regulation": "Fair Lending Act, ECOA"
    }
  },
  "outcome": {
    "id": "decision_output",
    "timestamp": 1709078400
  },
  "proof": {
    "system": "groth16",
    "curve": "bn128",
    "pi_a": ["<field-element>", "<field-element>", "1"],
    "pi_b": [["<fe>", "<fe>"], ["<fe>", "<fe>"], ["1", "0"]],
    "pi_c": ["<field-element>", "<field-element>", "1"],
    "public_signals": []
  },
  "verification": {
    "key": {
      "protocol": "groth16",
      "curve": "bn128",
      "nPublic": 0,
      "vk_alpha_1": [...],
      "vk_beta_2": [...],
      "vk_gamma_2": [...],
      "vk_delta_2": [...],
      "IC": [...]
    },
    "key_hash": "0x<32-byte-hex>"
  },
  "signature": {
    "algorithm": "Ed25519",
    "kid": "0x<16-byte-hex>",
    "public_key": "0x<32-byte-hex>",
    "value": "0x<64-byte-hex>"
  },
  "issued_at": 1709078400,
  "expires_at": 1740614400
}

2. Verification Algorithm

To verify a Decision Attestation, execute these steps IN ORDER. ALL must pass. If any fails, the attestation is INVALID.

Step 1: Schema Validation

  • vdi_version must be a supported version
  • All required fields present
  • attestation_id matches format vdi:att:0x[64 hex chars]

Step 2: Timestamp Validation

  • issued_at must be in the past
  • expires_at must be in the future (or attestation is expired)

Step 3: Pipeline Integrity

  • pipeline.hash must be a valid SHA-256 hex string

Step 4: Policy Integrity

  • policy.manifest_hash must be a valid SHA-256 hex string
  • policy.authority.type must be one of the defined types

Step 5: ZK Proof Verification

  • Using verification.key, verify the Groth16 proof: snarkjs.groth16.verify(verification.key, proof.public_signals, proof)
  • This is pure math. No server required.

Step 6: Signature Verification

  • Reconstruct the canonical payload (all fields except signature.value)
  • Verify: Ed25519.verify(signature.value, canonical_payload, signature.public_key)

Step 7: Verification Key Integrity

  • Compute SHA-256 over the RFC 8785 canonical JSON serialization of verification.key (the same canonicalization scheme as the attestation signing payload; not JSON.stringify unless it happens to match that canonical form).
  • The digest MUST match verification.key_hash (after normalizing optional 0x prefixes).

Step 8: Revocation status (profile-dependent)

  • Under VDI_VERIFY_STRICT_V1, the caller MUST supply revocation alongside the attestation (offline CRL-style set and/or online fetch result). See Section 7.
  • If the profile requires revocation data and revocation is omitted: INVALID (VDI_ERR_REVOCATION_DATA_REQUIRED).
  • If attestation_idrevocation.revokedAttestations: INVALID (VDI_ERR_ATTESTATION_REVOKED).
  • If signature.kidrevocation.revokedKids: INVALID (VDI_ERR_SIGNING_KEY_REVOKED).
  • If revocation.snapshotTime is set and issued_at > snapshotTime: INVALID (VDI_ERR_REVOCATION_STALE — snapshot predates issuance).

Step 9: Authority binding (profile-dependent)

  • Under VDI_VERIFY_STRICT_V1, manifest.authority_signature MUST be present.
  • authority_signature.signed_hash MUST equal policy.manifest_hash.
  • Verify Ed25519: signature MUST be valid over UTF-8 bytes of the string signed_hash (identical message encoding to registry Manifest.verifyAuthority).

Step 10: Circuit governance (optional)

  • If circuit is present, implementations SHOULD append a metadata step.
  • Pin enforcement is configurable: it is OFF unless the caller provides options.circuitRegistry.
  • If verifyDecision is called with options.circuitRegistry, the verifier MUST compare circuit.circuit_hash to the pin for circuit.circuit_id (wasm_sha256 or circuit_hash field in the pin object). Mismatch ⇒ INVALID (VDI_ERR_CIRCUIT_HASH_MISMATCH). Pins with "deprecated": true ⇒ INVALID (VDI_ERR_CIRCUIT_DEPRECATED).
  • Example pin file: protocol/conformance/circuit-registry.example.json.
  • The example pin file is derived from protocol/ARTIFACT_MANIFEST.json (circuits.<id>.artifacts.wasm.sha256) and MUST be refreshed whenever circuit artifacts are regenerated.

Result

On success: { valid: true, steps: [...], profileId, ... }. On failure: { valid: false, failedStep, code, reason, profileId?, steps: [...] }. The code string is stable and MUST match §2.1 for normative failures.

2.1 Verification error codes (normative)

CodeWhen
VDI_ERR_UNKNOWN_PROFILEprofileId not in the implementation’s profile registry
VDI_ERR_INTERNALUnexpected exception inside the verifier
VDI_ERR_SCHEMA_*Step 1 schema violations (suffix encodes field)
VDI_ERR_TIMESTAMP_ISSUED_ATIssued in the future (beyond skew)
VDI_ERR_TIMESTAMP_EXPIREDPast expires_at
VDI_ERR_PIPELINE_HASH_FORMATMalformed pipeline hash
VDI_ERR_POLICY_HASH_FORMATMalformed policy.manifest_hash
VDI_ERR_POLICY_AUTHORITY_TYPEUnknown authority type
VDI_ERR_ZK_VERIFYZK verifier threw (malformed inputs)
VDI_ERR_ZK_INVALIDGroth16 verify returned false
VDI_ERR_SIGNATURE_VERIFYException while verifying attestation Ed25519
VDI_ERR_SIGNATURE_INVALIDAttestation Ed25519 verify returned false
VDI_ERR_KEY_INTEGRITYkey_hash does not match canonical key digest
VDI_ERR_REVOCATION_DATA_REQUIREDStrict profile, no revocation object
VDI_ERR_ATTESTATION_REVOKEDID in revokedAttestations
VDI_ERR_SIGNING_KEY_REVOKEDkid in revokedKids
VDI_ERR_REVOCATION_STALEsnapshotTime too old vs issued_at
VDI_ERR_AUTHORITY_SIGNATURE_REQUIREDStrict profile, missing manifest.authority_signature
VDI_ERR_AUTHORITY_MANIFEST_HASHMissing policy.manifest_hash for binding
VDI_ERR_AUTHORITY_HASH_MISMATCHsigned_hashpolicy.manifest_hash
VDI_ERR_AUTHORITY_ALGORITHMUnsupported authority_signature.algorithm
VDI_ERR_AUTHORITY_KEY_FORMATBad key/signature length or encoding
VDI_ERR_AUTHORITY_SIGNATURE_INVALIDAuthority Ed25519 verify false
VDI_ERR_AUTHORITY_SIGNATURE_VERIFYException during authority verify
VDI_ERR_AUTHORITY_LEVELBelow profile min_authority_level
VDI_ERR_AUTHORITY_NOT_ACCEPTEDAuthority type not in profile allowlist
VDI_ERR_MANIFEST_TRUST_CLASSStrict profile requires manifest.trust_class === "published"
VDI_ERR_CIRCUIT_IDStep 10: missing circuit.circuit_id
VDI_ERR_CIRCUIT_HASHStep 10: missing circuit.circuit_hash
VDI_ERR_CIRCUIT_HASH_MISMATCHStep 10: hash does not match circuitRegistry pin
VDI_ERR_CIRCUIT_DEPRECATEDStep 10: pin marked deprecated
VDI_ERR_CIRCUIT_GOVERNANCEStep 10: other governance failure

2.2 Policy object: registry-bound issuance (optional)

When an issuer binds an attestation to a published registry manifest, policy.manifest_hash SHOULD equal that manifest’s canonical hash, and the attestation SHOULD include an optional policy.enforcement_parameters_digest (SHA-256 hex) fingerprinting the enforced circuit parameters (e.g. compiled threshold values), so verifiers can distinguish manifest identity from parameterization.

2.3 Conformance execution (non-normative)

Reference conformance artifacts are in protocol/conformance/ and are consumed by JS, Go, and Python test suites. A one-command auditor runner is provided:

bash protocol/scripts/run-vdi-audit-suite.sh

This executes attestation and receipt conformance checks across all three reference implementations.

2.4 Runtime crypto dependency requirements (non-normative)

Implementations MUST NOT silently degrade cryptographic checks.

  • Python verifier deployments require:
    • py_ecc for full Groth16 bn128 pairing verification
    • PyNaCl for Ed25519 signature verification
  • If unavailable, verification SHOULD fail closed with deterministic VDI_ERR_* codes rather than structural-only or skipped verification behavior.

3. Canonical Payload Format

For signature computation, the canonical payload is computed as:

  • Take all fields of the attestation object EXCEPT signature.value
  • Serialize using RFC 8785 (JSON Canonicalization Scheme)
  • The signature is computed over the bytes of this canonical form

4. Policy Manifest Format

A Policy Manifest is a published, versioned set of constraints:

json
{
  "manifest_version": "1.0.0",
  "manifest_id": "vdi:manifest:fair-lending-v1",
  "name": "Fair Lending Act Compliance Constraints",
  "regulation": "Fair Lending Act, ECOA, CFPB Regulation B",
  "authority": { "type": "legal_review", "name": "...", "reference": "..." },
  "constraints": [
    { "id": "no_protected_class", "description": "...", "critical": true },
    { "id": "adverse_action_justified", "description": "...", "critical": true },
    { "id": "rate_within_bounds", "description": "...", "critical": false }
  ],
  "manifest_hash": "0x<SHA-256 of constraints array>"
}

5. Trust Levels

LevelAuthorityWhat it means
0self_attestedIssuer defines own constraints. No external validation.
1legal_reviewNamed law firm reviewed and attested constraint correctness.
2audit_firmLicensed audit firm validated constraints as part of engagement.
3standards_bodyStandards organization (NIST, ISO, AICPA) published the constraints.

6. Verification Key Distribution

Verification keys are embedded in the attestation object itself. No key server or PKI infrastructure is required. The key_hash field allows caching and deduplication.

7. Revocation

7.1 Offline vs regulated verification

  • Offline / minimal profiles: Revocation MAY be omitted. Verifiers only see cryptographic validity and timestamps.
  • VDI_VERIFY_STANDARD_V1: Revocation SHOULD be supplied when the deployment maintains CRLs or OCSP-style lists; if omitted, verification proceeds (revocation step is informational pass).
  • VDI_VERIFY_STRICT_V1: Revocation data MUST be supplied as an object revocation passed into verifyDecision(attestation, { revocation }). Implementations treat an empty object { "revokedAttestations": [], "revokedKids": [] } as a valid explicit “empty CRL” snapshot.

7.2 Revocation object

json
{
  "revokedAttestations": ["vdi:att:0x..."],
  "revokedKids": ["0x..."],
  "snapshotTime": 1709078400
}
  • snapshotTime (optional): Unix seconds. If set, an attestation with issued_at after snapshotTime MUST fail with VDI_ERR_REVOCATION_STALE (the snapshot does not cover that issuance period).

7.3 Online hints

Attestations MAY include "revocation_endpoint": "https://..." as a hint for fetchers; the protocol does not mandate TLS or response format here—callers map fetches into the revocation object before calling strict verification.

8. Verification Receipts

A Verification Receipt is a deterministic, signed, cacheable proof-of-verification. When a verifier checks an attestation, it produces a receipt that says: "Verifier X ran these checks, at this time, with this implementation, and got PASS."

Receipts are second-order artifacts. They enable:

  • Caching: Verify once, reuse many times
  • Trust routing: Specialist verifiers emit receipts consumed by downstream agents
  • Multi-hop trust: Agents build trust graphs without every node re-verifying
  • Audit trails: Receipts document who verified what, when, with what result

8.1 Receipt Format

json
{
  "vdi_receipt_version": "1.0.0",
  "type": "verification_receipt_v1",
  "receipt_id": "vdi:receipt:0x<32-byte-hex>",
  "attestation_id": "vdi:att:0x...",
  "attestation_hash": "0x<32-byte-hex>",
  "verifier": {
    "implementation": "@quantzk/vdi-verifier",
    "version": "1.0.0",
    "verifier_id": "vdi:verifier:0x<16-byte-hex>"
  },
  "policy_manifest_hash": "0x...",
  "circuit_id": "causalProof",
  "result": {
    "valid": true,
    "checks": {
      "schema": true,
      "timestamps": true,
      "pipeline_integrity": true,
      "policy_integrity": true,
      "zk_proof": true,
      "signature": true,
      "key_integrity": true
    },
    "failed_step": null
  },
  "verified_at": 1709078400,
  "expires_at": 1709164800,
  "signature": {
    "algorithm": "Ed25519",
    "public_key": "0x<32-byte-hex>",
    "value": "0x<64-byte-hex>"
  }
}

8.2 Receipt Verification

To verify a receipt:

  1. Check receipt_id format: vdi:receipt:0x[64 hex chars]
  2. Verify attestation_hash matches SHA-256 of the referenced attestation
  3. Verify Ed25519 signature over the canonical receipt payload
  4. Check verified_at is in the past, expires_at is in the future
  5. Optionally: check verifier identity against a trusted verifier set

8.3 Trust Propagation

Agents MAY accept a receipt instead of re-verifying the attestation, subject to:

  • The receipt was signed by a trusted verifier
  • The receipt has not expired
  • The attestation_hash matches the attestation in question

This enables "verified once, reused many times" at network scale.

8.4 Attestation Extension

Attestations MAY include an optional receipts array:

json
{
  "...existing attestation fields...": "",
  "receipts": [
    { "receipt": "object" },
    { "receipt": "object" }
  ]
}

9. Trusted Verifier Sets (TVS)

A Trusted Verifier Set defines which verifiers an agent accepts receipts from. This prevents receipt equivocation, a malicious verifier issuing false PASS receipts.

9.1 TVS Format

json
{
  "tvs_version": "1.0.0",
  "tvs_id": "vdi:tvs:acme-production",
  "name": "ACME Corp Production Verifier Set",
  "verifiers": [
    {
      "verifier_id": "vdi:verifier:0x...",
      "name": "ACME Compliance Verifier",
      "public_key": "0x...",
      "trust_level": "primary"
    },
    {
      "verifier_id": "vdi:verifier:0x...",
      "name": "External Audit Verifier",
      "public_key": "0x...",
      "trust_level": "secondary"
    }
  ],
  "tvs_hash": "0x<SHA-256 of verifiers array>"
}

9.2 Acceptance Policies

Agents MUST define an acceptance policy for receipt consumption:

Risk LevelPolicyDescription
lowAccept 1 receipt from any TVS memberFast path for non-critical decisions
mediumAccept 1 receipt from primary verifier, OR 2 from secondaryStandard enterprise policy
highRequire k-of-n receipts from independent verifiersHigh-stakes decisions (lending, clinical)
criticalk-of-n receipts + random spot-check full re-verificationMaximum assurance, spot-checks keep verifiers honest

9.3 Spot-Check Enforcement

For critical acceptance policy, the consuming agent MUST:

  1. Accept the receipt(s) per quorum rules
  2. With probability p (configurable, default 5%), perform full ZK re-verification
  3. If spot-check fails, revoke trust in the offending verifier
  4. Log all spot-check results for audit

10. Verification Profiles

A Verification Profile defines exactly what "verified" means. Receipts are only comparable if they reference the same profile.

10.1 Profile Format

json
{
  "profile_version": "1.0.0",
  "profile_id": "VDI_VERIFY_STRICT_V1",
  "name": "VDI Strict Verification Profile",
  "checks": [
    { "step": 1, "name": "schema", "required": true },
    { "step": 2, "name": "timestamps", "required": true, "max_clock_skew_seconds": 300 },
    { "step": 3, "name": "pipeline_integrity", "required": true },
    { "step": 4, "name": "policy_integrity", "required": true },
    { "step": 5, "name": "zk_proof", "required": true },
    { "step": 6, "name": "signature", "required": true },
    { "step": 7, "name": "key_integrity", "required": true },
    { "step": 8, "name": "revocation_status", "required": true },
    { "step": 9, "name": "authority_binding", "required": true },
    { "step": 10, "name": "circuit_governance", "required": false, "when_present": true }
  ],
  "accepted_proof_systems": ["groth16"],
  "accepted_curves": ["bn128"],
  "accepted_authority_types": ["legal_review", "standards_body", "audit_firm"],
  "min_authority_level": 1,
  "profile_hash": "0x<SHA-256 of profile definition>"
}

10.2 Profile Binding

Every receipt MUST include:

  • verification_profile: the profile ID used
  • profile_hash: SHA-256 of the profile definition

Downstream agents can enforce: "only accept receipts verified under profile X."

10.3 Standard Profiles

Profile IDPipeline checks (ordered)Authority / manifestRevocation
VDI_VERIFY_STRICT_V1Steps 1–9 (incl. revocation + authority binding)min_authority_level ≥ 1, published manifest trust class, cryptographic authority signatureMUST supply revocation
VDI_VERIFY_STANDARD_V1Steps 1–8 (incl. revocation check if data present; not required)Any accepted authority typeSHOULD supply when operational
VDI_VERIFY_MINIMAL_V1Steps 1, 2, 5 only (schema, timestamps, ZK proof)NoneN/A

10.4 Profile Enforcement (Normative)

The verifyDecision() function MUST accept optional profileId and revocation parameters. When provided, the verifier:

  1. Only runs the checks listed in the profile's checks array. For VDI_VERIFY_MINIMAL_V1, pipeline integrity, policy integrity, signature, key integrity, revocation, and authority binding are skipped entirely.
  2. Enforces accepted_authority_types. If the attestation's policy.authority.type is not in the profile's accepted list, verification fails with code VDI_ERR_AUTHORITY_NOT_ACCEPTED.
  3. Enforces min_authority_level. Authority types are mapped to levels: self_attested=0, legal_review=1, audit_firm=2, standards_body=3. If the attestation's authority level is below the profile's minimum, verification fails with VDI_ERR_AUTHORITY_LEVEL.
  4. Strict manifest: For VDI_VERIFY_STRICT_V1, after pipeline checks, manifest.trust_class MUST be "published" (VDI_ERR_MANIFEST_TRUST_CLASS).

When profileId is omitted, the reference implementation in @quantzk/vdi-verifier defaults to VDI_VERIFY_STRICT_V1. HTTP/integration layers SHOULD default to VDI_VERIFY_STRICT_V1 as well; callers that intentionally need reduced requirements MUST pass profileId: "VDI_VERIFY_STANDARD_V1" explicitly.

11. Receipt Chaining

Receipts can reference parent receipts, creating a trust graph.

11.1 Parent Receipt Reference

A receipt MAY include:

json
{
  "parent_receipt_hash": "0x...",
  "chain_depth": 2
}

This indicates the verifier considered a prior receipt when making its assessment.

11.2 Receipt Sets

Attestations MAY accumulate receipts over time:

json
{
  ...attestation...,
  "receipts": [
    { receipt_1 },
    { receipt_2 },
    { receipt_3 }
  ]
}

More receipts from diverse verifiers = higher confidence. This creates an emergent trust graph without central coordination.

11.3 Receipt Set Scoring

Agents MAY compute a trust score from a receipt set:

  • Count of unique verifier IDs
  • Count of distinct verification profiles used
  • Minimum trust level across all receipts
  • Whether any receipt includes a full ZK re-verification (spot-check)

12. Receipt Transparency Log

Prevents receipt equivocation. Modeled after Certificate Transparency (RFC 6962).

12.1 Log Structure

Append-only Merkle tree of receipt hashes. Each entry records:

  • log_index, entry_hash, attestation_id, verifier_id, result, appended_at

12.2 Equivocation Detection

If the same verifier submits contradictory results for the same attestation, the log flags equivocation_detected: true with the conflicting entry index.

12.3 Inclusion Proofs

Any party can request a Merkle inclusion proof for a receipt entry, proving it exists in the log without revealing other entries.

13. Verifier Key Lifecycle

13.1 Key Registration

Verifiers register with: public_key, organization, capabilities. Keys have validity windows (default 1 year).

13.2 Key Rotation

rotateKey(verifierId, newPublicKey, gracePeriod), old key remains valid during the grace period, new key becomes current.

13.3 Revocation

revoke(verifierId, reason), all keys immediately invalidated. Receipts signed before revocation remain valid if verified against the key's validity window at the time of signing.

13.4 Key Validation

validateKey(verifierId, publicKey, atTimestamp), checks whether a specific key was valid at a given time. Used during receipt verification to ensure the signing key was active when the receipt was issued.

14. Circuit Governance

Attestations SHOULD include circuit metadata for auditability:

json
{
  "circuit": {
    "circuit_id": "causalProof",
    "circuit_version": "2.0.0",
    "circuit_hash": "0x<SHA-256 of WASM>",
    "r1cs_hash": "0x<SHA-256 of R1CS>",
    "compiler": "circom",
    "compiler_version": "2.1.9",
    "proof_system": "groth16",
    "curve": "bn128",
    "constraints": 5447,
    "audit_reference": "NCC Group Report #2026-ZK-014"
  }
}

14.1 Purpose

Verifiers and auditors can confirm which circuit logic produced the proof. Without this, there is no way to distinguish proofs from different circuit versions.

14.2 Validation

Circuit metadata is informational, it does not affect proof validity. However, regulated use cases SHOULD require:

  • circuit_hash matches a known, audited circuit
  • compiler_version is on an approved list
  • audit_reference is present for production use

14.3 Artifact Manifest

An ARTIFACT_MANIFEST.json file SHOULD be maintained alongside compiled circuits. It records the SHA-256 hash of every artifact (WASM, zkey, vkey, R1CS, sym) for each circuit. On startup, the prover SHOULD validate all artifact hashes against the manifest. If any hash mismatches, the system SHOULD refuse to generate proofs.

14.4 Artifact authority policy (normative)

  1. Canonical zkey per circuit is the pin at ARTIFACT_MANIFEST.json:circuit.<id>.artifacts.zkey.
  2. MPC-backed status is determined from ARTIFACT_MANIFEST.json:circuit.<id>.ceremony fields plus transcript hash pins.
  3. Verification pin enforcement is configurable and only active when verifier callers pass circuitRegistry; strict profile does not implicitly force pin checks.
  4. Rotations MUST update manifest pins and SHOULD update conformance registry pins in the same change window.

14.5 Artifact lifecycle and compatibility rules

  • Attestations are validated against embedded verification.key / verification.key_hash and selected verification profile policy.
  • Artifact rotations are versioned and MUST NOT be silent.
  • Deprecation MUST be explicit (deprecated: true in registry pin metadata), not implied by replacement.
  • Historical verification windows and deprecation policy MUST be documented for each deployment.

Upgrade matrix (expected behavior)

Attestation artifact epochVerifier epoch/configVDI_VERIFY_STANDARD_V1VDI_VERIFY_STRICT_V1
oldnew verifier, no circuitRegistryPASS if embedded proof/signature/timestamps passPASS if strict-only checks pass (revocation + authority binding)
oldnew verifier with circuitRegistryPASS if circuit_hash matches pin; else VDI_ERR_CIRCUIT_HASH_MISMATCHsame as STANDARD + strict-only checks
newold verifierPASS if schema/crypto checks supported by that verifier implementationPASS/FAIL per old strict implementation semantics
newnew verifier with circuitRegistryPASS when manifest and registry pins are updated in lockstepsame as STANDARD + strict-only checks

Rotation runbook: protocol/docs/circuit-artifact-rotation-runbook.md.

15. enforced-policy and compliance circuits

In addition to the causal circuit family (which proves pipeline execution structure), VDI supports the enforced-policy mode where regulatory constraints are embedded directly in the arithmetic circuit. The prover cannot generate a valid proof for a decision that violates any constraint, not by policy, not by audit, by mathematics.

15.1 Attestation Extension

Enforced policy attestations include two additional top-level fields:

json
{
  "proof_status": "required",
  "policy_enforcement": "in_circuit"
}
  • proof_status: "required" indicates the proof is not optional or best-effort.
  • policy_enforcement: "in_circuit" indicates constraints are enforced by the circuit, not by application-layer validation.

15.2 Available Circuits

Circuit IDConstraintsRegulationPublic Inputs
causalProof5,447General proof of DAG execution necessityNone (zero public inputs)
fairLending36Fair Lending Act, ECOAmin_credit_score, max_dti_x100
hipaaAccess31HIPAA Privacy Rule (45 CFR 164)min_auth_level, max_fields, min_purpose_code
euAiAct47EU AI Act (Reg. 2024/1689, Art. 6-14)min_risk_level, min_oversight_score, min_transparency_score
soc2Access39AICPA Trust Services CC6min_auth_factors, max_permission_level, max_session_timeout
complianceCertificate1,937General compliance scoringframework_id, criteria_hash, claimed_score, score_threshold, certificate_id_hash, timestamp

15.3 Circuit Pattern

All enforced policy circuits follow the same structural pattern:

  1. Binary input validation, flags are constrained to {0, 1}.
  2. Forbidden action constraint, a === 0 constraint on prohibited fields (e.g., protected_class_used === 0, bulk_export_attempted === 0).
  3. Threshold comparators, private inputs compared against public policy parameters using GreaterEqThan / LessEqThan components.
  4. Conditional approval, approval (output === 1) requires all checks to pass; denial is always safe.

15.4 compliance certificate circuit

The compliance certificate circuit is a special-purpose circuit for continuous compliance scoring. It computes a weighted score from private evidence results and verifies it against a Poseidon-committed criteria definition.

Key properties:

  • 4-level Poseidon hash tree binds framework context, weights, criticality, and criterion IDs into a single criteria_hash public input.
  • Integer-arithmetic scoring, no division or floating point. Score is in basis points (10000 = 100%).
  • Critical criteria enforcement, if any criterion marked critical=1 has evidence_result=0, proof generation fails.
  • Score threshold, claimed_score >= score_threshold is enforced in-circuit.

16. Cryptographic Authority Binding

16.1 Purpose

Authority identity in Section 5 is declarative, a string name and type. This is sufficient for policy manifests distributed through trusted channels, but it does not prevent an attacker from claiming a false authority in a custom manifest.

Cryptographic authority binding provides an optional mechanism for authorities to Ed25519-sign their manifest hash, creating a verifiable chain: regulation → authority signature → manifest hash → attestation.

16.2 Authority Signature Format

A manifest MAY include an authority_signature field:

json
{
  "authority_signature": {
    "algorithm": "Ed25519",
    "public_key": "0x<32-byte-hex>",
    "value": "0x<64-byte-hex>",
    "signed_hash": "0x<manifest-hash>",
    "signed_at": 1709078400
  }
}

16.3 Verification

To verify an authority binding:

  1. Confirm signed_hash matches the manifest's computed hash.
  2. Verify the Ed25519 signature over the manifest hash bytes using public_key.
  3. Optionally, check public_key against a known authority key registry.

Authority binding is OPTIONAL. Manifests without an authority signature remain valid, they are equivalent to trust_class: "custom" with self_attested authority.

Verification keys are embedded in attestations. The verifier is open source.