Decision Receipt Specification — v1.0

An open, portable, cryptographically verifiable record of a single decision made or supported by an AI agent. Designed to be verified by anyone, on any node, without trusting the issuer.

Status: Stable · v1.0 · Reference implementation: this server · License: open. The fields, hashing rules and signature scheme defined here are normative — any conforming implementation must reproduce identical receipt hashes for identical bodies.

1. Design goals

2. Receipt object

All fields are required unless explicitly marked optional. Field order in transport is irrelevant — canonicalization is by sorted keys.

{
  "version": "1.0",
  "id": "STR-1A2B3C4D5E",
  "type": "decision_receipt",
  "sequence": 42,
  "agent": { "id": "agt_xxxxxxxx", "name": "FinanceBot" },
  "model": { "provider": "openai", "name": "gpt-4o", "version": "2026.4" },
  "decision": {
    "type": "loan_rejection",
    "input_hash":  "sha256:…",
    "output_hash": "sha256:…",
    "risk_level":  "high",
    "human_review": true,
    "permissions": ["credit.decide"],
    "policies":    ["eu-ai-act-high-risk"]
  },
  "metadata": { "request_id": "req_001" },
  "timestamp": "2026-06-07T10:00:00.000Z",
  "previous_hash": "sha256:…",
  "receipt_hash":  "sha256:…",
  "signature": { "algorithm": "ed25519", "public_key": "…", "value": "…" }
}

3. Field reference

FieldTypeRequiredNotes
versionstringyesSpec version. Always "1.0" for this revision.
idstringyesGlobally unique receipt identifier (issuer-assigned).
typestringyesAlways "decision_receipt" for receipts conforming to this spec.
sequenceintegeryesPer-agent monotonically increasing counter, starting at 1.
agent.idstringyesStable public identifier for the agent.
agent.namestringyesHuman-readable agent name at the time of signing.
modelobjectyesProvider, model name and version that produced the decision.
decision.typestringyesDecision class (e.g. loan_approval, content_moderation).
decision.input_hashstringyessha256:HEX over the canonical input. Computed by the client; raw input never sent.
decision.output_hashstringyessha256:HEX over the canonical output. Computed by the client; raw output never sent.
decision.risk_levelstringyesOne of low, medium, high, critical.
decision.human_reviewbooleanyestrue if a qualified human reviewed the decision before it took effect.
decision.permissionsstring[]optionalScopes this specific decision claimed to exercise. Used to detect scope violations against the agent's declared allow-list.
decision.policiesstring[]optionalPolicy / regulatory frame identifiers (e.g. eu-ai-act-high-risk).
metadataobjectoptionalFree-form, non-sensitive context. Must not contain raw decision data.
timestampstringyesRFC 3339 / ISO 8601 UTC, millisecond precision.
previous_hashstringyessha256:HEX of the previous receipt for the same agent, or sha256:GENESIS for the first.
receipt_hashstringyesSee §4.
signatureobjectyesSee §5.

4. Canonicalization & receipt_hash

  1. Take the receipt object and remove the receipt_hash and signature fields.
  2. Serialize the remainder as JSON with keys sorted lexicographically at every depth, using UTF-8 and no insignificant whitespace.
  3. Compute sha256 over those bytes; emit it as sha256:HEX (lowercase).
  4. Set receipt_hash to that value.

Any conforming implementation that runs steps 1–3 on a receipt must produce a value identical to the receipt's stored receipt_hash. This is how third parties verify body integrity without trusting the issuer.

5. Signature

The signature object has three fields:

{
  "algorithm":  "ed25519",
  "public_key": "<base64 raw 32-byte Ed25519 public key>",
  "value":      "<base64 Ed25519 signature over the UTF-8 bytes of receipt_hash>"
}

Verification:

  1. Recompute receipt_hash per §4. It must equal the stored value.
  2. Verify the Ed25519 signature.value against the UTF-8 bytes of receipt_hash using signature.public_key.

6. Append-only ledger

For a given agent, receipts form a chain ordered by sequence. Each receipt's previous_hash equals the prior receipt's receipt_hash; the first receipt uses sha256:GENESIS. Walking the chain and recomputing each hash (§4) and signature (§5) is sufficient to detect any modification, insertion or deletion of past receipts.

The reference implementation exposes this walk as GET /api/v1/verify/ledger.

7. Verification surface (reference implementation)

GET /api/v1/receipts/{id}/verify — verifies a receipt stored on the issuing node.

POST /api/v1/verify — verifies any receipt JSON against §4 and §5, no relationship with the issuer required.

GET /api/v1/verify/ledger — walks the full agent ledger per §6.

GET /api/v1/agents/{id}/passport — derived, signed Trust Passport summary (see Trust Passport).

GET /.well-known/signatrust.json — machine-readable discovery document advertising all conformant endpoints.

8. Compliance & non-goals

9. Versioning

Implementations must reject receipts whose version they do not recognize. Backwards-incompatible changes will bump the major version. Compatible additions (new optional fields) keep the major version.

Reference implementation: this Signatrust node · Verify any receipt at /verify · Inspect an agent's passport at /passport.