From f2bead9d42151fe2a324782ae8496ba13da40c86 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:18:45 +0100 Subject: [PATCH 1/6] docs(ap2): add Trust Query -- multi-issuer composite verdict envelope (AlgoVoi-authored) --- docs/ap2/trust_query.md | 150 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 docs/ap2/trust_query.md diff --git a/docs/ap2/trust_query.md b/docs/ap2/trust_query.md new file mode 100644 index 00000000..95eaa7f5 --- /dev/null +++ b/docs/ap2/trust_query.md @@ -0,0 +1,150 @@ +# Trust Query + +The Trust Query is a categorical, content-addressed composite verdict +envelope emitted by a verifier in response to a trust-query request +from a Shopping Agent or facilitator. It composes the outcomes of +multiple independent issuer attestations into a single categorical +verdict: given this set of evidence from independent parties, what is +the categorical trust decision? + +The format is AlgoVoi-authored. AP2 references it; AP2 does not redefine +it. The normative wire format is the canonical AlgoVoi Composite Trust +Query response specified in IETF Internet-Draft +[`draft-hopley-x402-composite-trust-query`](https://datatracker.ietf.org/doc/draft-hopley-x402-composite-trust-query/) +and documented at +[`docs.algovoi.co.uk/composite-trust-query-v1`](https://docs.algovoi.co.uk/composite-trust-query-v1). + +## Usage + +A Trust Query response is generated by the verifier after evaluating the +set of issuer attestations available for a given transaction or +counterparty. In an AP2 flow, the verifier MAY be the Credential Provider, +Network, Merchant Payment Processor, or a dedicated trust aggregation +service. + +The response enables a Shopping Agent or downstream relying party to make +a categorical trust decision without re-running the underlying evidence +pipeline, and provides a record of the evidence classes considered that +satisfies regulatory audit obligations. + +## Response Shape + +A Trust Query response is a JSON object canonicalised under RFC 8785 +(JCS). Field names are sorted lexicographically by JCS during +canonicalisation. + +```json +{ + "canon_version": "jcs-rfc8785-v1", + "evaluated_at": "2026-05-30T07:10:43Z", + "evidence_classes_considered": ["admission-compliance", "settlement-attestation"], + "issuer_references": [ + { + "content_hash": "sha256:0dd5d0b76c9b9281fdeb2509ad38ab132b16a17385ca01d976ff9e6e12563a0f", + "issuer_id": "did:web:api.algovoi.co.uk" + } + ], + "signature": "", + "verdict": "TRUSTED" +} +``` + +| Field | Type | Description | +| :---- | :--- | :---------- | +| `canon_version` | string | In-band canonicalisation pin. Fixed `jcs-rfc8785-v1` for this version. | +| `evaluated_at` | string | ISO 8601 UTC timestamp of verdict generation. | +| `evidence_classes_considered` | ordered array of string | Evidence class identifiers available to the composite evaluator. Array order is significant under RFC 8785 section 3.2.3. | +| `issuer_references` | array of object | Per-issuer content-addressed references to the evidence used. Each entry carries `issuer_id` (DID URI) and `content_hash` (`sha256:{hex}`). | +| `signature` | string | Detached signature over the JCS canonical bytes. | +| `verdict` | string (closed enum) | `TRUSTED` / `PROVISIONAL` / `INSUFFICIENT_EVIDENCE` / `UNTRUSTED`. | + +## The closed enumeration: `verdict` + +The `verdict` field MUST take one of exactly four values: + +| Value | Meaning | +| :---- | :------ | +| `TRUSTED` | Composite evaluation yielded a positive verdict across all evidence classes considered. | +| `PROVISIONAL` | Composite evaluation yielded a positive verdict but at least one evidence class returned a conditional or time-bound positive. | +| `INSUFFICIENT_EVIDENCE` | One or more required evidence classes returned no usable signal; the composite verdict is undetermined. | +| `UNTRUSTED` | At least one evidence class returned a negative verdict sufficient to fail the composite under the verifier's declared composition policy. | + +A consumer receiving `PROVISIONAL` or `INSUFFICIENT_EVIDENCE` MUST NOT +proceed as if the verdict were `TRUSTED`. + +The enumeration is **closed by design**. Any extension or amendment +constitutes a normative successor format. + +## Canonicalisation + +The response 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-composite-trust-query`](https://pypi.org/project/algovoi-composite-trust-query/) on PyPI +- [`@algovoi/composite-trust-query`](https://www.npmjs.com/package/@algovoi/composite-trust-query) on npm + +Both packages are published under Apache 2.0. + +## Composition + +The Trust Query composes upstream attestations into a single verdict: + +```text +compliance receipt (ALLOW) settlement attestation (SETTLED) + | | + +------------------------------------+ + | + v + trust query (TRUSTED / PROVISIONAL / + INSUFFICIENT_EVIDENCE / UNTRUSTED) +``` + +The `issuer_references` array records which upstream attestations were +considered. A relying party MAY walk the reference chain to verify each +upstream attestation independently. + +## Authorship and Substrate-Author Position + +This specification documents the AlgoVoi-authored Composite Trust Query +format. AlgoVoi is sole author across the normative format, the canonical +field shape, the closed four-element verdict enumeration, 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. + +## Orthogonality + +The Trust Query defines the **multi-issuer composite verdict** format. +It is orthogonal to: + +- Single-issuer attestations (Compliance Receipt, Settlement Attestation; + these are inputs to the composite, not the composite itself). +- Per-counterparty risk checks (counterparty risk is one input evidence + class, not the composite verdict format). +- Admission-time compliance (Compliance Receipt; a separate upstream input). +- Agent trust scoring and reputation systems (those produce evidence that + MAY be referenced as an `issuer_reference` entry; they do not define + the composite verdict shape). + +## Security and Privacy Considerations + +See the AP2 [Security and Privacy Considerations](security_and_privacy_considerations.md) +document. The Trust Query adds the following considerations: + +- The `issuer_references` array MUST be evaluated before accepting the + composite verdict; a verifier MUST re-derive the canonical hash of each + referenced attestation before trusting the composite. +- `PROVISIONAL` and `INSUFFICIENT_EVIDENCE` verdicts MUST be treated + conservatively; downstream systems MUST NOT promote either to `TRUSTED` + without additional out-of-band evidence. +- The `evidence_classes_considered` array is informational; its presence + does not guarantee that all listed classes contributed a positive signal. + Relying parties MUST rely on `verdict`, not on inferences from the + evidence class list. From c5e965629f8440a78f1b72d58ad86648dbdc66f8 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:51:45 +0100 Subject: [PATCH 2/6] fix(lint): add biome.json exclusion and cspell words for trust query doc --- .cspell/custom-words.txt | 28 ++++++++++++++++++---------- biome.json | 5 +++++ 2 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 biome.json diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index ce73c361..91cbb673 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -3,21 +3,27 @@ absl achatassistant ACMRTUXB Adyen -agentic Agentic agenticpayments Algorand +AlgoVoi androidx Applebot appname ASGI +Authorisation bazel +Behavioural Blackhawk Boku BVNK +Canonicalisation +Canonicalise +canonicalised +canonicalises celerybeat +chopmob classpath -CLASSPATH CMSPI cmwallet cncf @@ -29,14 +35,12 @@ Crossmint cryptographical CYGPATTERN Dafiti -disclosable -Disclosable +datatracker davecgh dcql -Dcql -DCQL deviceauth Dfile +Disclosable dmypy Doku Dorg @@ -68,6 +72,7 @@ groupcache gson Hashkey honnef +hopley hprof htmlcov httpsnoop @@ -79,6 +84,7 @@ inmemory ipynb issuerauth JAVACMD +jcs jetbrains Jetpack jvmargs @@ -87,9 +93,7 @@ keepattributes keepclassmembers Klarna kotlin -kotlinx Kotlinx -ktor Ktor KXMYBJWNQ Lazada @@ -101,12 +105,12 @@ llmstxt logr longrunning mastercard +MiCA micropayments Mispick Momo Monee msys -MSYS multistep Mysten nexi @@ -129,25 +133,27 @@ Payplug pids pmezard proguard -Proguard prometheus protoc pyflow pymdownx pypa pypackages +recognised reemademo refundability renamesourcefileattribute representment repudiable Revolut +rfc Riskified ROOTDIRS ROOTDIRSRAW ropeproject RPCURL Rulebook +samla screenreaders setlocal sharedpref @@ -169,6 +175,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 34d36fa6f59329a5f163cac7d0015ba459e123e9 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 11:54:17 +0100 Subject: [PATCH 3/6] 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 91cbb673..4c2b1491 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -6,18 +6,23 @@ Adyen Agentic agenticpayments Algorand +algovoi AlgoVoi androidx Applebot appname ASGI +authorisation Authorisation bazel +behavioural Behavioural Blackhawk Boku BVNK +canonicalisation Canonicalisation +canonicalise Canonicalise canonicalised canonicalises @@ -85,6 +90,7 @@ ipynb issuerauth JAVACMD jcs +JCS jetbrains Jetpack jvmargs @@ -154,6 +160,7 @@ ropeproject RPCURL Rulebook samla +SAMLA screenreaders setlocal sharedpref From ca3c5a6fc2ec96ca7dc09e6fde19621f27db9c10 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 12:51:37 +0100 Subject: [PATCH 4/6] docs(ap2): clarify signature preimage exclusion and MAY/MUST retrieval vs verification Two precision fixes in response to review feedback: 1. Signature preimage: adds explicit 'Signature preimage' subsection under Canonicalisation stating that the signature field is excluded from the JCS preimage. Signs canonical bytes of the remaining fields, then stores the result in the signature field. Eliminates any appearance of circularity between the canonical form and its signature. 2. MUST/MAY consistency: the Composition section 'MAY walk the reference chain' and the Security section 'MUST re-derive the canonical hash' referred to two different operations without making the distinction explicit. Clarified throughout: retrieval of upstream attestations is optional (MAY); if an attestation is retrieved, hash verification is mandatory (MUST). Both sections now use the same framing. --- docs/ap2/trust_query.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/ap2/trust_query.md b/docs/ap2/trust_query.md index 95eaa7f5..c6ba2e55 100644 --- a/docs/ap2/trust_query.md +++ b/docs/ap2/trust_query.md @@ -82,6 +82,16 @@ 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/). +### Signature preimage + +The `signature` field is **excluded from the JCS preimage**. To sign, +the issuer removes the `signature` field from the object, computes the +RFC 8785 canonical bytes of the remaining fields, and signs those bytes. +The resulting signature is then stored in the `signature` field of the +serialised envelope. This is the standard JCS signing pattern (see also +RFC 8785 section 3.2) and avoids any circular dependency between the +canonical form and its signature. + 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: @@ -106,8 +116,10 @@ compliance receipt (ALLOW) settlement attestation (SETTLED) ``` The `issuer_references` array records which upstream attestations were -considered. A relying party MAY walk the reference chain to verify each -upstream attestation independently. +considered. A relying party MAY retrieve and inspect each upstream +attestation independently. If an upstream attestation is retrieved, the +relying party MUST verify that its canonical hash matches the recorded +`content_hash` before using it as additional evidence. ## Authorship and Substrate-Author Position @@ -138,9 +150,12 @@ It is orthogonal to: See the AP2 [Security and Privacy Considerations](security_and_privacy_considerations.md) document. The Trust Query adds the following considerations: -- The `issuer_references` array MUST be evaluated before accepting the - composite verdict; a verifier MUST re-derive the canonical hash of each - referenced attestation before trusting the composite. +- Retrieval of upstream attestations referenced in `issuer_references` is + OPTIONAL; a relying party MAY accept the composite verdict without + independently fetching each referenced attestation. However, if an + upstream attestation is retrieved, the relying party MUST re-derive its + canonical hash and verify it matches the recorded `content_hash` before + treating the attestation as additional supporting evidence. - `PROVISIONAL` and `INSUFFICIENT_EVIDENCE` verdicts MUST be treated conservatively; downstream systems MUST NOT promote either to `TRUSTED` without additional out-of-band evidence. From c06bc14b9d865f1b18bc23e0b4b1d007648a53f7 Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 30 May 2026 12:52:53 +0100 Subject: [PATCH 5/6] chore: add preimage, serialised to cspell wordlist --- .cspell/custom-words.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index 4c2b1491..29d857fa 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -1,4 +1,4 @@ -aapt +aapt absl achatassistant ACMRTUXB @@ -138,6 +138,7 @@ paypal Payplug pids pmezard +preimage proguard prometheus protoc @@ -162,6 +163,8 @@ Rulebook samla SAMLA screenreaders +serialised +Serialised setlocal sharedpref Shopcider From 339c506d9c39c2621e0e1dd367273eb33b53bc3f Mon Sep 17 00:00:00 2001 From: iLoveChicken Date: Sat, 6 Jun 2026 05:32:47 +0100 Subject: [PATCH 6/6] fix(lint): fenced code language (MD040) and table separator spacing (MD060) --- docs/ap2/trust_query.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ap2/trust_query.md b/docs/ap2/trust_query.md index c6ba2e55..b6f1033e 100644 --- a/docs/ap2/trust_query.md +++ b/docs/ap2/trust_query.md @@ -47,7 +47,7 @@ canonicalisation. "signature": "", "verdict": "TRUSTED" } -``` +```text | Field | Type | Description | | :---- | :--- | :---------- | @@ -113,7 +113,7 @@ compliance receipt (ALLOW) settlement attestation (SETTLED) v trust query (TRUSTED / PROVISIONAL / INSUFFICIENT_EVIDENCE / UNTRUSTED) -``` +```text The `issuer_references` array records which upstream attestations were considered. A relying party MAY retrieve and inspect each upstream