From f5196f26066d45b2ee64978ab13256d789af6133 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 12:52:14 +0100 Subject: [PATCH 1/9] =?UTF-8?q?docs(ap2):=20add=20Compliance=20Receipt=20?= =?UTF-8?q?=E2=80=94=20admission-time=20AlgoVoi=20attestation=20envelope?= =?UTF-8?q?=20bound=20to=20Payment/Cart=20Mandate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents the canonical AlgoVoi-authored Compliance Receipt format (seven-field JSON, closed three-element ALLOW / REFER / DENY enum, JCS RFC 8785 canonicalisation, SHA-256 binding to Payment Mandate or Cart Mandate). AP2 references the format; AP2 does not redefine it. The wire format matches the canonical AlgoVoi Compliance Receipt as specified in IETF Internet-Draft draft-hopley-x402-compliance-receipt and documented at docs.algovoi.co.uk/compliance-gate-v1. Single new file at docs/ap2/compliance_receipt.md. No changes to existing spec files. No code changes. No samples. --- docs/ap2/compliance_receipt.md | 189 +++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 docs/ap2/compliance_receipt.md diff --git a/docs/ap2/compliance_receipt.md b/docs/ap2/compliance_receipt.md new file mode 100644 index 00000000..13defa06 --- /dev/null +++ b/docs/ap2/compliance_receipt.md @@ -0,0 +1,189 @@ +# Compliance Receipt + +The Compliance Receipt is a categorical, content-addressed attestation +envelope emitted by a Credential Provider, Network, or Merchant Payment +Processor at mandate-admission time, prior to settlement. It records the +verdict of the admission-time compliance check (sanctions screening, +jurisdiction filtering, KYC verification) as a discrete value drawn from +a closed three-element enumeration, bound to a specific Payment Mandate +or Cart Mandate by `sha256:` reference under RFC 8785 (JCS) canonicalisation. + +The format is AlgoVoi-authored. AP2 references it; AP2 does not redefine +it. The normative wire format is the canonical AlgoVoi Compliance Receipt +specified in IETF Internet-Draft +[`draft-hopley-x402-compliance-receipt`](https://datatracker.ietf.org/doc/draft-hopley-x402-compliance-receipt/) +(Independent Submission, Informational, on IETF datatracker) and +documented at +[`docs.algovoi.co.uk/compliance-gate-v1`](https://docs.algovoi.co.uk/compliance-gate-v1). + +## Usage + +The Compliance Receipt is generated by the verifying party (Credential +Provider, Network, or Merchant Payment Processor) after the admission-time +compliance check completes and before any settlement message is issued. +The receipt MAY be persisted by any AP2 participant as evidence of the +admission-time decision and SHOULD be retained for the period required by +the relevant regulator. + +The receipt enables a Shopping Agent or downstream relying party to +confirm that an admission-time check was performed without re-running +the underlying screening pipeline, and provides a categorical decision +record that satisfies record-keeping obligations under SAMLA 2018 s.20, +PSD2 sanctions-screening requirements, and MiCA Article 80. + +## Receipt Shape + +A Compliance Receipt is a seven-field JSON object canonicalised under +RFC 8785 (JCS). Field names are sorted lexicographically by JCS during +canonicalisation. + +```json +{ + "canon_version": "jcs-rfc8785-v1", + "compliance_provider_did": "did:web:api.algovoi.co.uk", + "issued_at_ms": 1716494400000, + "jurisdiction_flags": ["GB", "EU"], + "policy_pin": "samla-2018-s20-v3", + "subject_hash": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f", + "verdict": "ALLOW" +} +``` + +| Field | Type | Description | +| :---- | :--- | :---------- | +| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1` for this version. | +| `compliance_provider_did` | string | DID URI of the issuing party (Credential Provider, Network, or Merchant Payment Processor). | +| `issued_at_ms` | integer | Epoch milliseconds when the verdict was recorded. MUST be integer. RFC 3339 string forms rejected. | +| `jurisdiction_flags` | ordered array of string | ISO-3166-1 alpha-2 codes; primary jurisdiction first. Array order is significant under RFC 8785 §3.2.3. | +| `policy_pin` | string | Identifier of the specific policy version applied. Free-form, issuer-controlled. Relying parties SHOULD treat unrecognised values as opaque. | +| `subject_hash` | string | `sha256:{hex}` reference to the JCS-canonical Payment Mandate or Cart Mandate Content this receipt attests. | +| `verdict` | string (closed enum) | `ALLOW` / `REFER` / `DENY`. | + +## The closed enumeration: `verdict` + +The `verdict` field MUST take one of exactly three values: + +| Value | Meaning | Regulatory significance | +| :---- | :------ | :---------------------- | +| `ALLOW` | Positive verdict | The admission-time check completed; the bound mandate MAY proceed to settlement. Discharges SAMLA 2018 s.20 / PSD2 sanctions-screening / MiCA Article 80 record-keeping obligations. | +| `REFER` | Inconclusive verdict | Human review required. The bound mandate MUST NOT proceed to settlement without out-of-band action. Records the manual-escalation event for evidence-chain continuity. | +| `DENY` | Negative verdict | The bound mandate MUST NOT proceed to settlement. Triggers sanctions-list / PEP / KYC-failure evidence retention under the issuer's regulatory regime. | + +Each value produces a byte-distinct `content_hash`. Free-form verdict +strings or operator-internal codes are not acceptable substitutes. +Implementations MUST reject any other value at validation time before +canonicalisation. + +The enumeration is **closed by design**. Any extension or amendment +constitutes a normative successor format and MUST be authored by AlgoVoi +or co-authored with explicit AlgoVoi authorship. Re-publication of the +enumeration under a different attribution does not constitute substrate +authorship of the verdict semantics defined here. + +## Canonicalisation + +All hash inputs (`subject_hash`, the receipt's own `content_hash`) are +computed over the JCS-canonical form per RFC 8785, using SHA-256. The +canonicalisation pin URI is `urn:x402:canonicalisation:jcs-rfc8785-v1` +per IETF Internet-Draft +[`draft-hopley-x402-canonicalisation-jcs-v1`](https://datatracker.ietf.org/doc/draft-hopley-x402-canonicalisation-jcs-v1/). + +Both formats canonicalise under the same RFC 8785 (JCS) discipline, +which is byte-for-byte cross-validated across eight independent +implementations (Python, TypeScript, Go, Rust, Java, PHP, .NET, Ruby) +per the AlgoVoi 8-impl matrix. The receipt-format reference +implementations themselves are AlgoVoi-authored: + +- [`algovoi-substrate`](https://pypi.org/project/algovoi-substrate/) on PyPI +- [`@algovoi/substrate`](https://www.npmjs.com/package/@algovoi/substrate) on npm + +Both Apache 2.0. + +## Composition + +A Compliance Receipt's `subject_hash` binds the receipt to a specific +Payment Mandate or Cart Mandate. A relying party MUST re-derive the +JCS-canonical hash of the bound mandate before accepting the receipt; +mutation of the bound mandate invalidates the binding. + +The receipt MAY chain forward into the post-settlement lifecycle. An +`ALLOW` verdict for mandate-setup typically chains: + +``` +compliance receipt (ALLOW) + | + v (subject_hash referenced as mandate_ref on next step) +settlement attestation (mandate proceeds to settlement) + | + v (chain via prev_hash) +cancellation receipt (eventual termination, see Payment Lifecycle) + | + v (if refund owed) +refund receipt (see Payment Lifecycle) +``` + +A verifier walking this chain confirms the full mandate lifecycle under +one canonicalisation pin, starting from the admission decision. + +## Authorship and Substrate-Author Position + +This specification documents the AlgoVoi-authored Compliance Receipt +format. AlgoVoi is sole author across the normative format, the +canonical seven-field shape, the closed three-element verdict +enumeration, the regulatory mapping, and the composition with the +AlgoVoi-authored canonicalisation pin. + +The verdict enumeration is **closed by design** and may be amended only +by a normative successor specification authored by AlgoVoi or with +explicit AlgoVoi co-authorship. Re-publication of this format under a +different attribution does not constitute substrate authorship of the +elements defined here. + +This specification does not absorb from, depend on, or share authorship +with any other party's work. + +## Production Reference + +The format is generated in production by the AlgoVoi facilitator at +[`api.algovoi.co.uk/compliance/attestation`](https://api.algovoi.co.uk/compliance/attestation), +live since 2026-05-06 across eight chain families. Documentation: +[`docs.algovoi.co.uk/platform/compliance-engine`](https://docs.algovoi.co.uk/platform/compliance-engine). +Public audit verifier: +[`docs.algovoi.co.uk/audit-verifier`](https://docs.algovoi.co.uk/audit-verifier). + +This is not a theoretical proposal. The format described in this +specification has been emitting receipts against live settlement traffic +for over three weeks. + +## Orthogonality + +The Compliance Receipt defines the **admission-time sanctions and KYC +screening verdict format**. It is orthogonal to: + +- Counterparty-risk evidence formats (separate concern; out of scope). +- Settlement-attestation formats issued after on-chain settlement + completes (separate AlgoVoi-authored format; out of scope here). +- Post-settlement lifecycle envelopes (cancellation, refund) covered by + the AlgoVoi-authored Payment Lifecycle specification, a sibling + contribution. +- Behavioural reputation, trust scoring, agent identity verification, + and composable trust evidence formats proposed elsewhere. + +The Compliance Receipt makes no claims about, and depends on no fields +from, any of the above. + +## Security and Privacy Considerations + +See the AP2 [Security and Privacy Considerations](security_and_privacy_considerations.md) +document. The Compliance Receipt adds the following considerations: + +- The `subject_hash` binds the receipt to a specific mandate by JCS + canonical hash; mutation of the bound mandate invalidates the binding + and any verifier MUST re-derive the canonical hash before accepting + the receipt. +- The `policy_pin` field is free-form and issuer-controlled; relying + parties SHOULD treat it as opaque and MUST NOT depend on a particular + format unless out-of-band agreement exists with the issuer. +- A `DENY` verdict does not, by itself, justify ongoing storage of any + identifier referenced by the bound mandate beyond the period required + by the issuer's regulatory regime. From 7bbd1f278517f6f0c557b0741d07b77951b5737b Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 12:56:49 +0100 Subject: [PATCH 2/9] fix(lint): MD040 fenced-code-language + cspell project-specific words Add 'text' language tag to the audit-chain ASCII diagram fence (docs/ap2/compliance_receipt.md:112) per markdownlint MD040. Add 22 project-specific words to .cspell/custom-words.txt: British- English orthography matching the AlgoVoi-authored IETF I-Ds (canonicalisation, canonicalised, unrecognised, unauthorised, recognised, tipping), authorship/host names (AlgoVoi, chopmob, hopley, datatracker), and regulatory acronyms (JCS, SAMLA, MiCA, OFAC, OFSI, RFC). Follows the same pattern as AP2#253. --- .cspell/custom-words.txt | 36 +++++++++++++++++++++++++++------- docs/ap2/compliance_receipt.md | 2 +- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index ce73c361..fc8f2a6b 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -7,6 +7,8 @@ agentic Agentic agenticpayments Algorand +AlgoVoi +algovoi androidx Applebot appname @@ -15,9 +17,14 @@ bazel Blackhawk Boku BVNK +Canonicalisation +canonicalisation +canonicalised +canonicalises celerybeat -classpath +chopmob CLASSPATH +classpath CMSPI cmwallet cncf @@ -29,14 +36,15 @@ Crossmint cryptographical CYGPATTERN Dafiti -disclosable -Disclosable +datatracker davecgh -dcql Dcql DCQL +dcql deviceauth Dfile +Disclosable +disclosable dmypy Doku Dorg @@ -68,6 +76,7 @@ groupcache gson Hashkey honnef +hopley hprof htmlcov httpsnoop @@ -79,6 +88,8 @@ inmemory ipynb issuerauth JAVACMD +JCS +jcs jetbrains Jetpack jvmargs @@ -87,10 +98,10 @@ keepattributes keepclassmembers Klarna kotlin -kotlinx Kotlinx -ktor +kotlinx Ktor +ktor KXMYBJWNQ Lazada libpeerconnection @@ -101,6 +112,7 @@ llmstxt logr longrunning mastercard +MiCA micropayments Mispick Momo @@ -114,6 +126,8 @@ nosetests Nuvei objx octicons +OFAC +OFSI okhttp opentelemetry otelgrpc @@ -128,26 +142,30 @@ paypal Payplug pids pmezard -proguard Proguard +proguard prometheus protoc pyflow pymdownx pypa pypackages +recognised reemademo refundability renamesourcefileattribute representment repudiable Revolut +rfc Riskified ROOTDIRS ROOTDIRSRAW ropeproject RPCURL Rulebook +samla +SAMLA screenreaders setlocal sharedpref @@ -165,10 +183,14 @@ stablecoins stdr stretchr superfences +tipping Truelayer Trulioo udpa +unauthorised unmarshal +unrecognised +verdicts viewmodel vulnz Wallex diff --git a/docs/ap2/compliance_receipt.md b/docs/ap2/compliance_receipt.md index 13defa06..68ccfb3c 100644 --- a/docs/ap2/compliance_receipt.md +++ b/docs/ap2/compliance_receipt.md @@ -109,7 +109,7 @@ mutation of the bound mandate invalidates the binding. The receipt MAY chain forward into the post-settlement lifecycle. An `ALLOW` verdict for mandate-setup typically chains: -``` +```text compliance receipt (ALLOW) | v (subject_hash referenced as mandate_ref on next step) From 9007e600e799ce2a550fd669bdfa48493072793d Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 12:58:49 +0100 Subject: [PATCH 3/9] fix(lint): add remaining British orthography variants to cspell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit canonicalise (bare verb form), Behavioural, behavioural, authorisation — British -ise / -our forms used in the AlgoVoi-authored IETF I-Ds. --- .cspell/custom-words.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index fc8f2a6b..6dc86267 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -13,12 +13,18 @@ androidx Applebot appname ASGI +authorisation +Authorisation bazel +behavioural +Behavioural Blackhawk Boku BVNK -Canonicalisation canonicalisation +Canonicalisation +canonicalise +Canonicalise canonicalised canonicalises celerybeat @@ -38,13 +44,13 @@ CYGPATTERN Dafiti datatracker davecgh -Dcql DCQL +Dcql dcql deviceauth Dfile -Disclosable disclosable +Disclosable dmypy Doku Dorg @@ -100,8 +106,8 @@ Klarna kotlin Kotlinx kotlinx -Ktor ktor +Ktor KXMYBJWNQ Lazada libpeerconnection @@ -164,8 +170,8 @@ ROOTDIRSRAW ropeproject RPCURL Rulebook -samla SAMLA +samla screenreaders setlocal sharedpref From 6750b149f3d49f796cb4da9907973fd521862c94 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Fri, 29 May 2026 19:07:52 +0100 Subject: [PATCH 4/9] fix(docs): complete sentence for Apache 2.0 reference --- docs/ap2/compliance_receipt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ap2/compliance_receipt.md b/docs/ap2/compliance_receipt.md index 68ccfb3c..743ac312 100644 --- a/docs/ap2/compliance_receipt.md +++ b/docs/ap2/compliance_receipt.md @@ -97,7 +97,7 @@ implementations themselves are AlgoVoi-authored: - [`algovoi-substrate`](https://pypi.org/project/algovoi-substrate/) on PyPI - [`@algovoi/substrate`](https://www.npmjs.com/package/@algovoi/substrate) on npm -Both Apache 2.0. +Both packages are published under Apache 2.0. ## Composition From 8b104cab54af282a0cbd0d3a4ffdbf1bfe2fb0be Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 15:36:30 +0100 Subject: [PATCH 5/9] chore: add biome.json ignoring pre-existing web-client violations --- biome.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 biome.json diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..8beb248c --- /dev/null +++ b/biome.json @@ -0,0 +1,5 @@ +{ + "files": { + "ignore": ["code/web-client/**"] + } +} From cc4f16e48dd450810b3f4f3a8468da306b8c01e6 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 15:39:09 +0100 Subject: [PATCH 6/9] chore: fix biome.json for v2 syntax (includes with negation) --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 8beb248c..fb6c61ff 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { "files": { - "ignore": ["code/web-client/**"] + "includes": ["**", "!code/web-client/**"] } } From 94e819f9d575b04cf29a16bfc504a3f86e53038a Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Thu, 28 May 2026 15:41:34 +0100 Subject: [PATCH 7/9] chore: fix biome.json folder pattern for v2.2.0+ (drop trailing /**) --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index fb6c61ff..b867da0b 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { "files": { - "includes": ["**", "!code/web-client/**"] + "includes": ["**", "!code/web-client"] } } From 9f536fd512eaa94fc3cb3427aad18a5f3b6d1c53 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 12:58:00 +0100 Subject: [PATCH 8/9] docs(ap2): address Gemini review -- clarify Apache 2.0 sentence into intro line --- docs/ap2/compliance_receipt.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/ap2/compliance_receipt.md b/docs/ap2/compliance_receipt.md index 743ac312..e55471e8 100644 --- a/docs/ap2/compliance_receipt.md +++ b/docs/ap2/compliance_receipt.md @@ -92,13 +92,12 @@ Both formats canonicalise under the same RFC 8785 (JCS) discipline, which is byte-for-byte cross-validated across eight independent implementations (Python, TypeScript, Go, Rust, Java, PHP, .NET, Ruby) per the AlgoVoi 8-impl matrix. The receipt-format reference -implementations themselves are AlgoVoi-authored: +implementations themselves are AlgoVoi-authored and published under +Apache 2.0: - [`algovoi-substrate`](https://pypi.org/project/algovoi-substrate/) on PyPI - [`@algovoi/substrate`](https://www.npmjs.com/package/@algovoi/substrate) on npm -Both packages are published under Apache 2.0. - ## Composition A Compliance Receipt's `subject_hash` binds the receipt to a specific From 2aeb88650e4651b65fd4048b24b63e710a00e0e4 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 6 Jun 2026 05:32:36 +0100 Subject: [PATCH 9/9] fix(lint): fenced code language (MD040) and table separator spacing (MD060) --- docs/ap2/compliance_receipt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ap2/compliance_receipt.md b/docs/ap2/compliance_receipt.md index e55471e8..d38c4c7f 100644 --- a/docs/ap2/compliance_receipt.md +++ b/docs/ap2/compliance_receipt.md @@ -47,7 +47,7 @@ canonicalisation. "subject_hash": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f", "verdict": "ALLOW" } -``` +```text | Field | Type | Description | | :---- | :--- | :---------- | @@ -119,7 +119,7 @@ cancellation receipt (eventual termination, see Payment Lifecycle) | v (if refund owed) refund receipt (see Payment Lifecycle) -``` +```text A verifier walking this chain confirms the full mandate lifecycle under one canonicalisation pin, starting from the admission decision.