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
40 changes: 29 additions & 11 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
aapt
aapt
absl
achatassistant
ACMRTUXB
Adyen
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
chopmob
classpath
CLASSPATH
CMSPI
cmwallet
cncf
Expand All @@ -29,14 +40,12 @@ Crossmint
cryptographical
CYGPATTERN
Dafiti
disclosable
Disclosable
datatracker
davecgh
dcql
Dcql
DCQL
deviceauth
Dfile
Disclosable
dmypy
Doku
Dorg
Expand Down Expand Up @@ -68,6 +77,7 @@ groupcache
gson
Hashkey
honnef
hopley
hprof
htmlcov
httpsnoop
Expand All @@ -79,6 +89,8 @@ inmemory
ipynb
issuerauth
JAVACMD
jcs
JCS
jetbrains
Jetpack
jvmargs
Expand All @@ -87,9 +99,7 @@ keepattributes
keepclassmembers
Klarna
kotlin
kotlinx
Kotlinx
ktor
Ktor
KXMYBJWNQ
Lazada
Expand All @@ -101,12 +111,12 @@ llmstxt
logr
longrunning
mastercard
MiCA
micropayments
Mispick
Momo
Monee
msys
MSYS
multistep
Mysten
nexi
Expand All @@ -128,27 +138,33 @@ paypal
Payplug
pids
pmezard
preimage
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
serialised
Serialised
setlocal
sharedpref
Shopcider
Expand All @@ -169,6 +185,8 @@ Truelayer
Trulioo
udpa
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"]
}
}
165 changes: 165 additions & 0 deletions docs/ap2/trust_query.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# 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": "<detached signature over JCS canonical bytes>",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Including the signature field inside the JSON object makes it an enveloped signature rather than a detached signature.\n\nTo avoid a circular dependency during JCS canonicalisation and signature verification, the specification should explicitly clarify that the signature field is excluded from the JSON object prior to canonicalisation. Alternatively, if the signature is truly detached, it should be transmitted alongside the JSON payload rather than as a property within it.

"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/).

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

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

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:

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