# Inference Delivery Receipt — Format Specification (v1)

**Status:** Published 2026-08-11 · schema 1  
**Purpose:** A vendor-neutral, definitional specification of a *content-bound, dual-signed inference delivery receipt* for implementers, auditors, and agent tooling.

**Non-goals:** Marketing copy, pricing, marketplace listing text, SDK packaging.

## 1. Abstract

An **inference delivery receipt** is a small, offline-verifiable cryptographic object that attests:

> At time *T*, under environment *E*, for tenant *N*, an issuer with key id *K* asserts that  
> a specific **input** (by hash), **output** (by hash), **model weights** (by digest), and  
> **runtime measurement** (e.g. enclave PCR) participated in one inference event,  
> identified by **receipt_id**.

It is **not**:

- Proof of training-data provenance or dataset copyright  
- Proof that a human authorized a payment (that is payment-mandate / agent-identity territory)  
- A substitute for an independent third-party auditor unless the verifier independently holds the hashed material and trusts the key distribution  

Payment binding (optional) lives **outside** this format — e.g. in an HTTP 402 / x402 extension envelope that **references** `receipt_id` and may add settlement identifiers and HTTP entity digests. See §7.

### 1.1 Sibling products (non-confusion) — MUST

This document defines **only** the **inference delivery receipt**.

Other dual-signed receipt products — including **attestation / policy-verify** receipts returned by document-verify APIs — use a **different domain-separation context** and **different body fields** (e.g. `verdict`, `doc_sha256`, `measurements`). Those products:

- MAY share the same envelope/crypto stack (Ed25519 + ML-DSA-44, `kid`, offline verify), and  
- **do not** conform to §4, and  
- **MUST NOT** be described as inference delivery receipts under this specification.

Implementers MUST NOT treat every dual-signed wire blob as §4-conformant.  
§4 fields (`enclave_measurement`, `input_hash`, `output_hash`, `weights_digest`, …) apply only where an issuer mints an **inference delivery** body.

---

## 2. Conformance classes

| Class | Requirement |
|-------|-------------|
| **full** | Dual signatures: classical **Ed25519** + post-quantum **ML-DSA-44** (FIPS 204) over the same canonical body under a fixed domain-separation context string |
| **classical-only** | Ed25519 only — allowed for constrained verifiers; MUST be labeled; MUST NOT claim PQ assurance |

A verifier that requires **full** MUST reject classical-only envelopes.

---

## 3. Identifiers and domain separation

| Item | Rule |
|------|------|
| Field names | **Wire-literal** `snake_case` in the signed body. No silent camelCase rename on the crypto boundary. |
| `receipt_id` | Issuer-assigned, non-empty string. Opaque. Stable for the lifetime of the receipt. |
| Domain context | Signatures MUST use an explicit context string (domain separation) so a signature under one product surface cannot be replayed under another.  
| Example context (informative) | `vendor.tld/attestation/inference-receipt/v1` (informative reverse-DNS example) — implementations MUST use a fixed context string per schema version. |
| Schema version | Integer `schema` field in the body. This document defines **schema = 1**. |

---

## 4. Signed body (schema 1)

All multi-byte cryptographic fields below are **raw 32-byte digests** unless noted; on the wire they MAY be hex- or base64url-encoded so long as the **canonical preimage for signing** is defined and fixed (see §5).

| Field | Type | Required | Meaning |
|-------|------|----------|---------|
| `schema` | uint | yes | Must be `1` for this specification |
| `alg` | uint | yes | `1` = dual-sign Ed25519 + ML-DSA-44 |
| `env` | string | yes | Logical environment label, e.g. `live` or `sandbox` |
| `ts` | uint | yes | Unix time in **seconds** (UTC) of issuance. **Not** renamed to `iat` — that wire name belongs to the attestation/verify **sibling** body; this format freezes `ts` (schema 1). |
| `nonce` | bytes(32) | yes | Fresh uniqueness salt |
| `tenant` | string | yes | Opaque tenant id (not a mutable display name) |
| `receipt_id` | string | yes | Issuer receipt id |
| `input_hash` | bytes(32) | yes | SHA-256 of the **input material** as bound by the issuer |
| `output_hash` | bytes(32) | yes | SHA-256 of the **output material** as bound by the issuer |
| `weights_digest` | bytes(32) | yes | SHA-256 of the **weights artifact** *W* (preimage below) |
| `enclave_measurement` | bytes(32) | yes | Primary runtime measurement (e.g. Nitro **PCR0** of the EIF) |

### 4.1 Weights preimage (normative)

```
weights_digest = SHA-256(W)
```

- If a single file or single contiguous blob is loaded: *W* is those exact bytes.  
- If multiple files: for each relative path in **lexicographic UTF-8 order**, append  
  `uint64_be(len(path_utf8)) || path_utf8 || uint64_be(len(content)) || content`.  
- *W* MUST NOT include archive headers, compression wrappers, timestamps, or host metadata.

### 4.2 Input / output preimages

Issuers MUST document how `input_hash` and `output_hash` are formed for their product.  
When the delivery channel is HTTP, a **separate** payment-layer digest MAY bind the **decoded HTTP entity body** (after `Content-Encoding` removal); that digest is **not** a field of this body unless the product defines `output_hash` to be exactly that preimage.

---

## 5. Envelope and signatures

### 5.1 Logical envelope

An issued receipt is an **envelope** containing:

1. The **canonical body** (encoding fixed per implementation; CBOR or JSON with a frozen canonicalization rule — both MUST be versioned and test-vectored)  
2. **Key id** `kid` (32 bytes recommended) identifying the verifying public keys  
3. **Ed25519 signature** (64 bytes)  
4. **ML-DSA-44 signature** (2420 bytes) for class **full**  

Informative arity: five-element envelope (version, body, kid, ed25519_sig, ml_dsa_sig) has been used in production implementations; the normative requirement is dual-sig **full** class completeness, not a specific CBOR tag layout.

### 5.2 Verification (full class)

1. Parse envelope; reject malformed arity / lengths.  
2. Resolve `kid` against a **caller-supplied** keyset (or a pinned HTTPS keyset URL the verifier trusts).  
3. Recompute the body preimage under the fixed domain context.  
4. Verify Ed25519 and ML-DSA-44; both MUST succeed for **full**.  
5. Check `schema` / `alg` supported.  
6. Apply verifier policy on `ts`, `env`, and key status (active / retired / revoked).  

**Offline-by-default:** verification MUST NOT require a network call when the keyset and receipt bytes are already local. Network is only for optional key fetch or optional public-ledger inclusion (§7).

### 5.3 Exit / result codes (CLI-oriented, informative)

| Code | Meaning |
|------|---------|
| 0 | Valid (and inclusion valid if requested) |
| 1 | Usage / IO / incomplete inputs |
| 2 | Invalid receipt or inclusion |

---

## 6. What the receipt does *not* claim

Normative **non-claims** (product language MUST respect these):

1. **Not training provenance.** No statement about datasets, copyright, or training runs.  
2. **Not payment authority.** Does not prove a human or agent was authorized to spend.  
3. **Not global delivery proof alone.** A hash without the corresponding bytes held by the verifier is not delivery proof *to that verifier*.  
4. **Not a substitute for key trust.** Verifiers must obtain authentic public keys out of band or via a pinned key distribution channel.

---

## 7. Optional: public day inclusion

A receipt MAY be included in a **daily Merkle ledger** under:

| Binding | Value |
|---------|--------|
| Leaf identity | `request_id = receipt_id` |
| Endpoint label | product-defined constant (informative example: `pcrzero.pom.infer.v1`) |
| Units | typically `1` per receipt |

Inclusion proofs (event path + tenant path + checkpoint package + anchors) are **orthogonal** to dual-sign verify. A verifier MAY:

1. Verify the receipt offline (§5), then  
2. Verify inclusion against a **caller-supplied** checkpoint and anchors (zero phone-home if all files local).

---

## 8. Optional: payment binding (x402 and similar)

Payment protocols (e.g. **x402**) MAY attach a receipt by **reference**, not by rewriting §4:

| Layer | Role |
|-------|------|
| This format (§4–§5) | Content-bound dual-sign body |
| Payment extension envelope | Settlement id (`transaction` **xor** `commitmentId` **xor** explicit unbound), optional HTTP **decoded-entity** `contentHash`, pointer `receipt_id` / fetch URL |

Rules of composition:

- Frozen body fields MUST NOT be redefined by the payment envelope.  
- If both a payment-layer `contentHash` and `output_hash` exist, the product MUST document whether they share a preimage.  
- Batch settlement schemes MUST use a **commitment identifier**, not a fake transaction hash.

A separate draft extension key (a product-specific extension key) and an upstream `offer-receipt` v2 delta are **product / standards tracks**, not required to implement this format.

---

## 9. Test vectors

A conforming implementation MUST ship:

1. At least one **valid** dual-sign vector (golden body + signatures + keys)  
2. At least one **invalid** signature vector  
3. Boundary tests for weights multi-file preimage ordering  

Vector format SHOULD be language-neutral JSON (hex fields) so independent implementations can assert the same intermediates.

**Reference vectors (this repository):** [`inference-receipt-vectors-v1.json`](./inference-receipt-vectors-v1.json)  
(schema freeze companion; dual-sign golden + invalid cases).

---

## 10. Versioning

| Change type | Action |
|-------------|--------|
| New optional field, ignore-unknown safe | New minor doc revision; `schema` stays 1 only if signing preimage unchanged |
| Signing preimage or required field change | **New `schema` integer** + new domain context string |
| Alg suite change | New `alg` code + conformance class update |

---


## 11. Security considerations (summary)

| Threat | Mitigation in this format |
|--------|---------------------------|
| Cross-product signature replay | Domain context string |
| Key confusion | Explicit `kid` + keyset status |
| PQ-only or classical-only downgrade | Conformance class labels |
| Settlement / payment confusion | Payment binding outside body (§8) |
| Header size for dual-sig | Prefer fetch-by-reference for large envelopes |

Full threat models for payment binding and gateway emission live in separate design documents.

---

## 12. References (informative)

- FIPS 204 (ML-DSA)  
- Ed25519  
- x402 specifications (payment extensions; settlement schemes including batch-settlement)  

---

