> ## Documentation Index
> Fetch the complete documentation index at: https://docs.algovoi.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Compliance receipt verifier

> Standalone reference verifier for AlgoVoi JWS compliance receipts: offline capable, no infrastructure trust, Python and TypeScript with shared vectors.

The AlgoVoi compliance receipt verifier decodes, cryptographically verifies, and structurally validates a compact JWS compliance receipt against AlgoVoi's Ed25519 signing key. It is **standalone** — a recipient can verify any receipt without contacting AlgoVoi's gateway, control plane, or JWKS endpoint (the public key can be fetched once and cached).

Three deployment modes ship today, all from the same source code with the same byte-for-byte verification logic:

<CardGroup cols={2}>
  <Card title="Hosted endpoint" icon="cloud" href="https://api.algovoi.co.uk/v1/receipt/verify">
    `POST api.algovoi.co.uk/v1/receipt/verify` — submit any JWS receipt, get back a structured pass/fail report. Stateless. Rate-limited at 120 req/min.
  </Card>

  <Card title="Python (PyPI)" icon="python" href="https://pypi.org/project/algovoi-receipt-verifier/">
    `pip install algovoi-receipt-verifier`. Exposes `verify_compliance_receipt()` and `ReceiptVerificationError` with nine typed error codes.
  </Card>
</CardGroup>

## What the verifier checks

| # | Check                                                                                                                               | Error if fails              |
| - | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| 1 | JWS format — three-part `header.payload.signature` base64url                                                                        | `INVALID_JWS_FORMAT`        |
| 2 | Algorithm whitelist — `EdDSA`, `ES256K`, `RS256` only; reject without fallback                                                      | `UNSUPPORTED_ALG`           |
| 3 | Ed25519 signature — cryptographic verification against the issuer's public key                                                      | `TAMPERED_SIGNATURE`        |
| 4 | `canon_version` — must be in the supported registry (`jcs-rfc8785-v1`)                                                              | `UNSUPPORTED_CANON_VERSION` |
| 5 | JCS re-canonicalisation — re-canonicalise payload via RFC 8785; compare byte-for-byte                                               | `NON_CANONICAL_PAYLOAD`     |
| 6 | Required fields — `payer_ref`, `screen_result`, `screen_timestamp_ms`, `screen_provider_did`, `jurisdiction_flags`, `canon_version` | `MISSING_FIELD`             |
| 7 | `screen_result` enum — must be `ALLOW`, `REFER`, or `DENY`                                                                          | `INVALID_PAYLOAD`           |
| 8 | `payment_hash` binding — if `expected_payment_hash` is supplied, must match exactly                                                 | `PAYMENT_HASH_MISMATCH`     |

All nine error codes map 1:1 to the Phase 8 [Agent Trust Bench](https://agent-trust-bench.algovoi.co.uk/) threat surface (OWASP LLM09).

## Hosted endpoint

```bash theme={null}
curl -X POST https://api.algovoi.co.uk/v1/receipt/verify \
  -H 'Content-Type: application/json' \
  -d '{
    "jws": "<compact-jws>",
    "expected_payment_hash": "sha256:<hex>"
  }'
```

Response on success (`200 OK`):

```json theme={null}
{
  "verified": true,
  "screen_result": "ALLOW",
  "settlement_status": "SETTLED",
  "canon_version": "jcs-rfc8785-v1",
  "alg": "EdDSA",
  "payer_ref": "payer-abc123"
}
```

On failure (`422 Unprocessable Entity`):

```json theme={null}
{
  "verified": false,
  "error_code": "TAMPERED_SIGNATURE",
  "error_message": "signature verification failed"
}
```

Optional: pass `jwks` to verify a receipt signed by a third-party key rather than AlgoVoi's platform key.

## Programmatic use (Python)

```python theme={null}
from algovoi_receipt_verifier import verify_compliance_receipt, ReceiptVerificationError

# Fetch AlgoVoi's public key once and cache it
import urllib.request, json
jwks = json.loads(urllib.request.urlopen(
    'https://api.algovoi.co.uk/.well-known/jwks.json'
).read())

try:
    receipt = verify_compliance_receipt(
        jws_token,
        jwks=jwks,
        expected_payment_hash='sha256:...',
    )
    print(receipt.screen_result)   # ALLOW / REFER / DENY
except ReceiptVerificationError as e:
    print(e.code, e.message)
    # TAMPERED_SIGNATURE / UNSUPPORTED_ALG / UNSUPPORTED_CANON_VERSION /
    # NON_CANONICAL_PAYLOAD / PAYMENT_HASH_MISMATCH / MISSING_ENVELOPE /
    # MISSING_FIELD / INVALID_JWS_FORMAT / INVALID_PAYLOAD
```

## Programmatic use (TypeScript)

```typescript theme={null}
import { verifyComplianceReceipt, ReceiptVerificationError } from '@algovoi/receipt-verifier';

// Fetch AlgoVoi's public key once and cache it
const jwks = await fetch('https://api.algovoi.co.uk/.well-known/jwks.json')
  .then(r => r.json());

try {
  const receipt = verifyComplianceReceipt({
    jws: token,
    jwks,
    expectedPaymentHash: 'sha256:...',
  });
  console.log(receipt.screenResult);  // ALLOW / REFER / DENY
} catch (e) {
  if (e instanceof ReceiptVerificationError) {
    console.error(e.code, e.message);
  }
}
```

## Phase 8 ATB threat mapping

Each of the eight invalid cross-validation vectors maps directly to a Phase 8 Agent Trust Bench threat profile:

| Vector                               | ATB threat                       | Error code                                      |
| ------------------------------------ | -------------------------------- | ----------------------------------------------- |
| `i01_tampered_signature.json`        | `receipt-tampered-sig`           | `TAMPERED_SIGNATURE`                            |
| `i02_unsupported_alg.json`           | `receipt-alg-unknown`            | `UNSUPPORTED_ALG`                               |
| `i03_unsupported_canon_version.json` | `receipt-canon-version-mismatch` | `UNSUPPORTED_CANON_VERSION`                     |
| `i04_payment_hash_mismatch.json`     | `receipt-replay-modified`        | `PAYMENT_HASH_MISMATCH`                         |
| `i05_missing_envelope.json`          | `receipt-missing-envelope`       | `MISSING_ENVELOPE`                              |
| `i06_non_canonical_payload.json`     | `receipt-bad-jcs`                | `TAMPERED_SIGNATURE` or `NON_CANONICAL_PAYLOAD` |
| `i07_malformed_jws.json`             | —                                | `INVALID_JWS_FORMAT`                            |
| `i08_missing_screen_result.json`     | —                                | `MISSING_FIELD`                                 |

## Cross-validation vectors

13 self-contained JSON fixtures (`vectors/valid/` and `vectors/invalid/`) are run by both test suites. Each fixture embeds its own `jwks` — no external key store required.

| Suite      | Unit tests         | Vector tests | E2E (from registry) | Total     |
| ---------- | ------------------ | ------------ | ------------------- | --------- |
| Python     | 28                 | 13/13        | 13/13               | **41/41** |
| TypeScript | 19 (incl. vectors) | —            | 13/13               | **19/19** |

E2E tests install from the live registries (`algovoi-receipt-verifier==0.1.1` from PyPI and `@algovoi/receipt-verifier@0.1.1` from npm) into a clean environment and run all 13 vectors. Source: [`e2e/test_registry_python.py`](https://github.com/chopmob-cloud/algovoi-receipt-verifier/blob/main/e2e/test_registry_python.py) and [`e2e/test_registry_npm.mjs`](https://github.com/chopmob-cloud/algovoi-receipt-verifier/blob/main/e2e/test_registry_npm.mjs).

Regenerate vectors at any time:

```bash theme={null}
python vectors/generate_vectors.py
```

## JWKS endpoint

AlgoVoi's public key is available at:

```
GET https://api.algovoi.co.uk/.well-known/jwks.json
```

Pass the response body directly as `jwks`. The `kid` in the JWS header is used for key selection; falls back to the first key if no `kid` match.

## See also

* [Compliance gate](/compliance-gate-v1) — the `POST /compliance/screen` endpoint that *emits* the JWS receipts this verifier checks
* [JCS canonicalisation substrate](/canonicalisation-substrate) — the `build_compliance_receipt()` emitter and JCS substrate underlying the `canon_version` pin
* [Audit verifier](/audit-verifier) — selective-disclosure audit bundle verifier; composes with receipt verification in the compliance audit chain
* [Composite trust query](/composite-trust-query) — sits above this verifier; aggregates receipt signals into a single `TRUSTED` / `PROVISIONAL` / `UNTRUSTED` verdict
* [Settlement attestation](/settlement-attestation) — multi-chain settlement record that pairs with the compliance receipt
* [Agent Trust Bench](https://agent-trust-bench.algovoi.co.uk/) — Phase 8 receipt/substrate-integrity profiles (OWASP LLM09)
