# GAIP Receipt Specification v1 (open draft)

Status: open draft, version 1.0, 28 September 2026. Served at
`https://www.gaipagents.com/v1/free/evidence/receipt-spec`.

This document describes how GAIP receipts are formed, chained, proven and
verified, and how evidence packs, incident bundles and receipt exports are
built from them. Anyone may implement a compatible verifier or witness.

> **What a receipt is not.** A GAIP receipt, evidence pack or incident bundle is
> an *evidence compilation*. It is not a certification, an audit opinion,
> insurance advice, legal advice, a determination of fault or liability, or a
> regulatory filing. Every output carries `not_certification`,
> `not_legal_advice` and `not_a_regulatory_filing` set to `true`.

> **Signatures.** Receipts are currently
> **unsigned: integrity via hash chain and Merkle proof only.** GAIP will not sign receipts until a founder-approved
> signing-key policy exists. Where GAIP's history prefix has been timestamped
> through Sigstore/Rekor, verification reports that separately
> (`timestamp_status`); that anchoring covers the history root, not a per-receipt
> signature.

## 1. Receipt record

Every governed GAIP action appends one *observation* to an append-only history.
The history row is:

| Field | Type | Meaning |
|---|---|---|
| `observation` | object | The retained observation (see below). |
| `previous_record_sha256` | hex(64) | `record_sha256` of the previous row; 64 zeros for the first row. |
| `record_sha256` | hex(64) | SHA-256 of the canonical JSON of `{"previous_record_sha256", "observation"}`. |
| `recorded_at_utc` | RFC 3339 | Server time the row was stored (Postgres) or the observation time (file backend). |

Observation fields relevant to verification:

| Field | Meaning |
|---|---|
| `receipt_id` | Public identifier (1–128 chars of `A-Za-z0-9:._-`). Most tools use a UUIDv5 of the observation id. Some public observations (for example agent readiness checks) have no `receipt_id` and are verified by `record_sha256` and inclusion proof. |
| `observation_id` | Unique per history; reuse with different content is rejected. |
| `service` / `evidence_class` | What produced the record (for example `WITNESS_DELIVERY`, `WATCH_EVENT`, `CONFORMANCE_CHECK`, `COMMERCIAL_REPAIR`). |
| `*_sha256` | Digests of request, result or body. Bodies themselves are not retained. |
| `correction_of`, `dispute_of`, `quarantine_of`, `supersedes_receipt_id` | Later rows that change a receipt's lifecycle state. |

## 2. Hashing

* Canonical JSON for the chain: UTF-8, keys sorted, separators `,` and `:`,
  non-ASCII characters not escaped (Python
  `json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))`).
* `record_sha256 = SHA-256(canonical({"previous_record_sha256": p, "observation": o}))`.
* Exports that follow external proposals use RFC 8785 (JCS) where the proposal
  requires it (section 7).

## 3. Chain

Row *n* is valid when `previous_record_sha256` equals row *n−1*'s
`record_sha256` and `record_sha256` recomputes from the row. A verifier reports
`INTEGRITY_FAILURE` if any row fails; GAIP never rewrites history, it appends
corrections.

## 4. Merkle tree and inclusion proofs

* Leaves are the `record_sha256` values in history order.
* Each parent is `SHA-256(bytes(left) || bytes(right))` over the raw 32-byte
  digests. An odd level duplicates its last node.
* An inclusion proof is a list of `{"position": "left"|"right", "sha256": hex}`
  from leaf to root.
* To verify: start with the leaf; for each step, hash `sibling || current` when
  `position` is `left`, otherwise `current || sibling`; compare with
  `merkle_root_sha256` from the proof or from
  `GET /v1/free/receipts/transparency`.

## 5. Verification

1. `GET /v1/free/receipts/{receipt_id}/verify` (or MCP `verify_gaip_receipt`).
2. Check `chain_integrity.valid`, recompute the root from `transparency.inclusion_proof`.
3. Read `lifecycle` (corrected, disputed, quarantined, superseded).
4. Read `timestamp_status`: `INDEPENDENTLY_ANCHORED_SIGSTORE_REKOR` or
   `GAIP_RECORDED_NOT_INDEPENDENTLY_ANCHORED`.

Integrity shows the record is the one GAIP retained, unaltered. It does not
establish the truth of what a caller asserted, identity, ownership, value,
outcome or reputation.

## 6. Evidence packs and incident bundles

**Evidence pack** (`POST /v1/free/evidence/pack`, MCP `gaip_evidence_pack`,
schema `gaip.evidence-pack.v1`): input `subject` (an agent or supplier id or
public https URL — never a person), optional `scope` (`receipt_ids` ≤ 50,
`since`, `until`, `categories`, `max_items` ≤ 200) and optional `requester`
(`continuity_handle`, `purpose`). Output: items (category, `receipt_id`,
`verify_url`, whitelisted redacted `facts`, per-item verification with
inclusion proof and `item_sha256`), a `manifest` (counts, time span, gaps,
methods, redactions), `history_snapshot`, optional `observatory` status, a
`framework_reference_table`, and `pack_sha256` = SHA-256 of the canonical pack
without that field.

Inclusion rules: receipts the requester supplies by id; subject-matched records
bound to the requester's verified continuity handle; and public GAIP
observations (readiness checks, watch events, GAIP-initiated records). Other
callers' records about the same subject are counted only.

**Incident bundle** (`POST /v1/free/evidence/incident-bundle`, MCP
`gaip_incident_bundle`, schema `gaip.incident-evidence-bundle.v1`): verifies each
supplied receipt, orders a timeline (undated entries last), attributes each entry
to its source (`GAIP_RETAINED_RECORD` or `CALLER_SUPPLIED_STATEMENT`), notes
stated-versus-recorded time differences, and adds an EU AI Act Article 73
reference aid. It makes no finding of cause, responsibility, fault or liability.

**Framework references.** Rows say only that GAIP evidence categories *may help
locate evidence for* an AIUC-1 area or ISO/IEC 42001 clause during the reader's
own review. They never state that a requirement is met. Only area letters,
clause numbers and titles are cited:

* AIUC-1 (https://www.aiuc-1.com/): B. Security, D. Reliability, E. Accountability.
* ISO/IEC 42001:2023 (https://www.iso.org/standard/81230.html): 7.5, 8.1, 9.1,
  10.2, Annex A A.10.
* Regulation (EU) 2024/1689, Article 73 (https://eur-lex.europa.eu/eli/reg/2024/1689/oj).

## 7. Export formats

`GET /v1/free/receipts/{receipt_id}/formats/{x402|erc8004|vc}` or MCP
`gaip_receipt_export`. Every export is unsigned and read-only.

| Format | Follows | Notes |
|---|---|---|
| `x402` | Open proposal "Settlement Attestation Receipt (SAR)" v0.1, https://github.com/x402-foundation/x402/issues/1195 (not an adopted standard; dispute-evidence discussion at issue #3500) | `receipt_id = "sha256:" + hex(SHA-256(JCS(core)))`, core = all top-level fields except `receipt_id`, `sig`, `sig_alg`, `_perf`, `_ext`. `verdict` PASS / FAIL / INDETERMINATE comes **only** from GAIP Witness results (`MET`/`NOT_MET`/`INDETERMINATE`); any other receipt is INDETERMINATE with `GAIP_NOT_A_WITNESS_RESULT`. `sig`, `sig_alg`, `verifier_kid` are null. GAIP evidence sits in `_ext.gaip`. |
| `erc8004` | ERC-8004 (Draft) Validation Registry `validationResponse(requestHash, response, responseURI, responseHash, tag)`, https://eips.ethereum.org/EIPS/eip-8004 | Shape for off-chain publication only: no wallet, transaction or gas. `response` is 100 (PASS) or 0 (FAIL); INDETERMINATE has no value. Hashes are SHA-256 over JCS, not keccak256. `agentId` and `validatorAddress` are null. |
| `vc` | W3C VC Data Model 2.0 shape, https://www.w3.org/TR/vc-data-model-2.0/ | Unsecured envelope with no `proof`; VC-like in shape only. |

## 8. Compatible witnesses

A witness is compatible when it (a) publishes caller-declared, deterministic
checks before observing, (b) records PASS / FAIL / UNKNOWN per check and an
overall MET / NOT_MET / INDETERMINATE, (c) retains digests rather than bodies,
(d) appends to a hash chain as in sections 2–4, and (e) exposes a verify
endpoint returning chain status, inclusion proof and lifecycle. GAIP's Witness
Agent (`witness_register_terms`, `witness_delivery`) is the reference.

## 9. Privacy

Only the requester's own receipts or public data are itemised. Personal data,
URL query strings, credentials and caller identity context are never included;
emails, phone numbers, IP addresses, tokens and key-like strings are redacted
from text. Packs and bundles are computed on request and not stored by the
endpoint; the underlying receipts remain in GAIP's append-only public history
(see https://www.gaipagents.com/privacy).

## 10. Licence

This specification text may be copied, implemented and adapted under the
Creative Commons Attribution 4.0 International licence (CC BY 4.0), with
attribution to GAIP. Proposed licence pending founder confirmation. Third-party
standards and proposals referenced here remain under their owners' terms; this
document cites and links them and does not reproduce their text.

## 11. Legal notes for review (not legal advice)

These notes flag points for review by a qualified adviser. They are not legal
advice.

1. **No regulated or professional claims.** Outputs are labelled evidence
   compilations. Review whether any wording could be read as certification,
   assurance, an audit opinion, insurance advice or a regulated activity in the
   UK or EU, and whether the "may help locate evidence for" wording is sufficient.
2. **No fault findings.** Incident bundles order facts and attribute sources
   only. Review whether timeline ordering or the Article 73 aid could be read as
   an assessment of causation or a regulatory report.
3. **Data protection (UK GDPR / EU GDPR).** Confirm the lawful basis for
   retaining public receipts, the retention period for history rows, the
   adequacy of redaction, handling of subject references that could identify a
   sole trader, and data-subject rights against an append-only history
   (corrections are appended, not erased).
4. **Third-party standards.** AIUC-1 and ISO/IEC 42001 are copyrighted; only
   clause numbers and titles are cited. Confirm this is acceptable and that no
   trademark use implies endorsement by AIUC, ISO or IEC.
5. **x402 and ERC-8004.** Both are open proposals or drafts. Confirm that
   exporting "style" or "shaped" documents does not imply membership,
   endorsement or conformance.
6. **Unsigned receipts.** Until a signing-key policy exists, confirm the
   "unsigned" statement is prominent enough that no reader relies on a GAIP
   signature.
7. **Licence.** Confirm CC BY 4.0 for this specification.
