Receipt spec · telos/0.1-unsigned

The receipt envelope, exactly as minted.

Every observed action mints one unsigned integrity-hash evidence receipt. This page documents the envelope the telos-receipt package actually produces today, not an aspirational one. The receipt declares its own signing status; nothing here asks you to assume more than the record supports.

The receipt object

Canonical fields. Anything outside payload is metadata and intentionally outside the hash, so the same logical payload always yields the same hash regardless of when it was served.

FieldTypeWhat it records
receipt_version"telos/0.1-unsigned"Which contract produced this receipt. The name states the unsigned status on its face.
kindstringThe record type. action_governed is one reviewed action; other kinds share the same envelope.
agent_idstringWhich agent did the work. A label the operating team assigns.
payloadobjectThe hashed part: everything the record commits to. Must be JSON-native and finite; values with no canonical JSON form are refused at mint time rather than hashed nondeterministically.
payload.action_namestringThe action the agent took.
payload.action_params_hash"sha256:<hex>"SHA-256 commitment to the exact parameters. Raw arguments are never echoed, so the receipt is shareable without leaking content.
payload.verdictenumThe review outcome, from the public verdict vocabulary below.
payload.composite_scorenumberOverall score of the action against its purpose anchor. Calibration cutoffs are not published; we publish method, not calibration.
payload.scoresobjectPer-dimension scores behind the composite.
payload.pa_idstringThe purpose anchor: the declared, human-specified purpose the action was measured against.
issued_atiso8601When the receipt was issued. Metadata, not hashed.
integrity_hash"sha256:<hex>"Key-free SHA-256 over the canonical JSON of payload. Anyone can recompute it offline.
covered_fieldsstringStates exactly what the hash covers, in the receipt itself.
signing_status"unsigned_integrity_hash"The receipt's own declaration that it is unsigned. No reader can mistake the hash for a signature.
signaturenullNull in this contract version. When the signing ceremony lands, a real signature fills this field and signing_status flips, with no change to the envelope shape.
enginestringWhich engine produced the payload. The v0.1 default label states plainly that no governance engine is wired to it yet.
The verdict vocabulary

The verdict set is public: the shape of every outcome a review can record. The numeric thresholds that map a score to a verdict are not published.

These are raw descriptive schema values recorded by observation. A value never permits, blocks, or controls execution.

EXECUTERaw schema value, translated publicly as "within purpose". The action sat close to the declared purpose; noted, and the work went on.
CLARIFYRaw schema value, translated publicly as "question raised for review". The record carries a question for the human.
ESCALATERaw schema value, translated publicly as "surfaced for human review". The read routes to a person, and the human decision becomes part of the record.
A real receipt

Minted with telos-receipt 0.1.0 and verified offline before publication. Demo action, fixed timestamp, reproducible hash. The raw artifact is at sample-receipt.json.

sample-receipt.jsonunsigned · integrity hash
{
  "receipt_version": "telos/0.1-unsigned",
  "kind": "action_governed",
  "agent_id": "demo-agent",
  "payload": {
    "action_name": "send_customer_email",
    "action_params_hash": "sha256:0dabfdde7ab240266e7798c834c13ada37921438e2bbcc3140d6845185ebc29d",
    "verdict": "EXECUTE",
    "composite_score": 0.92,
    "scores": {
      "purpose_alignment": 0.94,
      "scope_discipline": 0.91,
      "risk_review": 0.9
    },
    "pa_id": "pa::demo::v1"
  },
  "issued_at": "2026-07-01T12:00:00+00:00",
  "integrity_hash": "sha256:5c4eb662d34f9e0a142e138c0697fd6923e630277794b2059845dae5c965217a",
  "covered_fields": "payload (canonical JSON, sort_keys, compact separators)",
  "signing_status": "unsigned_integrity_hash",
  "signature": null,
  "engine": "telos v0.1 (unsigned integrity-hash; no governance engine wired)"
}
Canonicalization & verification

The canonical form is Python's json.dumps(payload, sort_keys=True, separators=(",", ":")) with default ASCII escaping: keys sorted, no insignificant whitespace, non-ASCII characters escaped as \uXXXX. Same payload in, same hash out, on every run and every machine. Values with no canonical JSON form (non-finite floats, non-JSON types, circular references) are refused at mint time.

  1. Read the receipt's payload and its integrity_hash.
  2. Recompute SHA-256 over the canonical JSON bytes of payload.
  3. Compare. A match confirms the payload has not changed relative to the recorded hash. A mismatch means the payload was altered relative to that hash.

What a match does not establish: who issued the receipt, or when. The hash is key-free, so a holder could mint a fresh payload with a matching hash. Authorship and time need a digital signature, which this contract version does not carry; the receipt says so in its own signing_status field. Run the check on the verify page or in four lines of stdlib Python.

For agents

Validate receipts programmatically against the JSON Schema before relying on one you are handed, and read the envelope's own signing_status rather than assuming.

receipt-spec.schema.json →

Purpose In. Proof Out.

The work leaves evidence.

jb@telos-labs.ai