From 5475806b815ad1c9ba848377663aa0f60f5dbbbe Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:18:37 +0100 Subject: [PATCH 1/5] docs(ap2): add Settlement Attestation -- categorical post-settlement envelope (AlgoVoi-authored, MiCA Art. 80 / DORA Art. 14) --- docs/ap2/settlement_attestation.md | 161 +++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 docs/ap2/settlement_attestation.md diff --git a/docs/ap2/settlement_attestation.md b/docs/ap2/settlement_attestation.md new file mode 100644 index 00000000..bca48024 --- /dev/null +++ b/docs/ap2/settlement_attestation.md @@ -0,0 +1,161 @@ +# Settlement Attestation + +The Settlement Attestation is a categorical, content-addressed attestation +envelope emitted by a facilitator after settlement is confirmed on-chain. +It is the post-settlement categorical record: did the on-chain transaction +settle as expected, is it still awaiting finality, or was it reversed? + +The format is AlgoVoi-authored. AP2 references it; AP2 does not redefine +it. The normative wire format is the canonical AlgoVoi Settlement Attestation +specified in IETF Internet-Draft +[`draft-hopley-x402-settlement-attestation`](https://datatracker.ietf.org/doc/draft-hopley-x402-settlement-attestation/) +and documented at +[`docs.algovoi.co.uk/settlement-attestation-v1`](https://docs.algovoi.co.uk/settlement-attestation-v1). + +## Usage + +The Settlement Attestation is generated by the facilitator after on-chain +confirmation of a payment transaction. It SHOULD be emitted before any +post-settlement notification is issued to the merchant or shopping agent. + +The attestation enables a Shopping Agent or downstream relying party to +confirm the categorical settlement outcome without querying the chain +directly, and provides a categorical decision record that satisfies +record-keeping obligations under MiCA Article 80, AMLR Article 56, +DORA Article 14, and UK MLRs 2017 Regulation 40. + +## Attestation Shape + +A Settlement Attestation is a JSON object canonicalised under RFC 8785 +(JCS). Field names are sorted lexicographically by JCS during +canonicalisation. + +```json +{ + "amount_microunits": 1000000, + "asset_id": "eip155:84532/erc20:0x036CbD53842c5426634e7929541eC2318f3dCF7e", + "canon_version": "jcs-rfc8785-v1", + "chain": "eip155:84532", + "settled_at": "2026-05-30T06:38:46Z", + "settled_payment_ref": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f", + "settlement_status": "SETTLED", + "signature": "", + "tx_id": "0x3a3777f4e2b6e3e0e0e3f3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3" +} +``` + +| Field | Type | Description | +| :---- | :--- | :---------- | +| `amount_microunits` | integer | Settled amount in chain-native microunits. MUST be integer. RFC 3339 string forms rejected. | +| `asset_id` | string | CAIP-19 asset identifier of the settled asset. | +| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1` for this version. | +| `chain` | string | CAIP-2 chain identifier. | +| `settled_at` | string | ISO 8601 UTC timestamp of facilitator-side settlement confirmation. | +| `settled_payment_ref` | string | `sha256:{hex}` content-addressed reference to the settled Payment Mandate. | +| `settlement_status` | string (closed enum) | `SETTLED` / `PENDING_FINALITY` / `REVERSED`. | +| `signature` | string | Detached signature over the JCS canonical bytes. | +| `tx_id` | string | Chain-native transaction identifier as confirmed on-chain. | + +## The closed enumeration: `settlement_status` + +The `settlement_status` field MUST take one of exactly three values: + +| Value | Meaning | Regulatory significance | +| :---- | :------ | :---------------------- | +| `SETTLED` | Transaction confirmed on-chain at or beyond the chain-specific finality threshold | Discharges MiCA Article 80 / AMLR Article 56 / UK MLRs 2017 Reg 40 transaction record obligations for the settled payment. | +| `PENDING_FINALITY` | Transaction observed on-chain but has not yet reached the required confirmation depth | Enables downstream parties to defer post-settlement actions until finality is confirmed. | +| `REVERSED` | Transaction was previously SETTLED or PENDING_FINALITY but has subsequently been reorganised out, refunded, or otherwise reversed | Triggers DORA Article 14 operational-resilience incident handling at the facilitator. | + +A `PENDING_FINALITY` attestation MAY be superseded by a later `SETTLED` +or `REVERSED` attestation referencing the same `tx_id`. Implementations +MUST treat the latest attestation as authoritative for a given `tx_id`. + +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. + +## Canonicalisation + +The attestation is canonicalised under RFC 8785 (JCS) per the +canonicalisation pin URI `urn:x402:canonicalisation:jcs-rfc8785-v1`, +defined in IETF Internet-Draft +[`draft-hopley-x402-canonicalisation-jcs-v1`](https://datatracker.ietf.org/doc/draft-hopley-x402-canonicalisation-jcs-v1/). + +The discipline is byte-for-byte cross-validated across eight independent +implementations (Python, TypeScript, Go, Rust, Java, PHP, .NET, Ruby) +per the AlgoVoi 8-impl matrix. Reference implementations: + +- [`algovoi-settlement-attestation`](https://pypi.org/project/algovoi-settlement-attestation/) on PyPI +- [`@algovoi/settlement-attestation`](https://www.npmjs.com/package/@algovoi/settlement-attestation) on npm + +Both packages are published under Apache 2.0. + +## Composition + +The Settlement Attestation chains from the Compliance Receipt via the +`settled_payment_ref` field: + +```text +compliance receipt (ALLOW) + | + v +settlement attestation (SETTLED / PENDING_FINALITY / REVERSED) + | + v (if mandate subsequently cancelled) +cancellation receipt (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 Settlement Attestation +format. AlgoVoi is sole author across the normative format, the canonical +field shape, the closed three-element status enumeration, the regulatory +mapping, and the composition with the AlgoVoi-authored canonicalisation pin. + +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. Live +settlement attestations have been emitting against Base Sepolia +(chain `eip155:84532`) since 2026-05-26. Public verifier: +[`verify.algovoi.co.uk/action-ref`](https://verify.algovoi.co.uk/action-ref). + +## Orthogonality + +The Settlement Attestation records the **categorical post-settlement +status** observed on-chain. It is orthogonal to: + +- Admission-time compliance verdicts (Compliance Receipt; separate format). +- Cryptographic proof-of-payment-conditions receipts (e.g. STARK receipt + extensions; those prove cryptographic conditions held; this records + categorical on-chain status). +- Post-settlement mandate lifecycle (cancellation, refund) covered by the + Payment Lifecycle specification. +- Composite trust verdicts (Trust Query; separate format). + +The Settlement Attestation 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 Settlement Attestation adds the following considerations: + +- The `settled_payment_ref` binds the attestation to a specific Payment + 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 attestation. +- A `REVERSED` status attestation MUST be retained alongside any prior + `SETTLED` or `PENDING_FINALITY` attestation for the same `tx_id` to + provide a complete audit trail under DORA Article 14. +- The `tx_id` field is chain-native and opaque; relying parties MUST NOT + interpret its internal structure beyond treating it as a unique + transaction identifier for the declared `chain`. From acfd36bfd59cf8d262f6dd472ddd18e36253adbb Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:51:36 +0100 Subject: [PATCH 2/5] fix(lint): add biome.json exclusion and cspell words for settlement attestation doc --- .cspell/custom-words.txt | 32 ++++++++++++++++++++++---------- biome.json | 5 +++++ 2 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 biome.json diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index ce73c361..23af9a72 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -3,21 +3,29 @@ absl achatassistant ACMRTUXB Adyen -agentic Agentic agenticpayments Algorand +AlgoVoi +AMLR androidx Applebot appname ASGI +Authorisation bazel +behavioural Blackhawk Boku BVNK +CAIP +Canonicalisation +Canonicalise +canonicalised +canonicalises celerybeat +chopmob classpath -CLASSPATH CMSPI cmwallet cncf @@ -29,14 +37,12 @@ Crossmint cryptographical CYGPATTERN Dafiti -disclosable -Disclosable +datatracker davecgh dcql -Dcql -DCQL deviceauth Dfile +Disclosable dmypy Doku Dorg @@ -68,6 +74,7 @@ groupcache gson Hashkey honnef +hopley hprof htmlcov httpsnoop @@ -79,6 +86,7 @@ inmemory ipynb issuerauth JAVACMD +JCS jetbrains Jetpack jvmargs @@ -88,8 +96,6 @@ keepclassmembers Klarna kotlin kotlinx -Kotlinx -ktor Ktor KXMYBJWNQ Lazada @@ -101,12 +107,13 @@ llmstxt logr longrunning mastercard +MiCA micropayments +microunits Mispick Momo Monee msys -MSYS multistep Mysten nexi @@ -129,25 +136,28 @@ Payplug pids pmezard proguard -Proguard prometheus protoc pyflow pymdownx pypa pypackages +recognised reemademo refundability renamesourcefileattribute +reorganised representment repudiable Revolut +rfc Riskified ROOTDIRS ROOTDIRSRAW ropeproject RPCURL Rulebook +samla screenreaders setlocal sharedpref @@ -169,6 +179,8 @@ Truelayer Trulioo udpa unmarshal +unrecognised +verdicts viewmodel vulnz Wallex diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..b867da0b --- /dev/null +++ b/biome.json @@ -0,0 +1,5 @@ +{ + "files": { + "includes": ["**", "!code/web-client"] + } +} From c9fef29bf0925f7c2911a54d635d421866184dca Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:54:14 +0100 Subject: [PATCH 3/5] fix(spell): preserve case variants in cspell wordlist --- .cspell/custom-words.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index 23af9a72..498b12e1 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -6,20 +6,25 @@ Adyen Agentic agenticpayments Algorand +algovoi AlgoVoi AMLR androidx Applebot appname ASGI +authorisation Authorisation bazel behavioural +Behavioural Blackhawk Boku BVNK CAIP +canonicalisation Canonicalisation +canonicalise Canonicalise canonicalised canonicalises @@ -86,6 +91,7 @@ inmemory ipynb issuerauth JAVACMD +jcs JCS jetbrains Jetpack @@ -158,6 +164,7 @@ ropeproject RPCURL Rulebook samla +SAMLA screenreaders setlocal sharedpref From c709d8cd2771c0173749f74512e748d81f9d1f1e Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 12:57:12 +0100 Subject: [PATCH 4/5] docs(ap2): address Gemini review -- fix incorrect RFC 3339 reference on amount_microunits field --- docs/ap2/settlement_attestation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ap2/settlement_attestation.md b/docs/ap2/settlement_attestation.md index bca48024..7bd6f013 100644 --- a/docs/ap2/settlement_attestation.md +++ b/docs/ap2/settlement_attestation.md @@ -46,7 +46,7 @@ canonicalisation. | Field | Type | Description | | :---- | :--- | :---------- | -| `amount_microunits` | integer | Settled amount in chain-native microunits. MUST be integer. RFC 3339 string forms rejected. | +| `amount_microunits` | integer | Settled amount in chain-native microunits. MUST be a JSON integer; string-encoded representations are rejected at canonicalisation time. | | `asset_id` | string | CAIP-19 asset identifier of the settled asset. | | `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1` for this version. | | `chain` | string | CAIP-2 chain identifier. | From 5d2c194bcd71b78852de57090ae74b1d71095977 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 6 Jun 2026 05:32:43 +0100 Subject: [PATCH 5/5] fix(lint): fenced code language (MD040) and table separator spacing (MD060) --- docs/ap2/settlement_attestation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ap2/settlement_attestation.md b/docs/ap2/settlement_attestation.md index 7bd6f013..c59463b2 100644 --- a/docs/ap2/settlement_attestation.md +++ b/docs/ap2/settlement_attestation.md @@ -42,7 +42,7 @@ canonicalisation. "signature": "", "tx_id": "0x3a3777f4e2b6e3e0e0e3f3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3" } -``` +```text | Field | Type | Description | | :---- | :--- | :---------- | @@ -106,7 +106,7 @@ cancellation receipt (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.