



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,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC3339]  Klyne, G. and C. Newman, "Date and Time on the Internet:
              Timestamps", RFC 3339, July 2002,
              <https://www.rfc-editor.org/info/rfc3339>.

   [RFC6234]  Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms
              (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011,
              <https://www.rfc-editor.org/info/rfc6234>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, May 2017,
              <https://www.rfc-editor.org/info/rfc8174>.

   [RFC8259]  Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
              Interchange Format", STD 90, RFC 8259, December 2017,
              <https://www.rfc-editor.org/info/rfc8259>.

   [RFC8792]  Watsen, K., Auerswald, E., Farrel, A., and Q. Wu,
              "Handling Long Lines in Content of Internet-Drafts and
              RFCs", RFC 8792, June 2020,
              <https://www.rfc-editor.org/info/rfc8792>.




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,
              <https://www.usenix.org/conference/usenixsecurity19/
              presentation/torres-arias>.

   [PROV-DM]  Moreau, L., Ed. and P. Missier, Ed., "PROV-DM: The PROV
              Data Model", W3C Recommendation, April 2013,
              <https://www.w3.org/TR/prov-dm/>.

   [RFC6962]  Laurie, B., Langley, A., and E. Kasper, "Certificate
              Transparency", RFC 6962, June 2013,
              <https://www.rfc-editor.org/info/rfc6962>.

   [RFC8785]  Rundgren, A., Jordan, B., and S. Erdtman, "JSON
              Canonicalization Scheme (JCS)", RFC 8785, June 2020,
              <https://www.rfc-editor.org/info/rfc8785>.

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]
