Network Working Group S. Saha Internet-Draft Independent Intended status: Standards Track 8 September 2026 Expires: 12 March 2027 Stage Receipts: A Verifiable Record Format for Staged Pipelines draft-saha-stage-receipts-00 Abstract A staged pipeline -- a document-ingestion flow, a retrieval-augmented generation chain, an agent workflow, a benchmark -- produces results that are hard to reproduce, hard to diff between two runs, and hard to localize when they go wrong. This document defines the stage receipt: a small, canonically serialized JSON record that each stage of such a pipeline emits, describing exactly what went in, what came out, under which pinned instrument, with which outcome, and linked by digest to the receipt before it. A chain of stage receipts lets a developer reproduce a run, diff two runs to the first stage that differs, and localize a fault to the stage where it entered; the same chain lets an independent party, later and offline, establish what the records assert without trusting whoever produced them. The document specifies the record, its canonical form, the chain manifest, the coverage and emission declarations that make a chain honest about its own edges, the anchoring declaration that separates consistency from originality, and the behaviour required of a conforming verifier. Golden conformance vectors -- records that must be accepted and records that must be refused, each with its reason -- are part of the specification. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 12 March 2027. Saha Expires 12 March 2027 [Page 1] Internet-Draft Stage Receipts September 2026 Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Scope and Applicability . . . . . . . . . . . . . . . . . 4 1.2. Relationship to Other Work . . . . . . . . . . . . . . . 5 1.3. Requirements Language . . . . . . . . . . . . . . . . . . 6 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6 3. Design Principles . . . . . . . . . . . . . . . . . . . . . . 7 4. The Stage Receipt . . . . . . . . . . . . . . . . . . . . . . 8 4.1. Value Types . . . . . . . . . . . . . . . . . . . . . . . 9 4.2. format . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.3. run_id and stage . . . . . . . . . . . . . . . . . . . . 10 4.4. prev . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.5. time . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.6. instrument . . . . . . . . . . . . . . . . . . . . . . . 10 4.7. inputs and outputs . . . . . . . . . . . . . . . . . . . 11 4.8. assertions . . . . . . . . . . . . . . . . . . . . . . . 12 4.9. outcome . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.10. External Effects . . . . . . . . . . . . . . . . . . . . 13 5. Canonical Serialization and Digest . . . . . . . . . . . . . 13 6. The Chain Manifest . . . . . . . . . . . . . . . . . . . . . 14 7. What a Digest Stands For . . . . . . . . . . . . . . . . . . 15 8. Coverage and Boundaries . . . . . . . . . . . . . . . . . . . 16 9. Emission Semantics . . . . . . . . . . . . . . . . . . . . . 17 10. Anchoring: Consistency and Originality . . . . . . . . . . . 18 11. Verifier Behaviour . . . . . . . . . . . . . . . . . . . . . 19 11.1. Five Constraints . . . . . . . . . . . . . . . . . . . . 19 11.2. Three Outcomes . . . . . . . . . . . . . . . . . . . . . 19 11.3. Required Checks . . . . . . . . . . . . . . . . . . . . 20 11.3.1. Serialization . . . . . . . . . . . . . . . . . . . 20 11.3.2. Self-description . . . . . . . . . . . . . . . . . . 20 11.3.3. States That Must Not Collapse . . . . . . . . . . . 20 11.3.4. Coverage . . . . . . . . . . . . . . . . . . . . . . 20 11.3.5. Chain . . . . . . . . . . . . . . . . . . . . . . . 20 Saha Expires 12 March 2027 [Page 2] Internet-Draft Stage Receipts September 2026 11.3.6. Anchoring . . . . . . . . . . . . . . . . . . . . . 21 11.4. What a Verifier Must Not Do . . . . . . . . . . . . . . 21 12. Operations on Chains . . . . . . . . . . . . . . . . . . . . 21 12.1. Diff . . . . . . . . . . . . . . . . . . . . . . . . . . 21 12.2. Localize . . . . . . . . . . . . . . . . . . . . . . . . 22 12.3. Reproduce . . . . . . . . . . . . . . . . . . . . . . . 22 13. Conformance . . . . . . . . . . . . . . . . . . . . . . . . . 22 14. Versioning . . . . . . . . . . . . . . . . . . . . . . . . . 23 15. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23 16. Security Considerations . . . . . . . . . . . . . . . . . . . 23 17. Privacy Considerations . . . . . . . . . . . . . . . . . . . 25 18. References . . . . . . . . . . . . . . . . . . . . . . . . . 25 18.1. Normative References . . . . . . . . . . . . . . . . . . 25 18.2. Informative References . . . . . . . . . . . . . . . . . 26 Appendix A. Golden Vectors . . . . . . . . . . . . . . . . . . . 26 A.1. A Chain That Verifies . . . . . . . . . . . . . . . . . . 26 A.2. Ten Records That Must Be Refused . . . . . . . . . . . . 31 Appendix B. Open Requirements . . . . . . . . . . . . . . . . . 33 Appendix C. Editor's Notes for This Revision . . . . . . . . . . 34 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 35 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 35 1. Introduction Most pipelines that transform data through several stages keep logs. Logs are prose about what happened; they are written for the operator, in the operator's vocabulary, and they are only as complete as the operator remembered to make them. When a run produces a wrong answer, the questions that follow -- which stage changed its output since the last good run; can this run be repeated; where exactly did the bad data enter; is what is deployed the same thing that was approved -- are answered, if at all, by reading logs and guessing. A stage receipt is the alternative this document proposes: a record each stage emits, in a fixed shape, containing digests of the bytes that entered and left it, the identity and pinned version of the component that ran, the constants its assertions depend on, its outcome, and the digest of the receipt that preceded it. The record is serialized in a canonical form so that its digest is the same on every platform, and it never contains its own digest, so that the chain rather than the record is the proof of its final state. The immediate beneficiary is the developer. Given two chains, the first receipt whose input digests, instrument version, configuration digest or output digest differ is the stage where two runs diverged. Given one chain and the pipeline's code, the stages that declare themselves re-derivable can be run again from their recorded inputs and their outputs compared byte for byte. Given a chain with a bad Saha Expires 12 March 2027 [Page 3] Internet-Draft Stage Receipts September 2026 result, the first receipt whose outcome is not "ok", or whose recorded output does not match what the next stage consumed, is where the fault entered. None of these operations requires trusting the producer, a network, a key, or a service. The same properties serve a second reader: someone who was not present, holds only the records, and needs to establish what they assert. This document is careful about what such a reader can and cannot establish. A chain whose links all verify is consistent with itself; it is not thereby shown to be the chain that was made, because an operator holding every copy can rewrite one record and recompute every later link. Only anchoring to a commitment the operator cannot rewrite converts consistency into originality, and this document requires every record to say which of the two it offers. 1.1. Scope and Applicability This document specifies the receipt (Section 4), its canonical serialization and digest (Section 5), the chain manifest (Section 6), the subjects a digest may stand for (Section 7), coverage, emission and anchoring declarations (Sections 8, 9 and 10), verifier behaviour (Section 11), conformance (Section 13) and golden vectors (Appendix A). This revision applies to linear chains: a run whose stages form a sequence, in which each receipt has at most one predecessor and each retry of a stage is recorded as a distinct attempt with its own receipt. Fan-out, fan-in, branches, loops, compensation and partial commits, exactly-once versus at-least-once delivery, out-of-order arrival, and an ordering model for stages whose clocks disagree are not specified here. They are a recognized requirement of the format and the largest thing it does not yet do; a producer whose pipeline has such a topology MUST declare the boundary (Section 8) rather than flatten the topology into a sequence that did not occur. This document does not specify a transport, a storage system, a signature envelope, a key lifecycle, an anchoring mechanism, or a service. A receipt is bytes in a file; anything that moves or keeps those bytes is out of scope provided it does not alter them. Saha Expires 12 March 2027 [Page 4] Internet-Draft Stage Receipts September 2026 1.2. Relationship to Other Work Canonical JSON serialization has been specified before, notably the JSON Canonicalization Scheme [RFC8785]. The canonical form in this document (Section 5) is deliberately narrower: it forbids JSON numbers outright, because a format that serializes 500.00 as a number has already lost the distinction between "500.00" and "500", and that distinction has cost a real defect. A JCS serializer produces the same bytes as this document's canonical form for any object that contains no numbers, which is every conforming receipt. Provenance is an established discipline, and this document is an application of it rather than a replacement for it. The PROV data model [PROV-DM] describes entities, activities and agents as a graph; a chain of receipts is a linear instance of that graph in which every entity is identified by the digest of its bytes and every activity by a pinned instrument, and a receipt chain can be projected into PROV without loss. Lineage-event conventions used by data platforms emit run and dataset events to a collecting service; a receipt is instead a file whose checkability depends on no service, which Section 11.1 requires. Software-supply-chain attestation frameworks, of which in- toto [INTOTO] is the reference, record, for each build step, digests of the materials consumed and the products produced, signed by the party that ran the step and checked against a layout that names the expected steps; that is the nearest relative of a stage receipt. A receipt applies the same idea to a runtime data pipeline and adds what a build step does not need: an outcome class in which refusal is a result, a coverage declaration that states where the chain does not see, an emission policy, an anchor declaration, and trust classes on artifacts -- while leaving signatures to a later revision rather than making them a precondition of checkability. Observability tooling -- traces, spans, metrics and logs -- records what a system is doing for the people who operate it, sampled and retained for a period, in the operator's vocabulary. A receipt records what a run did to specific bytes, unsampled, for a reader who was not present and need not trust the operator. The two are complementary, and a producer that runs both SHOULD record the trace and span identifiers of the stage in the receipt's "assertions" and the receipt's digest as an attribute of the span, so that either record leads to the other. Software bill-of-materials formats describe what a component is made of. A receipt's instrument declaration (Section 4.6) names and pins the component that ran a stage and is intended to carry, in a later revision, a per-receipt dependency record aligned with those formats; it does not replace them. Saha Expires 12 March 2027 [Page 5] Internet-Draft Stage Receipts September 2026 Transparency logs and timestamping services provide commitments an operator cannot rewrite. This document does not select one; it requires a record to declare whether it is anchored to any such commitment and, if so, to what (Section 10). Per-action authorization of agent actions -- whether a proposed action may be performed now -- is a decision made before an action runs. A stage receipt is a record made after a stage ran. The two compose: an authorization decision's evidence can be recorded as an input to the stage it governed, and the stage's receipt can be the report that closes the decision. Neither depends on the other. 1.3. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2. Terminology Run: One execution of a pipeline, identified by a run identifier chosen by the producer. Stage: One step of a run that consumes inputs and produces outputs under a single instrument. A retry of a stage is a distinct stage attempt. Receipt: The record a stage emits, as specified in Section 4. "Stage receipt" and "receipt" are used interchangeably. Chain: The ordered receipts of one run, each linked to its predecessor by digest, together with the chain manifest. Manifest: The record that lists a chain's receipts, their digests and the chain head (Section 6). Distinct from the pipeline manifest, below. Pipeline manifest: The producer's description of the approved pipeline -- its stages and the pinned components expected to run them -- whose digest each receipt cites. Its format is not specified here; its digest is. Instrument: The component that ran a stage: a converter, a chunker, a retriever, a model, a verifier, a benchmark harness. An instrument is named and pinned or the stage's receipt is invalid. Saha Expires 12 March 2027 [Page 6] Internet-Draft Stage Receipts September 2026 Producer: The party, and by extension the software, that emits receipts. Verifier: Software that checks receipts and chains against this document, reporting PASS, FAIL or NOT RUN for each property (Section 11). Consumer: Any reader of receipts other than a verifier: a diff tool, a replay tool, a person, a model. Artifact: Bytes that entered or left a stage. A receipt carries an artifact's digest, size, media type, name and trust class, never the artifact itself. Trust class: The declared origin of an artifact's content: operator- authored, model-generated, or externally-sourced (Section 4.7). Re-derivable stage: A stage that, run again from its recorded inputs under its pinned instrument, produces the same output bytes. Its receipt is a receipt in the full sense. Declared stage: A stage that cannot promise repeatability -- a call to a hosted model, an external system answering from world state -- whose record freezes exactly what went in and came out and says on its face that replay is not promised. A declaration is weaker than a receipt and is labelled as weaker. Coverage: The relation between the stages a run declared it would emit and the stages that emitted; and the declared boundaries beyond which the chain does not see (Section 8). Anchor: A commitment, outside the producer's control, to a chain head or a root over many chain heads, made at a stated cadence (Section 10). Digest: The SHA-256 [RFC6234] hash of a sequence of bytes, written as the string "sha256:" followed by 64 lowercase hexadecimal digits. 3. Design Principles The rules in later sections follow from a small number of principles, stated here so that a case this document does not anticipate can be decided the same way. Saha Expires 12 March 2027 [Page 7] Internet-Draft Stage Receipts September 2026 1. *A record describes itself.* Every receipt names its format, its run, its stage, its instrument, the constants its assertions depend on, and the zone of every time it carries. A reader needs nothing outside the record to know what the record claims. 2. *Bytes are the record.* A receipt is the exact bytes of its canonical serialization, not any equivalent of them. Its digest is over those bytes. A verifier compares bytes; it does not normalize nearly-canonical bytes into canonical ones. 3. *A record never contains its own digest.* A record cannot contain the proof of its own final state. The digest lives in the next receipt and in the manifest. 4. *Absent, declared-none and recorded are three states.* A field that is missing, a field that says there is nothing, and a field that records something are distinguishable and round-trip distinguishably. A failed measurement is not a measured zero. 5. *A refusal is a result.* A stage that declined to produce output records that it declined and why. A format that records only successes describes a happy path. 6. *What cannot be established is reported, not implied.* A verifier has three outcomes, never two. A record that is not anchored says so, and a verifier repeats it. 7. *Checkability depends on no one.* A conforming verifier needs no network, key, account, licence, or live third party. Evidence whose checkability needs a living authority inherits that authority's lifespan. 8. *The verifier does not judge the work.* A well-formed record of a wrong answer verifies. Whether the pipeline was correct is a question for a different tool, whose output is written beside the records and never into them. 4. The Stage Receipt A stage receipt is a JSON [RFC8259] object with exactly the thirteen members of Table 1, serialized in canonical form (Section 5). Every one of them is REQUIRED. A receipt lacking any of them is invalid. Saha Expires 12 March 2027 [Page 8] Internet-Draft Stage Receipts September 2026 +============+================+=============+ | Member | Type | Defined in | +============+================+=============+ | format | string | Section 4.2 | +------------+----------------+-------------+ | run_id | string | Section 4.3 | +------------+----------------+-------------+ | stage | object | Section 4.3 | +------------+----------------+-------------+ | prev | string or null | Section 4.4 | +------------+----------------+-------------+ | time | object | Section 4.5 | +------------+----------------+-------------+ | coverage | object | Section 8 | +------------+----------------+-------------+ | emission | object | Section 9 | +------------+----------------+-------------+ | anchor | object | Section 10 | +------------+----------------+-------------+ | instrument | object | Section 4.6 | +------------+----------------+-------------+ | inputs | array | Section 4.7 | +------------+----------------+-------------+ | outputs | array | Section 4.7 | +------------+----------------+-------------+ | assertions | object | Section 4.8 | +------------+----------------+-------------+ | outcome | object | Section 4.9 | +------------+----------------+-------------+ Table 1: Required members of a stage receipt 4.1. Value Types Member values are JSON strings, objects, arrays, or the literal null where this document permits it. *JSON numbers MUST NOT appear anywhere in a receipt.* Every numeric quantity -- a byte count, a stage index, a threshold, a count -- is carried as a decimal string, exactly as the producer measured or configured it, with its precision intact. This document defines no member whose value is a JSON boolean; the members that carry a truth value carry the strings "true" and "false". Unknown members MAY appear. They are part of the bytes and therefore of the digest, but a verifier MUST NOT interpret them and a producer MUST NOT rely on them for any semantics this document assigns to a defined member. The member names "receipt_digest" and "receipt_id" are reserved and MUST NOT appear (Section 5). Saha Expires 12 March 2027 [Page 9] Internet-Draft Stage Receipts September 2026 4.2. format The string "stage-receipt/0.1". A verifier that encounters a different value proceeds as described in Section 14. 4.3. run_id and stage "run_id" is a non-empty string chosen by the producer, unique among that producer's runs. Its structure is not specified. "stage" is an object with two REQUIRED members: "index", a decimal string giving the receipt's one-based position in the chain, and "name", a non-empty string naming the stage. The name of a stage SHOULD match the name the pipeline manifest gives it, since coverage (Section 8) is computed over names. A retried stage is a new stage attempt with the next index; the producer MAY record the attempt number in "assertions" and SHOULD keep the name unchanged. 4.4. prev The digest of the exact bytes of the preceding receipt in the chain, or the literal null for the first receipt of a run. A receipt with index "1" MUST carry null; every other receipt MUST carry a digest. This member is what makes the chain a chain: editing any earlier receipt changes its digest, which breaks the link in every later receipt. 4.5. time An object with two REQUIRED members, "started" and "ended", each a timestamp in the Internet profile of ISO 8601 [RFC3339] including its UTC offset or the designator "Z". A timestamp without its zone is half a timestamp; a verifier MUST reject it. Fractional seconds are permitted. "ended" MUST NOT precede "started". These are the producer's clock readings. Nothing in a receipt makes them true; anchoring (Section 10) is what lets a reader bound when a record existed. 4.6. instrument An object naming and pinning the component that ran the stage. The REQUIRED members are: id: A non-empty string naming the instrument. kind: A string classifying it (for example "retriever", "cross- Saha Expires 12 March 2027 [Page 10] Internet-Draft Stage Receipts September 2026 encoder", "generator", "verifier"). Values are not enumerated by this document. version: A non-empty string. A version string that does not identify a single, immutable build of the instrument, such as "latest", does not pin it; a producer MUST NOT emit one. manifest_digest: The digest of the pipeline manifest under which the stage was approved to run. A receipt whose "manifest_digest" is empty or absent cannot be compared with anything and MUST be refused by a verifier; the conforming producer behaviour when the manifest is unknown is to refuse to emit, not to emit a blank. config_digest: The digest of the instrument's effective configuration for this stage, in a serialization the producer documents. rederivable: The string "true" if running the stage again from its recorded inputs under this instrument produces the same output bytes, or "false" if the producer cannot promise that. When "false", the member "rederivable_note" SHOULD state why, so that a reader knows the record is a declaration (Section 2) and a replay tool knows not to attempt it. A record whose instrument cannot be named or pinned is not a weak record; it is not a record. The rejection vector R02 (Appendix A) exists for this case. 4.7. inputs and outputs Each is an array, possibly empty, of artifact references. An empty array is a statement that the stage consumed, or produced, nothing -- the declared-none state of Section 3 -- and is distinct from the member being absent, which is invalid. The third golden receipt records a stage that produced no output and says so with an empty array and a "refused" outcome. An artifact reference is an object with the REQUIRED members: name: A string naming the artifact within the stage. media_type: The artifact's media type as a string. bytes: The artifact's size in bytes, as a decimal string. digest: The digest of the artifact's stored bytes, computed as Section 7 requires for the artifact's kind. Saha Expires 12 March 2027 [Page 11] Internet-Draft Stage Receipts September 2026 trust_class: Exactly one of "operator-authored" (content the pipeline's operator or its code constructed), "model-generated" (content produced by a model), or "externally-sourced" (content that arrived from outside the pipeline, including user input and retrieved documents). Any other value, or the member's absence, MUST be refused. The trust class does not make externally-sourced content safe. It makes its origin visible to every downstream reader, human or model, which is the most a record format can promise. A consumer that feeds artifact content to a model SHOULD carry the trust class with it. An output of one stage that is an input of the next SHOULD appear in both receipts with the same digest; the difference between the two, when there is one, is itself a finding (Section 12.2). 4.8. assertions An object in which the producer records what the stage asserts about its work: counts, thresholds, derived quantities, references to corpus manifests, prompt digests. Its members are not enumerated by this document, with one exception: if "assertions" is non-empty, it MUST contain a member "constants", an object naming every transform constant -- tokenizer, join rule, batch size, top-k, threshold, offset unit -- on which the other assertions depend. A relation that holds only under an unstated constant tests the constant, not the relation. The empty object is permitted and means the stage asserts nothing beyond its inputs, outputs and outcome. A count in "assertions" is testimony unless the receipt states how it was derived. A producer SHOULD record the derivation of any aggregate (as the fourth golden receipt does for a zero) so that a consumer can recompute it rather than believe it. 4.9. outcome An object whose REQUIRED member "class" is exactly one of: ok: The stage completed and its outputs are what it produced. A stage MUST NOT report "ok" for a check it did not perform; if a stage's purpose is to check something and the check could not be established, the class is "refused" or "error", never "ok". refused: The stage declined to produce a result, by its own contract. The members "reason" (a string) and, where useful, "detail" SHOULD say why. A refusal is a result; the chain continues. Saha Expires 12 March 2027 [Page 12] Internet-Draft Stage Receipts September 2026 error: The stage failed. The members "status", "body" and "origin" are REQUIRED: what the failing component reported, the body of that report, and which component it was. An error without its body is a status code wearing an explanation, and a verifier MUST refuse it (vector R06). Other members MAY be present. The class is the only member a verifier interprets. 4.10. External Effects A stage that acts on the world -- sends a message, writes to an external system, places an order -- produces an effect whose state is not one of its output bytes. A receipt for such a stage SHOULD carry the OPTIONAL member "effects", an array of objects each with the REQUIRED members "target" (a string naming the external system) and "state", exactly one of "attempted", "returned-a-response", or "confirmed-by-the-external-system", and the OPTIONAL member "evidence", an artifact reference for the response or confirmation bytes. These are three states, not one state with three names. "attempted" says the request left; "returned-a-response" says something came back, whose bytes may be recorded; "confirmed-by-the-external-system" says the external system's own record agrees. A consumer MUST NOT read the first as the third, and a producer MUST NOT promote a state it did not observe. // Marked for re-read after the pathology fixtures: the exact // evidence a confirmation requires is expected to be sharpened by // them. 5. Canonical Serialization and Digest A receipt, a chain manifest, and any other object this document digests is serialized in the following canonical form. A file holding a receipt contains exactly these bytes and nothing else. 1. The encoding is UTF-8 without a byte-order mark. 2. Object members are ordered by the Unicode code points of their names, ascending, comparing code point by code point. 3. No whitespace appears outside string literals. 4. No JSON numbers appear. Every numeric value is a decimal string (Section 4.1). Saha Expires 12 March 2027 [Page 13] Internet-Draft Stage Receipts September 2026 5. The values NaN, Infinity, negative Infinity and negative zero do not exist in this format and cannot be represented. 6. String contents are encoded as UTF-8 and are not escaped beyond what JSON requires: the quotation mark, the reverse solidus, and the control characters U+0000 through U+001F. Non-ASCII characters appear as themselves, not as \u escapes. 7. The serialization ends with the closing brace of the object. No trailing newline, no trailing whitespace. 8. The object does not contain the members "receipt_digest" or "receipt_id", or any member whose value is the digest of the object itself. The digest of an object is SHA-256 [RFC6234] over its canonical bytes, written as "sha256:" followed by 64 lowercase hexadecimal digits. The digest of a file is SHA-256 over the file's bytes; for a conforming receipt these are the same thing, and a verifier establishes that they are (Section 11.3.1). A serializer that reads a JSON object, sorts its members, and writes it without whitespace produces this form, provided it refuses numbers. In particular, a serializer conforming to [RFC8785] produces identical bytes for any object that satisfies rules 4 and 8. The reference canonicalizer published with the golden vectors is twenty lines and is the normative statement of this section in executable form; where prose and code disagree, the disagreement is a defect in this document and the vectors decide. Line endings, byte-order marks, path length and file-system normalization are named traps. A producer that writes a receipt through a text layer that converts line endings has not written a receipt; a verifier that reads one through such a layer will report a false mismatch. Receipts are read and written as binary. 6. The Chain Manifest A run's receipts are listed by a chain manifest: a JSON object in canonical form with the REQUIRED members: format: The string "stage-receipt-chain/0.1". run_id: The run identifier, equal to that of every receipt listed. chain: An array of objects in receipt order, each with the members Saha Expires 12 March 2027 [Page 14] Internet-Draft Stage Receipts September 2026 "index" (decimal string), "stage" (the stage name), "file" (a path relative to the manifest, using "/" as separator) and "digest" (the digest of that file's bytes). chain_head: The digest of the last receipt in "chain". anchor: An anchor declaration for the chain as a whole, in the form of Section 10. The manifest MAY carry other members. It is itself digested in canonical form when it is anchored or listed by a root over many chains. The chain is valid when, for every receipt, "prev" equals the digest listed for the preceding receipt (null for the first), the listed digest equals the digest of the file's bytes, and "chain_head" equals the digest of the last receipt. A chain with a missing receipt is not a chain with a gap; it is a chain that fails, and the emission declaration (Section 9) is how a producer records an absence it knew about rather than leaving a verifier to discover one. 7. What a Digest Stands For A digest in a receipt is only as meaningful as the rule that says which bytes it was computed over. This section fixes that rule for each kind of subject. A producer MUST digest each subject as stated and MUST record in "assertions.constants" any parameter this section says is declared. File bytes (binary artifacts: documents, images, packages, model weights). The file exactly as stored, with no transformation of any kind. Text artifacts (converted text, cleaned text, prompts, answers). Normalized once, at write time, to UTF-8 with LF line endings and no byte-order mark; written to the store; then digested as file bytes. The normalization is done when the artifact is written, never when it is verified. A receipt MAY note the normalization so that a reader who receives the text through a lossy channel can reconstitute the exact bytes. Chunks and spans (parts of a digested parent). A chunk's digest is over the UTF-8 bytes of the chunk text under the text rule. Its location is a pair of offsets into the parent's stored bytes, and the offset unit -- bytes or code points -- MUST be declared in "constants". A record that does not name its offset unit cannot be checked. A pipeline that records containment lineage instead of stored spans -- each chunk names Saha Expires 12 March 2027 [Page 15] Internet-Draft Stage Receipts September 2026 its parent and is verifiably a substring of the parent under a declared join rule -- MUST declare which of the two profiles it uses; the derivation of a span at check time is itself a stage with the three outcomes unique, ambiguous (with the occurrence count), and not found. Manifests and other set-valued outputs (chunk sets, ranked results, a census). Serialized in canonical form and digested. Arrays keep the stage's declared order -- sequence, rank -- because the order is part of what the stage asserts. Merkle roots (large sets; anchoring many chains). Leaves are item digests in manifest order; adjacent pairs are concatenated as raw 32-byte values and hashed; the process repeats to the root. The rule for an odd leaf MUST be declared; the reference rule promotes the odd leaf unchanged. Inclusion proofs and a tampered-member rejection vector are expected in a later revision (Appendix B). The receipt itself. Canonical form including "prev"; the digest is what the next receipt's "prev" and the manifest cite. Wire bytes (external calls: request and response). The raw bytes as sent and as received, captured at the transport boundary, before parsing, re-serialization or pretty-printing. The parsed object is not what was received; only the received bytes are evidence. Secrets, credentials and personal data. Never digested into anything. A digest of a secret is a commitment that can never be unwound once published, and a value inside a published preimage is frozen the moment the first hash is published (Section 16). 8. Coverage and Boundaries "coverage" is an object with the REQUIRED members: declared_stages: The ordered names of the stages the pipeline manifest expects the run to emit. emitting_stages: The names of the stages that have emitted a receipt in this run, as known at the time this receipt was emitted. boundaries: An array, possibly empty, of objects each naming a point Saha Expires 12 March 2027 [Page 16] Internet-Draft Stage Receipts September 2026 beyond which the chain does not see: a stage that runs outside the producer's instrumentation, an upstream system whose output is taken on trust, a downstream consumer that is not receipted. Each has the REQUIRED members "name" and "kind" (a string; values not enumerated here) and MAY carry "note". completeness: Exactly one of "complete" or "incomplete". Never absent. "complete" is a claim and a verifier checks it: every declared stage MUST appear among the emitting stages, and "boundaries" MUST be empty. A receipt that asserts "complete" while a declared stage is missing is lying about its own edges, and a verifier MUST fail it (vector R07), not warn. Coverage is derived by the producer from the manifest and the run, never typed by hand. Its purpose is the following rule, which binds every consumer of these records: *where coverage is "incomplete", no consumer may assert a root cause across an undeclared boundary.* A tool that cannot see the edge of its own chart will eventually report confidently about something it never observed. The claim this document permits a producer to make of a chain is, accordingly, bounded: for the receipted portion of a workflow, an independent verifier can determine whether the executed topology and component versions matched the approved manifest -- and nothing about the unreceipted portion. A run may legitimately be "incomplete": a pipeline with a non-linear region (Section 1.1) declares it as a boundary and receipts the linear portions on either side. That is the honest shape. Flattening the region into a sequence that did not run is not. 9. Emission Semantics "emission" is an object with the REQUIRED members: policy: Exactly one of "fail-closed" (the stage does not run, or its result is discarded, if its receipt cannot be written) or "fail- open" (the stage runs and its result stands even if its receipt cannot be written). gaps: An array, possibly empty, of objects each recording a receipt the producer knows it failed to write: the REQUIRED members "stage" (the name), "index" (decimal string) and "reason" (a string). Saha Expires 12 March 2027 [Page 17] Internet-Draft Stage Receipts September 2026 The policy is chosen by the operator at configuration time and MUST be declared; a producer MUST NOT default it. A policy the operator did not choose is a policy they cannot be held to. Under either policy an absence is recorded as a declared gap, in the next receipt that is written and in the manifest. Fail-open does not mean that errors disappear; it means the pipeline continued and the record says where it did so unreceipted. A gap makes the run's coverage "incomplete" (Section 8) with the gap as a boundary. 10. Anchoring: Consistency and Originality "anchor" is an object with the REQUIRED member "state", exactly one of "anchored" or "unanchored". Absence is a failure (vector R08): "unanchored" is a state, not a silence. When "state" is "unanchored", the member "reason" SHOULD say why. When "state" is "anchored", the following members are REQUIRED: kind: A string naming the class of commitment: for example a commit or tag in a version-control history the producer does not control, an entry in an append-only transparency log (of which [RFC6962] is one kind), a timestamp attestation over a root. Values are not enumerated by this document. reference: A string by which a reader can locate the commitment. subject: The digest that was committed: this chain's head, or a root over many chain heads under the Merkle rule of Section 7, in which case "proof" carries the inclusion path. cadence: A string stating how often the producer anchors. The cadence is the tamper window: a record can be rewritten without detection until the next anchor. This section is the most important in the document, and it is short because what it says is simple. A chain whose links all verify proves that its records are consistent with one another. It does not prove that they are the records that were made: an operator who holds every copy can rewrite one, recompute every later "prev", and produce a chain that verifies. *A hash proves a record is consistent with itself, never that it is the record that was made.* Only a commitment the operator cannot rewrite converts consistency into originality, and only the anchor's cadence bounds how stale that conversion is. This revision specifies the declaration, not a mechanism. A declaration is the part a format can require and a verifier can test. Whether a given anchor is in fact unrewritable is a property of the Saha Expires 12 March 2027 [Page 18] Internet-Draft Stage Receipts September 2026 system that holds it, is not testable from the records, and is not claimed by any conforming producer or verifier. A verifier reports originality as NOT RUN on every unanchored record, with that reason, so that a green chain can never be read as more than it is. 11. Verifier Behaviour A verifier answers one question: can a stranger, holding only these records, establish what they assert, without trusting whoever produced them? Everything in this section follows from that, including the refusals. 11.1. Five Constraints A conforming verifier: 1. requires no network access -- not for schemas, revocation, telemetry, or anything else; 2. requires no key, account, or licence; 3. requires no live third party; 4. is implementable from this document and the golden vectors alone; and 5. never mutates the records it checks. These are not implementation preferences. A verifier that violates any of them has re-created the dependence the format exists to remove. The publisher of a conforming verifier is correspondingly bound: it MUST NOT operate a certificate authority, key escrow, or any service on which a record's checkability depends. 11.2. Three Outcomes For every property it checks, a verifier reports exactly one of: PASS: the property was established; FAIL: the property was contradicted, and the verifier emits what it found; NOT RUN, with reason: the property could not be established. The reason is REQUIRED; an unexplained skip is a failure of the verifier. Saha Expires 12 March 2027 [Page 19] Internet-Draft Stage Receipts September 2026 A verifier that reports only pass and fail will eventually report PASS for something it did not check. A verifier MUST NOT be silent about a property this section requires it to check. 11.3. Required Checks 11.3.1. Serialization The file's bytes are the canonical serialization of the object they encode -- identical, not equivalent (vector R10). No JSON number appears (R01). The object contains no reserved self-referential member (R09). 11.3.2. Self-description Every required member is present. The instrument is named and pinned (R02). Every non-empty "assertions" names its constants (R04). Every timestamp carries its zone (R03). Every artifact reference declares a permitted trust class (R05). 11.3.3. States That Must Not Collapse The outcome class is one of the three permitted values. An "error" outcome carries status, body and origin (R06). An empty array and an absent member are distinguished, and the verifier reports which it found. 11.3.4. Coverage "completeness" is present and is one of its two values. Where it is "complete", every declared stage is an emitting stage and there are no boundaries; a contradiction is a FAIL (R07). Where it is "incomplete", the verifier reports the boundaries and gaps it found and reports the originality of anything beyond them as NOT RUN. 11.3.5. Chain Each receipt's "prev" equals the digest of the preceding receipt's bytes. Each digest in the manifest equals the digest of the named file's bytes. "chain_head" equals the last receipt's digest. Saha Expires 12 March 2027 [Page 20] Internet-Draft Stage Receipts September 2026 11.3.6. Anchoring "anchor.state" is present and is one of its two values (R08). Where it is "unanchored", the verifier MUST report originality as NOT RUN with the stated reason. Where it is "anchored", the verifier reports the declaration's presence and well-formedness and MUST NOT report the anchor as established unless it has itself resolved the reference -- which, under Section 11.1, it cannot do online. A verifier MAY accept a locally supplied copy of the commitment and report against it, saying so. 11.4. What a Verifier Must Not Do * *Not infer.* An absent member is absent, not defaulted. * *Not repair.* No normalization of nearly-canonical bytes into canonical ones. * *Not rank, score or opine.* It reports; it does not interpret. An interpreter's output is testimony and is written beside the records, never into them. * *Not judge the work.* A well-formed record of a wrong answer verifies. The verifier says nothing about whether the pipeline was correct, the retrieval relevant, or the answer true. * *Not require its own producer.* A verifier that accepts records only from one producer has certified an implementation, not a format. A verifier MUST NOT be able to tell, from the records alone, which producer emitted them, except where the instrument declaration deliberately says so. 12. Operations on Chains The verifier establishes that records are what they claim. The operations in this section are what a developer does with records that have been established. They are defined here so that two tools performing them on the same chains reach the same answers; they read only the records and, for replay, the pipeline's own code. 12.1. Diff Given two chains of the same pipeline, the diff is the first index at which the receipts differ in any of: the digests of their inputs, the instrument's "id", "version" or "config_digest", the "constants", or the digests of their outputs -- reported in that order, so that a changed input is not mistaken for a changed instrument. Timestamps, "run_id" and "prev" are excluded from the comparison. Two chains Saha Expires 12 March 2027 [Page 21] Internet-Draft Stage Receipts September 2026 that differ nowhere but in those members ran the same pipeline on the same bytes and produced the same bytes. 12.2. Localize Given one chain, localization walks it in order and reports the first receipt whose outcome class is not "ok"; whose declared output digest is not the input digest the next receipt records for the same artifact; or whose coverage records a gap or boundary. The report names the stage and which of the three conditions held. A localization that crosses a declared boundary stops there and says so (Section 8). 12.3. Reproduce Given one chain and the pipeline's code at the versions the receipts pin, reproduction runs each stage whose instrument declares "rederivable" as "true" from the artifacts its receipt records as inputs, and reports per stage whether the output bytes' digest equals the recorded output digest. Stages declared not re-derivable are reported as NOT RUN with the instrument's note as the reason. A reproduction that reaches an artifact it does not hold reports NOT RUN for that stage rather than substituting. Reproduction produces a new chain; it never rewrites the old one, and a corrected run is a new version of the result, never an undo of the previous one. 13. Conformance A *conforming producer* emits receipts that contain exactly the required members with the value constraints of Section 4, serialized as Section 5 requires, digested as Section 7 requires, linked as Section 6 requires, with coverage derived rather than typed, with an operator-declared emission policy, and with an anchor declaration on every receipt. It refuses to emit rather than emit a receipt whose instrument it cannot name and pin. Every receipt it emits MUST verify, and it MUST NOT emit any of the ten rejection vectors' defects. A *conforming verifier* satisfies the five constraints of Section 11.1, reports the three outcomes of Section 11.2, performs every check of Section 11.3, and does none of the things in Section 11.4. It MUST report PASS on the golden chain of Appendix A.1 with exactly the NOT RUN outcomes that chain's anchor declarations require, and it MUST refuse each of the ten rejection vectors of Appendix A.2 *for the stated reason*. Refusing the right file for the wrong reason is a failing test that happens to look green. Saha Expires 12 March 2027 [Page 22] Internet-Draft Stage Receipts September 2026 A verifier that requires knowledge of which framework or producer emitted a record, beyond what the instrument declaration states, does not conform. One verifier checking records from several independent producers, blind, is the bar this document is aimed at; if such a verifier cannot be written, the format has dialects and this document has failed. Conformance says nothing about whether a pipeline is correct, a model good, a system fast, a record tamper-resistant, or a deployment certified. None of those is tested by anything in this document and none may be claimed on its authority. 14. Versioning The "format" member carries "stage-receipt/MAJOR.MINOR". Within a major version, a minor revision MAY add optional members, permitted values of unenumerated strings, and required checks that only fail on records the earlier minor already forbade; it MUST NOT remove a required member, change a member's type, or change the canonical form. A verifier MUST accept any minor version of the major it implements and MUST report NOT RUN, with a version reason, for any check the record's minor version did not define. A major revision MAY change required semantics. A verifier that encounters a record whose "format" is a major version it does not implement -- including the pre-standard value "stage- receipt/0.0-preview", which corresponds to this document's golden chain before its format string was assigned -- MUST report NOT RUN with the version as the reason. It MUST NOT report PASS, since it did not check the record against the rules the record claims, and it MUST NOT report FAIL, since the record contradicted nothing the verifier knows. 15. IANA Considerations This document has no IANA actions. A later revision may register the media type "application/stage-receipt+json" for receipts and "application/stage-receipt-chain+json" for chain manifests; nothing in this revision depends on such registration. 16. Security Considerations *Consistency is not originality.* The central security property of this format is stated in Section 10 and is repeated here because it is the one most likely to be misread: a chain that verifies is consistent with itself and nothing more. An operator can rewrite an unanchored chain without detection. A reader who treats verification as proof of history has been misled by the reader, not the record, Saha Expires 12 March 2027 [Page 23] Internet-Draft Stage Receipts September 2026 and the format's defence is to require every record and every verifier to say so out loud. The anchor cadence is the tamper window; a producer choosing a cadence is choosing how long a rewrite can go unnoticed. *Digests are commitments.* A published digest of a secret, a credential, or a personal record is a commitment to bytes that can never be withdrawn; anyone who later obtains the bytes can prove they existed at anchoring time. Artifacts MUST be reviewed as publishable before their digests are anchored, and secrets are never digested into anything (Section 7). Low-entropy artifacts -- a short answer, a yes-or-no field, a small set of candidates -- can be recovered from their digests by enumeration; a producer that needs to record such a value without disclosing it MUST use a keyed or salted construction outside this document and record the construction's identity in "constants". *Records are data, not instructions.* Artifact contents, names, notes and reasons in a receipt are written by the producer and, through externally-sourced inputs, by parties the producer does not control. A consumer that feeds any of them to a model MUST treat them as untrusted content and SHOULD carry the trust class alongside them. The trust class makes origin visible; it does not make content safe. *The verifier is a target.* A verifier parses attacker-controlled bytes. It MUST bound the size of what it reads, MUST NOT follow paths in a manifest outside the manifest's directory, and MUST NOT execute, fetch, or resolve anything a record names. The constraint that it requires no network is also a defence: a verifier that cannot reach anything cannot be made to. *Signatures are not specified.* This revision binds no record to an actor. A signature envelope and a key lifecycle are recognized requirements, sequenced behind actor identity (Appendix B). Until they exist, a receipt's "instrument" and a manifest's "anchor" say what ran and where the head was committed, not who vouches for either. *What is not defended.* The format is tamper-evident to the extent of its anchoring and not tamper-resistant at all. It does not prevent a producer from emitting false records; it makes a false record cost a consistent lie across every later record and every anchor, and it makes the absence of an anchor visible. Deployment isolation between tenants, the integrity of the host, and the honesty of the operator are outside what any record can establish. Saha Expires 12 March 2027 [Page 24] Internet-Draft Stage Receipts September 2026 17. Privacy Considerations A receipt carries digests, sizes, names, media types, timestamps and operator-written notes; it does not carry artifact content. Names and notes are free text and a producer MUST NOT place personal data in them. Timestamps at millisecond precision, combined with stage names, can identify a person's interaction with a system; a producer that publishes chains SHOULD consider whether the run identifiers and times it publishes are themselves personal data. An anchored digest of an artifact that contains personal data is a permanent commitment to that data's existence, which may conflict with an obligation to erase it. Erasure of the artifact does not erase the commitment. Producers subject to such obligations SHOULD NOT anchor digests of artifacts that may need to be erased, or SHOULD digest them through a keyed construction whose key can be destroyed, recording the construction in "constants" so that the record remains self-describing. 18. References 18.1. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997, . [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, July 2002, . [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017, . [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, December 2017, . [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, "Handling Long Lines in Content of Internet-Drafts and RFCs", RFC 8792, June 2020, . Saha Expires 12 March 2027 [Page 25] Internet-Draft Stage Receipts September 2026 18.2. Informative References [INTOTO] Torres-Arias, S., Afzali, H., Kuppusamy, T. K., Curtmola, R., and J. Cappos, "in-toto: Providing farm-to-table guarantees for bits and bytes", Proceedings of the 28th USENIX Security Symposium, August 2019, . [PROV-DM] Moreau, L., Ed. and P. Missier, Ed., "PROV-DM: The PROV Data Model", W3C Recommendation, April 2013, . [RFC6962] Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, June 2013, . [RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, June 2020, . Appendix A. Golden Vectors The files in this appendix are part of the specification. Long lines are folded as described in [RFC8792]; a receipt's bytes are recovered by unfolding, and the SHA-256 of the recovered bytes is given in each figure's title so that the unfolding can be checked before anything else is. The same objects were published on 2026-09-11, before this document, as a preview under the format string "stage- receipt/0.0-preview"; that edition differs from this one only in the format strings and, consequently, in every digest. A.1. A Chain That Verifies One run of a four-stage pipeline: retrieve, rerank, generate, verify. The third receipt records a refusal -- the generator produced no claim that could be bound to a retrieved passage -- and the fourth records zero claims examined and states how the zero was derived. Every receipt declares itself unanchored, so a conforming verifier reports PASS for every other property and NOT RUN, with that reason, for originality: on this chain, 103 PASS, 0 FAIL, 4 NOT RUN. The artifacts the digests reference are not published; the structure is the point. Saha Expires 12 March 2027 [Page 26] Internet-Draft Stage Receipts September 2026 ========== NOTE: '\' line wrapping per RFC 8792 =========== {"anchor":{"reason":"preview sample; epoch anchoring is a declared r\ equirement and is not implemented","state":"unanchored"},"assertions\ ":{"candidate_count":"1500","constants":{"join":"blank-line","tokeni\ zer":"unicode-nfkc-lower","top_k":"1500"},"corpus_manifest":"sha256:\ b3d5f7a9c1e3d5b7f9a1c3e5d7b9f1a3c5e7d9b1f3a5c7e9d1b3f5a7c9e1d3b5"},"\ coverage":{"boundaries":[],"completeness":"complete","declared_stage\ s":["retrieve","rerank","generate","verify"],"emitting_stages":["ret\ rieve","rerank","generate","verify"]},"emission":{"gaps":[],"policy"\ :"fail-closed"},"format":"stage-receipt/0.1","inputs":[{"bytes":"57"\ ,"digest":"sha256:9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c0219\ 0ecf1e430635ab","media_type":"text/plain","name":"question","trust_c\ lass":"externally-sourced"}],"instrument":{"config_digest":"sha256:2\ a7d9e4b1c8f0356ae2d4b6c8f1a3e5d7b9c0f2a4e6d8b0c2f4a6e8d0b2c4f6a","id\ ":"bm25+dense-hybrid","kind":"retriever","manifest_digest":"sha256:6\ f1b1c0d4a2e9d7c3b58ae0f21d4c6b98e7a5f30c1d2e4b6a8093f5c7e1d2b4a","re\ derivable":"true","version":"1.4.0"},"outcome":{"class":"ok"},"outpu\ ts":[{"bytes":"184213","digest":"sha256:0d5c1a8f3e7b2946d0c8a1f5e39b\ 7d2c460a8e1f3b5d7c9a0e2f4b6d8c0a2e4f","media_type":"application/json\ ","name":"candidates","trust_class":"operator-authored"}],"prev":nul\ l,"run_id":"run-2026-09-11-0001","stage":{"index":"1","name":"retrie\ ve"},"time":{"ended":"2026-09-11T09:14:02.774+02:00","started":"2026\ -09-11T09:14:02.118+02:00"}} Figure 1: receipts/01-retrieve.json (SHA-256 3a3e67631b62fbf8107a12b989a97f16072b487d54b18e64ac0eabbcb54fe673) Saha Expires 12 March 2027 [Page 27] Internet-Draft Stage Receipts September 2026 ========== NOTE: '\' line wrapping per RFC 8792 =========== {"anchor":{"reason":"preview sample; epoch anchoring is a declared r\ equirement and is not implemented","state":"unanchored"},"assertions\ ":{"chance_floor":"3.88","constants":{"batch_size":"32","max_input_t\ okens":"512","score_order":"descending","truncation":"auto"},"scored\ _pairs":"1500"},"coverage":{"boundaries":[],"completeness":"complete\ ","declared_stages":["retrieve","rerank","generate","verify"],"emitt\ ing_stages":["retrieve","rerank","generate","verify"]},"emission":{"\ gaps":[],"policy":"fail-closed"},"format":"stage-receipt/0.1","input\ s":[{"bytes":"184213","digest":"sha256:0d5c1a8f3e7b2946d0c8a1f5e39b7\ d2c460a8e1f3b5d7c9a0e2f4b6d8c0a2e4f","media_type":"application/json"\ ,"name":"candidates","trust_class":"operator-authored"}],"instrument\ ":{"config_digest":"sha256:5e7c9a1f3d5b7e9c1a3f5d7b9e1c3a5f7d9b1e3c5\ a7f9d1b3e5c7a9f1d3b5e7c","id":"reranker-a","kind":"cross-encoder","m\ anifest_digest":"sha256:233902d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0c2e4b6d8\ f0a2c4e6b8d0f2a4c6e8","rederivable":"true","version":"pinned"},"outc\ ome":{"class":"ok"},"outputs":[{"bytes":"41120","digest":"sha256:7a9\ c1e3f5b7d9a1c3e5f7b9d1a3c5e7f9b1d3a5c7e9f1b3d5a7c9e1f3b5d7a9c","medi\ a_type":"application/json","name":"ranked","trust_class":"operator-a\ uthored"}],"prev":"sha256:3a3e67631b62fbf8107a12b989a97f16072b487d54\ b18e64ac0eabbcb54fe673","run_id":"run-2026-09-11-0001","stage":{"ind\ ex":"2","name":"rerank"},"time":{"ended":"2026-09-11T09:14:02.774+02\ :00","started":"2026-09-11T09:14:02.118+02:00"}} Figure 2: receipts/02-rerank.json (SHA-256 0765685137f1d693a9532e91e0bf691d258977c688b2a941eaa5da35b65cdf76) Saha Expires 12 March 2027 [Page 28] Internet-Draft Stage Receipts September 2026 ========== NOTE: '\' line wrapping per RFC 8792 =========== {"anchor":{"reason":"preview sample; epoch anchoring is a declared r\ equirement and is not implemented","state":"unanchored"},"assertions\ ":{"claims":[],"constants":{"prompt_digest":"sha256:3b5d7f9a1c3e5b7d\ 9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d"}},"coverage":{"bou\ ndaries":[],"completeness":"complete","declared_stages":["retrieve",\ "rerank","generate","verify"],"emitting_stages":["retrieve","rerank"\ ,"generate","verify"]},"emission":{"gaps":[],"policy":"fail-closed"}\ ,"format":"stage-receipt/0.1","inputs":[{"bytes":"41120","digest":"s\ ha256:7a9c1e3f5b7d9a1c3e5f7b9d1a3c5e7f9b1d3a5c7e9f1b3d5a7c9e1f3b5d7a\ 9c","media_type":"application/json","name":"ranked","trust_class":"o\ perator-authored"},{"bytes":"12904","digest":"sha256:e5c7a9f1d3b5e7c\ 9a1f3d5b7e9c1a3f5d7b9e1c3a5f7d9b1e3c5a7f9d1b3e5c7","media_type":"tex\ t/plain","name":"evidence_passages","trust_class":"externally-source\ d"}],"instrument":{"config_digest":"sha256:8d0f2a4c6e8b0d2f4a6c8e0b2\ d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f","id":"instrument-b","kind":\ "generator","manifest_digest":"sha256:c1e3a5f7d9b1c3e5a7f9d1b3c5e7a9\ f1d3b5c7e9a1f3d5b7c9e1a3f5d7b9c1e3","rederivable":"false","rederivab\ le_note":"generation is not bit-reproducible; the instrument is decl\ ared, the output is recorded, replay is not promised","version":"pin\ ned"},"outcome":{"class":"refused","detail":"the generator produce\ d no claim that could be bound to a retrieved passage; a refusal i\ s recorded, not an empty answer","reason":"contract: no claim surviv\ ed evidence binding"},"outputs":[],"prev":"sha256:0765685137f1d693a9\ 532e91e0bf691d258977c688b2a941eaa5da35b65cdf76","run_id":"run-2026-0\ 9-11-0001","stage":{"index":"3","name":"generate"},"time":{"ended":"\ 2026-09-11T09:14:02.774+02:00","started":"2026-09-11T09:14:02.118+02\ :00"}} Figure 3: receipts/03-generate.json (SHA-256 f1e74907f1c47ff905f2860d9213d00f084c1632d652580f8bde036ff80522b0) Saha Expires 12 March 2027 [Page 29] Internet-Draft Stage Receipts September 2026 ========== NOTE: '\' line wrapping per RFC 8792 =========== {"anchor":{"reason":"preview sample; epoch anchoring is a declared r\ equirement and is not implemented","state":"unanchored"},"assertions\ ":{"claims_contradicted":"0","claims_examined":"0","claims_supported\ ":"0","constants":{"contradiction_threshold":"0.60","support_thresho\ ld":"0.30"},"derivation":"counts recomputed from stage 3 outcome; ze\ ro claims were emitted, therefore zero were examined"},"coverage":{"\ boundaries":[],"completeness":"complete","declared_stages":["retriev\ e","rerank","generate","verify"],"emitting_stages":["retrieve","rera\ nk","generate","verify"]},"emission":{"gaps":[],"policy":"fail-close\ d"},"format":"stage-receipt/0.1","inputs":[],"instrument":{"config_d\ igest":"sha256:f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c\ 5e7b9d1f3a5","id":"claim-binder","kind":"verifier","manifest_digest"\ :"sha256:a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f\ 9a1c3","rederivable":"true","version":"0.3.1"},"outcome":{"class":"o\ k","note":"nothing to verify is a result, not an absence"},"outputs"\ :[],"prev":"sha256:f1e74907f1c47ff905f2860d9213d00f084c1632d652580f8\ bde036ff80522b0","run_id":"run-2026-09-11-0001","stage":{"index":"4"\ ,"name":"verify"},"time":{"ended":"2026-09-11T09:14:02.774+02:00","s\ tarted":"2026-09-11T09:14:02.118+02:00"}} Figure 4: receipts/04-verify.json (SHA-256 1549e9c85091af54d7fce8c2d2832427be9eeda26ed5a0b7af49352d44a74e1a) ========== NOTE: '\' line wrapping per RFC 8792 =========== {"anchor":{"reason":"preview sample; epoch anchoring is a declared r\ equirement and is not implemented","state":"unanchored"},"chain":[{"\ digest":"sha256:3a3e67631b62fbf8107a12b989a97f16072b487d54b18e64ac0e\ abbcb54fe673","file":"receipts/01-retrieve.json","index":"1","stage"\ :"retrieve"},{"digest":"sha256:0765685137f1d693a9532e91e0bf691d25897\ 7c688b2a941eaa5da35b65cdf76","file":"receipts/02-rerank.json","index\ ":"2","stage":"rerank"},{"digest":"sha256:f1e74907f1c47ff905f2860d92\ 13d00f084c1632d652580f8bde036ff80522b0","file":"receipts/03-generate\ .json","index":"3","stage":"generate"},{"digest":"sha256:1549e9c8509\ 1af54d7fce8c2d2832427be9eeda26ed5a0b7af49352d44a74e1a","file":"recei\ pts/04-verify.json","index":"4","stage":"verify"}],"chain_head":"sha\ 256:1549e9c85091af54d7fce8c2d2832427be9eeda26ed5a0b7af49352d44a74e1a\ ","format":"stage-receipt-chain/0.1","note":"Golden chain of draft-s\ aha-stage-receipts-00. Digests are over each file's exact bytes.","r\ un_id":"run-2026-09-11-0001"} Figure 5: MANIFEST.json (SHA-256 3e797cdb4882368d7016df8f44782f597e128d2366a6a4596bce4e3f2c8bc1b8) Saha Expires 12 March 2027 [Page 30] Internet-Draft Stage Receipts September 2026 A.2. Ten Records That Must Be Refused Each of the following is the first golden receipt with one defect introduced. A conforming verifier MUST refuse each one and MUST state the reason given. The exact bytes of each vector are obtained by applying the stated change to the first golden receipt and re- serializing in canonical form (except R10, whose defect is its serialization); the SHA-256 of the resulting file is given so that an implementer can confirm the vector was reconstructed correctly. R01 (R01-json-number.json): Change: "assertions.candidate_count" becomes the JSON number 1500. Reason: a JSON number where a decimal string is required ('500.00' and '500' must stay distinct). SHA-256 of the file: a331ddb798be868f0769ffcfecb9e50b 5979ed57be92b3ff9dab62934b4f8ee7 (one string; shown with a space for line width). R02 (R02-null-instrument.json): Change: "instrument.manifest_digest" becomes the empty string. Reason: instrument cannot be named or pinned; refusal is required, not a blank field. SHA-256 of the file: c1cc9258fa8f4c6e1969278a5dea85f9 db6c3afb1ffbe94e3e810051824ea1bb (one string; shown with a space for line width). R03 (R03-timestamp-no-zone.json): Change: "time.started" becomes "2026-09-11T09:14:02.118", with no offset. Reason: a timestamp without its zone is half a timestamp. SHA-256 of the file: ff99a81cd7c8320b840efbb1496f91cd 29c8cdd40643a290800bd859e182eb38 (one string; shown with a space for line width). R04 (R04-missing-constants.json): Change: "assertions.constants" is removed. Reason: an assertion that does not name its transform constants. SHA-256 of the file: 8f87aa87ca7731c5d131076f98d648da a5b01eddcee687e348e413594f0cd476 (one string; shown with a space for line width). Saha Expires 12 March 2027 [Page 31] Internet-Draft Stage Receipts September 2026 R05 (R05-untrusted-class.json): Change: "inputs[0].trust_class" becomes "unknown". Reason: an input with no declared trust class. SHA-256 of the file: 37be84ab9b559f0a919205964bf48b4e a8d7472cbbbeb007d4ba4df72e24785a (one string; shown with a space for line width). R06 (R06-error-without-body.json): Change: "outcome" becomes {"class":"error","status":"403"}. Reason: an HTTP error without its body is a status code wearing an explanation. SHA-256 of the file: fdddfe162027eac5fb57b0751a7cdf1e 1ad9738f3570c66c928472641d19ad0a (one string; shown with a space for line width). R07 (R07-coverage-lie.json): Change: "coverage.emitting_stages" becomes ["retrieve","rerank"]. Reason: 'complete' asserted while declared stages are missing from the emitting list. SHA-256 of the file: 6e678e5da16a5e3e7cd00bc9e69500c5 793e47e04f18e9451898df9fbbd2576c (one string; shown with a space for line width). R08 (R08-anchor-absent.json): Change: "anchor" is removed. Reason: anchor state absent rather than declared; unanchored is a state, not a silence. SHA-256 of the file: a5ae3bd9148df44e1848a31d3b3aa81d 6aaaf209ef451eff710d7feb58d30429 (one string; shown with a space for line width). R09 (R09-self-digest.json): Change: a member "receipt_digest" with the value "sha256:00" is added. Reason: a record may not contain the proof of its own final state. SHA-256 of the file: 9a068cc45f41a94981da22d8db97218f b34d9eedbd88bdd0e5144b97119037d4 (one string; shown with a space for line width). Saha Expires 12 March 2027 [Page 32] Internet-Draft Stage Receipts September 2026 R10 (R10-not-canonical.json): Change: the object is serialized with two-space indentation and newlines instead of in canonical form. Reason: pretty-printed; file bytes are not the canonical serialization. SHA-256 of the file: 891a20d03391b01112ade85dea864478 99e139d6908a71cd49111b77457d77f4 (one string; shown with a space for line width). A format with no rejection vectors has not specified anything; it has described a happy path and left every implementer to guess at the edges. Implementers are asked to publish the results of their verifier against both appendices, including any disagreement with the reference implementation. A disagreement between two independent verifiers is the most valuable report this document can receive, because it means the specification is ambiguous and the ambiguity was found before anyone depended on it. Appendix B. Open Requirements The format was specified against a register of thirteen requirements, each raised by a defect or a reviewer, and the register is published with the format's validation battery. This revision satisfies some, declares some, and leaves some standing. Naming the last group is the point of this appendix. +====+===============+=========================================+ | # | Requirement | This revision | +====+===============+=========================================+ | 1 | Merkle corpus | Root construction specified | | | manifest | (Section 7); inclusion proofs and a | | | | tampered-member vector deferred. | +----+---------------+-----------------------------------------+ | 2 | Epoch | Declaration specified (Section 10); | | | anchoring | mechanism not specified. | +----+---------------+-----------------------------------------+ | 3 | Tenant | Not specified; a tenant identifier is | | | isolation | expected in a later revision. | +----+---------------+-----------------------------------------+ | 4 | Signature | Not specified; sequenced behind actor | | | envelope | identity. | +----+---------------+-----------------------------------------+ | 5 | Per-receipt | Not specified; intended to align with | | | dependency | existing bill-of-materials formats. | | | record | | +----+---------------+-----------------------------------------+ Saha Expires 12 March 2027 [Page 33] Internet-Draft Stage Receipts September 2026 | 6 | Signing-key | Not specified; follows 4. | | | lifecycle | | +----+---------------+-----------------------------------------+ | 7 | Receipt | Linear chains and retries as attempts | | | topology | (Section 1.1); everything else declared | | | | as a boundary. The largest open item. | +----+---------------+-----------------------------------------+ | 8 | Disclosure | Partially met: a chain verifies with | | | layer | artifact contents withheld, since | | | | receipts carry digests only. | +----+---------------+-----------------------------------------+ | 9 | Coverage | Specified (Section 8). | | | attestation | | +----+---------------+-----------------------------------------+ | 10 | Content trust | Specified (Section 4.7). | | | class | | +----+---------------+-----------------------------------------+ | 11 | Emission | Specified (Section 9). | | | failure | | | | semantics | | +----+---------------+-----------------------------------------+ | 12 | Schema | Specified minimally (Section 14). | | | evolution | | +----+---------------+-----------------------------------------+ | 13 | External | Specified as an optional member | | | effect | (Section 4.10). | | | records | | +----+---------------+-----------------------------------------+ Table 2: Disposition of the thirteen requirements in this revision Appendix C. Editor's Notes for This Revision This section will be removed before publication as an RFC. The format was specified after its validation battery and before its reference implementation, in that order deliberately: the exam is published before the code it judges. The sections most likely to change when the battery's pathology fixtures are written against real code are Section 4.10, the error body requirements in Section 4.9, the boundary object in Section 8, and the gap object in Section 9. Each is marked in the text. Nothing in the canonical form, the required members, or the rejection vectors is expected to change. The preview verifier published with the samples predates this document and does not yet perform every check this document requires: it does not check that "complete" implies an empty "boundaries", that Saha Expires 12 March 2027 [Page 34] Internet-Draft Stage Receipts September 2026 "ended" does not precede "started", that "prev" is null exactly when "index" is "1", that "rederivable" is one of its two values, or that the manifest's "run_id" equals every receipt's. A conforming verifier performs all of them. Rejection vectors for each are expected in the next revision, since a requirement without a vector that fails is a requirement nobody has tested. Acknowledgements Three independent reviewers read the requirement register and the battery before this document was written. The coverage requirement and the wording of the bounded claim in Section 8 came from two of them separately; the topology requirement, the external-effect states and the observation that a format nobody wants on a Tuesday will not be installed came from the third. The defects that motivated the rejection vectors were the author's own. Author's Address Shamik Saha Independent Amsterdam Netherlands Email: shamik.saha.rcciit@gmail.com Saha Expires 12 March 2027 [Page 35]