Skip to main content

Self-Verifiable Retention Chain for Payment Receipts
draft-hopley-x402-retention-chain-07

Document Type Active Internet-Draft (individual)
Author MR CHRISTOPHER HOPLEY
Last updated 2026-06-25
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-hopley-x402-retention-chain-07
Independent Submission                                       C. Hopley
Internet-Draft                                                 AlgoVoi
Intended status: Informational                             25 June 2026
Expires: 25 December 2026

         Self-Verifiable Retention Chain for Payment Receipts
                  draft-hopley-x402-retention-chain-07

Abstract

   This document specifies eight cryptographic constructions for
   self-verifiable agentic payment records.  The first, the Retention
   Chain Reference (retention_chain_ref), enables tamper-evident audit
   chains linking payment receipts without requiring external
   infrastructure.  The second, the Payment Action Lifecycle, defines
   a content-addressed model for the exactly-once execution of payment
   actions, including an action reference primitive (action_ref) and a
   per-state transition hash (transition_hash) with a provable SKIP-on-
   retry idempotency guarantee.  The third, the Settlement-Action
   Binding (binding_ref), binds a settled payment to the verified agent
   action it paid for and to the retention chain entry recording it, so
   that a settlement attestation proves not only that a payment occurred
   but which verified action it corresponds to.  The fourth, the Policy
   Binding (policy_bound_ref), binds a content-addressed snapshot of the
   governing policy to an existing binding or chain reference, so that a
   decision is verifiable against the exact policy version that admitted
   it and a policy rotation is detectable by recomputation.  The fifth,
   the Compliance Gate Binding (gate_ref), binds a categorical
   ALLOW/REFER/DENY compliance verdict and a no-PII payer reference to a
   policy or binding reference, so that a screening decision is provably
   tied to the policy in force when it was made and carries no personal
   data in the bound record.  The sixth, the Pre-Payment Decision
   Chain (guardrail_ref), composes an agent identity reference, a spend
   authority reference, and the policy in force into one recomputable
   pre-payment ALLOW/DENY decision.  The seventh, Post-Decision
   Execution Evidence (execution_ref), binds an executed action to the
   exact decision that authorized it, so the recorded execution is
   provably consistent with the decision and not merely correlated with
   an agent identity.  The eighth, Cross-Party Authority Delegation
   (delegation_ref), binds a delegation of authority from one party to
   another and chains hand-offs, so a verifier can confirm that authority
   did not widen across an organizational boundary.  All
   constructions use only SHA-256 and the JSON Canonicalization Scheme
   (JCS, RFC 8785),
   and are verifiable by any party holding the relevant receipts without
   contacting the issuer.  The constructions satisfy the transaction
   recording and audit trail obligations of MiCA Article 80, DORA
   Article 14, and AMLR Article 56.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 25 December 2026.

Copyright Notice

   Copyright (c) 2026 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (https://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with
   respect to this document.

Table of Contents

   1.  Introduction
   2.  Terminology
   3.  Preimage Schema
   4.  Chain Reference Computation
       4.1.  JCS Canonicalization
       4.2.  SHA-256 Digest
       4.3.  Output Encoding
   5.  Chain Construction Rules
       5.1.  Genesis Record
       5.2.  Subsequent Records
   6.  Verification Procedure
       6.1.  Single-Link Verification
       6.2.  Sequence Verification
   7.  Payment Action Lifecycle
       7.1.  Action Reference
       7.2.  Transition Hash
       7.3.  Lifecycle States
       7.4.  Exactly-Once Guarantee (SKIP-on-retry)
       7.5.  Input Validation Rules
       7.6.  Settlement-Action Binding
       7.7.  Policy Binding
       7.8.  Compliance Gate Binding
       7.9.  Pre-Payment Decision Chain
       7.10. Post-Decision Execution Evidence
   8.  Conformance Vectors
       8.1.  Retention Chain Vectors: Test Inputs
       8.2.  Retention Chain Vectors: Vector 0 -- Genesis
       8.3.  Retention Chain Vectors: Vector 1 -- Chain Link
       8.4.  Retention Chain Vectors: Vector 2 -- Chain Link
       8.5.  Lifecycle Vectors: Action Reference
       8.6.  Lifecycle Vectors: State Transitions
       8.7.  Lifecycle Vectors: SKIP-on-retry Idempotency
       8.8.  Adversarial Boundary Vectors
       8.9.  Settlement-Action Binding Vectors
       8.10. Policy Binding Vectors
       8.11. Compliance Gate Binding Vectors
       8.12. Pre-Payment Decision Chain Vectors
       8.13. Post-Decision Execution Evidence Vectors
   9.  Regulatory Applicability
       9.1.  MiCA Article 80
       9.2.  DORA Article 14
       9.3.  AMLR Article 56
   10. Security Considerations
       10.1. Collision Resistance
       10.2. Subset Auditability
       10.3. Chain Truncation
       10.4. Issuer Isolation
       10.5. Exactly-Once Security Properties
   11. IANA Considerations
   12. References
       12.1. Normative References
       12.2. Informative References
   Author's Address

1.  Introduction

   Agentic payment systems that operate under MiCA, DORA, or AMLR are
   required to maintain tamper-evident records of every payment
   transaction and to make those records available for regulatory audit
   on demand.  Existing approaches rely on centralised audit logs, which
   introduce availability risk and require auditors to trust the
   operator's infrastructure.

   This document specifies two constructions that together cover the
   full lifecycle of a regulated agentic payment:

   1.  The Retention Chain Reference links receipts into a verifiable
       audit chain.  Any party holding receipts can verify chain
       integrity without contacting the issuer.

   2.  The Payment Action Lifecycle assigns a stable, content-addressed
       identity (action_ref) to each payment action, and a per-state
       digest (transition_hash) to each lifecycle stage.  The
       construction provides a provable SKIP-on-retry guarantee: a
       re-presented identical transition request reproduces the prior
       transition_hash byte-for-byte and cannot constitute a second
       effect.

   Both constructions require only:

   o  A SHA-256 implementation (available in every standard library).
   o  A JCS canonicalization implementation (RFC 8785).
   o  The receipts and/or transition records themselves.

   The constructions are designed for use with x402 payment receipts
   [X402] but are not limited to that protocol.  The preimage schemas
   use only primitive JSON types (integer and string), making them
   compatible with any receipt format that can supply the required
   fields.

2.  Terminology

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
   and "OPTIONAL" in this document are to be interpreted as described
   in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in
   all capitals, as shown here.

   chain_seq:
      A non-negative integer identifying the position of a receipt in
      an issuer's sequence.  The genesis receipt has chain_seq = 0.
      Each subsequent receipt increments chain_seq by 1.

   issuer_id:
      A non-empty string uniquely identifying the receipt issuer within
      the deployment.  Issuers SHOULD use URN or DID syntax.

   receipt_hash:
      The SHA-256 digest of a payment receipt, encoded as the string
      "sha256:" followed by 64 lowercase hexadecimal characters.

   prev_receipt_hash:
      The receipt_hash of the immediately preceding receipt in the
      issuer's chain.  MUST be the empty string "" for the genesis
      record (chain_seq = 0).

   retention_chain_ref:
      The output of the chain reference computation defined in
      Section 4.  Encoded as the string "sha256:" followed by 64
      lowercase hexadecimal characters.

   action_ref:
      A content-addressed identifier for a payment action, computed
      as the SHA-256 digest of the JCS canonical form of the action's
      identity preimage (Section 7.1).  Encoded as 64 lowercase
      hexadecimal characters (no "sha256:" prefix).  MUST NOT change
      across any state of the action's lifecycle.

   transition_hash:
      A content-addressed digest of a payment action's state at a
      specific lifecycle stage, computed as the SHA-256 digest of the
      JCS canonical form of the transition preimage (Section 7.2).
      Encoded as 64 lowercase hexadecimal characters (no "sha256:"
      prefix).

   timestamp_ms:
      A non-negative integer representing a point in time as
      milliseconds since the Unix epoch (1970-01-01T00:00:00Z).
      Implementations MUST NOT represent timestamps as RFC 3339
      strings, floating-point values, booleans, or null.

   JCS:
      JSON Canonicalization Scheme as defined in RFC 8785.

3.  Preimage Schema

   The preimage is a JSON object with exactly four fields.  When
   serialised using JCS (Section 4.1), the fields appear in the
   following lexicographic order:

      chain_seq          (integer, non-negative)
      issuer_id          (string, non-empty)
      prev_receipt_hash  (string, "sha256:<64-hex>" or "")
      receipt_hash       (string, "sha256:<64-hex>")

   Implementations MUST NOT include additional fields in the preimage.
   Implementations MUST NOT omit any of the four fields.

   Field constraints:

   o  chain_seq MUST be a non-negative integer.  Floating-point
      representations are not permitted.

   o  issuer_id MUST be a non-empty string.

   o  prev_receipt_hash MUST be "" when chain_seq = 0, and MUST be a
      valid receipt_hash string (as defined above) when chain_seq > 0.

   o  receipt_hash MUST match the pattern "sha256:[0-9a-f]{64}".
      Uppercase hexadecimal characters are not permitted.

4.  Chain Reference Computation

4.1.  JCS Canonicalization

   The preimage object MUST be serialised using the JSON
   Canonicalization Scheme [RFC8785].  JCS produces a deterministic
   byte sequence by:

   o  Sorting object keys lexicographically by Unicode code point.
   o  Serialising numbers without insignificant leading zeros or
      trailing decimals.
   o  Encoding strings using minimum-length Unicode escape sequences.
   o  Omitting all insignificant whitespace.

   For the four-field preimage defined in Section 3, the keys in
   lexicographic order are:

      chain_seq, issuer_id, prev_receipt_hash, receipt_hash

   Example canonical form for the genesis vector (Section 8.2):

      {"chain_seq":0,"issuer_id":"algovoi:test",
      "prev_receipt_hash":"","receipt_hash":"sha256:24c3e22bc6ece631
      e4524e3beeb904553fbb1cd6fd124e1cb3c68a9a277ba23a"}

   (Line breaks above are for readability only; the actual canonical
   form contains no whitespace between tokens.)

4.2.  SHA-256 Digest

   The SHA-256 digest [FIPS180-4] MUST be computed over the UTF-8
   encoding of the JCS canonical byte sequence produced in Section 4.1.
   The result is a 32-byte (256-bit) digest.

4.3.  Output Encoding

   The retention_chain_ref is the string formed by concatenating the
   literal prefix "sha256:" with the lowercase hexadecimal encoding of
   the 32-byte SHA-256 digest.  The result is always exactly 71
   characters: 7 prefix characters followed by 64 hexadecimal
   characters.

   Pseudocode:

      preimage = {
          "chain_seq":         chain_seq,
          "issuer_id":         issuer_id,
          "prev_receipt_hash": prev_receipt_hash,
          "receipt_hash":      receipt_hash,
      }
      canonical_bytes      = JCS(preimage)
      digest               = SHA256(canonical_bytes)
      retention_chain_ref  = "sha256:" + hex(digest)

5.  Chain Construction Rules

5.1.  Genesis Record

   The first receipt in an issuer's chain MUST satisfy:

   o  chain_seq = 0
   o  prev_receipt_hash = ""

   Implementations MUST reject a genesis record whose prev_receipt_hash
   is non-empty.

5.2.  Subsequent Records

   Each subsequent receipt MUST satisfy:

   o  chain_seq = (previous chain_seq) + 1
   o  prev_receipt_hash = receipt_hash of the immediately preceding
      receipt (NOT the preceding retention_chain_ref)

   The chain links via receipt_hash values, not via
   retention_chain_ref values.  This design allows an auditor who holds
   a receipt but not its chain reference to reconstruct chain linkage
   from the receipts alone.

6.  Verification Procedure

6.1.  Single-Link Verification

   To verify a single retention_chain_ref:

   1.  Extract chain_seq, issuer_id, prev_receipt_hash, and
       receipt_hash from the receipt under examination.

   2.  Check field constraints as defined in Section 3.  Fail if any
       constraint is violated.

   3.  Compute retention_chain_ref as defined in Section 4.

   4.  Compare the computed value to the retention_chain_ref stored in
       or alongside the receipt.

   5.  The link is valid if and only if the values are identical.

6.2.  Sequence Verification

   To verify a contiguous sequence of N receipts R[0], R[1], ...,
   R[N-1]:

   1.  Verify R[0] as a single link per Section 6.1.

   2.  For each i in 1..N-1:

       a.  Verify R[i] as a single link per Section 6.1.

       b.  Check that R[i].chain_seq = R[i-1].chain_seq + 1.

       c.  Check that R[i].prev_receipt_hash = R[i-1].receipt_hash.

   3.  The sequence is valid if and only if all per-link verifications
       pass and all adjacency checks pass.

   An auditor holding a non-contiguous subset of receipts MAY verify
   each individual link independently.  The subset does not constitute
   a complete chain audit but does demonstrate that each held receipt
   is internally consistent.

7.  Payment Action Lifecycle

   This section specifies the content-addressed model for the exactly-
   once execution of payment actions.  It defines two primitives:
   action_ref (the stable identity of an action across its lifecycle)
   and transition_hash (the state-specific digest for each lifecycle
   stage).

7.1.  Action Reference

   An action_ref uniquely identifies a payment action.  It is computed
   as the SHA-256 digest of the JCS canonical form of the following
   four-field identity preimage:

      action_type    (string, non-empty)
      agent_id       (string, non-empty)
      scope          (string, non-empty)
      timestamp_ms   (integer, non-negative)

   JCS lexicographic key order:

      action_type, agent_id, scope, timestamp_ms

   Pseudocode:

      identity = {
          "action_type":  action_type,
          "agent_id":     agent_id,
          "scope":        scope,
          "timestamp_ms": timestamp_ms,
      }
      canonical_bytes = JCS(identity)
      action_ref      = hex(SHA256(canonical_bytes))

   The action_ref is encoded as 64 lowercase hexadecimal characters
   with no prefix.  Implementations MUST NOT include the "sha256:"
   prefix used by retention_chain_ref and receipt_hash.

   The action_ref MUST remain constant across all lifecycle states of
   the action.  It serves as the binding key that connects every
   transition_hash for a given action.

7.2.  Transition Hash

   A transition_hash records the state of a payment action at a
   specific lifecycle stage.  It is computed as the SHA-256 digest of
   the JCS canonical form of the following five-field transition
   preimage:

      action_ref               (string, 64 lowercase hex chars)
      authority_verified_at_ms (integer, non-negative)
      revocation_check_at_ms   (integer, non-negative)
      state                    (string, non-empty)
      transition_timestamp_ms  (integer, non-negative)

   JCS lexicographic key order:

      action_ref, authority_verified_at_ms, revocation_check_at_ms,
      state, transition_timestamp_ms

   Pseudocode:

      transition = {
          "action_ref":               action_ref,
          "authority_verified_at_ms": authority_verified_at_ms,
          "revocation_check_at_ms":   revocation_check_at_ms,
          "state":                    state,
          "transition_timestamp_ms":  transition_timestamp_ms,
      }
      canonical_bytes  = JCS(transition)
      transition_hash  = hex(SHA256(canonical_bytes))

   The transition_hash is encoded as 64 lowercase hexadecimal
   characters with no prefix.

7.3.  Lifecycle States

   Three lifecycle states are defined:

   PENDING:
      The action has been initiated and is awaiting settlement.

   COMMITTED:
      The action has settled.  This is the "once" in exactly-once:
      a COMMITTED transition_hash is the authoritative proof of
      settlement.

   REVERSED:
      The action has been reversed following a COMMITTED transition.

   Because the state field is load-bearing in the JCS preimage, each
   lifecycle state produces a distinct transition_hash even when all
   other fields are identical.  Implementations MUST NOT treat
   transition_hash values from different states as interchangeable.

7.4.  Exactly-Once Guarantee (SKIP-on-retry)

   The SKIP-on-retry invariant is a consequence of the deterministic
   JCS+SHA-256 construction: if two calls to the transition_hash
   computation use identical values for all five preimage fields, they
   MUST produce identical output.

   Therefore: a payment processor that re-presents an identical
   transition request (same action_ref, same state, same timestamps)
   MUST produce the same transition_hash as the original.  The retry
   is byte-identical to the first attempt; it cannot constitute a
   second effect.

   Implementations MUST NOT introduce randomness, a nonce, or a
   wall-clock re-sampling into the transition preimage.  Doing so
   would break the idempotency guarantee.

   This guarantee is content-addressed and requires no session state,
   no idempotency-key registry, and no coordination between retrying
   parties.  Any party holding the original transition_hash can verify
   a retry by recomputing the hash from the five fields.

7.5.  Input Validation Rules

   Implementations MUST enforce the following constraints before
   computing any hash defined in this section.  A violation MUST cause
   the computation to be rejected; implementations MUST NOT silently
   accept or coerce invalid inputs.

   Timestamp fields (timestamp_ms, transition_timestamp_ms,
   authority_verified_at_ms, revocation_check_at_ms):

   o  MUST be a non-negative integer JSON value.
   o  MUST NOT be a string (including RFC 3339 date-time strings).
   o  MUST NOT be a floating-point value, a boolean, or null.

   The action_ref field in a transition preimage:

   o  MUST be exactly 64 characters in length.
   o  MUST consist entirely of lowercase hexadecimal characters
      ([0-9a-f]).

   String fields (agent_id, action_type, scope, state):

   o  MUST be non-empty strings.
   o  MUST NOT be null.

   These constraints are load-bearing: violating any of them alters
   the JCS canonical form and therefore the computed hash.  Accepting
   an invalid input silently would cause the implementation to compute
   a hash for a different logical object than intended.

7.6.  Settlement-Action Binding

   A settlement attestation proves that a payment occurred.  On its own
   it does not prove which verified agent action the payment
   corresponds to, nor that the correspondence is recorded in a
   tamper-evident chain.  The Settlement-Action Binding closes this
   post-settlement accountability gap.

   A binding_ref is computed as the SHA-256 digest of the JCS canonical
   form of the following four-field binding preimage:

      action_ref           (string, 64 lowercase hex chars)
      retention_chain_ref  (string, "sha256:" + 64 lowercase hex chars)
      settlement_ref       (string, 64 lowercase hex chars)
      transition_hash      (string, 64 lowercase hex chars)

   The four fields are, respectively: the action identity (Section
   7.1); the retention chain entry recording the action (Section 4);
   the content hash of the settlement attestation receipt
   ([SETTLEMENT-ATTESTATION]); and the COMMITTED transition for the
   action (Sections 7.2, 7.3).

   JCS lexicographic key order:

      action_ref, retention_chain_ref, settlement_ref, transition_hash

   Pseudocode:

      binding = {
          "action_ref":          action_ref,
          "retention_chain_ref": retention_chain_ref,
          "settlement_ref":      settlement_ref,
          "transition_hash":     transition_hash,
      }
      canonical_bytes = JCS(binding)
      binding_ref     = "sha256:" + hex(SHA256(canonical_bytes))

   The binding_ref is emitted with the "sha256:" prefix, consistent
   with retention_chain_ref.  No new hashing primitive is introduced:
   the binding is JCS + SHA-256 over four references already defined by
   this document and [SETTLEMENT-ATTESTATION].

   The following invariants hold and MUST be preserved by any
   conformant implementation:

   o  Stability: an identical four-field preimage reproduces the same
      binding_ref byte-for-byte.

   o  Settlement-binding: changing settlement_ref changes binding_ref.
      A settlement cannot be re-pointed to another action's record.

   o  Action-binding: changing action_ref changes binding_ref.  An
      action cannot claim another identity's settlement.

   o  State-binding: changing transition_hash changes binding_ref.
      Only the exact COMMITTED transition (Section 7.3) binds; a
      PENDING or REVERSED transition_hash yields a distinct binding_ref,
      so a non-committed state cannot be presented as settled-bound.

   o  Chain-binding: changing retention_chain_ref changes binding_ref.
      The chain position recording the record is load-bearing.

   Because action_ref and transition_hash derive from
   epoch-millisecond-integer preimages (Section 7.5, Rule on
   timestamps), an implementation that admits an RFC 3339 string
   timestamp upstream computes a different action_ref and therefore a
   different binding_ref; it cannot reproduce the binding bytes of a
   conformant implementation.

   The binding_ref MAY itself be carried in an HTTP request that is
   signed using HTTP Message Signatures (RFC 9421); the construction of
   that signing base is specified informatively in
   [I-D.hopley-x402-rfc9421-binding].  The signature and the binding
   are independent checks: a valid signature does not imply a correct
   binding, and a correct binding does not imply a valid signature.

7.7.  Policy Binding

   A binding_ref (Section 7.6) or a retention_chain_ref (Section 4)
   proves which verified action settled and that the record is chained.
   Neither proves which policy, or ruleset, was in force when the action
   was admitted.  The Policy Binding closes this gap: it binds a
   content-addressed snapshot of the governing policy to an existing
   reference, so that a decision is verifiable against the exact policy
   version that produced it and a policy rotation is detectable by
   recomputation.

   The policy reference (policy_ref) is the SHA-256 digest of the JCS
   canonical form of the policy document.  The policy document is any
   JCS-serialisable object (for example an AML ruleset, a mandate, or a
   governance profile):

      policy_ref = "sha256:" + hex(SHA256(JCS(policy_document)))

   The policy binding (policy_bound_ref) is computed as the SHA-256
   digest of the JCS canonical form of the following two-field preimage:

      policy_ref   (string, "sha256:" + 64 lowercase hex chars)
      subject_ref  (string, "sha256:" + 64 lowercase hex chars)

   subject_ref is any content-addressed reference defined by this
   document that the policy is bound to: a Settlement-Action binding_ref
   (Section 7.6) or a retention_chain_ref (Section 4), of any version.
   It is imported by hash only, so the construction is identical across
   versions and never depends on which layer produced the reference.

   JCS lexicographic key order:

      policy_ref, subject_ref

   Pseudocode:

      policy_ref = "sha256:" + hex(SHA256(JCS(policy_document)))
      bound = {
          "policy_ref":  policy_ref,
          "subject_ref": subject_ref,
      }
      canonical_bytes = JCS(bound)
      policy_bound_ref = "sha256:" + hex(SHA256(canonical_bytes))

   The policy_bound_ref is emitted with the "sha256:" prefix, consistent
   with binding_ref and retention_chain_ref.  No new hashing primitive
   is introduced, and no construction defined elsewhere in this document
   is modified: the policy binding is JCS + SHA-256 over a policy
   snapshot and one existing reference, imported by hash.

   The following invariants hold and MUST be preserved by any conformant
   implementation:

   o  Stability: an identical (policy_ref, subject_ref) preimage
      reproduces the same policy_bound_ref byte-for-byte.

   o  Snapshot-binding: changing the policy document changes policy_ref
      and therefore policy_bound_ref.

   o  Rotation-detection: a policy P and a rotated policy P' yield
      distinct policy_bound_ref values for the same subject_ref.  A
      record sealed under P fails recomputation under P', so a policy
      rotation between decision and verification is detectable.

   o  Subject-binding: changing subject_ref changes policy_bound_ref.
      A policy decision cannot be re-pointed to another action's record.

   o  Key-order-invariance: JCS canonicalisation absorbs the key order
      of the policy document, so policy_ref is independent of how the
      policy is serialised.

7.8.  Compliance Gate Binding

   A policy_bound_ref (Section 7.7), a binding_ref (Section 7.6), or a
   retention_chain_ref (Section 4) records what settled, under which
   policy, and in what chain.  None records the compliance decision
   itself.  The Compliance Gate Binding closes this gap: it binds a
   categorical screening verdict, together with a payer reference that
   carries no personal data, to one of those references, so that an
   ALLOW, REFER, or DENY decision is verifiable against the exact policy
   or action it was made for, and a policy rotation between decision and
   verification is detectable by recomputation.

   The payer reference (payer_ref) is the SHA-256 digest of the JCS
   canonical form of a two-field preimage.  The cleartext address is
   never emitted; only its digest appears:

      address  (string, the screened account or wallet address)
      network  (string, the network the address belongs to)

      payer_ref = "sha256:" + hex(SHA256(JCS({address, network})))

   The verdict is a closed enumeration with exactly three members:

      "ALLOW", "REFER", "DENY"

   REFER is byte-distinct from DENY: a referral obligation (for example
   a suspicious-activity report) is not a refusal, and the two MUST NOT
   collapse to one value.

   The gate binding (gate_ref) is computed as the SHA-256 digest of the
   JCS canonical form of the following three-field preimage:

      payer_ref    (string, "sha256:" + 64 lowercase hex chars)
      subject_ref  (string, "sha256:" + 64 lowercase hex chars)
      verdict      (string, one of "ALLOW", "REFER", "DENY")

   subject_ref is any content-addressed reference defined by this
   document that the decision is bound to: a policy_bound_ref
   (Section 7.7), a Settlement-Action binding_ref (Section 7.6), or a
   retention_chain_ref (Section 4), of any version.  It is imported by
   hash only.

   JCS lexicographic key order:

      payer_ref, subject_ref, verdict

   Pseudocode:

      payer_ref = "sha256:" + hex(SHA256(JCS({
          "address": address,
          "network": network,
      })))
      bound = {
          "payer_ref":   payer_ref,
          "subject_ref": subject_ref,
          "verdict":     verdict,
      }
      canonical_bytes = JCS(bound)
      gate_ref = "sha256:" + hex(SHA256(canonical_bytes))

   The gate_ref is emitted with the "sha256:" prefix, consistent with
   the other references in this document.  No new hashing primitive is
   introduced, and no construction defined elsewhere in this document is
   modified.  The binding is content-addressed; this document defines no
   signature over gate_ref.

   The following invariants hold and MUST be preserved by any conformant
   implementation:

   o  No-PII: payer_ref is a digest, so the cleartext address does not
      appear in payer_ref or in gate_ref.

   o  Verdict-binding: the three verdicts over an identical
      (payer_ref, subject_ref) yield three distinct gate_ref values.

   o  Closed-enumeration: a verdict outside {"ALLOW","REFER","DENY"}
      MUST be rejected, not hashed.

   o  Policy-binding: when subject_ref is a policy_bound_ref, a verdict
      sealed under policy P yields a different gate_ref under a rotated
      policy P', so a policy rotation between decision and verification
      is detectable.

   o  Subject-binding: changing subject_ref changes gate_ref.  A
      decision cannot be re-pointed to another subject's record.

7.9.  Pre-Payment Decision Chain

   Sections 7.6 through 7.8 bind a settled action, the policy in force,
   and a compliance verdict.  A payment agent also makes a decision
   BEFORE it executes a payment: whether the spend is permitted, given
   the agent's identity, the spending authority, and the policy.  The
   Pre-Payment Decision Chain composes that decision from three
   content-addressed references into one recomputable guardrail_ref.

   An agent identity reference (passport_ref) is the SHA-256 digest of
   the JCS canonical form of:

      agent_id, issuer, scope, validity_window   (all strings)

   A spend authority reference (mandate_ref) is the SHA-256 digest of
   the JCS canonical form of:

      cap, payer, period, revocation_state        (all strings)

   The pre-payment decision (guardrail_ref) binds the agent, the
   authority, the policy in force (policy_bound_ref, Section 7.7), and
   the categorical verdict:

      agent_ref           ("sha256:" + 64 lowercase hex; the passport_ref)
      mandate_ref         ("sha256:" + 64 lowercase hex)
      policy_bound_ref    ("sha256:" + 64 lowercase hex; Section 7.7)
      verdict             (string; "ALLOW" or "DENY")

   JCS lexicographic key order:

      agent_ref, mandate_ref, policy_bound_ref, verdict

   Pseudocode:

      decision = {
          "agent_ref":        agent_ref,
          "mandate_ref":      mandate_ref,
          "policy_bound_ref": policy_bound_ref,
          "verdict":          verdict,
      }
      guardrail_ref = "sha256:" + hex(SHA256(JCS(decision)))

   No new hashing primitive is introduced: the decision is JCS +
   SHA-256 over references already defined by this document and the
   identity and authority references above.

   The following invariants hold and MUST be preserved by any
   conformant implementation:

   o  Stability: an identical preimage reproduces guardrail_ref
      byte-for-byte.

   o  Agent-binding: changing agent_ref changes guardrail_ref.  A
      decision made for one agent cannot be re-attributed to another.

   o  Authority-binding: changing mandate_ref changes guardrail_ref.  A
      decision checked against one spend authority cannot be presented
      as made against another.

   o  Policy-binding: changing policy_bound_ref changes guardrail_ref.
      An ALLOW made under one policy snapshot does not recompute under a
      rotated policy (Section 7.7).

   o  Verdict-binding: an ALLOW and a DENY over the same three
      references yield distinct guardrail_refs; a verdict cannot be
      silently flipped.

   o  Composition: passport_ref, mandate_ref, and policy_bound_ref are
      each independently recomputable from their own preimages, so the
      whole chain is verifiable end-to-end with no issuer contact and no
      registry lookup.

   The guardrail_ref MAY itself be carried in an HTTP request signed
   using HTTP Message Signatures (RFC 9421); the signature and the
   decision are independent checks, as in Section 7.6.

   The byte-level conformance artifact is the Apache-2.0
   spend_decision_chain_v1 set in the AlgoVoi JCS conformance corpus
   [ALGOVOI-VECTORS] (Section 8.12), which reproduces this chain for
   both ALLOW and DENY from the raw identity, authority, and policy
   inputs.

7.10.  Post-Decision Execution Evidence

   Section 7.9 binds a pre-payment decision (guardrail_ref) from the
   agent identity, the spend authority, and the policy in force.  That
   decision authorizes an action; it does not, on its own, record what
   the agent then DID, nor bind the recorded execution back to the
   decision that authorized it.  A reference that proves only the
   identity of an executed action (Section 7.1) establishes
   correlation with an agent, not consistency with a decision.  Post-
   Decision Execution Evidence closes that gap with a single content-
   addressed reference, execution_ref, that binds an executed action to
   the exact decision that authorized it.

   The execution evidence reference (execution_ref) is the SHA-256
   digest of the JCS canonical form of:

      decision_ref     ("sha256:" + 64 lowercase hex; the guardrail_ref
                        of Section 7.9, the decision that authorized the
                        execution)
      action_type      (string; what was executed)
      scope            (string; the scope it executed under)
      outcome          (string; closed set, below)
      executed_at_ms   (integer epoch milliseconds; the integer epoch-millisecond
                        rule of Section 7.5; hashed as an integer, never a
                        converted string)

   outcome is a closed set of four values:

      COMMITTED   the action committed exactly once
      SKIPPED     a duplicate of an already-committed action, suppressed
      FAILED      the action did not complete
      REVERSED    a previously committed action was reversed

   JCS lexicographic key order:

      action_type, decision_ref, executed_at_ms, outcome, scope

   Pseudocode:

      execution = {
          "decision_ref":   decision_ref,
          "action_type":    action_type,
          "scope":          scope,
          "outcome":        outcome,
          "executed_at_ms": executed_at_ms,
      }
      execution_ref = "sha256:" + hex(SHA256(JCS(execution)))

   No new hashing primitive is introduced: the reference is JCS +
   SHA-256 over the decision reference defined in Section 7.9 plus the
   four execution fields above.  executed_at_ms is hashed as an integer
   epoch-millisecond value, not a converted string; an implementation
   that hashes a string timestamp produces a different execution_ref and
   is non-conformant.

   No agent identifier appears in the preimage.  The agent is already
   bound inside decision_ref (through agent_ref, Section 7.9), so
   execution_ref carries no personal data of its own.

   The following invariants hold and MUST be preserved by any
   conformant implementation:

   o  Stability: an identical preimage reproduces execution_ref
      byte-for-byte.

   o  Decision-binding: changing decision_ref changes execution_ref.  An
      execution recorded under one decision cannot be re-attributed to
      another.  This is the consistency property: the evidence is bound
      to the decision that authorized it, not merely to an identity.

   o  Outcome-binding: a COMMITTED and a REVERSED over the same decision
      and action yield distinct execution_refs; an outcome cannot be
      silently changed.

   o  Time-binding: changing executed_at_ms changes execution_ref.

   o  Composition: decision_ref is itself recomputable from its own
      preimage (Section 7.9), which composes from passport_ref,
      mandate_ref, and policy_bound_ref, so the whole keystone is
      verifiable end-to-end with no issuer contact:

         passport_ref -> mandate_ref -> policy_bound_ref
            -> guardrail_ref (decision) -> execution_ref (execution)

      A composite trust verdict (trust_query_ref, defined in
      draft-hopley-x402-composite-trust-query) MAY
      assess the ordered list of these references, including
      execution_ref, so a single verdict spans identity through
      execution.

   An execution_ref MAY be carried as an entry in a signed, hash-linked
   evidence chain (Section 7.1) under entry type "execution_evidence",
   so that a sequence of executions is tamper-evident and offline-
   verifiable under the document's chain rules.

7.11.  Cross-Party Authority Delegation

   Sections 7.9 and 7.10 bind a single agent's decision and the execution
   that followed it.  Authority is frequently not exercised by the agent
   that was granted it: one party delegates a slice of its authority to
   another party's agent, which then builds its own keystone under that
   delegation and executes.  A receipt of the executed action proves what
   happened; it does not prove that the executing party stayed within the
   authority delegated to it, nor that the hand-off was between the
   intended parties inside the window the delegator allowed.  Cross-Party
   Authority Delegation closes that gap with a content-addressed
   reference, delegation_ref, that binds one hand-off of authority and
   chains hand-offs into a tamper-evident sequence.

   The delegation reference (delegation_ref) is the SHA-256 digest of the
   JCS canonical form of:

      delegate_id          (string; the party receiving the authority)
      delegator_id         (string; the party granting the authority)
      not_after_ms         (integer epoch milliseconds; end of the
                           validity window; Section 6 Substrate Rule for
                           integer-millisecond timestamps applies)
      not_before_ms        (integer epoch milliseconds; start of the
                           validity window)
      prev_delegation_ref  ("" for a root delegation, or the
                           "sha256:"-prefixed delegation_ref of the prior
                           hand-off, which chains delegations)
      scope                (string; the authority delegated)

   JCS lexicographic key order:

      delegate_id, delegator_id, not_after_ms, not_before_ms,
      prev_delegation_ref, scope

   Pseudocode:

      delegation = {
          "delegate_id":         delegate_id,
          "delegator_id":        delegator_id,
          "not_after_ms":        not_after_ms,
          "not_before_ms":       not_before_ms,
          "prev_delegation_ref": prev_delegation_ref,
          "scope":               scope,
      }
      delegation_ref = "sha256:" + hex(SHA256(JCS(delegation)))

   No new hashing primitive is introduced: the reference is JCS + SHA-256
   over the six fields above.  not_before_ms and not_after_ms are hashed
   as integer epoch-millisecond values, not converted strings; an
   implementation that hashes a string timestamp produces a different
   delegation_ref and is non-conformant.  not_after_ms MUST be greater
   than not_before_ms.

   The following invariants hold and MUST be preserved by any conformant
   implementation:

   o  Stability: an identical preimage reproduces delegation_ref
      byte-for-byte, including under reordering of the envelope keys,
      which JCS canonicalizes.

   o  Tamper-binding: changing the delegated scope, either validity
      bound, or either party changes delegation_ref.  A delegation cannot
      be silently widened, extended, or re-pointed to a different
      delegate.

   o  Chain integrity: prev_delegation_ref binds each hand-off to the one
      before it.  In a chain of delegations the prev_delegation_ref of
      each link MUST equal the computed delegation_ref of the prior link;
      a broken or forged link is detectable offline:

         delegation_ref(A->B) -> delegation_ref(B->C) -> ...

   o  Authority composition: because the executed action (Section 7.10),
      the decision that authorized it (Section 7.9), and the delegation
      that conferred the authority are each content-addressed and
      recomputable, a verifier MAY check, with no issuer contact, that
      authority did not widen across the party boundary: that the executed
      scope is contained within the decision scope, the decision scope
      within the delegated scope, that the delegate named by one hand-off
      is the delegator of the next, and that the execution time falls
      within the delegation's validity window.  This is the authorization
      property a receipt alone cannot establish: that the executing party
      stayed within what was delegated to it, end to end across the
      boundary.

   A delegation_ref MAY be carried as an entry in a signed, hash-linked
   evidence chain (Section 7.1) under entry type "delegation", so that a
   sequence of hand-offs is tamper-evident and offline-verifiable under
   the document's chain rules.

8.  Conformance Vectors

   Implementations MUST produce the hash values in Sections 8.2
   through 8.7 and Sections 8.9 through 8.11 for the given inputs.  The
   adversarial vectors in Section 8.8 MUST be rejected as specified.  An
   extended
   vector set covering multi-issuer isolation, sequence-gap detection,
   and the full set of adversarial boundaries is published at:

      https://github.com/chopmob-cloud/algovoi-jcs-conformance-vectors

8.1.  Retention Chain Vectors: Test Inputs

   The following receipt_hash values are used across Sections 8.2
   through 8.4.  Each is the SHA-256 digest of the UTF-8 encoding of
   the literal string shown:

      receipt_0: SHA-256("receipt_0") =
         sha256:24c3e22bc6ece631e4524e3beeb904553fbb1cd6fd124e1cb3c6
                8a9a277ba23a

      receipt_1: SHA-256("receipt_1") =
         sha256:55d4a60cbf6928423fd1cd0e06f7cccd98011e9064240a3fd24f
                7c6bbae8266a

      receipt_2: SHA-256("receipt_2") =
         sha256:08a132f9262230f24640a591c60a08e756d313dbf15ff578b4c1
                0fdd30120a4a

   issuer_id = "algovoi:test" for all three vectors.

8.2.  Retention Chain Vectors: Vector 0 -- Genesis

   Input:
      chain_seq:         0
      issuer_id:         "algovoi:test"
      prev_receipt_hash: ""
      receipt_hash:      sha256:24c3e22bc6ece631e4524e3beeb904553fbb1
                         cd6fd124e1cb3c68a9a277ba23a

   JCS canonical form (UTF-8, no whitespace):
      {"chain_seq":0,"issuer_id":"algovoi:test","prev_receipt_hash":
      "","receipt_hash":"sha256:24c3e22bc6ece631e4524e3beeb904553fbb1
      cd6fd124e1cb3c68a9a277ba23a"}

   Expected retention_chain_ref:
      sha256:f15a1dcd03cc039204dff24619ff4815ad041ad8796b94f59d5225
             2043d0d08f

8.3.  Retention Chain Vectors: Vector 1 -- Chain Link

   Input:
      chain_seq:         1
      issuer_id:         "algovoi:test"
      prev_receipt_hash: sha256:24c3e22bc6ece631e4524e3beeb904553fbb1
                         cd6fd124e1cb3c68a9a277ba23a
      receipt_hash:      sha256:55d4a60cbf6928423fd1cd0e06f7cccd98011
                         e9064240a3fd24f7c6bbae8266a

   Expected retention_chain_ref:
      sha256:7114dc39543710bf26d0a5825acddd915ffd51fb5b14503024f70f
             da403053d9

8.4.  Retention Chain Vectors: Vector 2 -- Chain Link

   Input:
      chain_seq:         2
      issuer_id:         "algovoi:test"
      prev_receipt_hash: sha256:55d4a60cbf6928423fd1cd0e06f7cccd98011
                         e9064240a3fd24f7c6bbae8266a
      receipt_hash:      sha256:08a132f9262230f24640a591c60a08e756d31
                         3dbf15ff578b4c10fdd30120a4a

   Expected retention_chain_ref:
      sha256:d3bddca79477e6003cb6ef199897bffed185f5d785b4e7333f9b05
             85b2b81144

8.5.  Lifecycle Vectors: Action Reference

   The following fixed identity preimage is used throughout Sections
   8.5 through 8.7:

      agent_id:     "agent_alpha"
      action_type:  "payment"
      scope:        "vauban:stark_settlement"
      timestamp_ms: 1716494400000

   JCS canonical form (keys in lexicographic order):
      {"action_type":"payment","agent_id":"agent_alpha",
      "scope":"vauban:stark_settlement","timestamp_ms":1716494400000}

   Expected action_ref (64 lowercase hex, no prefix):
      7528529a8be2044488e603b7913efaa4f83620dbcc63010d4a1478cf7e9a473c

   This action_ref is stable and MUST be reproduced identically for
   the PENDING, COMMITTED, and REVERSED transition vectors in
   Section 8.6.

8.6.  Lifecycle Vectors: State Transitions

   All three transition vectors use the action_ref from Section 8.5.
   Implementations MUST produce distinct transition_hash values for
   each state.

   Vector: PENDING

      action_ref:               7528529a8be2044488e603b7913efaa4f836
                                20dbcc63010d4a1478cf7e9a473c
      state:                    "PENDING"
      transition_timestamp_ms:  1716494400000
      authority_verified_at_ms: 1716494400500
      revocation_check_at_ms:   1716494400800

   Expected transition_hash:
      0957638b64c790292c11d90e9ae15576a6454f37f23a0aade222acf9e2ea18b0

   Vector: COMMITTED

      action_ref:               7528529a8be2044488e603b7913efaa4f836
                                20dbcc63010d4a1478cf7e9a473c
      state:                    "COMMITTED"
      transition_timestamp_ms:  1716494500000
      authority_verified_at_ms: 1716494500300
      revocation_check_at_ms:   1716494500500

   Expected transition_hash:
      f49faa7c4f82bd842705374311f5f6af073826539d519d0b65de3263258eac5f

   Vector: REVERSED

      action_ref:               7528529a8be2044488e603b7913efaa4f836
                                20dbcc63010d4a1478cf7e9a473c
      state:                    "REVERSED"
      transition_timestamp_ms:  1716494600000
      authority_verified_at_ms: 1716494600300
      revocation_check_at_ms:   1716494600500

   Expected transition_hash:
      681a6026dbbac7555c46282eaf617d3f02560925ed8b44c31e3c854fcfc1f613

8.7.  Lifecycle Vectors: SKIP-on-retry Idempotency

   A re-presented COMMITTED transition with fields identical to the
   COMMITTED vector in Section 8.6 MUST reproduce the same
   transition_hash:

      action_ref:               7528529a8be2044488e603b7913efaa4f836
                                20dbcc63010d4a1478cf7e9a473c
      state:                    "COMMITTED"
      transition_timestamp_ms:  1716494500000
      authority_verified_at_ms: 1716494500300
      revocation_check_at_ms:   1716494500500

   Expected transition_hash (MUST equal the COMMITTED value above):
      f49faa7c4f82bd842705374311f5f6af073826539d519d0b65de3263258eac5f

   An implementation that produces a different value for this input
   has introduced non-determinism into the transition preimage and
   MUST be considered non-conformant.

8.8.  Adversarial Boundary Vectors

   The following inputs MUST be rejected by a conformant
   implementation.  For each vector, the reject_reason states the
   violated constraint from Section 7.5.

   adv-001 -- RFC 3339 string timestamp

      transition_timestamp_ms: "2026-06-09T00:00:00Z"  (string)
      reject_reason: timestamp_ms MUST be a non-negative integer;
                     string values are not permitted.

   adv-002 -- Negative timestamp

      authority_verified_at_ms: -1  (negative integer)
      reject_reason: timestamp_ms MUST be non-negative.

   adv-003 -- Boolean timestamp

      revocation_check_at_ms: true  (boolean)
      reject_reason: timestamp_ms MUST be an integer; booleans are
                     not permitted.

   adv-004 -- Malformed action_ref (non-hex characters)

      action_ref: "gggggggg..."  (64 chars, not lowercase hex)
      reject_reason: action_ref MUST consist entirely of lowercase
                     hexadecimal characters [0-9a-f].

   adv-005 -- Short action_ref

      action_ref: "abcd1234"  (8 chars)
      reject_reason: action_ref MUST be exactly 64 characters.

   adv-006 -- Empty state

      state: ""
      reject_reason: state MUST be a non-empty string.

   All inputs in the extended adversarial vector set (published at the
   URL in Section 8) produce byte-identical JCS canonicalization
   across 8 independent RFC 8785 implementations, confirming that
   these are reproducible, real inputs that MUST be rejected at the
   validation layer rather than the canonicalization layer.

8.9.  Settlement-Action Binding Vectors

   These vectors exercise the binding_ref of Section 7.6.  All six
   share the following component references:

      action_ref =
         7528529a8be2044488e603b7913efaa4f83620dbcc63010d4a1478cf7e9
         a473c
      transition_hash (COMMITTED) =
         f49faa7c4f82bd842705374311f5f6af073826539d519d0b65de3263258e
         ac5f
      settlement_ref =
         0ead75bfe7fc74cc0421124903e56cb5c5006d02c393231a1d5f260fa87e
         96d3
      retention_chain_ref =
         sha256:d23aeb006c5f3db9dd96315916410393904f56c4c871593065eb7
         3b783fff35f

   Vector sab-v1-001 (reference) -- the binding of the four references
   above:

      binding_ref =
         sha256:7dc4a2bf62b3c5eabd10fc875ff7fc10f188666f15838c4a51464
         cc72e80f6ca

   Vector sab-v1-002 (stability) -- the identical preimage re-presented
   MUST reproduce sab-v1-001 byte-for-byte:

      binding_ref == sab-v1-001

   Vector sab-v1-003 (settlement-binding) -- settlement_ref replaced by
   0ead... -> e7777a9a77a9c3f02339594395bfb2620e07edc62d3dcb48c4f2e82a
   8c37a1c4, all other fields unchanged.  MUST differ from sab-v1-001:

      binding_ref =
         sha256:cf6eb49236702195b0a8b960929ffa993d38d3ddbbb302a1f68f3
         2e54bab23ca

   Vector sab-v1-004 (action-binding) -- action_ref replaced by
   57e861cb0929fe602823a15e2bc5a5587f0b9c3bd39147baa49819dd014c56a6,
   all other fields unchanged.  MUST differ from sab-v1-001:

      binding_ref =
         sha256:0bae722c5489179921d8cb3e747f9457d42036f50642fab0e8617
         ec89d41d5c2

   Vector sab-v1-005 (state-binding) -- transition_hash replaced by the
   PENDING transition
   0957638b64c790292c11d90e9ae15576a6454f37f23a0aade222acf9e2ea18b0,
   all other fields unchanged.  MUST differ from sab-v1-001:

      binding_ref =
         sha256:d1d3b29e5d081f091376f886bfd11f0bb85034df7e6104a1726ed
         3929dfa2af3

   Vector sab-v1-006 (chain-binding) -- retention_chain_ref replaced by
   sha256:43f888f00ea70e38fb8e38c205219b3fff51a90c62197d890b9f270f0f8
   1fe42, all other fields unchanged.  MUST differ from sab-v1-001:

      binding_ref =
         sha256:c9cb63c77330d7a3bd9f6252ffe7f3b5d967d4594984cf2120f80
         b146dc43d76

   All six binding_ref values reproduce byte-for-byte across eight
   independent RFC 8785 implementations.

8.10.  Policy Binding Vectors

   These vectors exercise the policy_bound_ref of Section 7.7.  The
   subject_ref is the binding_ref of vector sab-v1-001 (Section 8.9):

      subject_ref =
         sha256:7dc4a2bf62b3c5eabd10fc875ff7fc10
         f188666f15838c4a51464cc72e80f6ca

   Two policy documents are used.  Policy P:

      {"policy_id": "aml.transfer", "version": 1, "max_amount": 1000,
       "deny_jurisdictions": ["XX"]}

   and the rotated policy P':

      {"policy_id": "aml.transfer", "version": 2,
       "max_amount": 100000, "deny_jurisdictions": []}

   Their policy_ref values (Section 7.7):

      policy_ref(P) =
         sha256:acc943b05fa8e8096e5b313288bc4f91
         9cc2661f167c833770509a53049afa1c
      policy_ref(P') =
         sha256:858fd6694716f503448ea89da802c0c2
         942e2619938f126d0088cb4ba9af5d35

   Vector pb-v1-001 (reference) -- policy_bound_ref binding policy_ref(P)
   to the subject_ref above:

      policy_bound_ref =
         sha256:aaee2091799f376ee8cac802ea4920fe
         aa4eca52950488a3e047ff82e6959a21

   Vector pb-v1-002 (rotation) -- policy_ref(P') bound to the same
   subject_ref.  MUST differ from pb-v1-001, demonstrating that a record
   sealed under policy P does not verify under the rotated policy P':

      policy_bound_ref =
         sha256:e6629ede721146e62ce148fc25c52b79
         a58103a7476784397b328809e0f027e2

   Vector pb-v1-003 (key-order-invariance) -- policy P re-serialised
   with its keys in a different order MUST reproduce policy_ref(P), and
   therefore pb-v1-001, byte-for-byte.

   The policy_ref and policy_bound_ref values reproduce byte-for-byte
   across the Python and TypeScript reference implementations.

8.11.  Compliance Gate Binding Vectors

   These vectors exercise the gate_ref of Section 7.8.  The subject_ref
   is the policy_bound_ref pb-v1-001 of Section 8.10 (policy P bound to
   the binding_ref of vector sab-v1-001):

      subject_ref =
         sha256:aaee2091799f376ee8cac802ea4920fe
         aa4eca52950488a3e047ff82e6959a21

   The payer reference is computed from a screened address and its
   network; the cleartext address does not appear in the result:

      address = "0x00000000000000000000000000000000DEADBEEF"
      network = "base"

      payer_ref =
         sha256:8637798158677e9aa7d218d81713db9a
         f656e2f28a5bcce97b4f2a73286f5765

   Vector cg-v1-001 (ALLOW) -- gate_ref binding the ALLOW verdict to the
   payer_ref and subject_ref above:

      gate_ref =
         sha256:43d8d8cb0ba6ccbd3c36167a28075a3f
         d5b8858ce0414f6871a22a96f86f96a5

   Vector cg-v1-002 (REFER) -- the REFER verdict over the same payer_ref
   and subject_ref.  MUST differ from cg-v1-001:

      gate_ref =
         sha256:9a25b3d9d9c1ff4ba1c9c1da66668c59
         caf8164d4a081df30826c007d9b6b845

   Vector cg-v1-003 (DENY) -- the DENY verdict over the same payer_ref
   and subject_ref.  MUST differ from cg-v1-001 and cg-v1-002:

      gate_ref =
         sha256:bff6375120c2ea003a7ae18a05cb1468
         e91cd787cb910a4b593f7fb7be2e1c6c

   Vector cg-v1-004 (policy rotation) -- the ALLOW verdict and the same
   payer_ref, but with subject_ref set to pb-v1-002 of Section 8.10 (the
   same subject under the rotated policy P').  MUST differ from
   cg-v1-001, demonstrating that a verdict made under policy P does not
   verify under P':

      gate_ref =
         sha256:d4a1f0f4581dd078df2c1d0ed1ffb253
         ca8ecdd454179f02894fd5a1e9401247

   A verdict outside {"ALLOW","REFER","DENY"}, and a malformed
   subject_ref or payer_ref, MUST be rejected, not hashed.

   The payer_ref and gate_ref values reproduce byte-for-byte across the
   Python and TypeScript reference implementations.

8.12.  Pre-Payment Decision Chain Vectors

   The spend_decision_chain_v1 set recomputes passport_ref, mandate_ref,
   and policy_bound_ref from raw fields, shows each equals the published
   output of its own lite set and is the reference the decision binds,
   and recomputes guardrail_ref for ALLOW and DENY.

   Reference values (recomputed 2026-06-23, rfc8785 + SHA-256):

      passport_ref      sha256:b3594e33998af01bd1ad208172c5c1ac586daa8c7
                              5781379f034d97e50b1a9be
      mandate_ref       sha256:a4f8cb5ee09b29478ac1cc2f468d66e16d3d25f7a2
                              29a31d22ad521e11d04d35
      policy_bound_ref  sha256:aaee2091799f376ee8cac802ea4920feaa4eca5295
                              0488a3e047ff82e6959a21
      guardrail_ref     sha256:2a444c629892f44fde1bd004aba9be01dd6cc7fe25
       (ALLOW)                1eecdd545b82dca9f0bf97
      guardrail_ref     sha256:792a5b43e9df0fc460d6bf99d6357afafbdcf910ef
       (DENY)                 1e81a340e3581bc27109cf

   These values are reproduced byte-for-byte by independent Python and
   Node implementations and by a clean-box install of the published
   Apache-2.0 packages.

8.13.  Post-Decision Execution Evidence Vectors

   The execution_ref_v1 set recomputes execution_ref over the exact
   decision_ref produced by Section 7.9, for the COMMITTED, SKIPPED,
   FAILED, and REVERSED outcomes, and shows each field is byte-load-
   bearing (including rejection of a string-format timestamp).  The
   keystone_v1 composition then recomputes the full chain end-to-end and
   caps it with a trust_query_ref over the ordered references, including
   execution_ref.

   Reference values (recomputed 2026-06-24, rfc8785 + SHA-256):

      decision_ref      sha256:2a444c629892f44fde1bd004aba9be01dd6cc7fe25
       (ALLOW; 7.9)            1eecdd545b82dca9f0bf97
      execution_ref     sha256:f6e2bfc15b085ed51c4c972de81d1c6b00f4e55b27
       (COMMITTED)            2e2aa12e56bb7c521fc65a
      trust_query_ref   sha256:18fb601a08c71eb6bed11e1c117f33bdc0ada6d635
       (full keystone)        ea9bb9cca15e8410ce7ebd

   The execution_ref preimage for the COMMITTED value above is
   {decision_ref (ALLOW), action_type "payment", scope "bilateral",
   outcome "COMMITTED", executed_at_ms 1716460800000}.  The trust_query_ref
   assesses the ordered chain [passport_ref, mandate_ref, policy_bound_ref,
   decision_ref, execution_ref] with trust_outcome "TRUSTED".

   These values are reproduced byte-for-byte by independent Python and
   Node implementations, by the execution_ref_v1 and keystone_v1 sets in
   the AlgoVoi JCS conformance corpus [ALGOVOI-VECTORS], and by a clean-
   box install of the published Apache-2.0 algovoi-execution-ref package
   on algovoi-substrate v0 and v1.

8.14.  Cross-Party Delegation Vectors

   The delegation_ref_v1 set recomputes delegation_ref from raw fields,
   shows a two-link chain (A->B then B->C) in which the
   prev_delegation_ref of the second link equals the computed
   delegation_ref of the first, detects tamper across the scope,
   validity, delegate, and chain-link families, and rejects a malformed
   (string-format) validity bound.

   Reference values (recomputed 2026-06-25, rfc8785 + SHA-256):

      delegation_ref    sha256:4e59d4d1fcee3e2fa6a9be3cfa905b4bc09e5746a4
       (root; A->B)            0c1dab96c277c4e10d3276
      delegation_ref    sha256:91329d2887d8eb879cef066c36418245266116b527
       (chain; B->C)          58c386246fdb927d34494a

   The root delegation_ref preimage is {delegate_id
   "did:web:agent-1.example", delegator_id "did:web:org.example",
   not_after_ms 1716498000000, not_before_ms 1716494400000,
   prev_delegation_ref "", scope "payments:usdc:<=100"}.  The chain
   link's prev_delegation_ref is the root value above, so the two links
   form a tamper-evident A->B->C sequence.

   These values are reproduced byte-for-byte by independent Python and
   Node implementations, by the delegation_ref_v1 set in the AlgoVoi JCS
   conformance corpus [ALGOVOI-VECTORS], and by a clean-box install of
   the published Apache-2.0 algovoi-delegation-ref package.

9.  Regulatory Applicability

9.1.  MiCA Article 80

   MiCA Article 80 requires crypto-asset service providers to maintain
   records of all transactions in a manner that permits reconstruction
   of each transaction.  The constructions in this document satisfy
   this requirement:

   o  The retention chain embeds a tamper-evident linkage directly
      into each receipt (Section 4).  Any individual receipt can be
      verified in isolation (Section 6.1); any contiguous sequence
      can be verified as a complete audit trail (Section 6.2).

   o  The Payment Action Lifecycle (Section 7) provides a stable,
      content-addressed identity for each transaction (action_ref)
      and a verifiable state record for each lifecycle stage
      (transition_hash), satisfying the reconstruction requirement
      for the full lifecycle of each transaction.

   o  No issuer infrastructure is required for verification.

9.2.  DORA Article 14

   DORA Article 14 requires financial entities to maintain audit logs
   of ICT-related incidents and operational transactions with integrity
   guarantees.  The constructions provide:

   o  Cryptographic ordering (chain_seq) that prevents receipt
      insertion or reordering without detection.
   o  Hash linkage that makes deletion of any receipt in a sequence
      detectable by the holder of adjacent receipts.
   o  Issuer isolation (issuer_id field) that partitions chains by
      operational entity.
   o  The exactly-once guarantee (Section 7.4) provides a verifiable
      record that each operational transaction was executed at most
      once, supporting ICT incident reconstruction.

9.3.  AMLR Article 56

   AMLR Article 56 requires obliged entities to retain records of
   financial transactions for a period of at least five years and to
   ensure those records are available to competent authorities.  The
   retention chain satisfies the integrity dimension of this
   requirement: a competent authority holding a set of receipts can
   verify their integrity without requesting further data from the
   obliged entity, reducing audit friction and eliminating the
   possibility of post-hoc record manipulation by the issuer.  The
   transition_hash provides an additional integrity primitive: an
   authority can verify that a COMMITTED transition was not
   subsequently altered by recomputing the hash from the five fields.

10.  Security Considerations

10.1.  Collision Resistance

   The security of both constructions depends on the collision
   resistance of SHA-256.  As of the date of this document, no
   practical collision attack against SHA-256 is known.  Preimage
   lengths vary with field values but are always well above the
   threshold at which length-extension attacks become relevant.

10.2.  Subset Auditability

   An auditor holding only a non-contiguous subset of receipts can
   verify each held link individually but cannot detect gaps in the
   sequence.  To detect gaps, the auditor MUST obtain a complete
   contiguous range and apply sequence verification (Section 6.2).
   Issuers SHOULD provide receipts in complete contiguous sequences to
   auditors.

10.3.  Chain Truncation

   An issuer could present a chain that begins at chain_seq > 0 and
   claim it is complete.  Auditors SHOULD verify that the chain begins
   with a genesis record (chain_seq = 0, prev_receipt_hash = "") unless
   they have independent evidence of the chain's starting point.

10.4.  Issuer Isolation

   The issuer_id field is included in the preimage to prevent cross-
   issuer chain forgery: a receipt from issuer A with a given
   receipt_hash cannot be substituted for a receipt from issuer B with
   the same receipt_hash.  Issuers MUST use distinct, non-guessable
   issuer_id values within any deployment.

10.5.  Exactly-Once Security Properties

   The SKIP-on-retry guarantee (Section 7.4) is a consequence of
   determinism, not of access control.  It provides a verifiable
   proof that a retry is byte-identical to the original, but it does
   not prevent an attacker who controls the preimage inputs from
   constructing a different transition with a different timestamp.

   The action_ref binding property prevents replay under a different
   agent identity: an identical state+timestamps tuple under a
   different action_ref produces a different transition_hash.  This
   means a transition_hash is bound to exactly one action_ref.

   The input validation rules in Section 7.5 are security-critical.
   An implementation that accepts an RFC 3339 string as a timestamp
   will compute a different transition_hash than one that enforces the
   integer constraint, breaking cross-implementation interoperability
   and the exactly-once guarantee.

11.  IANA Considerations

   This document has no IANA actions.

12.  References

12.1.  Normative References

   [FIPS180-4]
              National Institute of Standards and Technology, "Secure
              Hash Standard (SHS)", FIPS PUB 180-4, August 2015.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in
              RFC 2119 Key Words", BCP 14, RFC 8174,
              DOI 10.17487/RFC8174, May 2017.

   [RFC8785]  Rundgren, A., Jordan, B., and S. Erdtman, "JSON
              Canonicalization Scheme (JCS)", RFC 8785,
              DOI 10.17487/RFC8785, June 2020.

   [SETTLEMENT-ATTESTATION]
              Hopley, C., "Settlement Attestation for x402 Payments",
              Work in Progress, Internet-Draft,
              draft-hopley-x402-settlement-attestation, 2026.

12.2.  Informative References

   [I-D.hopley-x402-rfc9421-binding]
              Hopley, C., "RFC 9421 Signing-Base Binding for x402
              Receipts", Work in Progress, Internet-Draft,
              draft-hopley-x402-rfc9421-binding, 2026.

   [VECTORS]  Hopley, C., "AlgoVoi JCS Conformance Vectors",
              chopmob-cloud/algovoi-jcs-conformance-vectors, June 2026,
              <https://github.com/chopmob-cloud/
              algovoi-jcs-conformance-vectors>.

   [X402]     x402 Working Group, "x402 HTTP Payment Protocol",
              Work in Progress, 2026.

Author's Address

   C. Hopley
   AlgoVoi
   United Kingdom

   Email: chopmob@gmail.com