Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,30 @@ agentic
Agentic
agenticpayments
Algorand
AlgoVoi
algovoi
androidx
Applebot
appname
ASGI
authorisation
Authorisation
bazel
behavioural
Behavioural
Blackhawk
Boku
BVNK
canonicalisation
Canonicalisation
canonicalise
Canonicalise
canonicalised
canonicalises
celerybeat
classpath
chopmob
CLASSPATH
classpath
CMSPI
cmwallet
cncf
Expand All @@ -29,14 +42,15 @@ Crossmint
cryptographical
CYGPATTERN
Dafiti
disclosable
Disclosable
datatracker
davecgh
dcql
Dcql
DCQL
Dcql
dcql
deviceauth
Dfile
disclosable
Disclosable
dmypy
Doku
Dorg
Expand Down Expand Up @@ -68,6 +82,7 @@ groupcache
gson
Hashkey
honnef
hopley
hprof
htmlcov
httpsnoop
Expand All @@ -79,6 +94,8 @@ inmemory
ipynb
issuerauth
JAVACMD
JCS
jcs
jetbrains
Jetpack
jvmargs
Expand All @@ -87,8 +104,8 @@ keepattributes
keepclassmembers
Klarna
kotlin
kotlinx
Kotlinx
kotlinx
ktor
Ktor
KXMYBJWNQ
Expand All @@ -101,6 +118,7 @@ llmstxt
logr
longrunning
mastercard
MiCA
micropayments
Mispick
Momo
Expand All @@ -114,6 +132,8 @@ nosetests
Nuvei
objx
octicons
OFAC
OFSI
okhttp
opentelemetry
otelgrpc
Expand All @@ -128,26 +148,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
Expand All @@ -165,10 +189,14 @@ stablecoins
stdr
stretchr
superfences
tipping
Truelayer
Trulioo
udpa
unauthorised
unmarshal
unrecognised
verdicts
viewmodel
vulnz
Wallex
Expand Down
5 changes: 5 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files": {
"includes": ["**", "!code/web-client"]
}
}
188 changes: 188 additions & 0 deletions docs/ap2/compliance_receipt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# 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"
}
```text

| 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 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

## 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:

```text
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)
```text

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.
Loading