ModelRig Quickstart Routing & reliability Route bundles Probes Bake-offs & replay How it fits Grade protocol Optimization loop Caching lifecycle Bring your traces (OTLP) Observe a pipeline Migration playbook (T0–T2) Recognition playbooks Tenants & statements Published receipts Provenance & trust Artifact content custody The MCP oracle Use-case templates Template: ticket triage Template: document extraction Template: CS next action Template: lead qualification Template: compliance review Template: catalog cleansing Template: call disposition QA Template: financial classification Template: medical classification Leaderboard

Receipts — what gets published, what never does

A receipt is a signed, published record of what ModelRig measured on one bake-off, run, or route. It is the one document shape (Receipt@v1) that six growth loops ride: a customer (or ModelRig, for launch reports) can publish any receipt as a login-free page anyone can verify — without the public path ever touching a database, and without any content ever leaving the org.

Hook: See. Grade. Improve. A receipt is the evidence behind "Improve" — the measured proof a swap carries, not an assertion.

What a receipt contains

Receipt@v1 (modelrig/receipts):

FieldWhat
kindbakeoff · regret · run · fact-sheet (+ masking-proof, egress, disclosure, statement, launch-report as their missions land)
issuer.org_aliasthe org's chosen public alias — never org_id
subject.*_aliasroute/task/pipeline names, aliased by default
measurednumbers, booleans, enums, hashes, identifiers — scores, counts, CIs, n, costs
modelsprovider/model (+ snapshot) compared
honest_limitsverbatim claim-ceiling lines from the producing spec
hashsha256:<hex> over the canonical JSON of everything above
signatureEd25519 (alg, key_id, sig) over the hash

What NEVER gets published

The classification gate (isReceiptSafe, property-tested) runs before anything is signed or written and refuses (fail-closed) a receipt where:

So: content never leaves. What would be content is a hash or a count.

Aliasing

Route, task, and pipeline names are aliased by default — the published object shows route-a1b2c3, not your internal route name. The alias is a stable, non-reversible label (per-org); the raw→alias mapping never leaves the org (only the fact that a field was aliased, as aliases.<field> = "aliased"). An org can opt to reveal a field per publish (reveal: { route: true }).

Publishing, listing, revoking

This deletes only ModelRig's own published receipt object (in the public public/receipts/* key space). It is unrelated to artifact content custody, where customer bytes under {org_id}/{artifact_id} remain write-once.

Residual limit (honest): the public /v1/r/:id JSON is served with a short cache (public, max-age=300), not an immutable one. A reader (or CDN) that cached a 200 within the last 5 minutes before a revoke may briefly still see that cached copy until the entry expires; after ≤5 min every fresh read returns 410. This is the deliberate trade for cache efficiency — a revoke is not instantaneous across already-warm downstream caches, but it is bounded to 5 minutes, and the origin object is gone immediately.

visibility: "recipient" publishes to one recipient: the 128-bit receipt id is the capability. No listing endpoint exposes it, so anyone holding the link can read the receipt until revoked. Used for TB-1 statements and D3 disclosures ("send this link to your customer").

Verify — by API

GET /v1/verify/:id re-fetches the published object, re-canonicalizes it, re-hashes it, and checks the signature → { valid, hash, key_id, issued_at }. Any byte changed since publication makes valid false. This route, like GET /v1/r/:id and the badge, never queries a database — it is fed by the published object alone (public = published data only).

Verify — by hand

The public keys are served at GET /.well-known/modelrig-receipts.json ({ keys: [{ key_id, public_key, alg }] }, public_key = base64 SPKI DER).

1. Fetch the receipt JSON from /v1/r/<id>. 2. Drop hash and signature; canonicalize the rest (JCS: keys sorted recursively, arrays in order, no whitespace, UTF-8). 3. sha256 the canonical bytes → compare to the receipt's hash (as sha256:<hex>). 4. Verify the Ed25519 signature.sig (base64) over the hash string against the public key whose key_id matches signature.key_id.


import { createPublicKey, verify } from "node:crypto";
const r = await (await fetch(`${BASE}/v1/r/${id}`)).json();
const { hash, signature, ...body } = r;
const canon = JSON.stringify(sortKeysRecursively(body)); // JCS-style
const recomputed = "sha256:" + createHash("sha256").update(canon, "utf8").digest("hex");
const { keys } = await (await fetch(`${BASE}/.well-known/modelrig-receipts.json`)).json();
const k = keys.find((k) => k.key_id === signature.key_id);
const pub = createPublicKey({ key: Buffer.from(k.public_key, "base64"), format: "der", type: "spki" });
const ok = recomputed === hash &&
  verify(null, Buffer.from(hash, "utf8"), pub, Buffer.from(signature.sig, "base64"));

Honest limits

A published receipt proves what was measured on the stated n. It is not an audit, not a certification, and not a guarantee about future traffic. The one sanctioned line on a receipt is "measured by ModelRig — verify" — a pointer to the check, never an endorsement. Recipient links are capability URLs: anyone holding the link can read the receipt until it is revoked.