Skip to main content

A SCITT Profile for AI-Agent Action Receipts
draft-noa-scitt-ai-agent-receipt-01

Document Type Active Internet-Draft (individual)
Author Tora Toraman
Last updated 2026-08-14
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-noa-scitt-ai-agent-receipt-01
SCITT                                                         T. Toraman
Internet-Draft                                                NordenSoft
Intended status: Standards Track                          15 August 2026
Expires: 16 February 2027

              A SCITT Profile for AI-Agent Action Receipts
                  draft-noa-scitt-ai-agent-receipt-01

Abstract

   This document profiles the IETF SCITT (Supply Chain Integrity,
   Transparency, and Trust) architecture for AI-agent action receipts:
   tamper-evident, signed, offline-verifiable records of what an
   autonomous agent was recorded as doing at the governed boundary,
   under which recorded principal class, with what recorded verdict, and
   -- where the issuer records one -- under which policy identity.  Each
   receipt is a signed record over a canonical JSON payload, hash-
   chained so that each record commits to its predecessor, and presented
   either bare -- the payload with its own native signature -- or
   enveloped in a COSE_Sign1.  This revision specifies how such a
   receipt is carried as a SCITT Signed Statement, with the protected
   claims a Transparency Service requires, so that a receipt can be
   registered.  Registration obtains a Transparency Service's signed
   proof that the statement was registered in its log -- a property a
   self-signed chain cannot provide alone.  It does not, by itself, give
   an offline holder non-equivocation: that requires consistency proofs
   and monitoring of the log, which this profile does not specify.  The
   profile makes a deliberately narrow, checkable claim: this is an
   issuer-authenticated, signature-verifiable, tamper-evident record of
   the action, the recorded principal class, the recorded verdict, and
   any policy identity the receipt carries.  It explicitly does not
   claim that the agent was correct, safe, or wise, that the recorded
   inputs were true or complete, that a named approver authorized this
   exact action before it ran, that a downstream controller succeeded,
   or that any physical effect occurred.  This revision separates those
   last three as distinct claims with independent failure behaviour,
   states the boundary of a shared action digest, and keeps a
   deterministic offline policy-replay capability out of scope.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

Toraman                 Expires 16 February 2027                [Page 1]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   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 16 February 2027.

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 the adjacent slot . . . . . . . . . . . . . . .   6
     1.2.  Relationship to other work  . . . . . . . . . . . . . . .   6
     1.3.  Requirements Language . . . . . . . . . . . . . . . . . .   7
     1.4.  Actors  . . . . . . . . . . . . . . . . . . . . . . . . .   7
     1.5.  What this profile does not define . . . . . . . . . . . .  10
   2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .  11
   3.  Receipt structure (payload) . . . . . . . . . . . . . . . . .  15
     3.1.  Field semantics and cross-field rules . . . . . . . . . .  17
     3.2.  Canonicalization parameters . . . . . . . . . . . . . . .  20
     3.3.  Optional members, and what their absence means  . . . . .  22
   4.  COSE Signed Statement profile . . . . . . . . . . . . . . . .  24
     4.1.  Protected header  . . . . . . . . . . . . . . . . . . . .  25
     4.2.  Payload binding, and the two signatures . . . . . . . . .  27
     4.3.  Carrying a receipt as an RFC 9943 Signed Statement  . . .  31
   5.  Hash-chaining and completeness  . . . . . . . . . . . . . . .  33
     5.1.  Chain-level failure axes  . . . . . . . . . . . . . . . .  34
     5.2.  Checkpoint structure  . . . . . . . . . . . . . . . . . .  40
   6.  Identity binding  . . . . . . . . . . . . . . . . . . . . . .  43
     6.1.  Who signed is not who approved  . . . . . . . . . . . . .  45

Toraman                 Expires 16 February 2027                [Page 2]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   7.  Registration in a Transparency Service  . . . . . . . . . . .  48
   8.  What a receipt does not claim about the external world  . . .  51
     8.1.  Three claims, three independent failures  . . . . . . . .  51
     8.2.  Validity and sufficiency are separate results . . . . . .  52
     8.3.  Absence is not a negative claim . . . . . . . . . . . . .  54
     8.4.  Why the base record is not extended . . . . . . . . . . .  55
   9.  Pre-execution authorization and post-execution evidence . . .  56
   10. The shared action digest boundary . . . . . . . . . . . . . .  57
   11. Policy replay is out of scope . . . . . . . . . . . . . . . .  59
   12. Implementation status . . . . . . . . . . . . . . . . . . . .  60
   13. Security Considerations . . . . . . . . . . . . . . . . . . .  73
   14. Privacy Considerations  . . . . . . . . . . . . . . . . . . .  77
   15. Open questions for the working group  . . . . . . . . . . . .  78
   16. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  81
   17. References  . . . . . . . . . . . . . . . . . . . . . . . . .  81
     17.1.  Normative References . . . . . . . . . . . . . . . . . .  81
     17.2.  Informative References . . . . . . . . . . . . . . . . .  83
   Appendix A.  Changes since -00  . . . . . . . . . . . . . . . . .  85
     A.1.  Interface stability, and the two corrections a citing
           document must act on  . . . . . . . . . . . . . . . . . .  85
     A.2.  What the author committed to on 23 July, item by item . .  90
     A.3.  Corrections this revision makes to -00's own text . . . .  91
   Appendix B.  Acknowledgments  . . . . . . . . . . . . . . . . . .  96
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  97

1.  Introduction

   An AI agent books the flight, moves the money, or tells a machine on
   a factory floor to move an object.  Afterwards someone asks a plain
   question: _what actually happened, and who can prove it?_

   Today the answer usually comes from the party that ran the agent: its
   own logs, its own summary, its own word.  This creates a first-party
   evidence problem when an action is disputed.

   This document defines a *receipt*: one small, signed record per
   governed agent action, describing what was done, under which recorded
   principal class, with what verdict, and -- when the issuer records it
   -- under which policy.  A bare receipt can be checked by anyone
   holding the issuing key; an enveloped one is checked against that key
   *and* the key that signed the envelope, which need not be the same
   (Section 4.2).  Either way the check needs no access to the agent,
   the vendor, or any running service.  It is deliberately _narrow_. A
   receipt proves that this record was issued by that key and has not
   been altered since.  It does not prove that the agent was right, that
   its inputs were true, or that the world changed the way the record
   suggests.

Toraman                 Expires 16 February 2027                [Page 3]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Being narrow is the point.  A record that promises more than it can
   support is worse than no record, because a relying party cannot tell
   where the support ends.  This profile therefore states, in normative
   language, the things a receipt does *not* establish -- and, where the
   industry needs those things established, points at the separate
   documents that do it.

   *Three documents, one system.* This revision is written as one part
   of a shipped, measured architecture, and a reader should be able to
   see the whole shape from here:

   *  *This profile -- the record.* One signed record per action, hash-
      chained (each record carries a fingerprint of the one before it,
      so a deletion _between two presented records_ is visible -- a
      deletion from the end is not, which is what Section 5.1 is about),
      and carriable as a Signed Statement for registration in a
      transparency log (Section 4.3).
   *  *The action digest [I-D.toraman-noa-action-digest], published 14
      August 2026 -- the binding.* A fixed, public way to compute one
      value from an approval and its exact execution attempt, so that
      records made by parties who share no schema can be shown to commit
      to the same action projection.
   *  *Settlement evidence [I-D.toraman-noa-settlement-evidence],
      published 14 August 2026 -- the independent witness.* For
      payments, a signed side artifact that lets a relying party check
      the effect against a public ledger's own record, instead of
      against the paying party's assurance.

   The division of labour is the argument: the record says what the
   governed boundary decided or dispatched, the digest says which action
   a later document is about, and the witness says what an outside
   system observed.  Each fails on its own (Section 8.1), and no one of
   them is asked to carry the others' weight.

   The gap this fills is a specification gap, not only a product one.
   Protocol specifications for agent connectivity and orchestration, and
   the agent runtimes built on them, leave the _accountability_ layer --
   a standardized, tamper-evident, issuer-authenticated record of an
   agent's actions -- open.  OWASP's MCP Top 10 lists "Lack of Audit and
   Telemetry" as MCP08:2025 [OWASP-MCP].  Several recent efforts emit
   signed PERMIT/DENY _decision_ receipts for agent actions; what is
   missing is a single, SCITT-native, COSE-based profile for *per-
   action* receipts that is (a) carriable as a Signed Statement for
   registration in a Transparency Service -- a log a third party can
   check for consistency -- and (b) honest about exactly what a receipt
   does and does not prove.

Toraman                 Expires 16 February 2027                [Page 4]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   This profile does not define a new signature container.  It defines
   an application payload profile carried in a COSE_Sign1 [RFC9052], so
   the outer signature can be verified by conforming COSE
   implementations that support the fully-specified Ed25519 algorithm
   identifier used by this profile.  Section 4.3 specifies the
   additional protected claims that make one an RFC 9943 Signed
   Statement, and states plainly which of those the reference
   implementation does not yet emit.

   *What this revision adds.* Review on the SCITT mailing list in July
   2026 found that the single phrase "real-world outcome" in -00 hides
   three claims that a consumer must be able to fail separately: whether
   a named person authorized this exact action _before_ it ran, what a
   downstream machine _reported_ afterwards, and whether the intended
   _physical_ effect actually occurred.  Section 8 and Section 9 pull
   them apart and require each to be reported as a result a verifier
   renders, not a caveat a reader has to remember.  Section 10 draws the
   boundary around the value that lets records about one action be
   joined at all.  Appendix A tells the whole story of this revision --
   what was asked, what was built and measured, and what the document
   now guarantees -- and every change is listed there.

   The base record noa.receipt/0.1 is not modified: no member is added,
   removed, or re-typed.  What that guarantees is byte-level and nothing
   wider: every receipt, hash chain and checkpoint produced under -00
   still hashes to the same value, its signatures are still signatures
   over the same bytes, and no linkage is invalidated.  It does *not*
   follow that a -00 receipt is accepted by a -01 verifier -- acceptance
   is a separate question, answered in the next paragraph.

   It does *not* guarantee that every -00 receipt is _valid_ under -01,
   and the difference is worth enumerating rather than glossing.  This
   revision states validity conditions -00 did not: the verdict, risk-
   class and governance-mode vocabularies are closed with a MUST-reject
   (Section 2); the object is closed against unknown members
   (Section 3); a timestamp must be a valid RFC 3339 date-time and not
   merely shape-correct (Section 3.3); id is bounded at 128 code points,
   seven members must be non-empty strings and a present
   governance.compliance.verdict must be ALLOW or DENY (Section 3.1);
   sig.alg must be the exact literal ed25519 (Section 4.2); and the
   cross-field rules of Section 3.1 refuse combinations -00 permitted.
   A receipt carrying an out-of-vocabulary verdict, an unknown member,
   an impossible instant, an empty or over-long identifier, or
   contradictory simulation markers would have passed a permissive -00
   verifier and is malformed here.  A verifier's NFC configuration moves
   the verdict on non-NFC strings in both directions (Section 3.3).

Toraman                 Expires 16 February 2027                [Page 5]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   For a document adopting this profile's chain convention by reference
   (Section 1.2), the practical statement is therefore: the
   _construction_ is unchanged; the _acceptance rules_ are stricter.

1.1.  Scope and the adjacent slot

   Two related SCITT-AI drafts occupy _different_ slots: an EU AI Act
   Article 50 _disclosure_ profile (what content was generated and
   disclosed) and a _session-archive_ format (a portable bundle of a
   whole agent session).  This profile is orthogonal to both: it defines
   the *per-action signed receipt* -- one signed record per agent
   action, carried bare or in a COSE_Sign1 (Section 4), and holding the
   action, the recorded principal class, the recorded verdict, and any
   policy identity the issuer chose to record.

   Three slots adjacent to this one are named here because this revision
   defines its boundaries against them rather than against prose: a
   _reconciliation_ layer that admits heterogeneous attestations about
   one action and reports per-source verdicts [I-D.hillier-scitt-arp];
   an _executor-side admission boundary_ that decides whether an action
   may be consumed [I-D.schrock-action-evidence-boundary]; and a
   _correlation value_ that lets records produced by parties with no
   shared schema commit to the same action projection
   [I-D.toraman-noa-action-digest].  None of the three is a dependency
   of this profile, and this profile is not a dependency of them.

1.2.  Relationship to other work

   *  *SCITT Architecture* [RFC9943]: this is a Signed Statement
      profile; it adds AI-agent-action semantics, not new transparency
      machinery. (-00 cited this as a work-in-progress draft; it was
      published as an RFC in June 2026.)
   *  *Signed decision receipts for machine-to-machine access control*
      [ACTA]: a custom-JSON receipt field catalogue covering the same
      ground in a custom JSON envelope; this profile is SCITT-native
      (COSE_Sign1) where that format requires an adapter to register.  A
      field-by-field mapping between them changes no requirement here
      and is left to whoever needs to port one.
   *  *draft-dawkins-scitt-ai-article50* [AI-ART50], *draft-stone-aivs*
      [AIVS], *draft-marques-asqav-compliance-receipts* [ASQAV], *draft-
      nivalto-agentroa-route-authorization* [AGENTROA]: adjacent work,
      none of it a SCITT-native per-action receipt profile.  The first
      two target regulatory disclosure and session archives; the third
      is a compliance profile _of_ signed action receipts, which
      overlaps this one in subject and not in mechanism -- it is not a
      COSE/SCITT profile and defines no registration path; the fourth
      authorizes agent routes rather than recording actions.

Toraman                 Expires 16 February 2027                [Page 6]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *draft-kamimura-scitt-vcp* [SCITT-VCP]: a domain SCITT profile
      (algorithmic-trading audit) whose structure this document follows.
   *  *draft-wilder-scitt-physical-site-engage-receipt* [PSER]: a
      physical-site engagement profile that adopts the hash-chain
      convention of Section 5 by reference.  That section's number,
      title and anchor are unchanged from -00. *Two sentences of its
      text were factually wrong in -00 and are corrected in this
      revision*; Appendix A gives the before and after, and an
      implementer of [PSER] should read that entry before relying on
      -00's wording.  Its new subsection Section 5.1 adds Chain-
      Verifier-class requirements that -00 did not state: a document
      that adopts Section 5's convention to _build_ receipts is
      unaffected, while a _verifier_ claiming conformance to -01 takes
      on those obligations.
   *  *The action digest and one of its consumers*
      [I-D.toraman-noa-action-digest],
      [I-D.toraman-noa-settlement-evidence], both published 14 August
      2026: a domain-separated correlation value -- one value computed
      under a fixed public rule, so two parties can tell they mean the
      same action -- and a profile that carries it into an external
      system.  Both are referenced, neither is required; Section 10
      states what a receipt does and does not contribute to such a
      construction.

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.

1.4.  Actors

   Requirements in this document are written in one of two forms.  Most
   *name their actor* directly, and most sections address a single actor
   and say so in their first sentence; where a section carries
   requirements for more than one, each requirement names its own and
   the section preamble lists them.  The rest are written *about an
   artifact* -- "a receipt MUST contain no member other than those
   shown", "sig.value MUST be canonical base64", "the kid SHOULD be
   carried in the protected header" -- a shorthand used deliberately for
   schema and encoding constraints, because writing each of them twice
   would bury them.

   An artifact-form sentence binds the *Producer* that builds the
   artifact, at the strength written.  It does not, on its own, bind the
   verifier that receives it, and the two strengths are not symmetric: a

Toraman                 Expires 16 February 2027                [Page 7]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Producer MAY is a permission, and the corresponding verifier duty is
   to ACCEPT what that permission allows, not to enjoy the same
   latitude.  Section 4 shows the shape — kid MAY be carried in the
   unprotected header, and a verifier MUST resolve it from either
   bucket.

   A verifier's disposition is therefore stated explicitly wherever the
   profile requires one: an artifact-form MUST is paired with the
   rejection it implies, and an artifact-form SHOULD or MAY is paired
   with the acceptance a verifier owes a conforming artifact that
   exercises the permission.  An artifact-form SHOULD is never, by
   itself, a ground for a verifier to reject.  Where this document
   states a Producer SHOULD and assigns no verifier disposition, none is
   required: the receiver's behaviour is unconstrained and conformance
   is not tested on it.

   A sentence that fits neither form is an editorial error rather than a
   hidden obligation.  Two kinds of sentence deliberately carry no
   keyword and no obligation: the blocks marked non-normative, and
   statements about what a _future revision_ might do.  Seven actors
   appear: three verifiers of increasing scope, and four parties that
   make, operate, register and consume.  A section states its actor in
   its first sentence where the whole section is addressed to one; where
   a section mixes actors, each requirement names its own.

   +===============+================+=================================+
   | Actor         | Holds / is     | Is required to                  |
   |               | given          |                                 |
   +===============+================+=================================+
   | *Producer*    | the signing    | build receipts to Section 3,    |
   | (Issuer)      | key, and the   | Section 3.1 and Section 3.2,    |
   |               | facts it       | and sign them per Section 4.2   |
   |               | records        |                                 |
   +---------------+----------------+---------------------------------+
   | *Receipt      | one receipt; a | check that one object: shape,   |
   | Verifier*     | keyring;       | canonical form, the recomputed  |
   |               | optionally an  | chain.hash, the signatures it   |
   |               | identity       | is given, and -- when a         |
   |               | manifest       | manifest is supplied --         |
   |               |                | attribution                     |
   +---------------+----------------+---------------------------------+
   | *Chain        | a presented    | everything above for each       |
   | Verifier*     | set of         | member, plus the set-level      |
   |               | receipts; a    | conditions of Section 5.1       |
   |               | keyring;       |                                 |
   |               | optionally a   |                                 |
   |               | checkpoint and |                                 |
   |               | an identity    |                                 |

Toraman                 Expires 16 February 2027                [Page 8]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   |               | manifest       |                                 |
   +---------------+----------------+---------------------------------+
   | *Evidence     | all of the     | everything above, plus          |
   | Verifier*     | above, plus    | authorization, outcome, signer  |
   | (not a        | the separately | relationship and sufficiency    |
   | conformance   | signed         | for that intent -- described    |
   | role in this  | artifacts of   | here, but NOT testable against  |
   | revision)     | Section 8 and  | this document, because those    |
   |               | Section 9, a   | artifacts, that configuration   |
   |               | trust          | and the result representation   |
   |               | configuration, | are all left undefined          |
   |               | and the        | (Section 1.5).  Nothing in this |
   |               | consumer       | revision can be conformant or   |
   |               | intent it was  | nonconformant _as an Evidence   |
   |               | asked to       | Verifier_; the passages         |
   |               | answer         | addressed to it are analysis,   |
   |               |                | and a future revision or        |
   |               |                | companion must define its       |
   |               |                | inputs and outputs before the   |
   |               |                | role can carry conformance      |
   +---------------+----------------+---------------------------------+
   | *Transparency | a submitted    | apply the Registration Policy   |
   | Service*      | Signed         | of Section 7, which states      |
   |               | Statement, and | which of its checks are         |
   |               | a means of     | conditional on what it can      |
   |               | resolving the  | resolve                         |
   |               | registrant's   |                                 |
   |               | verification   |                                 |
   |               | key            |                                 |
   +---------------+----------------+---------------------------------+
   | *Relying      | a verifier's   | read that result within the     |
   | Party*        | result, and    | limits Section 8 states; where  |
   |               | any receipts   | it compares, indexes or alerts  |
   |               | it chose to    | on receipt fields itself, apply |
   |               | keep           | the byte-comparison and parsing |
   |               |                | rules of Section 3.1 and        |
   |               |                | Section 13                      |
   +---------------+----------------+---------------------------------+
   | *Deployment*  | the running    | choose the configurations this  |
   | (Operator)    | system:        | profile leaves open --          |
   |               | producers,     | identifier syntax, NFC mode,    |
   |               | verifiers,     | resource limits, checkpoint     |
   |               | keys, and what | issuance and freshness, what is |
   |               | is presented   | registered -- and present       |
   |               | or registered  | complete chains for             |
   |               |                | verification                    |
   +---------------+----------------+---------------------------------+

Toraman                 Expires 16 February 2027                [Page 9]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

                                 Table 1

   Three rules govern the table, and each closes a way of misreading it.

   *  *Inputs are part of the obligation, and an input may be empty.* A
      requirement addressed to an actor assumes the inputs in its row.
      Where a requirement needs an input that may be absent -- a
      checkpoint, an identity manifest -- it is written conditionally
      ("when a checkpoint is supplied ... MUST"), and an actor that was
      not given the input has not failed the requirement.  The keyring
      is different from those two and the difference matters: it is a
      listed input of both verifier roles, and an implementation that
      accepts it but is handed an *empty* one is still that actor, still
      conformant, and simply cannot authenticate anything.  That is the
      state Section 5.1 means by "holds no keyring" -- an accepted input
      with nothing in it, not an implementation that refuses the input
      and thereby declines the role.
   *  *A wider verifier inherits the narrower one's checks, and nothing
      else.* A Chain Verifier performs every Receipt-Verifier check on
      each receipt in the set, because the set-level conditions are
      meaningless over objects that are not individually valid.  It does
      not inherit Evidence-Verifier obligations, and no verifier
      inherits Producer obligations.
   *  *One role per claim of conformance.* An implementation conforms to
      the role whose obligations it performs.  Verifying only receipts
      is Receipt-Verifier conformance and nothing more; a Receipt
      Verifier that cannot detect a chain-level condition is conformant,
      because it was never given the set.

1.5.  What this profile does not define

   Several requirements in Section 6.1, Section 8, Section 9 and
   Section 10 are addressed to the *Evidence Verifier* over objects
   whose wire formats are *not* specified here.  (The attribution rule
   of Section 6 is not among them: it is a Receipt-Verifier requirement,
   conditional on a manifest being supplied.)  This section lists them
   once, so that no reader mistakes a boundary for an omission and no
   implementer mistakes an unimplementable MUST for an interoperability
   requirement:

   *  the *identity manifest* (binding agent.id to authorized key
      identifiers): its encoding, distribution, signing, versioning and
      revocation rules;
   *  the *approval artifacts* of Section 9 -- hold, decision, execution
      grant, consumption and uncertainty records -- and therefore grant
      identifiers, single-use nonces, audiences and expiries;
   *  the *outcome artifacts* of Section 8 -- controller-reported
      outcome and physical observation;

Toraman                 Expires 16 February 2027               [Page 10]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  the *trust configuration* from which a signer relationship is
      derived, and the digests that identify it;
   *  a *shared action digest*, defined separately in
      [I-D.toraman-noa-action-digest];
   *  the *result schema* in which a verifier reports any of the above.
      This revision names result _tokens_ in several places -- the six
      chain conditions and the two named checkpoint-axis outcomes, the
      four absence results, the relationship vocabulary, the intents,
      UNTRUSTED, and the per-receipt outcomes VALID, MALFORMED and
      TAMPERED -- so that implementations describing the same finding
      use the same word. *Two* results are deliberately *not* tokenised
      in this revision: the conflict result of Section 8.2 and the
      unproven-authorization result of Section 9.  A third case that
      might look like one is not: the indeterminate comparison of
      Section 10 is reported with Section 8.3's INDETERMINATE, which is
      a token this document defines.  An implementation MAY report the
      two untokenised results under a name of its own; what it MUST NOT
      do is present that name as this profile's vocabulary, since a
      second implementation reading this document will not have chosen
      the same one.  Whether they should be tokenised here is left to
      the working group (Section 15).  This revision also does not
      define how any of them are carried, so two implementations will
      not be wire-compatible in their outputs until something does.

   Where such an object is absent, the corresponding requirement is not
   a requirement a conforming implementation can fail: it has nothing to
   evaluate, and Section 8 states what a bare receipt cannot establish.
   Deployments that need these claims need those artifact definitions,
   which live in the companion documents and in the reference
   implementation cited in Section 12 -- not here.

2.  Terminology

   _Definitions bind every actor.  Where an entry carries a requirement
   it names its own actor: the entries below address the *Producer*
   (what it MUST emit), the *Receipt Verifier* (what it MUST reject),
   the *Relying Party* (what it MUST NOT read into a value) and the
   *Deployment* (what it selects)._

   *  *Action Receipt:* the application-layer record defined by this
      document -- a signed record attesting one agent action, presented
      either *bare* (the canonical JSON payload plus its native
      signature) or *enveloped* in a COSE_Sign1 (Section 4).  Both
      presentations are defined here.  It becomes an RFC 9943 _Signed
      Statement_ in the enveloped form, when that envelope also carries
      the protected claims of Section 4.3 -- necessary conditions, with
      the boundary noted there. *An Action Receipt is NOT a SCITT
      Receipt.* The two documents that define the other object use it at

Toraman                 Expires 16 February 2027               [Page 11]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      different widths, and the difference matters.  [RFC9942],
      Section 3 defines a _Receipt_ generically: a COSE Single Signer
      Data Object carrying one or more verifiable-data-structure proofs
      -- inclusion, consistency, non-inclusion -- with no Transparency
      Service, Signed Statement or registration event required.
      [RFC9943] applies that object to the SCITT case, where the proof
      is issued by a Transparency Service over a registered Signed
      Statement.  This document calls the SCITT case a *Transparency
      Receipt* wherever it appears (Section 7), meaning RFC 9943's use
      of RFC 9942's object rather than the general class.  The two are
      different objects with different producers: a Transparency Service
      issues the Transparency Receipt; the agent's governed boundary
      issues the Action Receipt.  Where this document says "receipt"
      without qualification inside a SCITT context, it means the Action
      Receipt, and it says so.
   *  *Principal class:* the _category_ of authority the issuer recorded
      the action as being taken on behalf of. agent.principal carries
      one of exactly four enumerated values -- HUMAN, SERVICE, POLICY,
      SANDBOX_SIM -- and nothing else.  It is a class marker, not an
      identity: it names no person, service or key, and a verifier MUST
      NOT read an identity out of it.  SANDBOX_SIM marks a simulated
      action.
   *  *Lifecycle verdict:* the value of governance.verdict, drawn from a
      closed set of exactly seven uppercase tokens. (-00 called this a
      _terminal_ verdict.  It is not: DEFERRED records that no decision
      has been made, and ALLOWED records a permission a later attempt
      may still consume.  The name is corrected here rather than carried
      forward.)  The tokens are: ALLOWED, BLOCKED, DEFERRED, EXECUTED,
      FAILED, ROLLED_BACK, SIMULATED.  The comparison is exact and case-
      sensitive; no other value is valid, and a verifier MUST reject a
      receipt whose verdict is outside this set as malformed rather than
      treating it as an unrecognized extension.  Two of the seven carry
      the normative weight used elsewhere in this document: ALLOWED
      records that the action was permitted at the governed boundary,
      and is the verdict from which an authorization descends -- an
      Evidence Verifier MUST NOT accept a receipt carrying any other
      verdict as the authorization for an action (Section 9); EXECUTED
      records that the action was dispatched or attempted there, and
      nothing about what happened downstream (Section 8.1).  EXECUTED
      covers both "dispatched" and "attempted": those are different
      states, this field does not separate them, and neither means the
      action took effect.  The remaining five record a refusal
      (BLOCKED), a decision not yet made (DEFERRED), a failure at the
      governed boundary (FAILED), an action the issuer records as
      compensated (ROLLED_BACK -- the profile can check neither the
      original effect nor the compensation), and a simulation
      (SIMULATED).

Toraman                 Expires 16 February 2027               [Page 12]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Simulation markers, and the rule that keeps them honest:* three
      members can say something about simulation -- agent.principal ==
      SANDBOX_SIM, governance.verdict == SIMULATED, and
      governance.sandboxed.  A producer MUST make them agree: if any one
      of them marks the action as simulated, governance.sandboxed MUST
      be true, and a verifier MUST reject a receipt in which
      governance.sandboxed is false while either of the other two marks
      a simulation.  The converse is deliberately permitted -- a
      sandboxed run may carry an ordinary lifecycle verdict -- because a
      deployment may exercise the real decision path inside a sandbox.
      What the rule buys is exactly one thing: a receipt cannot say both
      at once.  An issuer that consistently marks a real action as
      simulated, or a simulation as real, produces a receipt no verifier
      can contradict -- the record is the issuer's account of its own
      run, and this profile has no external truth source for it
      (Section 8).  Without the rule even the internal contradiction
      would pass, and a reader could not tell which of two markers to
      believe.
   *  *Risk class:* the value of action.riskClass, drawn from a closed
      set of exactly five uppercase tokens: LOW, MEDIUM, HIGH, CRITICAL,
      IRREVERSIBLE.  The comparison is exact and case-sensitive, and a
      verifier MUST reject a receipt carrying any other value as
      malformed rather than treating it as an unrecognized extension.
      The value is issuer-assigned: it records the class the issuing
      boundary applied to this action, not an independent assessment of
      danger, and a relying party MUST NOT read it as one.  A
      *Deployment* that gates approval authority on risk -- for example
      requiring a higher approver tier for CRITICAL and IRREVERSIBLE
      than for HIGH -- selects that tier from this field, which is why
      an issuer that understates it weakens its own approval requirement
      rather than the verifier's checks (Section 9).
   *  *Governance mode:* the value of governance.mode, drawn from a
      closed set of exactly four lowercase tokens: off, shadow,
      approvals_on, on.  The same exactness applies: the tokens are
      lowercase, the comparison is case-sensitive, and any other value
      MUST be rejected as malformed.  The field records which governance
      posture the issuing boundary was operating under when the receipt
      was produced.  This profile assigns it no authorization semantics:
      a verifier MUST NOT infer from any value that an approval was
      obtained, that a policy was enforced, or that an action was
      permitted -- those are governance.verdict and the artifacts of
      Section 9.
   *  *Policy:* a decision rule set with a stable content hash
      (policyHash) used as its published identity.  A deployment will
      normally want it to be deterministic and side-effect-free -- that
      is what makes a commitment to it worth anything -- but this
      profile specifies no way to evaluate a policy and therefore no way
      for a verifier to check either property; the words are a

Toraman                 Expires 16 February 2027               [Page 13]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      description of intended practice, not a requirement it can test.
      A receipt carries that hash only when the optional commitment of
      Section 3.3 is present; governance.ruleId alone is a label, not a
      commitment.
   *  *Keyring:* the set of verification keys a verifier trusts for this
      evaluation, each addressed by a key identifier.  It is supplied to
      the verifier out of band; this profile defines neither its
      encoding nor how a verifier comes to trust it, and every statement
      here about a "trusted key" means "a key in the keyring the
      verifier was given".
   *  *Identity manifest:* an out-of-band, operator-vouched binding of
      agent.id to its authorized key identifier(s) (kid), used to
      authenticate _which agent_ acted, not merely that a trusted key
      signed.
   *  *Genesis-bound chain:* a per-scope hash chain whose checkpoint
      authority is bound to the _opener_ of the chain -- precisely, to
      the keys an identity manifest authorizes for the agent.id of the
      receipt at sequence 0 (Section 5.2), which is a set rather than
      one key -- so that a re-heading attacker cannot substitute a
      foreign checkpoint.  Without a manifest there is no such binding
      and the property does not hold.
   *  *Transparency Service (TS):* as defined by the SCITT Architecture
      [RFC9943].
   *  *Pre-execution authorization:* a statement, made _before_ an
      action runs, that a named, accountable principal approved _that
      exact action_ under stated bounds.  It is a statement about what
      may happen.
   *  *Post-execution evidence:* a statement, made _after_ an action was
      dispatched, about what some party observed.  It is a statement
      about what did happen, under that party's own semantics.
   *  *Controller-reported outcome:* the terminal status a downstream
      system reported for a request, under that system's own semantics.
      It is evidence about a _report_, not about an effect.
   *  *Physical completion:* whether the intended real-world effect
      actually occurred, as observed by an identified witness under a
      criterion fixed before execution.
   *  *Consumer intent (purpose):* the question a relying party is
      asking of a presented record -- for example "is this an
      authorization?", "is this independent outcome proof?".
      Cryptographic validity is evaluated against the artifact;
      sufficiency is evaluated against the intent, and the two results
      are separate (Section 8.2).
   *  *Authorization signer / outcome signer:* the key that signed the
      authorization record, and the key that signed an outcome statement
      about the same action.  Their _relationship_ is a property a
      verifier derives, not a property either signer may assert about
      itself (Section 6.1).

Toraman                 Expires 16 February 2027               [Page 14]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Shared action digest:* a value, computed under a pinned
      construction, that lets records produced by different parties be
      joined as committing to the same _action projection_. Correlation
      only, and never a statement that the action was authorized; see
      Section 10.

3.  Receipt structure (payload)

   _Every requirement below names its actor: construction rules bind the
   *Producer*, validation rules the *Receipt Verifier*, the tenant rule
   of Section 3.3 the *Chain Verifier*, and the comparison rules for
   identifiers and timestamps the *Relying Party* (Section 1.4)._

   The receipt payload is the JSON Canonicalization Scheme (JCS)
   [RFC8785] serialization of a JSON object.  A Producer MUST emit
   integers only (no floating-point), and a Receipt Verifier MUST reject
   a payload carrying a non-integer number.  String normalization is
   specified in Section 3.2: producers MUST emit NFC, and verifiers MUST
   NOT normalize.  A verifier MAY be configured to _refuse_ a non-NFC
   receipt, but a verifier that accepts one MUST NOT repair it, and in
   either mode a *Relying Party* MUST NOT infer that a verified
   receipt's strings are NFC (Section 3.3).  The fields:

Toraman                 Expires 16 February 2027               [Page 15]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   {
     "spec":   "noa.receipt/0.1",
     "id":     "<receipt id>",
     "ts":     "<RFC 3339 date-time>",
     "scope":  { "tenant": "<id>"?, "chain": "<chain id>" },
     "agent":  { "id": "<agent id>",
                 "model": "<vendor/model|null>"?,
                 "principal": "HUMAN|SERVICE|POLICY|SANDBOX_SIM" },
     "action": { "id": "<tool/action id>",
                 "canonical": "<risk-table key>",
                 "riskClass": "LOW|MEDIUM|HIGH|CRITICAL|IRREVERSIBLE",
                 "paramsHash": "sha256:<hex>|hmac-sha256:<hex>",
                 "reversible": <bool>,
                 "rollbackRef": "<id>|null"? },
     "governance": { "mode": "<governance mode>",
                     "verdict": "<lifecycle verdict>",
                     "sandboxed": <bool>,
                     "ruleId": "<id>|null"?,
                     "approval": { "by": "<approver>",
                                   "at": "<RFC 3339 date-time>" }|null?,
                     "compliance": { "policyHash": "sha256:<hex>",
                                     "readSetHash": "sha256:<hex>",
                                     "inputsHash": "sha256:<hex>",
                                     "verdict": "ALLOW|DENY"? }|null? },
     "chain":  { "seq": <int>,          ; >= 0
                 "prevHash": "sha256:<hex>|null",
                 "hash": "sha256:<hex>" },
     "sig":    { "alg": "ed25519",
                 "kid": "<key id>",
                 "value": "<base64 Ed25519 signature>" }
   }

   *The object is closed.* A receipt MUST contain no member other than
   those shown here, at any level; a verifier MUST reject an unknown
   member rather than ignore it.  Extension by adding members is
   therefore not possible in noa.receipt/0.1 -- that is what makes the
   hash construction of Section 4.2 reproducible across implementations,
   and it is why Section 8.4 carries new claims in separate artifacts
   instead.

   A ? marks a member that MAY be absent; every other member is
   REQUIRED, including sig.  No member of this record is added, removed,
   or re-typed by this revision; -00's figure omitted sig and did not
   mark the optional members, and both omissions are corrected here to
   match the shipped schema (Section 3.3).

Toraman                 Expires 16 February 2027               [Page 16]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *A Producer MUST NOT place raw prompts, tool arguments or secrets in
   any member*, and the commitments this record carries are hashes
   rather than values.  That is a rule about what a producer may write,
   not a property the format enforces, and its limit is worth stating
   precisely -- several members (id, agent.id, agent.model, action.id,
   action.canonical, governance.ruleId, governance.approval.by,
   action.rollbackRef) are constrained in length and emptiness at most
   (Section 3.1) and in content not at all, so a producer can put
   anything in them and no verifier can detect it.  The prohibition
   binds producers; it is not a property a verifier can check, and
   Section 14 says what follows. paramsHash MAY be hmac-sha256:<hex>
   with a tenant-scoped key where a plain SHA-256 over a low-entropy
   value (an amount, an id, a boolean) would be guessable.

   *These commitments are per-producer, and this profile does not make
   them comparable.* Neither action.paramsHash nor the three hashes of
   governance.compliance has a preimage construction defined here: what
   is hashed, in what serialization, under what domain separation, is
   the producer's own contract with whoever will later open the
   commitment.  Two conforming producers given identical parameters can
   therefore compute different values -- by design rather than by
   omission.  Section 10 explains why a cross-producer join key needs a
   construction identifier before any two parties may compare digests,
   and names the companion that defines one.  A verifier MUST NOT
   compare these values across producers, and MUST NOT treat equality of
   them as evidence of anything.  For the keyed form the same reasoning
   cuts harder: the key is a tenant secret, so an offline third party
   cannot check an hmac-sha256 commitment at all, and this profile
   defines no key identifier, rotation rule or distribution mechanism
   for it.  A producer that rotates that key can still open earlier
   commitments for as long as it retains the retired key -- and cannot
   once it destroys it.  Which of those happens is a deployment's key-
   management decision, not something this profile requires or can
   check; what it means is that the openability of a keyed commitment
   depends on a practice outside the record.

   chain.hash is "sha256:" followed by the lowercase hex of SHA-256 over
   the JCS serialization of the receipt with chain.hash and sig.value
   removed; Section 4.2 pins that construction byte-exactly, together
   with the signature computed over the same digest.  Receipts in one
   scope.chain are linked by prevHash; prevHash is null only at the
   genesis receipt (seq == 0).

3.1.  Field semantics and cross-field rules

   _The cross-field rules address the *Receipt Verifier*; the emission
   obligations they imply address the *Producer*. The tenant rule of
   Section 3.3 addresses the *Chain Verifier*._

Toraman                 Expires 16 February 2027               [Page 17]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   The figure above shows shapes; this subsection fixes the meanings a
   verifier may rely on, and the combinations it must refuse.  Where a
   member's meaning is the issuer's to choose, that is said plainly
   rather than left to be inferred.

   *Notation.* In the figure, null denotes the JSON null literal, never
   the four-character string "null"; a quoted alternative such as
   "sha256:<hex>|null" means "either that string form or JSON null".
   Angle brackets mark a value the issuer supplies.

   *The figure's types are normative.* A Receipt Verifier MUST reject a
   receipt in which a member's JSON type differs from the one shown,
   rather than coerce it: <bool> means the JSON literals true or false
   and never the strings "true"/"false" or the numbers 1/0; <int> means
   a JSON number that is an integer within the range Section 3.2 fixes;
   every other member is a string except where null is shown as an
   alternative.  Three shapes are fixed exactly, because a later
   comparison depends on them:

   *  chain.seq MUST be an integer and MUST NOT be negative;
   *  chain.hash, chain.prevHash when not null, and each of
      governance.compliance's policyHash, readSetHash and inputsHash
      MUST be "sha256:" followed by exactly 64 lowercase hexadecimal
      digits;
   *  action.paramsHash MUST be that same form or "hmac-sha256:"
      followed by exactly 64 lowercase hexadecimal digits.

   Uppercase hexadecimal is not an accepted spelling of any of them.
   These are byte-level rules, not presentation preferences: the digest
   is inside the signed payload, so two spellings of one digest are two
   different receipts.

   *spec.* The exact string noa.receipt/0.1.  A verifier MUST reject any
   other value rather than attempt a best-effort parse: this profile
   defines no version negotiation, no downgrade rule, and no forward-
   compatibility contract, and a future wire version will carry a
   different spec and its own signing domain (Section 8.4).

   *id, and identifiers generally.* id identifies this receipt within
   its issuer's own naming.  This profile defines no namespace, no
   uniqueness requirement across issuers, and no collision procedure --
   and the same is true of scope.chain, agent.id, action.id,
   action.canonical, governance.ruleId, action.rollbackRef and
   governance.approval.by.  Two issuers may use the same string for
   different things.  A relying party that treats any of them as
   globally meaningful MUST supply the namespace itself, typically by
   scoping to the issuing key; equality of these strings across receipts
   from different issuers establishes nothing (Section 13).

Toraman                 Expires 16 February 2027               [Page 18]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *Two syntactic bounds are pinned, because every implementation
   already enforces them and no document said so.* Both bind the
   *Producer* on construction and the *Receipt Verifier* on validation:

   *  id MUST be at most 128 Unicode code points, and a verifier MUST
      reject a longer one.  The unit is code points, not UTF-16 code
      units: an identifier of 65 astral characters is 65 code points and
      130 code units, so a verifier counting units rejects a receipt a
      verifier counting points accepts, on identical signed bytes.
   *  Seven members MUST be non-empty strings, and a verifier MUST
      reject a receipt in which any of them is the empty string: id,
      scope.chain, agent.id, action.id, action.canonical, sig.kid and
      sig.value. governance.approval.by is deliberately not among them
      -- it is an opaque label this profile never authenticates
      (Section 6.1), and forbidding one of its values would suggest the
      others mean something.  The checkpoint object of Section 5.2
      carries the same rule for three further members, which is ten
      string boundaries across the two objects.

   *ts.* The time the _issuer recorded the receipt_. It is not the time
   a decision was taken, nor the time an action was attempted, nor an
   observation time, and it is signer-chosen: nothing in this profile
   makes it checkable (Section 3.3).

   *action.canonical.* A key into the issuer's own risk table -- the
   stable name under which the issuer classifies this kind of action.
   The table is not defined here, has no registry, and is not comparable
   across issuers; action.id names the specific tool or operation
   invoked.

   *Cross-field rules a verifier MUST enforce.* These are the
   combinations that would let one record say two things:

   *  governance.sandboxed MUST be true whenever agent.principal is
      SANDBOX_SIM or governance.verdict is SIMULATED (Section 2);
   *  action.rollbackRef MUST be absent or null unless action.reversible
      is true, and a governance.verdict of ROLLED_BACK MUST be
      accompanied by action.reversible: true;
   *  where governance.compliance.verdict is present it records the
      policy evaluation's own result, which is a different question from
      governance.verdict; the two MUST NOT be read as one, and a
      verifier MUST NOT resolve a disagreement between them by
      preferring either -- it reports both.  The member is a closed two-
      value set: where present it MUST be exactly ALLOW or DENY, and a
      verifier MUST reject any other value rather than carry an
      unrecognized string through into a report a relying party will
      read.

Toraman                 Expires 16 February 2027               [Page 19]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *What no rule constrains, stated so nobody assumes it.*
   governance.approval may accompany any lifecycle verdict, and its at
   may be later than ts: this profile places no temporal invariant on
   them, because a signer-chosen timestamp cannot establish that an
   approval preceded an action (Section 6.1).  A verifier MUST NOT infer
   ordering from these fields.

3.2.  Canonicalization parameters

   A digest is only interoperable if the parameters that produced it are
   pinned.  Naming a canonicalization ("canonical JSON") without pinning
   its parameters is the failure mode that does not announce itself: two
   implementations each behave correctly under their own reading and
   produce different bytes, or -- worse -- the same bytes for inputs
   that should differ.  This section therefore pins every parameter of
   the construction above, normatively and exhaustively *for the receipt
   object as a whole*. One carve-out belongs next to the claim rather
   than three sections away: the encoding of the action sub-object is
   not fixed _for a party computing its own digest over that sub-
   object_, because an optional member may be absent or present-as-null
   and the two produce different bytes (Section 10).  Inside a receipt
   that choice is signed and therefore settled; across producers
   computing an independent digest it is not.

     +===============+==============================================+
     | Parameter     | Value for noa.receipt/0.1                    |
     +===============+==============================================+
     | Serialization | JCS [RFC8785]                                |
     +---------------+----------------------------------------------+
     | Member sort   | UTF-16 code unit (RFC 8785); NOT Unicode     |
     |               | code point -- the two diverge for astral     |
     |               | characters, which encode as surrogates       |
     |               | D800-DBFF and sort BEFORE E000-FFFF          |
     +---------------+----------------------------------------------+
     | Number        | RFC 8785; integers only, abs(n) <= 2^53 - 1; |
     | rendering     | non-integer and non-finite values MUST be    |
     |               | rejected                                     |
     +---------------+----------------------------------------------+
     | Unicode       | NONE applied by the canonicalizer, ever.     |
     | normalization | Producers MUST emit NFC ([UAX15]); verifiers |
     |               | MUST NOT normalize before hashing.  A        |
     |               | verifier MAY refuse a non-NFC receipt        |
     |               | outright (see Section 3.3); what it MUST NOT |
     |               | do is silently repair one                    |
     +---------------+----------------------------------------------+
     | String        | RFC 8785: " (U+0022) and \ (U+005C) escaped; |
     | escaping      | the short forms \b \t \n \f \r used where    |
     |               | defined; every other control character below |

Toraman                 Expires 16 February 2027               [Page 20]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

     |               | U+0020 escaped as \u00xx; every other code   |
     |               | point emitted literally as UTF-8             |
     +---------------+----------------------------------------------+
     | Unpaired      | MUST be rejected (they would collapse to     |
     | surrogates    | U+FFFD at the UTF-8 hashing step, mapping    |
     |               | distinct inputs onto one digest)             |
     +---------------+----------------------------------------------+
     | Duplicate     | MUST be rejected at the parse boundary, not  |
     | member names  | resolved last-wins                           |
     +---------------+----------------------------------------------+
     | Forbidden     | __proto__, prototype and constructor MUST be |
     | member names  | rejected at the parse boundary, in every     |
     |               | JSON document a verifier parses -- receipt,  |
     |               | keyring, identity manifest, checkpoint --    |
     |               | and not filtered after parsing               |
     +---------------+----------------------------------------------+
     | Digest        | SHA-256 ([FIPS180-4]), lowercase hex,        |
     |               | sha256: prefixed. action.paramsHash MAY      |
     |               | instead be HMAC-SHA-256 ([RFC2104]) under a  |
     |               | tenant-scoped key, written hmac-sha256:<hex> |
     +---------------+----------------------------------------------+
     | Timestamps    | RFC 3339 [RFC3339] date-time, with Z or a    |
     |               | numeric offset -- the accepted spellings are |
     |               | pinned in Section 3.3, which permits both.   |
     |               | A verifier MUST reject a value that is not a |
     |               | valid RFC 3339 date-time, and valid syntax   |
     |               | still does not make a timestamp truthful     |
     +---------------+----------------------------------------------+
     | Domain        | the receipt signature is over the UTF-8      |
     | separation    | bytes of "NOA-Receipt-v0.1-sig:" followed by |
     |               | the raw SHA-256 of the hash input, pinned    |
     |               | byte-exactly in Section 4.2; the checkpoint  |
     |               | signature uses a distinct tag (Section 5.2), |
     |               | so neither can be replayed as the other      |
     +---------------+----------------------------------------------+

                                 Table 2

   The forbidden-name rule is a parse rule rather than a schema rule,
   and the difference is the whole point of it: in several host
   languages, materializing a member with one of those names mutates the
   object being built, so a document carrying one can change how the
   verifier's own checks behave before any schema runs.  A receipt could
   not carry them in any case, since the object is closed (Section 3) --
   but the keyring, identity manifest and checkpoint a verifier also
   parses are not closed by this profile, and the parse boundary is
   where all four documents meet the same rule.

Toraman                 Expires 16 February 2027               [Page 21]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   On the outer COSE path, verifiers MUST NOT normalize, re-order, or
   re-render a received payload before verifying it: the bytes as
   received are the bytes that were signed.  On the derived path of
   Section 4.2 the verifier does re-serialize, by construction -- it
   must, since two members are omitted -- and this table is exactly the
   rule that makes that re-serialization reproduce the producer's bytes.

   action.paramsHash is a per-producer commitment to that producer's own
   parameter set.  It is NOT a cross-producer correlation key and MUST
   NOT be treated as a shared action digest: it does not commit to the
   tenant, chain, authorization, execution attempt, or nonce, and it may
   legitimately repeat across retries of the same action.  Section 10
   states what a construction must carry before any two parties may
   compare digests at all.

3.3.  Optional members, and what their absence means

   Seven members of Section 3 MAY be absent: scope.tenant, agent.model,
   action.rollbackRef, governance.ruleId, governance.approval,
   governance.compliance, and -- inside a present compliance -- its
   verdict.  Absence is a producer's version or configuration choice; it
   is never, by itself, evidence of tampering, and a verifier MUST NOT
   convert it into one.  Five of them -- agent.model,
   action.rollbackRef, governance.ruleId, governance.approval and
   governance.compliance -- may also be present-as-null, which a
   verifier MUST treat as the value null and not as absence: the two
   encodings produce different canonical bytes and therefore different
   hashes and signatures.

   The two whose absence changes what a verifier may conclude are
   singled out below; the rest are ordinary optional fields carrying no
   security consequence beyond that rule.

   *  *scope.tenant* MAY be absent, and the security-bearing rule is
      stated first (this one is *Chain-Verifier-class*, since it
      compares receipts to one another): *a conforming Chain Verifier
      MUST reject a transition between two present, unequal scope.tenant
      values within one scope.chain.* One chain belongs to one tenant,
      so a change of tenant inside it is a splice of two histories
      rather than a version change.  Absence then carries forward rather
      than resetting: a verifier MUST NOT treat an absent scope.tenant
      as a fresh start, so A -> absent -> B is the same cross-tenant
      splice as A -> B and MUST receive the same verdict, while A ->
      absent -> A (the same tenant resuming) and absent -> A
      (enrichment) remain valid.  Without the carry-forward rule, an
      optional field becomes a splice channel.

Toraman                 Expires 16 February 2027               [Page 22]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *governance.compliance* MAY be present.  When present it carries a
      commitment to the policy's published identity (policyHash), to the
      policy's closed read-set (readSetHash), and to the recorded
      decision inputs (inputsHash) -- hashes only, never the inputs
      themselves.  Its presence does NOT make the receipt policy-
      replayable under this profile: this document does not specify the
      evaluation grammar, operator set, or evaluation order that a re-
      derivation would need, and Section 11 still governs.  Its presence
      also does not establish that the referenced policy was adequate or
      in force.

   *On rejecting non-NFC input.* A verifier MAY offer a mode that
   refuses any receipt carrying a non-NFC string, reporting it as
   malformed.  That mode is conformant and is a reasonable default for a
   relying party that indexes on these fields; what is NOT conformant is
   normalizing a received payload before hashing it, in any mode.  A
   verifier's default SHOULD be stated in its documentation, because the
   two modes give different answers on the same bytes and a caller
   cannot tell which it got from a boolean.

   *On timestamps.* ts and governance.approval.at are RFC 3339 [RFC3339]
   date-time values, and a conforming verifier *MUST reject a value that
   is not a valid RFC 3339 date-time*. A digit-and-separator shape check
   is not sufficient: 2026-13-45T99:99:99Z matches the shape while lying
   outside the grammar's own numeric ranges, and a receipt carrying it
   is malformed.

   Because these values are inside the hashed payload, the _spelling_ is
   part of the signed bytes, and two spellings of one instant are two
   different receipts with two different hashes.  The profile therefore
   pins what is accepted rather than leaving it to each implementation:

   *  the T and Z separators MAY be upper or lower case, as RFC 3339
      permits;
   *  a numeric offset (+HH:MM / -HH:MM) is permitted as well as Z; a
      receipt is not required to be written in UTC, and -00:00 carries
      the meaning RFC 3339 gives it;
   *  a fractional-second part of 1 to 9 digits is permitted, and
      trailing zeroes are significant bytes rather than a canonical form
      to be trimmed;
   *  a Producer MUST NOT emit a date-time whose seconds field reads 60,
      and a verifier MUST reject one.  This profile forbids the leap-
      second representation rather than requiring anyone to validate it.
      The reason is that no other rule here can be enforced offline
      without it: [RFC3339], Section 5.7 admits 60 only at an actual
      leap second, adjusted by the numeric offset, and says future leap
      seconds cannot be predicted -- so a verifier holding no leap-
      second table cannot decide whether 2030-06-30T23:59:60Z is a valid

Toraman                 Expires 16 February 2027               [Page 23]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      date-time at all, and the requirement to reject what is not valid
      RFC 3339 would have no determinate answer.  Forbidding the
      representation costs a Producer nothing it needs: an agent action
      stamped during a leap second is recorded at :59 or at the
      following second, and the receipt still denotes an instant.  This
      is a deliberate narrowing of RFC 3339 by this profile, not a claim
      about RFC 3339, and Section 15 records it as a decision a working
      group may reverse.

   A verifier MUST NOT normalize a timestamp before hashing, for the
   same reason it MUST NOT normalize anything else (Section 3.2).
   Relying parties comparing timestamps across receipts MUST parse them
   into instants first: byte equality and instant equality are different
   questions here.

   Valid RFC 3339 syntax does not establish that the timestamp is
   truthful; it remains signer-chosen.  A verifier that accepts a well-
   formed timestamp has learned that the issuer wrote a well-formed
   timestamp, and nothing about when anything happened.

   governance.ruleId is a signer-asserted label naming which rule fired.
   It is not a content commitment to a policy, and a relying party MUST
   NOT treat it as one.  Where a receipt carries no
   governance.compliance, the receipt's "policy identity" is exactly
   that label and nothing stronger. (-00's terminology defined a
   policyHash that -00's payload never carried; this subsection resolves
   that inconsistency in favour of what the wire format actually does.)

   This profile adds no member to noa.receipt/0.1.  A claim that this
   record does not carry travels as a separate signed artifact, linked
   by hash -- see Section 8.4 for why that choice is load-bearing rather
   than stylistic.

4.  COSE Signed Statement profile

   *A receipt may be presented in two forms, and this profile defines
   both.* A receipt's _payload_ is the JSON object of Section 3, and its
   native signature (Section 4.2) is computed over that object; a
   receipt presented as payload plus native signature, with no COSE
   envelope, is a *bare receipt*. A receipt carried inside a COSE_Sign1
   is an *enveloped receipt*, and only an enveloped receipt can become a
   Signed Statement (Section 4.3).  Both forms are legitimate
   presentations: the reference implementation's chain path verifies
   bare receipts and never touches COSE (Section 12), while its COSE
   path produces the enveloped form.  Every requirement below that names
   the envelope applies to the enveloped form only; a Receipt Verifier
   given a bare receipt checks the payload, the recomputed chain.hash
   and the native signature, and reports that no envelope was present.

Toraman                 Expires 16 February 2027               [Page 24]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Whether a SCITT-native profile should _require_ the envelope is left
   open (Section 15).

4.1.  Protected header

   _Every requirement below names its actor: what a *Producer* MUST
   emit, and what a *Receipt Verifier* -- given one receipt and a
   keyring (Section 1.4) -- MUST check.  No set and no evidence
   artifacts are needed._

   An enveloped receipt is a COSE_Sign1 carried as the *tagged* form,
   CBOR tag 18: a Producer MUST emit the tag, and a verifier MUST reject
   an untagged COSE structure rather than guess at its type.  Its
   protected header MUST contain alg; the receipt MUST additionally
   carry a key identifier, which SHOULD be in the protected header and
   MAY be in the unprotected header (see below -- this avoids the RFC
   2119 contradiction of requiring kid in the protected header while
   also permitting it in the unprotected one).  In detail:

   *  *alg (label 1) = -19 (Ed25519)* as registered in the IANA COSE
      Algorithms registry by [RFC9864], Section 2.2 (the fully-specified
      Ed25519 identifier; [RFC8032] Section 5.1 parameter set).  Issuers
      MUST use -19. *Verifiers MUST reject every other alg value*
      (algorithm-confusion defense).  That includes the polymorphic
      EdDSA identifier -8, which [RFC9864], Section 4.2.2 marks
      Deprecated (it was registered in [RFC9053]).  It is not a special
      case, and for this profile there is no legacy-compatibility
      exception.  The signing key MUST be an OKP key with crv = 6
      (Ed25519), the curve registered for Ed25519 in the COSE Elliptic
      Curves registry ([RFC9053], Section 7.1); a verifier that can
      inspect the resolved key's type or curve MUST reject any key that
      is not Ed25519 rather than attempt the verification, since a check
      against a key of another type answers a different question than
      the alg value claims.  [RFC9864] makes alg = -19 self-
      disambiguating, so a verifier MUST NOT rely on the key's crv alone
      to determine the algorithm.
   *  *A key identifier sufficient to resolve the verification key.* kid
      (label 4) is the baseline: a Producer MUST emit one, and it MUST
      be sufficient on its own for a verifier holding the right keyring
      to resolve the verification key.  The kid SHOULD be carried in the
      protected header (where it is covered by the signature and cannot
      be stripped or swapped); it MAY instead be carried in the
      unprotected header -- a verifier MUST resolve it from either
      bucket, preferring the protected copy when both are present, and
      MUST report which bucket it used.  Resolving a key and naming an
      identity are two different acts, and this profile separates them:
      an unprotected kid MAY be used to *resolve* the verification key,
      and MUST NOT be reported as the emitter's *identity*, because it

Toraman                 Expires 16 February 2027               [Page 25]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      is not covered by the signature and can be swapped without
      breaking it (Section 6).  [RFC9052] treats kid as a hint that need
      not be unique; this profile narrows that for a verifier's own key
      store.  Where one kid resolves to more than one key, a verifier
      MUST try each candidate and accept only if exactly one verifies;
      where more than one key was tried it MUST report the identifier as
      ambiguous rather than silently choose -- attribution built on a
      collision is attribution to the wrong party. kid is an opaque byte
      string in [RFC9052] and this profile does not narrow that; what it
      does require is that no verifier resolve it through a *lossy
      decode*. A verifier whose key store is keyed by text MUST decode
      the kid bytes, re-encode the result, and require the original
      bytes back before using the identifier, and MUST refuse to resolve
      one that fails that round trip -- a lossy decode maps every
      invalid byte sequence onto the same replacement character, so
      distinct signed identifiers collapse onto one entry and
      attribution goes to whoever holds it.
   *  *Certificate references are OPTIONAL and additional, never a
      substitute.* A deployment using a PKI MAY additionally carry x5t
      (label 34) or x5chain (label 33) as defined by [RFC9360].  A
      receipt MUST NOT rely on them as its only key identifier, because
      a verifier conforming to this profile is required to resolve kid
      and is not required to process certificates.  The reference
      implementation ignores both headers and refuses a receipt carrying
      neither a protected nor an unprotected kid (Section 12).
   *  *Unknown headers are ignored, critical ones are fatal.* The mere
      presence of an additional registered header parameter -- kid,
      content type, CWT_Claims, or crit itself -- is never on its own a
      reason to reject a COSE_Sign1.  What decides the outcome is crit
      (label 2). *This profile requires* a verifier to ignore any header
      parameter it does not understand that crit does not list, rather
      than reject the object -- that rule is this document's, not
      [RFC9052]'s, which defines crit without imposing it.  What
      [RFC9052], Section 3.1 does state is the fatal direction: a crit
      entry naming a header parameter that is not in the protected
      bucket is a fatal processing error.  A verifier MUST likewise
      reject an object whose crit lists a header parameter it cannot
      process.  Section 4.3 adds one further rejection rule, for
      CWT_Claims appearing in both buckets.

   The protected header MUST satisfy the Core Deterministic Encoding
   Requirements of [RFC8949], Section 4.2.1: shortest-form argument
   encodings and map keys sorted in bytewise lexicographic order of
   their deterministic encodings, each key occurring once.  Verifiers
   MUST reject any other encoding.

Toraman                 Expires 16 February 2027               [Page 26]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

4.2.  Payload binding, and the two signatures

   _Construction rules address the *Producer*; verification rules
   address the *Receipt Verifier*, which is given the receipt and a
   keyring (Section 1.4)._

   The payload is the JCS serialization from Section 3, carried
   *attached* as the COSE_Sign1 payload.  This profile does not define a
   detached-payload mode: in COSE, verifying a detached payload requires
   the verifier to be supplied the payload bytes themselves for the
   Sig_structure, so a detached receipt is not self-contained, and
   chain.hash -- a digest over the receipt with chain.hash and sig.value
   removed -- is a chain-linkage value, not a substitute for those
   bytes.  A verifier conforming to this profile MUST reject a
   COSE_Sign1 whose payload element is absent or null.  (An earlier
   revision said a detached payload's digest was bound through
   chain.hash; that was wrong in both directions, and is corrected
   rather than carried forward.  A detached mode, if one is ever wanted,
   is future work -- see Section 12.)

   A receipt in this profile carries *two independent signatures*, and
   conflating them is the failure this subsection exists to prevent.

   1.  The *native receipt signature*, sig.value, is computed over a
       domain-separated preimage, fixed byte-exactly by the construction
       below.
   2.  The *outer COSE_Sign1 signature* covers the RFC 9052
       Sig_structure over the protected header and the payload -- and
       the payload is the whole receipt _including_ its native sig
       member.  The external_aad field of that structure is the *empty
       byte string* in this profile; a verifier MUST use a zero-length
       external_aad and MUST NOT accept an envelope that only verifies
       under some application-supplied value, since nothing in the
       envelope would record what that value was.

   The native construction, in full:

Toraman                 Expires 16 February 2027               [Page 27]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   HASH-INPUT = JCS( the receipt object with exactly two members
                     removed: chain.hash and sig.value; every other
                     member, including sig.alg and sig.kid, is present )

   MESSAGE    = UTF8("NOA-Receipt-v0.1-sig:")  ; 21 octets: tag then ":"
             || SHA-256(UTF8(HASH-INPUT))      ; RAW 32-octet digest,
                                               ; NOT its hex form
                                               ; 21 + 32 = 53 octets

   sig.value  = base64(Ed25519(MESSAGE))       ; standard alphabet,
                                               ; with padding
   sig.alg    = "ed25519"                      ; exact lowercase literal
   chain.hash = "sha256:" || lowercase-hex(SHA-256(UTF8(HASH-INPUT)))

   || denotes octet-string concatenation, and base64 is the standard
   alphabet with padding ([RFC4648], Section 4).  Two encoding rules
   close variants that would otherwise let one signature be written two
   ways: sig.value MUST be canonical base64 -- exactly one padded form,
   no whitespace, no URL-safe alphabet, and the unused bits of the final
   quantum set to zero, as [RFC4648], Section 3.5 requires of a
   canonical encoding -- and MUST decode to exactly 64 octets.  Re-
   encoding the decoded value and requiring the original string back
   enforces every one of those rules at once, and is the check a
   verifier SHOULD implement rather than testing each separately.  The
   signature itself MUST be a canonical Ed25519 encoding, with the
   scalar S reduced modulo the group order.  A verifier MUST reject a
   non-canonical encoding of either kind rather than accept it as an
   equivalent form.  This matters more here than in a bare COSE profile
   because sig.value is excluded from the hash input (Section 4.2): a
   permissive decoder would let two byte-different receipts share one
   chain hash.  The digest that is signed and the digest that appears in
   chain.hash are the same digest of the same input, in two encodings.
   The domain tag means a receipt signature cannot be replayed as a
   signature for any other object class in the same system, and the
   checkpoint tag (Section 5.2) is distinct from it.

   *The native algorithm label is checked before any cryptography.*
   sig.alg MUST be the exact lowercase string ed25519.  A Receipt
   Verifier MUST reject any other value -- including a differently cased
   spelling, and including a value naming an algorithm it happens to
   support -- before attempting a signature check.  A verifier that
   selects its algorithm from the resolved key or from its own
   configuration answers a different question than the receipt asks.

   *The verification equation is pinned.* A verifier MUST check the
   equation [S]B = R + [k]A' -- the cofactorless check that [RFC8032],
   Section 5.1.7 names as "sufficient, but not required" beside the
   cofactored [8][S]B = [8]R + [8][k]A'.  Both are permitted by RFC 8032

Toraman                 Expires 16 February 2027               [Page 28]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   and they do not accept the same set of signatures: every signature
   the cofactorless equation accepts is accepted by the cofactored one,
   and the reverse does not hold.  Leaving the choice to the implementer
   would leave _validity itself_ implementation-defined, and in a hash
   chain a disagreement about one signature is a disagreement about
   accepted history -- which is the hazard this profile exists to
   remove.  This revision therefore pins the narrower equation, so that
   two conforming verifiers accept the same set.  Section 15 records
   that the working group may revisit the choice; what it may not do is
   leave it unmade.

   Determinism is a product of this equation together with the encoding
   rules around it -- the canonical S above, the canonical base64 that
   carries the signature, and the public-key rules below -- and not of
   the equation alone.  Section 12 reports which shipped verifiers
   satisfy the pinned equation and which do not.

   *The verification key itself.* Three rules bind whichever actor
   resolves a key for a native signature check, and they exist for the
   same reason -- the same signed chain must not be accepted by one
   verifier and rejected by another:

   *  The resolved key MUST be an Ed25519 key ([RFC8032], Section 5.1).
      A verifier that can inspect the resolved key's type or curve MUST
      reject any other key rather than attempt the verification:
      dispatching the verification algorithm on the key's type instead
      of on sig.alg is the same algorithm-confusion defect Section 4.1
      closes on the envelope path.
   *  A public key whose encoded y-coordinate is not a canonical field
      element MUST be rejected: after the sign bit (bit 255) is cleared,
      the remaining 255-bit little-endian value MUST be less than 2^255
      - 19.  A public key that is one of the eight canonical small-order
      Ed25519 point encodings MUST also be rejected.  Both rules are
      about the *key*, not about the verification equation: they remove
      the two classes on which widely deployed libraries were measured
      to disagree, so that two verifiers handed one signed chain do not
      accept two different histories.  The verification equation itself
      is pinned above, not left to the implementer.
   *  Where a verifier accepts a key in an encoded form, that encoding
      MUST be canonical: the verifier MUST re-encode the key it parsed
      and require byte equality with the input, and MUST reject a base64
      spelling that does not re-encode to itself.  This profile defines
      no keyring format (Section 1.5), so the rule binds whatever
      encoding a deployment chooses.  Without it one logical key has
      many accepted spellings, and any later comparison on key bytes --
      a fingerprint, a pin, a deduplication -- is bypassable by re-
      spelling the key.

Toraman                 Expires 16 February 2027               [Page 29]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   The relationship between the two signatures is normative:

   *  A verifier MUST NOT treat a valid outer COSE signature as evidence
      that the native signature verifies, and MUST NOT treat a valid
      native signature as evidence that the envelope is authentic.  Each
      is checked on its own inputs. *A Receipt Verifier (Section 1.4)
      given an enveloped receipt MUST run both*, and MUST report which
      of the two produced any result it returns; given a bare receipt it
      runs the native check alone and MUST report that no envelope was
      verified.  What is never conformant is running one check and
      reporting the other's property.
   *  The two signatures MAY be produced by different keys.  Where they
      are, the COSE kid identifies the party that emitted _this
      envelope_ and sig.kid identifies the party that signed _this
      receipt into its chain_. A relying party MUST NOT collapse the two
      identities, and neither may a verifier: they are two claims about
      two different parties, and Section 6 says what each is checked
      against rather than letting one stand for both.  A verifier MUST
      report every identifier it reports *as an identity*, saying which
      claim each belongs to -- always the native sig.kid, and the outer
      kid when it came from the protected bucket.  An outer kid taken
      from the unprotected bucket resolved a key and named nobody
      (Section 4.1), and MUST NOT be reported as the emitter's identity.
   *  *chain.hash MUST be recomputed, and a mismatch MUST be rejected.*
      A Receipt Verifier MUST compute "sha256:" followed by the
      lowercase hex of SHA-256 over HASH-INPUT -- the same input the
      native signature covers -- and compare it to the receipt's
      chain.hash.  If they differ the receipt MUST be rejected as
      tampered.  This check is not optional and is not implied by either
      signature: HASH-INPUT removes chain.hash, so sig.value does not
      cover it, and the outer COSE signature that does cover it may have
      been applied by a different party (Section 4.2).  Without this
      recomputation a receipt whose chain.hash is an arbitrary value
      passes every other Receipt-Verifier check, and every artifact that
      references a receipt by hash (Section 8.4) inherits the forgery.
   *  *The two checks consume different inputs, and the difference is
      normative.* The outer COSE signature is verified over the payload
      *bytes exactly as received*: a verifier MUST NOT parse, re-
      serialize, re-order or normalize them first.  The native signature
      and chain.hash are verified over a *derived* input: the payload is
      parsed, the two named members are omitted, the result is re-
      serialized under Section 3.2, and that string is hashed.  A
      verifier MUST run both and MUST NOT substitute one input for the
      other.
   *  *The canonicality check is over the whole payload, not over the
      derived input.* A verifier MUST parse the received payload bytes,
      re-serialize the _complete_ parsed object under Section 3.2, and
      require the result to equal the received bytes: JCS(parse(bytes))

Toraman                 Expires 16 February 2027               [Page 30]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      == bytes.  If they differ, the receipt MUST be rejected rather
      than repaired, because the field values the verifier would go on
      to report are then not the values the outer signature covers.  The
      derived input of the native path omits two members by construction
      and therefore can never equal the received bytes; nothing in this
      profile asks it to.

4.3.  Carrying a receipt as an RFC 9943 Signed Statement

   _The mapping binds the *Producer*. The evaluation rule at the end
   binds whichever actor evaluates a receipt as a Signed Statement, and
   names it there._

   A COSE_Sign1 built to Section 4.1 alone is a valid signed object, but
   it is *not* by itself a Signed Statement in the sense of [RFC9943].
   That architecture states two protected-header requirements in the
   body of its Section 6: the protected header of a Signed Statement
   MUST include the CWT Claims header parameter, whose value MUST
   include the Issuer Claim (label 1) and the Subject Claim (label 2);
   and kid MUST be present in the protected header whenever neither x5t
   nor x5chain is present there.  A receipt that omits them will be
   refused at registration by a conforming Transparency Service.  This
   subsection specifies the mapping, so that the difference between "a
   signed receipt" and "a registrable Signed Statement" is a checkable
   property rather than a hopeful sentence.

   To be carried as a Signed Statement under this profile, a receipt
   MUST additionally have:

   +==============+===================================================+
   | Requirement  | Value for this profile                            |
   +==============+===================================================+
   | CWT_Claims   | REQUIRED ([RFC9943], Section 6)                   |
   | header       |                                                   |
   | parameter    |                                                   |
   | (label 15)   |                                                   |
   | in the       |                                                   |
   | *protected*  |                                                   |
   | header,      |                                                   |
   | encoded as   |                                                   |
   | specified in |                                                   |
   | [RFC9597],   |                                                   |
   | Section 2    |                                                   |
   +--------------+---------------------------------------------------+
   | iss (CWT     | the Issuer of the Signed Statement: the authority |
   | claim 1)     | on whose behalf the receipt is emitted.  It is a  |
   |              | signer-asserted string until something binds it   |
   |              | to the verification key -- Section 7 requires a   |

Toraman                 Expires 16 February 2027               [Page 31]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   |              | Transparency Service to make that binding and     |
   |              | states that this profile defines no mechanism for |
   |              | it.  This profile does not require iss to equal   |
   |              | the identity that submits the statement for       |
   |              | registration; the two are separable, and a        |
   |              | Transparency Service applies its own Registration |
   |              | Policy to the submission                          |
   +--------------+---------------------------------------------------+
   | iss when x5t | additionally MUST be a string conforming to the   |
   | or x5chain   | URI syntax, of length 1 to 8192 ([RFC9943],       |
   | is in the    | Section 6)                                        |
   | protected    |                                                   |
   | header       |                                                   |
   +--------------+---------------------------------------------------+
   | sub (CWT     | the scope.chain identifier, so one chain is one   |
   | claim 2)     | subject. scope.chain carries no namespace of its  |
   |              | own (Section 3.1), so two issuers can choose the  |
   |              | same string: a Transparency Service MUST scope    |
   |              | subjects by issuer rather than treat sub as       |
   |              | globally unique, and a chain carrying several     |
   |              | agents remains one subject                        |
   +--------------+---------------------------------------------------+
   | kid in the   | REQUIRED.  [RFC9943], Section 6 makes this        |
   | *protected*  | conditional on the absence of x5t/x5chain; this   |
   | header       | profile requires a resolvable kid unconditionally |
   |              | (Section 4.1) and requires it protected for       |
   |              | registration (Section 7), so the condition never  |
   |              | relaxes it here                                   |
   +--------------+---------------------------------------------------+

                                 Table 3

   The CWT_Claims header parameter MUST occur exactly once across the
   two header buckets, as [RFC9597], Section 2 requires: a receipt
   carrying label 15 in both the protected and unprotected headers is
   malformed, and a verifier MUST reject it rather than prefer one copy.

   *These claims are necessary, and this profile does not claim they are
   sufficient.* [RFC9943] describes a Statement as carrying a media type
   that tells a Transparency Service what it is holding, and this
   revision registers none (Section 16) while leaving the protected
   content type a SHOULD.  So a receipt that carries iss and sub has met
   the requirement this profile can state and may still be refused by a
   service that dispatches on a media type it does not have.  Closing
   that is the media-type registration named in Section 15, not a
   further claim here.

Toraman                 Expires 16 February 2027               [Page 32]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   A verifier or Transparency Service evaluating a receipt *as a Signed
   Statement* MUST reject one that lacks protected CWT_Claims carrying
   both iss and sub, per [RFC9943], Section 6.  A verifier evaluating a
   receipt merely as a signed record MUST NOT infer registrability from
   a successful signature check: the two are different questions and
   this profile keeps them apart deliberately.

   A receipt carried as a Signed Statement SHOULD also carry a protected
   content type (label 3) describing the payload.  This revision
   registers no media type (Section 16), which has a consequence worth
   stating rather than leaving to discovery: until one exists, nothing
   makes two conforming producers choose the same value, and where they
   choose differently a Transparency Service that dispatches policy on
   content type will treat them as different formats.  A *Deployment*
   SHOULD therefore agree the value with the Transparency Service it
   registers against, and MUST NOT rely on it for cross-deployment
   interoperability.  Registering a media type is the first IANA action
   a future revision should request.

   Producers that do not emit these claims produce receipts that verify
   offline exactly as specified everywhere else in this document, and
   that a conforming TS is entitled to refuse.  The reference
   implementation is currently in that position; Section 12 states it as
   a named conformance gap rather than leaving a reader to discover it
   at registration time.

5.  Hash-chaining and completeness

   _This section's number, title and anchor are unchanged from -00, and
   the construction it defines is unchanged. *Two sentences of -00's
   paragraph were factually wrong and are corrected here* rather than
   reproduced and contradicted twenty lines later.  Appendix A states
   the before and after, for the benefit of a document that adopts this
   section by reference (Section 1.2)._

Toraman                 Expires 16 February 2027               [Page 33]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Each receipt carries a monotonic chain.seq (genesis = 0) and
   prevHash.  A Chain Verifier checking a presented chain MUST verify:
   each prevHash equals the prior receipt's chain.hash; the genesis
   receipt has prevHash == null; and, when a signed checkpoint is
   present *and an identity manifest is supplied*, that the checkpoint
   was signed by one of the keys that manifest authorizes for the
   genesis receipt's agent.id, so that a foreign checkpoint produced by
   a re-heading attacker is rejected -- without a manifest that binding
   does not hold (Section 5.2).  This profile detects in-band tampering
   _within_ a presented chain, and detects tail truncation *only against
   an authenticated checkpoint* (Section 5.1), never from the presented
   set alone; it does NOT, by itself, detect *equivocation* (an issuer
   signing two divergent chains) -- that requires registration in a
   SCITT Transparency Service or an equivalent external witness.

5.1.  Chain-level failure axes

   _Section 5 and this subsection address the *Chain Verifier*
   (Section 1.4): a Receipt Verifier is given no set, cannot evaluate
   these conditions, and does not fail them._

   _This subsection is NEW in -01.  Section 5 keeps its number, title
   and anchor because another profile adopts it by reference
   (Section 1.2); two of its sentences are corrected in this revision
   and Appendix A states which; everything below adds Chain-Verifier-
   class requirements that -00 did not state, and Appendix A lists each
   of them._

   The checks above are properties of a receipt SET, not of any receipt.
   *Six conditions* are named below, and every one of them is a property
   of the presented receipts, decided by comparing them to one another:
   a verifier presented with any single receipt from the set will find
   that receipt individually well-formed, correctly hashed, and
   correctly signed.  They are named so that a reconciling verifier can
   report WHICH set-level property failed, rather than collapsing every
   one of them onto a single "invalid".

   A checkpoint is deliberately *not* among them.  It is a separate
   object, supplied separately, and what it answers is a separate
   question -- so it has its own axis, defined after this table.
   Nothing on that axis is a chain condition, and nothing on it can fail
   a chain.  That separation is Section 8.3's rule applied to this
   section: a finding about one object is never a finding about another.

Toraman                 Expires 16 February 2027               [Page 34]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   +==========================+=======================================+
   | Axis                     | Failure                               |
   +==========================+=======================================+
   | chain-link-broken        | a prevHash does not equal the prior   |
   |                          | receipt's chain.hash; a non-genesis   |
   |                          | receipt carries prevHash == null; or  |
   |                          | the genesis receipt carries a         |
   |                          | prevHash that is not null (Section 5  |
   |                          | requires it to be)                    |
   +--------------------------+---------------------------------------+
   | chain-sequence-duplicate | two receipts in one scope.chain carry |
   |                          | the same chain.seq                    |
   +--------------------------+---------------------------------------+
   | chain-sequence-gap       | the presented chain.seq values are    |
   |                          | not contiguous, or do not begin at 0. |
   |                          | A conforming Chain Verifier requires  |
   |                          | the complete chain from genesis; see  |
   |                          | below                                 |
   +--------------------------+---------------------------------------+
   | chain-scope-mismatch     | the presented set does not all carry  |
   |                          | one scope.chain.  A Chain Verifier is |
   |                          | handed a set _as presented_ and       |
   |                          | checks that it is one chain; it does  |
   |                          | not assume it.  A supplied checkpoint |
   |                          | that names a different chain is *not* |
   |                          | this condition -- it is a finding     |
   |                          | about the checkpoint (Section 5.2)    |
   +--------------------------+---------------------------------------+
   | chain-tenant-split       | two present, unequal scope.tenant     |
   |                          | values appear within one scope.chain  |
   |                          | (Section 3.3)                         |
   +--------------------------+---------------------------------------+
   | chain-key-discontinuity  | two receipts in the presented chain   |
   |                          | carry the same agent.id and different |
   |                          | sig.kid                               |
   +--------------------------+---------------------------------------+

                                 Table 4

   A Chain Verifier MUST detect all six conditions -- each is decided
   from the presented set alone, so none of them depends on an input the
   verifier may not have been given -- and MUST report them distinctly
   enough that a consumer can tell which held.

Toraman                 Expires 16 February 2027               [Page 35]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *The checkpoint axis, which is not a chain condition.* A checkpoint
   answers one question: _has the tail of this chain been cut?_ A Chain
   Verifier MUST report that question in exactly one of three states,
   and MUST NOT let any of them alter the verdict the six conditions
   produced:

   *  *answered* -- a checkpoint was supplied, was structurally valid,
      named this chain, and authenticated.  The verifier compared it to
      the presented head.  The comparison yields either _consistent_ --
      the head matches, or the presented chain is a consistent extension
      of it as described below -- or the failure checkpoint-head-
      conflict: the presented head and an authenticated checkpoint
      disagree.  Which of them is wrong -- a deleted tail, a fork, or a
      signer error -- is not established by the comparison, and a
      verifier MUST NOT name a cause it did not observe.
   *  *unanswered* -- no checkpoint was supplied.  The verifier MUST
      report the tail question as unanswered and MUST NOT report it as
      an absence of truncation (Section 5.2).
   *  *unusable* -- a checkpoint was supplied and could not be used: it
      was malformed, it named another chain, or it did not authenticate
      (Section 5.2).  The verifier MUST report _which_, MUST report the
      tail question as unanswered, and MUST NOT convert any of it into a
      finding about the receipts. checkpoint-unverified is this
      document's identifier for the authentication case.

   Two consequences follow, and both are the reason the axis is
   separate.  A presented chain that satisfies all six conditions is a
   valid chain whatever arrives beside it: a defective checkpoint
   subtracts an answer, it does not create a failure.  And whether the
   verifier could authenticate the checkpoint is what decides between
   _answered_ and _unusable_ -- never whether a keyring happened to be
   supplied.  Section 12 measures what the other reading costs: every
   shipped verifier branches on whether a keyring was passed, and both
   branches produce a finding against the chain.

   The distinction between the conditions is operational, not cosmetic:
   chain-sequence-duplicate and chain-scope-mismatch can indicate a
   splice of two genuine histories -- every receipt involved verifies in
   isolation.  A duplicate sequence has innocent causes too, a
   retransmitted copy being the common one: where the two receipts at
   that sequence are byte-identical a verifier SHOULD say so, and where
   they differ it has found an issuer that signed two histories at one
   position, which is the serious case -- while chain-link-broken
   indicates in-band alteration.  Reporting them as one verdict tells a
   relying party that something is wrong but not what an operator must
   do next.

Toraman                 Expires 16 February 2027               [Page 36]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   The six labels above are this document's identifiers for the six
   _conditions_, and checkpoint-head-conflict and checkpoint-unverified
   are its identifiers for the two named checkpoint-axis outcomes.  A
   Chain Verifier MAY report any of them under its own strings; what it
   MUST do is make them distinguishable in its output, and keep the
   chain conditions distinguishable from the checkpoint axis.  No
   particular spelling is required on the wire.  Implementers aligning
   with a reconciliation layer should note that these conditions
   correspond to divergence axes carried by [I-D.hillier-scitt-arp];
   that alignment was measured against this profile's own adversarial
   corpus (see Section 12).

   *Completeness is required, not optional.* A Chain Verifier MUST
   reject a presentation that does not begin at seq == 0, and a
   *Deployment* presenting a chain for verification MUST present it from
   genesis.  This is what every implementation of this profile already
   does -- five verifiers in five languages each require 0..n-1, though
   only one of the five is an independent oracle for the others
   (Section 12) -- and a presentation of, say, seq 1 and seq 2 is
   refused as a missing genesis rather than accepted as a partial view.
   Verification of a _range_ that does not start at genesis is therefore
   not a capability of this profile: it is neither specified here nor
   implemented anywhere, and Section 12 lists it as such. -00 said "a
   verifier checking a range of receipts" and left the boundary of a
   "range" unstated; this revision states it.  No implementation
   behaviour changes: the stricter reading is the one every
   implementation has always enforced, and only the documentation has
   caught up.

   *What a checkpoint comparison can and cannot show.* A mismatch
   between the presented head and a checkpoint's headHash can reveal
   truncation _relative to that checkpoint_ -- that is, relative to one
   signed assertion made at one moment by one key.  It is not a general
   detector of tail truncation: a prover who withholds both the tail and
   the checkpoint that would expose it presents a set with no mismatch
   in it, and no property of the presented set reveals the omission
   (Section 13).  Registration in a Transparency Service replaces the
   prover's own checkpoint with a third party's signed proof of
   registration, which is stronger and still not a general answer;
   Section 7 states exactly what it is worth to an offline holder.

   *An older checkpoint over a longer chain is not truncation.* A
   checkpoint asserts a head at the moment it was minted; a chain that
   has grown since then legitimately presents a _later_ head.  A
   verifier MUST therefore distinguish two mismatches.  Where the
   checkpoint's headHash appears in the presented chain at exactly its
   highestSeq, and the presented head's chain.seq is greater, the
   presented chain *extends* the checkpoint consistently: this is not

Toraman                 Expires 16 February 2027               [Page 37]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   checkpoint-head-conflict, and a verifier MUST NOT report it as a
   conflict.  Every other mismatch -- a head at a lower sequence, or a
   checkpoint whose asserted head does not appear in the presented chain
   at its own sequence at all -- is checkpoint-head-conflict: the
   presented set and an authenticated checkpoint disagree about the
   head.  A verifier MUST report the disagreement and MUST NOT report a
   cause for it.  Deletion of a tail is one explanation; an issuer that
   signed two divergent histories is another; a checkpoint minted over a
   different lineage, or a signer error, is a third.  The comparison
   separates none of them, and naming one is the same manufacture of a
   specific accusation Section 8.3 forbids -- which is why this revision
   renamed the condition rather than keep -00's reading of it as
   truncation.  The reference implementation does not draw this
   distinction and reports one verdict for both cases; that is recorded
   as a conformance gap in Section 12.

   *Why the unauthenticated case turns on authentication, and not on
   inputs.* The rule above -- that a checkpoint the verifier did not
   authenticate yields checkpoint-unverified and never a truncation
   finding -- is the one this whole document turns on.  A checkpoint is
   supplied to the verifier, often by the same party whose chain is in
   question.  If an unauthenticated one could establish truncation,
   anyone able to hand a verifier a file could mint a signed-looking
   forensic conclusion about someone else's chain -- an accusation
   manufactured from attacker-controlled bytes.  Only an authenticated
   checkpoint carries the authority to say a tail is missing, and
   checkpoint-unverified is the indeterminate result that names the
   reason instead.  Section 8.3 states the general form of the rule,
   over every input rather than this one; Section 12 measures two places
   where a shipped verifier breaks it.

   The prohibitions in the other direction are unchanged: an
   unauthenticated checkpoint MUST NOT be reported as a satisfied tail
   check, and MUST NOT upgrade any result.  A verifier MUST state, in
   its output, whether the checkpoint that produced any tail conclusion
   was authenticated, and Section 13 states what an authenticated one is
   and is not worth.

   *One agent, one key, within one presented chain.* A Chain Verifier
   MUST reject a presented chain in which two receipts share an agent.id
   and differ in sig.kid, reporting chain-key-discontinuity.  The
   condition needs no keyring: it compares the receipts to one another.

   This is the condition that catches the ordinary form of chain
   extension, and what it catches is narrower than "extension is
   closed".  Consider a party that holds any key the verifier trusts and
   appends receipts to another party's chain under the victim's own
   agent.id: the links are intact, there is no sequence gap, the

Toraman                 Expires 16 February 2027               [Page 38]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   scope.chain is constant and the tenant is constant, so none of the
   other conditions fires.  What gives that attacker away is that the
   appended receipts carry a different sig.kid while claiming the same
   agent.

   Two escapes remain, and they belong with the claim rather than after
   it, because a reader who takes the claim without them will believe
   the chain is closed when it is not:

   *  *It fires within one agent.id, and chains may carry several.* An
      attacker holding another trusted key can append receipts under a
      _new_ agent.id and no condition in the table fires: the set is
      still one chain, one tenant, contiguous and correctly linked.
      Closing that needs a rule about _which agents may appear in a
      chain_ -- an append-authority binding this profile does not define
      (Section 1.5).  The identity manifest binds an agent.id to keys;
      it does not bind a chain to a set of agents, and a Chain Verifier
      given one still has nothing to test the new agent against.
   *  *The comparison is on identifiers, and that is what it detects.*
      The condition compares sig.kid strings, because a Chain Verifier
      is defined over a presented set and needs no keyring to evaluate
      it.  One consequence is unavoidable and is stated rather than
      hidden: two _different_ keys presented under one kid are
      indistinguishable to it, so an attacker who can get a second key
      registered under the victim's identifier is not caught by this
      condition -- Section 7 and the keyring, not this comparison, are
      where that is addressed.  A verifier MAY additionally compare
      resolved key material where it can, and if it does it MUST report
      that as a separate result, because it is a different check with a
      different failure set; what it MUST NOT do is substitute one for
      the other under this condition's name.

   Within one presented chain, then, one agent speaks under one key
   identifier or the set fails -- and the two escapes above are the
   boundary of that sentence, not exceptions to be discovered later.
   The cost is the corresponding limit stated in Section 5.2: key
   rotation is not expressible inside a chain, and a deployment that
   rotates a signing key starts a new one.

   *Sequence orders a chain; timestamps do not.* chain.seq and prevHash
   are the only ordering this profile defines. ts is signer-chosen
   (Section 3.3) and this profile places no requirement that it be non-
   decreasing along a chain: a set whose timestamps run backwards can be
   fully conformant on every axis above, and a relying party that sorts
   or reasons by ts is using a field no check constrains.  Where a
   deployment needs temporal ordering it MUST obtain it from something
   other than these records.

Toraman                 Expires 16 February 2027               [Page 39]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Where more than one condition holds, a verifier MUST report all of
   them rather than the first it found: an operator's next step depends
   on the set, and a single-value result field cannot carry it.  This
   profile defines no wire encoding for that report -- how a verifier's
   output is structured is outside it (Section 1.5) -- only that the
   conditions be individually recoverable from it.

   *A condition that holds is not a note; it is a failure.* A Chain
   Verifier MUST NOT return a positive result for a set on which any of
   the six conditions holds.  That rule has no exception in this
   revision, and one case is worth spelling out because the reasoning
   above cuts the other way: two receipts at the same chain.seq that are
   byte-identical are a retransmitted copy rather than a divergent
   history, and a verifier SHOULD say so in its report -- but the
   condition still holds, so the result is still a failure.  De-
   duplicating such a set and returning a positive result is *not*
   conformant here.  Whether a _future_ revision should permit it is an
   open question (Section 15); this one answers it in the strict
   direction so that two verifiers cannot disagree about the same bytes
   today.

   A verifier MUST NOT report a chain-level axis as a per-receipt
   failure, and MUST NOT infer from the absence of these axes that the
   presented set is complete: completeness against records the prover
   never presented is not a property of the presented set (see
   Section 13).

5.2.  Checkpoint structure

   _The structure and signing rules address the *Producer* of a
   checkpoint; the authentication and scoping rules address the *Chain
   Verifier*, and apply only when a checkpoint is supplied._

   A _checkpoint_ is a separately signed assertion of a chain's current
   head.  It is not a receipt and is not part of any chain; it is the
   object the tail check of Section 5.1 compares against.

   {
     "spec":       "noa.checkpoint/0.1",
     "chain":      "<chain id>",         ; the scope.chain it speaks for
     "highestSeq": <int>,                ; chain.seq of the head receipt
     "headHash":   "sha256:<hex>",       ; chain.hash of that receipt
     "ts":         "<RFC 3339 date-time>",
     "sig":        { "alg": "ed25519", "kid": "<key id>",
                     "value": "<base64>" }
   }

Toraman                 Expires 16 February 2027               [Page 40]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Its signature mirrors the receipt construction of Section 4.2, and is
   pinned here to the same byte-exactness:

   CHECKPOINT-HASH-INPUT =
       JCS( the checkpoint object with exactly one member removed:
            sig.value; sig.alg and sig.kid remain present, and there
            is no chain.hash member to omit )

   CHECKPOINT-MESSAGE =
          UTF8("NOA-Checkpoint-v0.1-sig:")   ; 24 octets: tag then ":"
       || SHA-256(UTF8(CHECKPOINT-HASH-INPUT))
                                             ; RAW 32-octet digest,
                                             ; NOT its hex form

   sig.value = base64(Ed25519(CHECKPOINT-MESSAGE))
   sig.alg   = "ed25519"

   The domain tag is distinct from the receipt tag, so neither signature
   can be replayed as the other, and the colon is part of the signed
   prefix in both constructions.

   *The object is closed, and a Chain Verifier MUST validate its
   structure before authenticating it.* A checkpoint MUST carry exactly
   the members shown above and no others, at either level, and sig MUST
   carry exactly alg, kid and value.  A Chain Verifier MUST reject a
   checkpoint carrying any other member.  Closure is load-bearing here
   in a way it is not for an ordinary schema: CHECKPOINT-HASH-INPUT
   copies every member of the object except sig.value, so a smuggled
   member sits *inside* the signature.  Its signer signs it honestly,
   the signature verifies, and the closed-object check is the only
   control that rejects it.  The value rules, stated as requirements
   rather than left to be read off a figure:

   *  spec MUST be the exact string noa.checkpoint/0.1;
   *  chain MUST be a non-empty string, and a Chain Verifier MUST
      compare it to the scope.chain of the presented set.  A checkpoint
      naming another chain is not evidence about this one, and the
      finding is *about the checkpoint*: the verifier MUST report that
      the checkpoint does not describe the presented chain, MUST NOT use
      it for any tail conclusion, and MUST NOT let it fail an otherwise
      valid presentation.  It is not a chain-level condition
      (Section 5.1), for the reason Section 8.3 gives: nothing about the
      presented receipts failed;
   *  highestSeq MUST be an integer, at least 0, and within the range
      Section 3.2 fixes for numbers;
   *  headHash MUST be "sha256:" followed by 64 lowercase hexadecimal
      digits;

Toraman                 Expires 16 February 2027               [Page 41]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  ts MUST be a valid RFC 3339 date-time, under the same rule and for
      the same reason as a receipt's (Section 3.3);
   *  sig.alg MUST be the exact string ed25519; sig.kid and sig.value
      MUST be non-empty strings; and sig.value MUST satisfy the encoding
      rules of Section 4.2.

   A checkpoint failing any of these value rules is malformed, and so is
   one whose chain does not match.  Every such failure is a finding
   *about the checkpoint*: it MUST NOT establish checkpoint-head-
   conflict, MUST NOT be reported as a finding about the chain, and MUST
   NOT by itself turn an otherwise valid presented chain into a failure.
   The object the verifier was handed is defective, which is a different
   statement from the records being defective; a verifier that conflates
   the two lets anyone who can hand over a file manufacture an
   accusation about someone else's history.  What the verifier MUST do
   is report that it was given a checkpoint it could not use, and answer
   the tail question as unanswered (Section 5.1) -- the same outcome as
   being given no checkpoint at all, because that is what it effectively
   has.

   *Which key may sign it.* A checkpoint is authenticated against the
   same keyring as the receipts.  Authentication either succeeds or it
   does not, and a verifier that cannot perform it -- because it was
   given no keyring, or none holding that signer's key -- holds an
   _unauthenticated_ checkpoint rather than an absent one: it MUST
   report every checkpoint-derived conclusion as unauthenticated
   (Section 5.1), and MUST NOT fall back to comparing heads.  Key-level
   authentication alone, however, only establishes that _some_ trusted
   key asserted this head.  To bind the assertion to the chain, a Chain
   Verifier _that was supplied an identity manifest_ (Section 6) MUST
   require the checkpoint's sig.kid to be one of the keys that manifest
   authorizes for the agent.id of the *genesis receipt* -- the receipt
   at seq == 0, the chain opener.  A checkpoint signed by any other
   trusted key MUST be rejected as UNTRUSTED -- the result defined in
   Section 6 for a valid signature by a key this identity is not
   authorized to use -- rather than accepted as a tail check; this is
   what stops a co-trusted key from certifying its own truncated head.

   Two scoping rules follow, and both are limits rather than features.
   The comparison is between two *native* key identifiers -- the
   checkpoint's own sig.kid, and the identifiers the manifest authorizes
   for the genesis receipt's agent.id -- because a checkpoint is a
   native artifact and is not carried in a COSE envelope; a deployment
   that wraps receipts for registration therefore has two identifier
   spaces, and MUST NOT assume the outer envelope's kid is the one the
   manifest authorizes here.  And the guarantee is opener-scoped: on a
   chain carrying more than one agent.id, the opener's checkpoint
   certifies the opener's view of the head and does not certify a co-

Toraman                 Expires 16 February 2027               [Page 42]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   agent's tail.  A Chain Verifier MUST NOT report an unqualified tail
   check on such a chain, and MUST state which agent's view the check
   covers.

   *What a checkpoint does not commit to, and what follows.* The object
   above binds a chain identifier, a sequence, a head hash and a
   timestamp.  It does not bind the tenant, the issuer, the agent set,
   the genesis hash, or any manifest version.  Three consequences are
   normative for a Chain Verifier:

   *  *Freshness is not self-evident.* ts is signer-chosen, so an
      authentic checkpoint stays authentic forever.  This profile
      defines no expiry, and a verifier MUST NOT treat a checkpoint's
      age as bounded by anything in the object.  A deployment that needs
      freshness MUST impose a maximum age from its own clock and say so
      in its output; an attacker who can replay an obsolete but
      authentic checkpoint otherwise faces no barrier.
   *  *The guarantee is opener-scoped, and a co-agent's tail is not
      covered.* On a chain carrying more than one agent.id, a checkpoint
      authorized for the opener says nothing about receipts signed by a
      co-agent -- the requirement for that case is stated once, above.
   *  *Key identifiers are pinned within a presented chain.* The
      reference implementation binds each agent.id to the first sig.kid
      it presents and rejects any later change as a key swap
      (Section 12).  In-chain key rotation is therefore not expressible
      in this revision: a deployment that rotates a signing key starts a
      new chain, and this profile defines no rotation or revocation
      mechanism.

   Checkpoint issuance policy -- how often a checkpoint is minted, how
   it is distributed, and how a relying party obtains one it did not
   receive from the prover -- is deployment-specific and is not
   specified here.  A verifier given no checkpoint performs no tail
   check at all.  It MUST report the tail question as unanswered, and
   MUST NOT report it as an absence of truncation.  The absence
   vocabulary that names such a result is defined once, in Section 8.3;
   a Chain Verifier that uses it is reading a definition, not inheriting
   an Evidence-Verifier obligation.  Those are different answers, which
   is what Section 8.3 exists to keep apart.

6.  Identity binding

   _Attribution addresses the *Receipt Verifier*, conditional on an
   identity manifest being supplied.  The relationship rules of
   Section 6.1 address the *Evidence Verifier* and depend on artifacts
   listed in Section 1.5._

Toraman                 Expires 16 February 2027               [Page 43]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   agent.id is a signer-asserted label.  To authenticate WHICH agent
   acted (not merely that a trusted key signed), a verifier MAY be
   supplied an identity manifest binding agent.id to its authorized key
   identifiers.

   *Each signature attributes a different party, and the manifest
   answers only one of the two questions.* An enveloped receipt carries
   two identifiers, and treating either as a substitute for the other is
   the failure this subsection exists to prevent:

   *  The *native* sig.kid attributes the *agent*: it is the key that
      signed this receipt into its chain, and it is the identifier
      agent.id makes a claim about.  When a manifest is supplied, a
      verifier MUST check the (agent.id, native sig.kid) pairing against
      it, and MUST reject an unauthorized pairing as UNTRUSTED -- a
      result distinct from both "valid" and "tampered": the bytes are
      intact and the signature verifies, and the key that produced it is
      not one this agent.id is authorized to use.  A verifier MUST
      report that as its own outcome rather than folding it into a
      signature failure, for the same reason Section 5.1 separates its
      conditions.
   *  The *outer* COSE kid attributes the *party that emitted this
      envelope* -- an issuer submitting its own receipt, or a relay
      presenting someone else's.  A verifier that reports it as an
      identity at all MUST take it from the protected bucket, since an
      unprotected identifier is not covered by any signature.  This
      profile defines no authorization list for that party: the manifest
      binds agents to keys, not envelopes to emitters.
   *  Therefore two rules, and they are the ones that close the
      laundering.  A verifier MUST NOT use an authorized outer kid to
      satisfy the agent check: an envelope signed by a key that happens
      to be authorized for agent.id says nothing about who signed the
      receipt inside it.  And a verifier MUST NOT reject a receipt
      solely because its outer signer is not one of the agent's
      authorized keys: a relay is a legitimate presentation, and the
      agent claim is carried by the native signature it did not touch.
      A verifier MUST report the two results separately.

   A checkpoint has one signature and one claim: the manifest check is
   against the checkpoint's own sig.kid, under the opener-binding rule
   of Section 5.2.

   Without a manifest, attribution is key-level only -- "some key the
   verifier trusts signed this" and nothing about which agent -- and a
   verifier MUST surface that limitation to the relying party.

Toraman                 Expires 16 February 2027               [Page 44]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

6.1.  Who signed is not who approved

   governance.approval.by names an approver.  The receipt's signature
   establishes that the _issuer_ emitted this record and has not since
   altered it; it does not establish that the named party held any key,
   saw this action, or approved it before it ran.  A relying party MUST
   NOT treat governance.approval as pre-execution authorization by the
   named party.  Section 9 states what would be required instead.

   *Two levels, and the difference between them is the whole answer.*
   The strength of an approval claim depends on what the relying party
   was given, and a specification that states only one level misleads in
   one direction or the other.

   *  *A bare receipt, checked by a receipt verifier.*
      governance.approval.by is an opaque string.  The verification
      rules of this profile neither resolve it against a key nor compare
      it to any signer.  It is covered by the issuer's signature -- so
      the issuer cannot alter the name after the fact -- but the name
      and any key are unrelated _at this layer_: a receipt naming a
      person who has never held a key verifies exactly like one naming
      the true approver.  A relying party holding only a receipt
      therefore holds a recorded name, not a cryptographic party.
   *  *A complete evidence presentation.* Where a deployment also
      produces the approval artifacts of Section 9, the approver IS a
      cryptographic party: a key enrolled as an approver, holding the
      authority tier the action's risk class requires, neither revoked
      nor used before activation, signs the decision artifact _and_ the
      verdict receipt, and a verifier can require all three to be the
      same key.  What becomes checkable at this level is narrower than
      "a human decided": it is that _a key enrolled as an approver
      signed a decision bound to this action_, and its absence is fatal
      rather than assumed.  Whether a person held that key, saw the
      action, or understood it stays outside every check in this
      profile, as the paragraph below states.
   *  *An issuing gate MAY close the gap at emission time, and this
      profile recommends it.* Nothing prevents the party that mints a
      receipt from requiring governance.approval.by to name the key that
      signed the approval, and refusing to issue otherwise.  That is a
      producer-side control, so it binds nobody downstream and a
      verifier MUST NOT assume it ran.  What it changes is what the
      _issuer knows_, not what a later reader can check: the receipt
      still carries an opaque string, and no member records that the
      gate ran (Section 8.1).  A holder of that receipt alone is in the
      first case above, whatever the issuer's process was; the name
      becomes checkable only when the approval artifacts of Section 9
      travel with it.  The reference implementation's gate and grant
      signer both enforce the control (Section 12).

Toraman                 Expires 16 February 2027               [Page 45]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *A Receipt Verifier or Chain Verifier that reports anything about an
   approval MUST state that its result rests on the opaque name alone.*
   That requirement is testable: its input is a receipt and its subject
   is what a receipt carries.  The second level -- a name backed by the
   approval artifacts of Section 9 -- is described here but carries no
   requirement in this revision, because those artifacts are not defined
   by this document.  A bare receipt is precisely where the confusion
   arises -- and MUST NOT let a bare receipt's approval field be read as
   the second. *Neither level establishes that a named human physically
   held the signing device*: that binding is an out-of-band enrolment
   ceremony, outside every check either level performs, and it MUST be
   stated as a non-claim wherever an approval is presented.  Nor does
   either level establish that anyone read, understood, or consented to
   what was displayed.

   Section 12 reports a shipped instance of the second level and of the
   producer-side control, and states exactly which component leaves the
   name opaque and which refuses it.

   *The rest of this subsection is NON-NORMATIVE in this revision.* It
   runs over the signed outcome artifacts and the trust configuration
   Section 1.5 lists as undefined here, and over a "request signer" this
   document can only describe by example.  Nothing below can be tested
   against this specification alone, so none of it is stated as an RFC
   2119 requirement: it is what a companion that defines those artifacts
   has to require, written now so that the companion inherits the
   analysis instead of rediscovering it.  An implementation cannot fail
   this subsection, and Section 15 records the work of turning it into
   requirements somewhere it can be tested.

   Where an outcome about the action is _itself_ signed, independence is
   decided by comparing the *outcome signer* against *two* other
   parties, because a deployment that separates them has two distinct
   keys and collapsing them hides a real dependency:

   1.  the *request signer* -- the key that asked for the action (in the
       reference implementation, the gate key that signs the request
       receipt, the execution grant and the hold records); and
   2.  the *authorization signer* -- the key that approved it (the
       enrolled approver device key that signs the decision artifact and
       the verdict receipt).

   A verifier has to derive and report *each* relationship separately
   rather than a single merged verdict: an outcome independent of the
   approver but signed by the requesting gate is not independent
   evidence, and neither is its mirror image.  Comparing against
   whichever key merely _emitted_ the receipt answers a third question
   and is not a substitute for either.  Both relationships have to be

Toraman                 Expires 16 February 2027               [Page 46]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   derived by the verifier from its own trust configuration.  A self-
   declared relationship -- a producer writing "independent" about
   itself -- is not evidence of independence, and an undetermined
   relationship cannot be upgraded to an independent one.

   A verifier that reports such a relationship draws the value from the
   vocabulary below -- closed, though a verifier need not be able to
   produce every member of it (see the rule after the table) -- names
   the two parties it compared, marks the result as verifier-derived,
   and carries the identity of the trust configuration it used -- for
   example a trust-policy digest over the thresholds applied and a
   registry-snapshot digest over the key material consulted -- so that
   the determination can be recomputed by anyone holding the same
   configuration.  This profile does not define those digests'
   constructions (Section 1.5), so reproducibility here is scoped to
   parties who share a construction rather than promised in general.
   What it requires is that a verifier reporting a relationship publish
   enough for someone else to recompute it, and state the construction
   where consumers of the result can find it; values computed under
   different constructions are not comparable:

     +=================================+============================+
     | Relationship                    | Meaning                    |
     +=================================+============================+
     | SAME_SIGNING_KEY                | one key signed both        |
     +---------------------------------+----------------------------+
     | SAME_ADMINISTRATIVE_PARTY       | distinct keys under one    |
     |                                 | administrative registry    |
     +---------------------------------+----------------------------+
     | SEPARATE_ROLE_SAME_ORGANIZATION | distinct authorized        |
     |                                 | purposes, one organization |
     +---------------------------------+----------------------------+
     | INDEPENDENT_ORGANIZATION        | distinct organizations,    |
     |                                 | established from the       |
     |                                 | configuration              |
     +---------------------------------+----------------------------+
     | UNKNOWN                         | the configuration does not |
     |                                 | establish a relationship   |
     +---------------------------------+----------------------------+

                                 Table 5

   Two rules make this testable rather than decorative.

Toraman                 Expires 16 February 2027               [Page 47]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *A verifier should not offer a value its configuration cannot
      derive.* An enum member that no input can produce is an invitation
      to claim it: a consumer reads the vocabulary, not the derivation.
      A verifier that cannot establish organizational independence omits
      INDEPENDENT_ORGANIZATION from what it can return, rather than
      returning it on weak evidence.
   *  *SAME_SIGNING_KEY is decided on key material, not on a key
      identifier.* One key presented under two identifiers, in two
      roles, is the same signer; a determination that compares
      identifier strings alone reports independence to an attacker who
      registers a second name for one key.

   UNKNOWN is the default and is not a failure of the artifact; it is a
   statement about the verifier's configuration.  Where a consumer asks
   for independent evidence (Section 8.2), no result other than
   INDEPENDENT_ORGANIZATION satisfies that intent.  Separate keys prove
   only distinct keys; separate processes improve isolation; separate
   roles prove purpose authorization.  None of the three, alone,
   establishes independent administrative control.  Section 12 reports a
   shipped instance of this determination, including the value it
   deliberately does not offer.

7.  Registration in a Transparency Service

   _This section addresses the *Transparency Service*, except the first
   sentence, which addresses the submitting *Deployment*._

   A receipt carrying the protected claims of Section 4.3 is a Signed
   Statement and MAY be submitted to a Transparency Service.  A receipt
   without them is not, and MUST NOT be described as registrable.

   The Registration Policy for this profile is stated as a list because
   each item closes a specific substitution.  A Transparency Service
   registering a statement under this profile:

   1.  MUST verify the outer COSE_Sign1 signature, and MUST verify it
       *with a key it has bound to the Issuer named in iss* -- the
       resolved key or certificate belongs to that Issuer, or an
       explicit delegation from that Issuer to the signing key is
       presented and checked.  [RFC9943], Section 6.3 states the same
       requirement in its own terms: the signature is verified with the
       verification key _of the Issuer_. A service that cannot make that
       binding MUST NOT record the statement as that Issuer's;
   2.  MUST verify the protected header conforms to Section 4.1 -- an
       alg of -19 and deterministic CBOR -- and MUST require a
       *protected* kid for registration specifically.  A receipt whose
       kid is only in the unprotected header conforms to Section 4.1 and
       is not registrable under this policy: registration binds a

Toraman                 Expires 16 February 2027               [Page 48]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

       subject to an issuer, and an identifier the signature does not
       cover cannot do that.  Producers intending to register MUST
       protect the kid;
   3.  MUST verify that protected CWT_Claims are present and carry both
       iss and sub;
   4.  MUST verify that the payload is a well-formed receipt under
       Section 3; and, *where it can resolve the native signer's key*,
       MUST verify the payload's native signature.  Registering an
       envelope whose payload is a forged receipt is precisely the
       attack the outer signature does not stop, since Section 4.2
       permits the two signers to differ.  This profile defines no way
       for a Transparency Service to obtain that key -- the keyring is
       an out-of-band input (Section 2) -- so where the service cannot
       resolve it, *it MUST refuse the registration*. The alternative a
       reader might expect, registering while attesting that the payload
       was not checked, is not available: this profile defines no
       header, claim, log-entry field or media type in which that status
       could travel, so a later reader could not distinguish it from a
       checked one.  Refusal is the only outcome this document can
       specify without inventing a carrier it has not defined.  A future
       revision that defines one MAY relax this;
   5.  MUST verify that sub equals the payload's scope.chain, so that
       the subject a log indexes is the chain the statement is actually
       about; and
   6.  *The issuer/submitter relationship is the sixth item, and it is
       guidance rather than a requirement*, because this document cannot
       make it testable: a Transparency Service applies its own policy
       to the relationship between the Issuer named in iss and the party
       submitting the statement, and records which policy it applied.
       This profile does not require those two to be the same party,
       does not define the policy, and -- decisively -- defines neither
       the minimum contents of such a record nor anywhere it is carried,
       so a service that refused every submission under an unnamed
       policy would satisfy any wording used here.  What the profile can
       do is say plainly that the question exists and that a service
       which never asks it is registering statements whose issuer
       relationship nobody checked.

Toraman                 Expires 16 February 2027               [Page 49]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *What iss is worth, and where it stops.* This profile defines no
   issuer key discovery: no registry, no well-known location, no
   delegation format.  Item 1 therefore states a requirement whose
   _mechanism_ lives outside this document, and a deployment must supply
   one.  Until it does -- and for any holder who has only the receipt,
   with no registration behind it -- iss is an *issuer-asserted string*:
   it names the authority the signer claims to speak for, and nothing in
   the envelope proves the relationship.  A *Transparency Service*, and
   any *Receipt Verifier* that reads iss at all, MUST NOT report it as
   an authenticated identity on the strength of a valid outer signature
   alone, and MUST say which it had: an identity bound to the
   verification key, or a string the signer asserted.

   A Transparency Service knows this policy applies by agreement with
   the registrant, not by inspection: no media type is registered for
   the payload (Section 16), so a service cannot dispatch on content
   type alone.  Until one exists, a deployment states the profile out of
   band.

   Items 4 and 5 are the ones a reader should not skim.  Item 4 is what
   stops a trusted registrant obtaining a log entry -- and a
   Transparency Receipt -- for a receipt nobody in the chain ever
   signed.  Its cost is stated rather than hidden: a Transparency
   Service that cannot resolve native signer keys registers nothing
   under this profile, which is a real operational constraint and the
   honest consequence of having no way to publish "not checked".
   Without item 5 an issuer can register a chain-A receipt under sub =
   chain-B, leaving the log holding a subject history that no receipt
   supports.  On success the TS returns a Transparency Receipt: a third
   party's signed proof that this statement was registered in its log.
   In [RFC9942]'s terms that is a proof about the log's verifiable data
   structure, not the COSE countersignature header parameter of
   [RFC9052]; the two are different constructs, and this profile means
   the first everywhere it says Transparency Receipt.

   *What registration is worth, stated exactly.* An inclusion proof
   establishes membership in _the view that log served_. Non-
   equivocation -- that the log did not serve one history to one party
   and a different history to another -- is not established by any
   single receipt.  It requires consistency proofs between log states
   and a party that monitors them; this profile specifies neither the
   monitoring role nor any requirement on anyone to perform it, and a
   relying party that wants non-equivocation MUST obtain it from the
   Transparency Service's own ecosystem.

   *The offline case gets the same scepticism this document applies to
   checkpoints.* A Transparency Receipt handed to an offline relying
   party _by the prover_ is prover-supplied evidence, exactly like the

Toraman                 Expires 16 February 2027               [Page 50]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   checkpoint of Section 5.2: a better signer, and still no way for a
   party that never queries the log to detect a log that served two
   views.

   Two further honesty notes.  Nothing in Section 5 supplies any of
   this, so a deployment that never registers has strictly less.  And no
   reproducible demonstration of registration against an external
   Transparency Service has been published for this profile
   (Section 12): the policy above is a specification, not a report of an
   executed interop.

8.  What a receipt does not claim about the external world

   _The non-claims in this section constrain what any actor may assert,
   and each is written against the actor it binds.  Two blocks are
   marked NON-NORMATIVE where they appear -- the claim-separation duty
   of Section 8.1 and the intent machinery of Section 8.2 -- because
   their inputs are artifacts Section 1.5 lists as undefined; the
   absence vocabulary of Section 8.3 is normative, because a verifier's
   own results are something this document can constrain._

   A receipt in this profile is emitted at the _governed boundary_: the
   point where an action was admitted, refused, deferred, or dispatched.
   Everything beyond that boundary -- what a downstream controller did
   with the request, and what happened physically -- is outside the
   record.

8.1.  Three claims, three independent failures

   The following are distinct claims.  They may share one action digest
   as a join key (Section 10), but digest equality proves none of them.
   Each has to be evaluated and reported separately, so that one can
   fail while the others stand -- a requirement for whichever document
   defines claims 2 and 3, since this one does not (Section 1.5):

   1.  *Pre-execution authorization* -- a named, accountable principal
       approved _this exact action_ before it ran.
   2.  *Controller-reported outcome* -- an identified downstream system
       reported a terminal status for the request, under its own
       semantics.
   3.  *Physical completion* -- an identified witness observed the
       intended effect, against a criterion fixed before execution.

   A receipt under this profile carries NONE of claims 2 and 3, and
   carries claim 1 only as the signer-asserted label described in
   Section 6.1.  A deployment MAY apply the producer-side control
   Section 6.1 recommends -- refusing to issue unless
   governance.approval.by names the key that signed the approval -- but

Toraman                 Expires 16 February 2027               [Page 51]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   no receipt carries evidence that the control ran, so a verifier MUST
   NOT report anything about it.  Whether the control was applied is a
   fact about the issuer's process, established outside this profile or
   not at all.  These are NORMATIVE non-claims, *scoped to what a
   receipt establishes*. A *Producer* MUST NOT present a receipt as
   evidence of any of the three.  A verifier evaluating a receipt --
   alone or as part of a chain -- MUST NOT return a result whose named
   fields assert any of them *on that basis*, and where a consumer asked
   for one it MUST report that the receipt does not establish it.  For
   claims 2 and 3 Section 8.2 names the intent the consumer asked for
   and the evidence it would require.  For claim 1 it does not: this
   profile defines no intent token for pre-execution authorization, so
   the report carries the non-claim above rather than a name from
   Section 8.2.  The prohibition is about the basis of an assertion
   rather than about the claims themselves: a verifier that also holds
   an authenticated outcome or observation artifact may report what that
   artifact establishes, which is the case Section 8.2 describes.

   In particular, governance.verdict == EXECUTED records that the action
   was dispatched, or attempted, at the governed boundary.  It does not
   attest that a controller accepted the request, that the request
   succeeded, or that any physical effect followed.  A controller
   reporting "succeeded" attests success under its own semantics; that
   is a report, and a report is not an effect.

8.2.  Validity and sufficiency are separate results

   A receipt may be cryptographically impeccable and still be the wrong
   evidence for the question being asked.  Two questions therefore have
   to be kept apart:

   *  *artifact validity* -- signature, canonical form, chain position,
      identity binding;
   *  *sufficiency for the consumer's intent* -- whether what was
      presented answers the question asked.

   *One of the four intents is normative here and three are not*, and
   the line is drawn by what this document defines.  A verifier that
   supports intents at all MUST answer BASE_ACTION_RECEIPT from receipt
   validity alone, and MUST NOT report it as satisfied for an object
   that fails Section 3 or Section 4: its predicate is defined here in
   full, so two implementations can be tested against the same answer.
   The other three are satisfied only by artifacts Section 1.5 lists as
   undefined, and the machinery around them -- how an intent is
   supplied, how sufficiency is compared, how the answer is carried --
   is undefined with them. *Those three rows and the paragraphs that
   follow the table are NON-NORMATIVE in this revision*, for that reason
   -- with one exception, labelled where it appears at the end of this

Toraman                 Expires 16 February 2027               [Page 52]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   subsection, which is normative because its subject is a receipt.  It
   names four intents so that the common questions have shared
   spellings, and defines each by the evidence that answers it:

     +=====================+=========================================+
     | Intent              | Satisfied only by                       |
     +=====================+=========================================+
     | BASE_ACTION_RECEIPT | a receipt valid under Section 3 and     |
     |                     | Section 4                               |
     +---------------------+-----------------------------------------+
     | CONTROLLER_OUTCOME  | an authenticated controller-outcome     |
     |                     | artifact bound to this action.          |
     |                     | Section 8.4 describes what such an      |
     |                     | artifact must say; *this revision       |
     |                     | defines no wire format for it*          |
     |                     | (Section 1.5)                           |
     +---------------------+-----------------------------------------+
     | PHYSICAL_COMPLETION | an authenticated physical-observation   |
     |                     | artifact bound to this action, from a   |
     |                     | witness the verifier trusts for that    |
     |                     | purpose.  Same status: described in     |
     |                     | Section 8.4, *not defined here*         |
     +---------------------+-----------------------------------------+
     | INDEPENDENT_OUTCOME | one of the two artifact-based intents   |
     |                     | above -- CONTROLLER_OUTCOME or          |
     |                     | PHYSICAL_COMPLETION -- whose signer the |
     |                     | verifier derives as                     |
     |                     | INDEPENDENT_ORGANIZATION (Section 6.1). |
     |                     | A receipt cannot satisfy it: the        |
     |                     | receipt's issuer is the party whose     |
     |                     | account is in question, so it is never  |
     |                     | independent of itself                   |
     +---------------------+-----------------------------------------+

                                  Table 6

   Only the first is satisfiable from a receipt alone.  The other three
   need artifacts Section 1.5 lists as undefined in this revision, and
   INDEPENDENT_OUTCOME is additionally unsatisfiable by any verifier
   that cannot derive organizational independence -- which, per
   Section 12, is every implementation this document reports on.  A
   verifier that cannot satisfy an intent reports that in those terms
   rather than as a failure of the artifact.

   A verifier that supports intents should support at least these four
   and report a _named_ insufficiency rather than a generic failure: a
   relying party that asked for physical proof and received a valid
   receipt has learned something specific, and collapsing that onto

Toraman                 Expires 16 February 2027               [Page 53]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   "invalid" destroys it.  Where two authenticated claims conflict -- a
   controller reporting success and a witness reporting that the effect
   did not occur -- the conflict is its own result, carrying both
   claims, with neither erased in favour of the other; this document
   defines no token for it (Section 1.5).

   *One rule here is normative, because it constrains what may be said
   about artifacts this document does define.* A verifier MUST NOT
   report an unqualified "physical completion proven".  The strongest
   defensible result is proven _to the stated policy_, naming the trust
   configuration that made it so, and a receipt never supplies it
   (Section 8.1).

8.3.  Absence is not a negative claim

   A verifier MUST keep the following distinct, and MUST NOT collapse
   them:

       +================+==========================================+
       | Result         | Meaning                                  |
       +================+==========================================+
       | NOT_CLAIMED    | the producer made no claim on this point |
       +----------------+------------------------------------------+
       | NOT_PROVIDED   | a claim may exist, but the verifier was  |
       |                | not given acceptable evidence of it      |
       +----------------+------------------------------------------+
       | NOT_APPLICABLE | the point does not arise for this action |
       +----------------+------------------------------------------+
       | INDETERMINATE  | evidence was presented but does not      |
       |                | settle the question                      |
       +----------------+------------------------------------------+

                                  Table 7

   "The verifier did not receive acceptable evidence" is not "no
   evidence exists", and rendering the first as the second turns a gap
   in a presentation into a negative finding about the world.  This is
   the same discipline Section 5.1 applies to set-level failures: name
   the condition, do not merge it.  A verifier MUST NOT define a result
   code that asserts a negative fact about the world it did not observe;
   Section 12 records a shipped verifier that carries no such code by
   design.

Toraman                 Expires 16 February 2027               [Page 54]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *A finding names the object that failed, and no other.* The rule the
   paragraph above is one instance of, stated once so that an
   implementer can apply it to the case this document did not foresee:
   *a failure to authenticate or to understand one object MUST NOT
   produce a finding about a different object.* The subject of the
   finding is the object that failed.

   The rule is about _whose_ failure is being reported, not about
   whether failures may be reported at all.  A receipt whose own
   signature does not verify is TAMPERED -- a finding about that
   receipt, and the correct one.  A receipt this profile cannot parse is
   malformed -- again about that receipt.  What is forbidden is
   transferring the failure: an unauthenticated checkpoint yields
   checkpoint-unverified, a finding about the checkpoint, and never a
   finding about the chain (Section 5.1); a checkpoint whose structure
   or scope is wrong is a finding about the checkpoint (Section 5.2); a
   trust document a verifier does not recognise is a finding about that
   document, never about the receipts it was supposed to authenticate.
   In each case the honest object -- the chain, the receipts -- is not
   accused of anything, because nothing about it failed.

   This matters because the accusation is the whole thing these
   artifacts exist to make credible.  A verifier that turns its own
   inability to read one file into a finding against someone else's
   records has produced the one output a verification tool must never
   produce, and Section 12 records two measured places where a shipped
   implementation does exactly that.

8.4.  Why the base record is not extended

   A machine-checkable non-claim carried as a field of the base receipt
   -- for example a physical_completion member defaulting to "none" --
   was proposed on the SCITT list and is *not* adopted here, for two
   reasons that are worth stating rather than asserting.

   First, mechanics: adding a member to noa.receipt/0.1 changes the JCS
   bytes of every receipt that carries it, and therefore the receipt
   hash, the native signature, the prevHash linkage, every checkpoint
   over that chain, and every archived conformance vector.  That cost is
   payable only at a new wire version with a new signing domain, never
   by mutating a version other implementations have already frozen.

   Second, semantics: a default value on a frozen record cannot
   distinguish "the producer considered physical completion and claims
   nothing" from "the producer has never heard of the question".  A
   default is not a statement.

Toraman                 Expires 16 February 2027               [Page 55]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   The claims of Section 8.1 therefore belong in *separate signed
   artifacts*, each linked to the authorization by hash -- at minimum
   the hash of the receipt that carried the authorizing verdict and the
   hash of the execution grant, and OPTIONALLY a shared action digest
   (Section 10) -- and each carrying its own signer, its own vocabulary,
   and its own failure.  A controller-outcome artifact says what a
   controller reported; a physical-observation artifact says what a
   witness observed, under a named method, in a named window, against a
   criterion digest fixed before execution.  Motor or controller
   telemetry alone is not an observation of the object.

   This revision does not define those artifacts' wire formats.  It
   fixes the vocabulary and the failure model they must satisfy, so that
   the work can land in one place instead of fragmenting across
   profiles, and so that a receipt consumer today can be told exactly
   which question a receipt does not answer.

9.  Pre-execution authorization and post-execution evidence

   _This section is addressed to the *Evidence Verifier* (Section 1.4),
   over artifacts this profile does not define (Section 1.5), and is
   *NON-NORMATIVE in its entirety*: no bullet below carries an RFC 2119
   requirement, none of them can be failed, and there is no exception.
   The requirements they point at live where they are testable --
   Section 8.1 states the non-claims a receipt cannot escape, and
   Section 8 states what a bare receipt cannot establish.  A Receipt or
   Chain Verifier neither satisfies nor fails anything in this section._

   Authorization and evidence differ in time, in signer, and in failure
   mode.  An authorization is made before the action, by a party
   accountable for allowing it, and fails if that party did not approve
   _this exact action_. Evidence is made after the action, by a party
   that observed something, and fails if the observation is not bound to
   the same action or its signer is not trusted for the purpose.

   The substitution these differences permit is the one this section is
   about.  All three bullets run over artifacts, comparisons or results
   this document does not define -- the hold, decision and execution-
   grant records of Section 1.5, and the query that would ask about a
   named human -- and no binding defined here establishes which grant
   authorized a particular attempt, or that it preceded the attempt: ts
   cannot supply the ordering, because it is signer-chosen
   (Section 3.3).  They are written as what a companion defining those
   artifacts has to require.

Toraman                 Expires 16 February 2027               [Page 56]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  A verifier presented with a *post-execution record* where a *pre-
      execution authorization* was required has to refuse and name the
      failing check.  The refusal is not avoided because the record's
      signature verifies: attribution records who was recorded as
      acting; it never grants authority.
   *  A *machine policy decision* is not a human authorization.  A
      receipt carrying governance.verdict == ALLOWED under an automatic
      rule records that a policy allowed the action.  Where a consumer
      asks whether a named human authorized it, that receipt has to
      yield a result distinct from an accept -- and the reason this is
      not a requirement here is worth naming: "a named human authorized
      it" is not one of the intents this document defines, the identity
      is supplied by nothing defined here, no comparison against the
      receipt is specified, and no token or result schema carries the
      answer (Section 1.5).  The requirement that does exist is the non-
      claim, and it lives where its input is a receipt: Section 8.1
      forbids presenting a receipt as evidence that a named human
      authorized the action.  Per Section 8.3, an unproven result is
      also not a finding that no human approved.
   *  An authorization is bound to *one execution attempt* or it is not
      an authorization for the attempt that happened.  Where a
      deployment issues single-use, time-bounded execution grants, a
      verifier has to check that the grant presented is the grant that
      authorized _this_ attempt, and refuse a valid grant for a
      different attempt rather than accept it as generic permission.
      What makes that checkable -- a grant identifier, a single-use
      nonce, an audience and an expiry, and a binding to the attempt --
      is exactly what this profile does not define.

   A relying party that needs the authorization claim needs artifacts
   this profile does not define: a signed hold or deferral, a signed
   decision by a party holding an approval role, and a single-use
   execution grant, each under its own signing domain.  Section 12
   reports what the reference implementation does today, so that the gap
   between this profile and that implementation is a measurement rather
   than an impression.

10.  The shared action digest boundary

   _The first rule below binds the *Producer* that emits a digest -- it
   must travel with a construction identifier -- and every actor that
   compares one, in practice an *Evidence Verifier*. The second rule
   binds whoever reads the comparison._

   Records about one action are only comparable if they carry a value
   that means the same thing to both producers.  Two rules make that
   possible, and this profile states both while defining neither
   construction.

Toraman                 Expires 16 February 2027               [Page 57]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *Determinability, not assumption.* *This rule -- the one paragraph
   below, and nothing else in this section -- is NON-NORMATIVE here*:
   the digest it governs is not a member of this record and is defined
   by a companion (Section 1.5), and it is written because a companion
   defining one has to carry it.  The two requirements at the end of
   this section are normative and are labelled there.  Any digest
   offered as a cross-producer join key travels with a construction
   identifier, and that identifier commits to the construction's
   canonicalization parameters -- serialization, member sort, number
   rendering, normalization, escaping, digest algorithm, and domain
   separation.  A verifier presented with a digest under an unrecognised
   or non-matching construction identifier does not compare the values
   at all.  The comparison then yields nothing -- not a match, and not a
   mismatch -- and is reported as *indeterminate*: "these records were
   not shown to be about the same action", never "these records are
   about different actions".  That is the same distinction Section 8.3
   draws; a question the verifier could not reach is not a negative
   answer to it.  Two constructions that differ only in whether they
   apply Unicode normalization will agree on almost every input and
   disagree on the ones that matter; a shared vector, not a shared name,
   is what establishes that two parties compute the same value.

   *Correlation is not attestation.* Digest equality establishes that
   two records commit to the same _action projection_ -- the same field
   values under the same construction.  It establishes nothing about
   whether that action was authorized, whether a controller reported
   anything, or whether any effect occurred; each of those fails
   independently (Section 8.1).  A digest is a join key, and a join key
   that is mistaken for an authorization claim is the substitution
   Section 9 forbids.

   *Two rules do stay normative here, because their subject is this
   record.* action.paramsHash does not satisfy the first rule above and
   MUST NOT be used as a join key (Section 3.2); and a verifier MUST NOT
   treat equality of any digest as evidence that an action was
   authorized, which is the substitution Section 9 is about.  Nor does
   the base record carry a member for a shared digest: noa.receipt/0.1
   is closed (Section 3), so a correlation value travels _beside_ a
   receipt in whatever artifact references it, never inside one.  A
   deployment that wants correlation does not modify the receipt.

   A construction meeting both rules is published:
   [I-D.toraman-noa-action-digest] fixes the projection members, the
   domain tag, the preimage, the digest, and a published conformance
   corpus (counted in Section 12).  One consumer of it is
   [I-D.toraman-noa-settlement-evidence].  This profile does not restate
   that construction, does not require it, and would apply the same two
   rules to any other.

Toraman                 Expires 16 February 2027               [Page 58]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *On indeterminate positive controls.* In an independent
   reconciliation run reported on the SCITT list on 27 July 2026
   (https://mailarchive.ietf.org/arch/msg/scitt/zWZBQXXSGV-
   vgbTeOLTjlb9DGLg/), a _positive_ control was held INDETERMINATE
   because the digest it carried came from a construction the reconciler
   had no vector for.  That is the rule above working, not a harness
   defect: a positive control that upgrades itself on an unverified
   binding makes every negative case unreliable too.

   Three things follow, and they are different things.

   *  *What is now pinned.* The correlation construction this profile's
      producers use is published byte-exactly, with its vectors, so a
      reconciler holding those values has something to compute against
      rather than assume (Section 12).
   *  *What that does not do.* The control that came back INDETERMINATE
      carries another party's digest under that party's construction.
      Publishing ours does not upgrade it, and this profile does not
      claim otherwise: that row upgrades when its own preimage rule and
      vectors are published.  The rule is symmetric.
   *  *What is still open on our side, for a digest we did not define.*
      A party computing the reconciliation layer's own subject digest
      over a receipt's action object cannot do so reproducibly today,
      because this profile has never fixed that object's encoding:
      rollbackRef is optional, and present-as-null and omitted produce
      different digests.  Every receipt in the shipped corpus carries
      it, which is a convention, not a rule an implementer can cite.
      Any party wanting to compute a digest over action therefore needs
      two things this revision does not provide: a normative rule fixing
      the encoding, and an expected value published per conformance
      vector so a positive control has something to equal.  Both are
      named here as work rather than left for a harness to discover --
      which is the same rule this section applies to everyone else.

11.  Policy replay is out of scope

   _This section addresses the *Producer* and every verifier: none of
   them may present a receipt as carrying a re-derivable verdict._

   A deterministic, offline *policy-replay* capability -- a verifier re-
   running the in-force policy over the recorded inputs to re-derive the
   recorded verdict, with no access to the agent, model, or any service
   -- is a distinct capability that this revision deliberately does NOT
   specify.  The optional commitment of Section 3.3 carries hashes of a
   policy, its read-set, and the recorded inputs; it does not carry the
   replay _construction_ (the deterministic evaluation grammar, operator
   set, evaluation order, and conformance vectors), which is left to a
   separate companion profile and is not normative here.  A *Producer*

Toraman                 Expires 16 February 2027               [Page 59]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   and every verifier MUST NOT represent a receipt under this profile as
   carrying a re-derivable verdict, and MUST NOT infer from a present
   commitment that the referenced policy was adequate or in force.

12.  Implementation status

   _This section is to be removed by the RFC Editor before publication,
   per [RFC7942].  Removing it will renumber what follows, so a citation
   of this revision by section number should be read against this
   revision.  References to this section from the body are pointers to
   measurement, never to normative content: no requirement depends on
   it._

   A zero-runtime-dependency reference implementation (signer, offline
   verifier, deterministic CBOR, COSE_Sign1 profile, JCS canonicalizer,
   conformance vectors, and separately implemented verifiers in four
   further languages) is available under the Apache-2.0 license at
   https://github.com/NordenSoft/noa.  Unless explicitly stated
   otherwise, the measurements below are from main commit 4764cab.
   Later repository changes are identified by their own commit hashes
   and are not included in the pinned snapshot's counts.  No number in
   this section is an estimate: each was produced by running a command
   or counting files in that tree.  Three classes of measurement are
   reproducible from what is written here -- the corpus counts (three
   are file counts in the named directories; the action-digest and
   settlement-evidence corpora are each a single vectors.json whose
   entry array is counted, which is why counting files there gives the
   wrong answer), the conformance run (node impl-py/conformance.mjs),
   and the repository facts cited to a path.  The rest -- the 25-verdict
   cross-field measurement below, the divergence runs of D1, and the
   decoded header bytes -- were produced by ad-hoc scripts that are not
   committed, so they are reported as measurements with their inputs
   described rather than as anything a reader can re-run today.
   Committing them is open work.

   *Algorithm identifier.* The implementation emits the fully-specified
   Ed25519 identifier -19 ([RFC9864]) and rejects every other alg,
   including the polymorphic EdDSA identifier -8, which [RFC9864],
   Section 4.2.2 marks Deprecated (it was registered in [RFC9053]).
   There is one emission site and one verification gate; no code path
   emits -8 and no legacy-compatibility flag exists.

   The protected header it builds is the deterministic CBOR map {1: -19,
   4: kid} -- two members, because the kid is in the _signed_ bucket, so
   attribution cannot be swapped without breaking the signature.  Its
   bytes therefore begin a2 01 32 04 ..., the trailing part being the
   kid byte string; a measured envelope's header reads a2 01 32 04 49
   ... for a nine-octet kid.  A forged envelope carrying -8 under a

Toraman                 Expires 16 February 2027               [Page 60]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   genuine Ed25519 signature -- the only construction that tests the alg
   pin rather than the signature -- is rejected at the product API with
   "protected header alg is not Ed25519 (-19, RFC 9864)"; so are -7, alg
   as a text string, a non-canonical two-byte encoding of -19, a
   duplicated alg label, and an absent alg.

   *One implementation, stated as such.* The -19/-8 behaviour above is a
   property of a single COSE implementation.  The separately implemented
   Python verifier does not implement COSE at all, and the Go, Rust and
   C# verifiers contain none, so they provide no confirmation in either
   direction.  A third-party check does exist and did run -- a foreign
   stack (cbor2 + PyCA cryptography) reads alg = -19 from a shipped
   vector, verifies the Ed25519 signature over the RFC 9052
   Sig_structure, and rejects a tampered payload -- but that corpus
   holds one vector and it is a _positive_ one.  At the pinned snapshot
   that vector's own metadata still carried the stale a10132 header
   string beside an envelope whose protected header holds both alg and
   kid, so the file contradicted itself; df777a6 corrected it.  There is
   no cross-implementation NEGATIVE vector for -8; that refusal is
   proven only inside this implementation's own tests, and closing it is
   one of the open vector commitments recorded below.

   *The two signatures.* receiptToCose wraps the JCS-canonical receipt
   as the COSE_Sign1 payload; receiptFromCose verifies the COSE
   signature, re-canonicalizes the payload and requires byte equality
   with the signed bytes, and validates the receipt shape -- it does
   *not* verify the native sig.value or any chain property, which is the
   separate verifyChain path.  The two checks are genuinely independent,
   which is what Section 4.2 says they are; what no entry point does is
   run _both_, recorded as a gap below.

   *Chain-level axes.* All six chain conditions of Section 5.1 are
   detected and reported distinctly, under the implementation's own
   reason strings rather than under this document's labels: a broken
   link, a duplicate sequence number, a sequence gap, more than one
   chain partition in one input, the cross-tenant split, and a mid-chain
   key change for one agent -- the last reported as a "key swap", in
   both the TypeScript and the separately implemented Python verifier.
   What it gets wrong is the *checkpoint axis*, on both of its named
   outcomes: checkpoint-unverified is not distinguished at all, and
   checkpoint-head-conflict is reported over-broadly by treating a
   legitimate extension as one.  Both are in the gap list below.
   scope.tenant drift across one chain is fail-closed by default, and
   absence of the member does not reset the comparison.

   *On the word "separately".* What is demonstrated is five
   implementations in five languages that agree on a shared corpus, not
   five independent derivations of this specification: the Go, Rust and

Toraman                 Expires 16 February 2027               [Page 61]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   C# sources describe themselves as ports of the Python reference, and
   the Python one was written against the TypeScript one.  Agreement
   between a source and its port is weaker evidence than agreement
   between two independent readings of a specification, and this
   document does not claim the stronger thing.

   *Cross-implementation conformance, run rather than cited.* node impl-
   py/conformance.mjs, executed at the pinned 4764cab snapshot on
   2026-08-14, ran *99 checks* and exited *0*, with its own summary line
   reporting that the separately implemented Python verifier agrees with
   the TypeScript reference on every vector, including the
   impersonation, truncation and duplicate-key security verdicts.  The
   Go, Rust and C# verifiers are each compared against the Python one
   over a shared file-based corpus, and the TypeScript reference is
   compared against it too, so the topology is a star with the Python
   reference at its centre rather than five implementations tested
   against one another; what that can and cannot settle is stated at the
   end of the register below.  No claim of demonstrated external
   interoperability across all five is made here.

   *Conformance gaps against this revision's own rules, at the pinned
   snapshot.* What follows is the output of two independent reverse
   audits -- code read first, then the requirement it should have mapped
   to -- and it is deliberately long.  An earlier draft of this section
   listed six gaps and called that the whole count; the claim was false,
   and the correction is to publish the register rather than to shorten
   it.  "All five" below means the TypeScript reference and the
   separately implemented Python, Go, Rust and C# verifiers.  A fix for
   the first three is in flight in the reference repository; this
   register describes the code as measured at the pinned snapshot, not
   the code as it will be.

   *One measurement covers the first three rows, and it was run rather
   than reasoned.* Five receipts were built, each carrying
   action.riskClass: CRITICAL on a wire.transfer action, and each was
   presented as identical bytes to all five verifiers: (A)
   agent.principal: SANDBOX_SIM with governance.sandboxed: false and
   governance.verdict: EXECUTED; (B) governance.verdict: SIMULATED with
   governance.sandboxed: false; (C) action.reversible: false with
   action.rollbackRef: "snap_1"; (D) governance.verdict: ROLLED_BACK
   with action.reversible: false; (E) ts: "2026-13-45T99:99:99.000Z".
   *All 25 combinations returned VALID.*

   A and B are the worst of the five, for the reason this profile exists
   at all: a reader has to be able to tell a real action from a
   rehearsal.  A and B are signed, chain-valid, fully verifying receipts
   for an action the issuer itself classified CRITICAL, and they can be
   argued in both directions afterwards -- the issuer can say the record

Toraman                 Expires 16 February 2027               [Page 62]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   shows a simulation, the counterparty can say it shows an execution,
   and the receipt supports both readings.  The receipt carries no
   amount and this profile defines no way to open paramsHash
   (Section 3), so nothing here establishes what the action was worth;
   the risk class the issuer assigned is the whole of what the record
   says about its seriousness.

   *  *G1 -- contradictory simulation markers are accepted.* Section 3.1
      requires governance.sandboxed: true whenever agent.principal is
      SANDBOX_SIM or governance.verdict is SIMULATED.  The requirement
      is satisfied by no shipped verifier: each validates the primitive
      type of the three members and stops, so cases A and B verify in
      all five.
   *  *G2 -- contradictory rollback markers are accepted.* Section 3.1
      requires action.rollbackRef to be absent or null unless
      action.reversible is true, and a ROLLED_BACK verdict to be
      accompanied by action.reversible: true.  Neither relationship is
      checked by any shipped verifier; cases C and D verify in all five.
   *  *G3 -- a timestamp's shape is checked, its meaning is not.*
      Section 3.3 requires a verifier to reject a value that is not a
      valid RFC 3339 date-time.  Every implementation validates the
      shape of the string and none of them asks whether it denotes an
      instant, measured rather than inferred: case E -- month 13, day
      45, hour 99 -- verifies in all five.  The reference's own source
      records why it stays there, and the reason is narrower than an
      earlier draft of this register claimed: tightening the predicate
      changes no bytes, no digest and no signing domain, so it is *not*
      a wire-format change.  What it changes is the set of already-
      signed receipts an existing verifier accepts, which the pinned
      source calls "an API change, never a format change" -- five
      implementations have to move together or they disagree on receipts
      nobody can re-sign.  That is a release-coordination problem, not a
      version-of-the-record problem.
   *  *G4 -- no entry point is a conforming Receipt Verifier.*
      Section 4.2 requires a Receipt Verifier given an enveloped receipt
      to run both signature checks and to report which produced its
      result. receiptFromCose verifies the outer COSE signature, re-
      canonicalizes the payload and validates its shape but never
      touches sig.value; the native signature is checked in the chain
      path.  A caller can obtain both properties by calling both, and
      nothing prevents it; what the repository does not contain at the
      pinned snapshot is a caller that does.  The Receipt Verifier this
      profile defines is not an entry point the library exposes, and not
      one its own callers assemble.

Toraman                 Expires 16 February 2027               [Page 63]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *G5 -- whole-payload canonicality is proven on one path only.*
      Section 4.2 requires JCS(parse(bytes)) == bytes over the bytes as
      received. receiptFromCose performs exactly that comparison; the
      bare chain path in all five is handed parsed values and cannot
      prove the original bytes were canonical.
   *  *G6 -- an unauthenticated checkpoint produces an accusation.*
      Section 5.1 requires checkpoint-unverified and forbids a
      truncation or tampering finding.  With a keyring, all five answer
      TAMPERED; the four that carry a reason string give "checkpoint not
      authenticated against keyring" or their own wording of it, and the
      Go verifier returns the status token alone.  Without a keyring the
      head comparison runs anyway: an honest, complete chain presented
      together with an attacker-signed checkpoint returns TAMPERED in
      all five -- measured, on identical bytes -- under the reference's
      message "tail truncated/extended".  Neither branch produces the
      indeterminate result this revision requires, and both are the
      violation of Section 8.3 in its clearest form: a file anyone can
      hand the verifier becomes a finding against someone else's
      records.  It is also the shape Section 5.1 now forbids in as many
      words: the obligation keys on whether the checkpoint
      authenticated, and every shipped verifier branches on whether a
      keyring was passed.
   *  *G7 -- a legitimate extension is reported as a head failure.*
      Section 5.1 requires a verifier to distinguish a chain that has
      grown past an older checkpoint from one that conflicts with it.
      All five compare the checkpoint tuple against the current head
      only and report a single verdict for both cases.  In the reference
      the message says so in as many words -- "tail truncated/extended",
      which also names a cause Section 5.1 no longer permits the
      comparison to name; the Go verifier returns the status alone, so
      there the two cases are indistinguishable even in principle.
   *  *G8 -- no Signed Statement mode exists, on either side, and that
      is a capability absence rather than a rule broken.* The producer
      emits {1: -19, 4: kid} and no CWT_Claims, so what it mints is not
      registrable (Section 4.3); the verifier ignores label 15 as a non-
      critical header, and a committed test shows it accepting a
      protected header carrying a malformed 15: bstr as a perfectly good
      generic COSE_Sign1.  No code path anywhere evaluates a receipt *as
      a Signed Statement*. This profile requires no Producer to
      implement Signed Statement production -- bare receipts are a
      defined presentation (Section 4) -- so the honest statement is
      that the reference cannot be registered, not that it violates a
      requirement.  It is listed here because a reader who assumes
      registrability would be wrong, and because item 1 of the list
      further below says the same thing about the verifier half.
   *  *G9 -- only the first condition that holds is reported.*
      Section 5.1 requires a verifier to report every condition that
      holds.  All five return on the first failure they find, so a set

Toraman                 Expires 16 February 2027               [Page 64]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      that is both spliced and truncated reports one of the two, and the
      operator's next step depends on the set rather than on whichever
      check ran first.
   *  *G10 -- one implementation cannot distinguish the axes at all.*
      Section 5.1 requires the six chain conditions and the checkpoint
      axis to be distinguishable in a verifier's output, under whatever
      strings it chooses.  Four of the five return a status together
      with a reason string and distinguish the six chain conditions
      through it.  The Go verifier returns a status token alone -- its
      chain entry point's return type is a single string -- so every
      distinction it makes internally is a source comment, and nothing
      beyond MALFORMED, TAMPERED and UNTRUSTED is recoverable from its
      output.  In all five, the remaining two conditions are conflated
      by G6 and G7, so six is also the ceiling.
   *  *G11 -- an ambiguous kid cannot be handled at all.* Section 4.1
      requires a verifier to try every key a kid resolves to, to accept
      only if exactly one verifies, and to report the identifier as
      ambiguous when more than one was tried.  Every shipped keyring is
      a map from a kid string to *one* key, so the requirement is not
      expressible without changing that type: no implementation can
      satisfy it today and none reports the case.
   *  *G12 -- a public option turns off a MUST.* Section 3.3 requires a
      Chain Verifier to reject a transition between two present, unequal
      scope.tenant values.  The shipped verifier exposes
      requireTenantConsistency, which defaults to refusing such a chain
      but can be set to false -- and with it set, the repository's own
      vector for that case returns VALID on a chain whose tenant drifts.
      It is documented and opt-in, which makes it a migration path
      rather than an accident, and it is still a configuration in which
      the implementation does not conform.
   *  *G13 -- the two identifiers are returned, and nothing says which
      claim each carries.* Section 4.2 requires a verifier to report the
      identifiers it treats as identities and to say which claim each
      belongs to.  Both values are in fact reachable from the shipped
      COSE result: it returns the outer kid alongside the parsed
      receipt, whose sig.kid is the native one, so a caller does not
      have to re-read its input.  What is missing is the labelling and
      the second check -- the result does not distinguish "this key
      emitted the envelope" from "this key signed the receipt into its
      chain", and the native signature is not verified on that path at
      all.  G21 is the sharper form of the same defect.
   *  *G14 -- the attribution limitation is surfaced by one
      implementation of five.* Section 6 requires a verifier without an
      identity manifest to surface that attribution is key-level only.
      The TypeScript reference emits exactly that warning; the other
      four emit nothing.

Toraman                 Expires 16 February 2027               [Page 65]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *G15 -- an unanswered tail question is reported by one
      implementation of five.* Section 5.2 requires a verifier given no
      checkpoint to report the tail question as unanswered rather than
      to omit it.  Only the TypeScript result carries a tailChecked
      field; the other four return ordinary chain validity with no
      distinct absence result.
   *  *G16 -- the opener-scoped qualification is missing in two
      implementations.* Section 5.2 requires a multi-agent checkpoint
      result to state whose view the check covers.  TypeScript, Python
      and C# emit that warning; Go and Rust carry no warnings channel at
      all, measured as zero occurrences of any warning field in either
      source tree -- which also makes G14 and G15 unsatisfiable there
      without an API change.
   *  *G17 -- the approval reporting level does not exist, and the
      obligation that would need it is not triggered.* Section 6.1 binds
      a verifier *that reports something about an approval*: it has to
      say whether what it holds is an opaque name on a bare receipt or
      complete cryptographic evidence.  The shipped chain result carries
      a status, a chain identifier, a count, two booleans, a reason and
      warnings -- it does not carry governance.approval at all, so it
      reports nothing about approval and the conditional never fires.
      Nothing here is broken.  What is true, and why the row stays: a
      consumer that wants the distinction cannot obtain it from these
      results, and an implementation that later begins reporting
      approval takes on the obligation at that moment.
   *  *G18 -- the Transparency Service role is not implemented, which is
      coverage absence, not nonconformance.* Section 7 requires a
      Transparency Service to check the outer signature, the protected
      kid, the CWT claims, a well-formed payload, the native signature
      where the key is resolvable, and sub == scope.chain.  No
      implementation performs them, because none claims that role -- and
      Section 1.4 is explicit that an implementation conforms to the
      role whose obligations it performs, so declining a role is not a
      failure of it.  The register carries the row so that a reader
      counting shipped coverage against this document's roles sees the
      hole, not because something is broken.
   *  *G19 -- an unknown non-critical header can be fatal.* Section 4.1
      requires a verifier to ignore a header it does not understand that
      crit does not list.  The reference's CBOR decoder refuses the
      whole envelope when such a header's value uses a CBOR major type
      it does not implement, which is a refusal reached before header
      policy runs.
   *  *G20 -- the pinned equation is satisfied where it could be
      measured, and one implementation's is a property of its linked
      library rather than of its own source.* Section 4.2 pins the
      cofactorless check [S]B = R + [k]A'.  Read from source: the Python
      verifier computes exactly that equation; the Rust verifier calls
      verify_strict, which its own header names as cofactorless; and the

Toraman                 Expires 16 February 2027               [Page 66]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      Go verifier calls the standard library, whose implementation
      carries the comment [S]B = R + [k]A and byte-compares the
      recomputed point against the signature's first half.  The
      TypeScript reference verifies through node:crypto, so the equation
      it executes is the one its *linked OpenSSL* implements, not one
      this repository chooses: measured on Node v23.7.0 linked to
      OpenSSL 3.6.3, that library's Ed25519 verifier recomputes the
      strict equation and names it as such, so the reference satisfies
      the pin *in that pairing*. It is stated per version because that
      is what was measured; a different Node/OpenSSL pairing is a
      different measurement, and an in-repository comment describing the
      path as "cofactored" is a comment about key validation and is
      wrong about the equation.  The C# verifier delegates to a
      BouncyCastle assembly whose source is not present in the
      environment these measurements were taken in, so its equation is
      [UNVERIFIED] -- recorded that way rather than assumed in either
      direction. *An earlier draft of this register asserted
      categorically that the TypeScript reference failed the pin, on the
      strength of that source comment.  That was false*, and the
      correction is recorded here rather than quietly dropped: a
      register that over-accuses is as unreliable as one that under-
      reports.
   *  *G21 -- the COSE path checks the manifest against the wrong
      signature.* Section 6 now requires the agent claim to be checked
      against the *native* sig.kid, and forbids an authorized outer kid
      from standing in for it.  The shipped COSE path does the opposite:
      it pairs receipt.agent.id with the *outer* envelope kid and never
      checks the native sig.kid against the manifest at all (src/cose/
      receipt-cose.ts, the identity-binding block).  Two consequences
      follow, and both were *run against the built package rather than
      reasoned about*. Legitimate relay -- native signature by the key
      the manifest authorizes for alice, envelope signed by an unrelated
      relay: ok:false, "agent \"alice\" is not authorized for signing
      key \"k-relay\"", refusing a presentation Section 6 says MUST NOT
      be refused on that ground.  Laundering -- native signature by a
      key authorized for nobody, claiming alice, wrapped by the key the
      manifest does authorize for alice: ok:true, with the returned
      payload's native sig.kid naming the unauthorized key.  Both
      verdicts are the reverse of the rule.  The chain path is not
      affected -- it checks the native sig.kid -- so this is a defect of
      the envelope entry point only.  The probe is an ad-hoc script and
      is not committed, which is the reproducibility class stated at the
      top of this section.

   *Behaviour the reference enforces that this revision does not
   require.* These are not gaps against a rule; they are places where a
   receipt this profile calls conformant is refused by the reference
   implementation.  That is an interop hazard in the opposite direction

Toraman                 Expires 16 February 2027               [Page 67]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   and it is stated here rather than discovered in a bake-off.  The
   classes that earlier reviews found in this position have left this
   list, because this revision states them as requirements: checkpoint
   structure and scope; the native sig.alg literal; the key type,
   encoding and public-point rules; the id bound; the non-empty-string
   members; the forbidden member names; compliance.verdict; and the
   UTF-8 round trip before a kid is resolved.  What remains:

   *  *S1 -- a signing-key lifecycle.* Section 5.2 says this revision
      defines no rotation or revocation mechanism.  The reference has
      one: its keyring may be a noa.signing-key-lifecycle/0.1 document
      in which each key carries a retiredAt, and a receipt, checkpoint
      or envelope signed by a retired key is refused -- deliberately,
      since a signer-chosen timestamp cannot prove an artifact predates
      a compromise.  Whether that is a _divergence from the profile_
      depends on something this document does not fix: a keyring holds
      the keys a verifier trusts, and nothing here requires a retired
      key to remain in one.  A deployment that simply removes it reaches
      the same refusal without the lifecycle format, and S2 below says
      why both are conformant -- keyring encoding and lifecycle are
      undefined here.  What the format actually buys is a stated reason
      travelling with the refusal instead of a silent absence.  Whether
      revocation belongs in the profile is a question for the next
      revision.  A related detail of the same format: it carries the
      public key as an encoded key with no separate curve field, so the
      crv = 6 requirement of Section 4.1 is checked by inspecting the
      encoded key, which the reference does.
   *  *S2 -- unused keyring entries are shape-checked.* The TypeScript
      reference checks the shape of every static keyring entry before
      the chain walk -- each value must be a non-empty string -- and
      refuses the whole keyring if any entry fails, including entries
      for keys nobody signed with.  It does not decode those unused
      entries as SPKI or as Ed25519 keys, so the divergence is real for
      an empty or non-string entry and not for a well-shaped but
      cryptographically malformed one.  The other four look only at the
      key they actually use.  Keyring encoding is undefined here
      (Section 1.5), so both behaviours conform and the two answers are
      both correct.
   *  *S3 -- a non-UTF-8 COSE kid refuses the object.* Section 4.1 now
      requires a verifier not to *resolve* an identifier through a lossy
      decode.  The reference goes further and refuses the whole
      envelope, so a deployment using opaque non-UTF-8 identifiers
      cannot use it at all.

Toraman                 Expires 16 February 2027               [Page 68]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *S4 -- deterministic CBOR is enforced envelope-wide.* Section 4.1
      requires the Core Deterministic Encoding Requirements for the
      protected header.  The reference's decoder applies them to the
      whole COSE object including the unprotected map, so an envelope
      this profile permits can be refused for an encoding choice outside
      the protected bytes.
   *  *S5 -- input ceilings that differ, which is not the same as
      ceilings that are missing.* The TypeScript reference fixes a 16
      MiB input limit, a JSON nesting depth of 64, a canonicalizer depth
      of 64 and a CBOR depth of 32.  The others are not unbounded: the
      Go verifier defines its own parser ceiling of 2000 nesting levels
      (impl-go/parse.go), the C# verifier inherits JsonDocument's
      default maximum depth of 64, and the Rust verifier relies on
      serde_json's nesting limit, which its own source names as the
      control.  Python has no explicit gate and stops at the
      interpreter's recursion limit.  So five verifiers enforce *four
      different ceilings*, and a document between the tightest and the
      loosest is refused by some and accepted by others.  Section 13
      assigns limits to the *Deployment* and fixes no number here, so
      every one of them conforms -- which is precisely why the
      disagreement is a fact about interop rather than a defect in any
      of them.  An earlier draft of this register said the other four
      had "no equivalent fixed limits"; that was false, and this row is
      the correction.
   *  *S6 -- non-NFC handling.* The reference reports non-NFC strings in
      a warnings channel by default and can be configured to refuse them
      outright; the other four have no mode and no warning.  Section 3.3
      permits both, which means the same receipt legitimately receives
      two different verdicts from two conforming verifiers, and a caller
      cannot tell which mode produced the one it holds.

   *Divergences among the five that the conformance harness cannot see.*
   The harness compares verdicts over a shared corpus.  A behaviour only
   one implementation has, or that no vector exercises, is invisible to
   it -- and these were found by reading the five sources against one
   another rather than by running them.

   *  *D1 -- one trust document, two verdicts, and one of them is an
      accusation.* An honest two-receipt chain signed by one key was
      presented to all five verifiers twice: once with a plain {kid:
      publicKey} keyring, once with this package's own noa.signing-key-
      lifecycle/0.1 trust document carrying *the same key* with
      retiredAt: null.  Plain keyring: VALID in all five.  Lifecycle
      document: VALID in TypeScript, TAMPERED in Python, Go, Rust and
      C#, the Python reason reading "unknown kid k-life at seq 0".  The
      four do not know the format, read it as a flat map, fail to find
      the kid, and conclude the receipt was signed outside the trust
      root -- so a legitimate trust document holding the correct key

Toraman                 Expires 16 February 2027               [Page 69]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      makes four of five verifiers accuse an honest chain of tampering.
      It is G6's defect reached through a different input, and the same
      violation of Section 8.3.  No file under conformance/ mentions the
      format, so no runner ever feeds it to them.
   *  *D2 -- one implementation does not state the key-canonicality
      check.* TypeScript, Python, Rust and C# each carry the y >= q
      rejection in their own source.  The Go verifier rejects the eight
      small-order encodings and has no y-coordinate gate at all,
      inheriting whatever its standard library does.  Section 4.2 makes
      that rejection a MUST as of this revision, so the Go verifier does
      not state a check it is now required to make.
   *  *D3 -- two implementations have no channel for a required
      statement.* Go and Rust carry no warnings field, so G14, G15 and
      G16 cannot be satisfied in them without an API change.  The corpus
      compares verdicts, and a missing warning is not a verdict.
   *  *D4 -- COSE exists once.* The envelope path is implemented only in
      the TypeScript reference, so nothing on it -- the alg pin, crit
      handling, deterministic encoding, kid resolution -- has cross-
      implementation evidence in either direction.

   *What the harness can and cannot settle, stated once.* conformance/
   MATRIX.md is generated from four runs: the TypeScript reference
   against the Python one, and then the Go, Rust and C# verifiers each
   against the Python one.  The topology is a star with the Python
   reference at its centre, not five implementations tested against one
   another -- so a behaviour the Python verifier does not implement
   cannot be seen by that harness at all, and five-way agreement and
   five-way nonconformance coexist without contradiction.  G1 to G3 are
   exactly that case: all five agree with each other, and none of them
   agrees with this document.

   *Two claims in the reference implementation's own comments are
   retracted by this revision and not yet corrected there.* src/cose/
   receipt-cose.ts calls its output a "COSE_Sign1 Signed Statement" and
   promises "the external non-equivocation anchor NOA's self-signed
   chain lacks".  Neither survives this revision: Section 4.3 shows what
   a Signed Statement additionally requires and the register above
   records that the implementation emits none of it, while Section 7
   narrows what registration supplies.  A reader who opens the code will
   find the older wording; it is a comment, not a control, and
   correcting it is filed.

Toraman                 Expires 16 February 2027               [Page 70]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *Conformance corpora, counted at the pinned snapshot.*
   conformance/vectors/attack/ 16 files and conformance/vectors/
   malformed/ 9 (25 adversarial in total); conformance/action-digest/ 33
   vectors, 34 in the repository since df777a6; packages/rail-
   x402/conformance/settlement-evidence/ 72 (1 accept, 57 reject, 14
   control); packages/evidence/conformance/ 77 bundles.  Alongside them,
   conformance/golden/ answers a different question: whether a real past
   release's own signed output still verifies today.

   *What a third party measured.* On 27 July 2026 an independent
   reconciliation implementation ran against this corpus at a pinned
   commit and reported on the SCITT list
   (https://mailarchive.ietf.org/arch/msg/scitt/zWZBQXXSGV-
   vgbTeOLTjlb9DGLg/): *23 of 23* adversarial files then published
   produced at least one integrity-class divergence, with cross-chain-
   splice the clean case -- both receipts verify in isolation and the
   forgery exists only in the set.  The same run measured a shared
   subject digest agreeing with another party's canonicalization corpus
   on *22 of 22* cases, while a separate ledger-indexing construction
   that applies Unicode normalization agreed on 20 of 22 under a UTF-16
   member sort and 19 of 22 under a code-point sort -- the collisions
   being invisible without a shared vector, which is the argument
   Section 10 makes normative.  The corpus has since grown from 23
   adversarial files to 25.

   *What is still missing.* The purpose-specific negative vectors that
   Section 8, Section 8.2 and Section 9 call for are not in the public
   corpus, with one exception: the attribution-substitution vector
   landed at df777a6.  The rest -- a controller success with no physical
   evidence, a controller success against a witness reporting non-
   completion, same-party evidence presented as independent, a missing
   signer relationship, a stale or replayed observation, and the
   positive baselines mirroring each -- remain committed and unwritten,
   as does a cross-implementation negative for the alg pin.

   *Not implemented, stated plainly.* Ten things, so that no reader has
   to infer them.  Item 1 is gap G8 of the register above.  Item 2 is
   permitted but unimplemented; items 3 and 4 are capabilities this
   profile deliberately excludes (Section 4.2, Section 5.1); the rest
   are absences with nothing owed against a rule.  The distinction is
   the one Section 8.3 insists on, applied to this section.

   1.   *No Signed Statement mode exists anywhere in the reference
        implementation, on either side.* The producer emits {1: -19, 4:
        kid} and no CWT_Claims (label 15), so what it mints does not
        meet Section 4.3 and a conforming Transparency Service is
        entitled to refuse it at registration.  The verifier is the
        other half, and the half a reader is most likely to assume: it

Toraman                 Expires 16 February 2027               [Page 71]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

        *ignores* label 15 as a non-critical header, and a committed
        test shows it accepting a protected header carrying a malformed
        15: bstr as a perfectly good generic COSE_Sign1.  No code path
        anywhere evaluates a receipt _as a Signed Statement_.
   2.   *Certificate-based key resolution is permitted but not
        implemented.* Section 4.1 lets a deployment carry x5t or x5chain
        in addition to kid; the verifier ignores both headers and
        resolves kid alone.  Nothing is excluded -- it is simply not
        built.
   3.   *There is no detached-payload mode.* The parser requires the
        payload element to be a byte string and refuses a null one; the
        producer always attaches.  Section 4.2 describes that and
        nothing more.
   4.   *No range-presented verification.* Every implementation requires
        the complete chain from seq == 0; a presentation starting at seq
        1 is refused as a missing genesis, not verified as a partial
        view.  Section 5.1 states that as the rule.  A verifier that
        could authenticate a mid-chain range against a trusted anchor is
        a real capability and this profile does not have one.
   5.   *No controller-outcome artifact and no physical-observation
        artifact.* The vocabulary of Section 8.1 for claims 2 and 3 is
        specification ahead of implementation.  The plane that exists is
        a payment settlement plane over one rail family; it is an
        instance of the _shape_ (Section 8.2, Section 8.3), not an
        answer to the actuator case the review thread was about.
   6.   *No settlement-evidence enrolment registry at the pinned 4764cab
        snapshot* -- the registry an Evidence Verifier would consult to
        decide which action classes require settlement evidence.  Device
        enrolment through pairing is a different mechanism and did exist
        at that snapshot, with its own conformance vectors; this item is
        not about it.  Without the action-class registry, settlement
        evidence cannot be _required_, so at this snapshot its absence
        costs nothing and its presence buys no upgrade.  Subsequent
        implementation work is outside the measurements reported here.
   7.   *The relationship signal is not surfaced in bundle verdicts*,
        and no level of this implementation can derive organizational
        independence at all.
   8.   *The bundle verifier never reaches a network service*, by
        design: a verifier that silently depends on a reachable service
        is not an offline verifier.  Anything that would require a live
        query is therefore outside what one of its verdicts can
        establish.
   9.   *No published reproducible demonstration of registration with an
        external SCITT Transparency Service.*

Toraman                 Expires 16 February 2027               [Page 72]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   10.  *The purpose-specific negative vectors of Section 12 are not
        written*, including a cross-implementation negative for the alg
        pin.  The attribution-substitution vector that was open in
        earlier drafts of this list is no longer among them: it landed
        at df777a6.

   The boundary item 1 leaves is worth stating in the sharpest available
   words: *"the signature verifies" and "an RFC 9943 Signed Statement
   validates" are different properties, and this implementation
   currently establishes only the first.* Closing it is work on both
   sides -- the producer must emit the protected claims, and the
   verifier must gain a mode that checks them and refuses a receipt that
   lacks or malforms them, per Section 4.3 and [RFC9597], Section 2,
   which defines label 15 as a CWT Claims map that occurs exactly once
   across the two header buckets.

   Every one of these is a boundary this document states rather than a
   gap it hides.  Where a reader finds a normative requirement here
   whose enforcement is on this list, that requirement is a
   specification for implementers -- including this one -- and not a
   report of shipped behaviour.

13.  Security Considerations

   _Analysis binds every actor.  Where a sentence carries a requirement
   it names its actor; the requirements in this section fall on the
   *Producer* (what MUST NOT appear on a receipt), on verifiers (what
   they MUST NOT report), and on the *Relying Party* (how results may be
   read)._

   This profile attests exactly two things: (1) the record is tamper-
   evident and signature-verifiable under the issuer's key; and (2) the
   recorded fields -- action, principal class, verdict, and whichever
   optional members are present -- are bound into that signature.
   "Policy identity" is one of the optional ones: both carriers may be
   absent (Section 3.3), and a receipt that omits them records no policy
   identity at all while remaining conformant.  The principal field is a
   class marker and not an identity: a receipt recording HUMAN names no
   human, and a relying party MUST NOT read one out of it.  It does NOT
   attest that the recorded inputs are true, complete, or timely (no
   capture-completeness); that the policy was adequate; that no action
   occurred outside the instrumented boundary; that the agent was
   correct, safe, or wise; that a named approver authorized this exact
   action before it ran; that a controller succeeded; or that any
   physical effect occurred.  These non-goals are NORMATIVE:
   implementations and relying parties MUST NOT imply the stronger
   claims from a receipt.

Toraman                 Expires 16 February 2027               [Page 73]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   Equivocation -- one issuer signing two divergent histories and
   showing each to a different party -- is not detectable by any check
   in this profile.  Section 5.1 catches a fork only when both branches
   are _presented together_, as a duplicate sequence; nothing reaches a
   branch the prover withholds.  Registration in a Transparency Service
   is a necessary step toward detecting them and is not a sufficient
   one: detection additionally requires consistency proofs between log
   states and a party that monitors them (Section 7), neither of which
   this profile specifies or requires.  A deployment that registers and
   never monitors has an auditable record and no equivocation defence.
   Identity attribution above key level requires the out-of-band
   identity manifest.  Algorithm-confusion and key-confusion attacks are
   mitigated by the strict alg = -19 and pinned-curve requirements of
   Section 4.  Raw prompts, tool arguments, and secrets MUST NOT appear
   on a receipt; only hashes (optionally HMAC for low-entropy values)
   are carried.

   *The scope of a checkpoint check is the scope of the key that signed
   it.* A checkpoint can reveal truncation relative to itself, and only
   to the strength of the binding between checkpoint authority and
   chain.  With an identity manifest, that authority is bound to the
   keys the manifest authorizes for the genesis receipt's agent.id -- a
   set, not one key (Section 5.2) -- so a re-heading attacker's
   checkpoint over its own appended head is rejected.  WITHOUT a
   manifest, checkpoint authentication is key-level only: any key the
   verifier trusts can mint a checkpoint over any head, so a co-trusted
   key holder can delete the most recent receipts, sign a checkpoint
   over the truncated head, and obtain a verified tail check over an
   incomplete chain.  A Chain Verifier MUST surface this limitation to
   the relying party whenever a checkpoint authenticates without a
   manifest, and MUST NOT report such a result as an unqualified tail-
   truncation check.  Even with a manifest the guarantee is opener-
   scoped: on a chain carrying more than one agent.id, the opener's
   checkpoint does not certify a co-agent's tail.

   A verifier never normalizes a non-NFC string, and this profile sets
   no default for whether it rejects one (Section 3.3); the analysis
   below is written for the accepting configuration, and a verifier in
   the refusing configuration simply never sees the ambiguity.  In the
   accepting configuration, because a non-NFC string is neither
   normalized nor rejected (Section 3.2, Section 3.3), two receipts may
   carry agent.id or action.id values that render identically but differ
   in bytes, and both verify.  A verifier configured in the optional
   refusal mode rejects such a receipt as malformed instead -- which
   removes the ambiguity for that verifier and for nobody else, since
   the same bytes still verify elsewhere.  Relying parties that match,
   index, or alert on these fields MUST compare them as bytes.
   Normalizing at their own layer before comparing is *not* an

Toraman                 Expires 16 February 2027               [Page 74]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   equivalent option: it is precisely what collapses two distinct,
   validly signed identifiers onto one index entry, match or alert
   subject, which is the collision this paragraph exists to warn about.
   A relying party MUST NOT assume that visual equality implies byte
   equality.

   *A trusted key can try to extend someone else's chain, and one
   condition stops part of it.* Every receipt in a chain is individually
   valid; nothing in a receipt says who is entitled to add the _next_
   one.  A party holding any key the verifier trusts can therefore
   append well-formed receipts to another party's chain -- correct
   prevHash, contiguous sequence, same scope.chain, same tenant -- and,
   *where the appended receipts claim the victim's own agent.id*, every
   condition but one stays silent.  The one that fires is chain-key-
   discontinuity (Section 5.1): those receipts carry a different sig.kid
   under that same agent.id.  A Chain Verifier that omits the check
   accepts a forged tail as history.  Two escapes remain, stated here
   rather than left for an attacker to find: an attacker who appends
   under a *new agent.id* trips no condition at all, because this
   profile defines no append authority for a chain (Section 5.1,
   Section 1.5); and an attacker whose second key is registered under
   the victim's *kid* defeats a comparison made on identifiers rather
   than on resolved key material.  Where the attacker instead reuses the
   victim's own agent.id _and_ sig.kid, it is signing with the victim's
   key, which is a key-compromise problem this profile cannot address.

   *A receipt can be re-wrapped by anyone who holds a trusted key.* The
   payload is self-contained and self-signed, and Section 4.2 permits
   the outer COSE signer to differ from the native signer.  It follows
   that any party whose key a verifier trusts can take another party's
   receipt, strip its envelope, and re-emit the same payload under its
   own outer signature: both signatures verify, because both are
   genuine.  Nothing in the bytes distinguishes the original emitter
   from a relay.  The consequences are bounded but real: the relay
   cannot alter a field without breaking the native signature, so the
   _content_ is safe; what it can do is present someone else's record as
   something it emitted, and -- if the verifier attributes from the
   outer kid -- have that attribution land on itself.  What stops that
   is the attribution model of Section 6, and it is worth being exact
   about which half does the work.  The manifest binds agent.id to
   authorized keys and is checked against the *native* sig.kid, so a
   relay cannot make itself the agent: the agent claim is carried by a
   signature the relay did not produce and cannot alter.  The relay is
   not refused for relaying -- Section 6 forbids rejecting a receipt
   solely because its outer signer is not one of the agent's keys,
   because relaying is a legitimate presentation.  What a verifier MUST
   NOT do is report the outer signer as the party that made the record.
   Without a manifest, attribution is key-level only and even the agent

Toraman                 Expires 16 February 2027               [Page 75]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   claim is unbound.  Registration does not help here: a Transparency
   Service that follows Section 7 will happily register a relayed
   statement, because every signature in it is valid.

   *Same-party evidence is the forensic trap this profile names rather
   than solves.* A signed outcome produced under the same administrative
   control as the authorization is not independent evidence, however
   sound its cryptography; independence is a property of the trust
   configuration a verifier applies, never of a field a producer writes
   about itself (Section 6.1).  An implementation that renders UNKNOWN
   as "independent" has defeated the control.

   *Substitution across claim classes is a signature-valid attack.* Both
   the post-execution record presented as authorization and the machine
   decision presented as human approval (Section 9) carry genuine
   signatures.  An *Evidence Verifier* that returns one boolean cannot
   express "signature good, claim wrong".  That is a defect in what such
   a result can tell its reader, not a conformance failure:
   Section 8.2's claim-class machinery is non-normative in this
   revision, so nothing here makes a one-boolean result nonconformant.
   A reader deciding whether to rely on such a verifier should treat the
   missing distinction as the gap it is.

   *Parsing attacker-supplied input is a cost this profile does not
   bound.* A verifier ingests JSON and CBOR from whoever presents them,
   and the checks required here -- duplicate-member detection, surrogate
   validation, canonical re-serialization -- are all performed on that
   input before anything about it is trusted.  This profile bounds
   exactly one string -- id, at 128 code points (Section 3.1) -- and
   sets no maximum payload size, nesting depth, member count, or chain
   length, and a Chain Verifier is additionally required to hold a
   complete chain from genesis (Section 5.1), which grows without bound.
   A *Deployment* MUST impose its own limits and MUST refuse input that
   exceeds them rather than attempting a partial verification; a limit
   that is exceeded is not a tampering finding and MUST NOT be reported
   as one.  A deployment that omits limits has a denial-of-service
   surface, not a correctness problem.

   *An unpinned digest construction is a silent join.* Comparing digests
   produced under different constructions can both miss a real
   correlation and, where one construction normalizes and another does
   not, map two different actions onto one value.  Section 10 requires
   the comparison to fail closed and be reported as indeterminate.

   *Absence of scope.tenant is not a tenancy reset* (Section 3.3); a
   verifier that treats it as one accepts a cross-tenant splice that
   carries no tampering evidence of its own.

Toraman                 Expires 16 February 2027               [Page 76]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

14.  Privacy Considerations

   _This section addresses the *Producer* and the *Deployment*
   (Section 1.4); verifiers inherit no obligation from it._

   A receipt is designed to be shown to parties who were not present
   when the action ran, so what it carries is a privacy decision as much
   as a security one.

   *Raw parameters are forbidden, not prevented.* This profile prohibits
   a *Producer* from placing raw prompts, tool arguments, secrets or
   other sensitive parameters anywhere on a receipt (Section 3), and
   action.paramsHash carries a digest in place of the values.  What the
   format cannot do is enforce it: several members are unconstrained
   strings (Section 3.1), so a producer that writes a secret into one
   produces a receipt every verifier accepts.  A deployment handling
   sensitive parameters therefore needs a producer-side control, and a
   relying party that needs the parameters must obtain them out of band.
   Whether it can then _open_ the commitment is a matter for the
   producer's own contract, not for this profile: Section 3 states that
   the preimage construction is undefined here, and for the keyed form
   the key is a tenant secret.  So the privacy property is one-
   directional -- the receipt does not disclose the parameters
   themselves -- and the verification property it might seem to imply
   does not follow from this document alone.  What the receipt does
   disclose is set out below: a guessable commitment is an oracle, and
   the identifiers and timestamps are linkable by design.

   *A hash of a low-entropy value is not a privacy control.* Where the
   committed parameters are guessable -- an amount, a boolean, a small
   identifier -- SHA-256 is a confirm-by-guess oracle rather than a
   shield, since anyone can hash a candidate and compare.  For those
   cases the profile provides the keyed form hmac-sha256:<hex> under a
   tenant-scoped key, which removes the oracle from anyone who does not
   hold the key.  Producers SHOULD use it whenever the parameter space
   is enumerable, and MUST NOT treat a plain digest of a low-entropy
   value as a disclosure control.

   *What remains linkable, by design.* A receipt still carries
   scope.chain, agent.id, action.id, action.canonical, timestamps and,
   where present, governance.approval.by.  These are opaque strings to
   this format, but they are stable across receipts, which is what makes
   a chain a chain: any party holding two receipts can tell they concern
   the same chain or the same agent, and timestamps support timing
   correlation.  A *Deployment* that treats those identifiers as
   sensitive SHOULD choose opaque, non-descriptive values -- an internal
   identifier rather than a person's address -- because the format
   cannot enforce that and a verifier cannot undo a descriptive choice.

Toraman                 Expires 16 February 2027               [Page 77]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *Registration publishes, to the extent the log retains.* Submitting a
   Signed Statement places it and the CWT Claims in its protected header
   into an append-only log whose purpose is that third parties can
   inspect it.  How much of the payload they can see is the log's
   choice, not this profile's.  [RFC9943], Section 6.2 contemplates
   statements whose payload is carried as a hash rather than in full --
   and *that construction is not conformant with this profile as
   specified*: Section 4.2 requires the receipt itself to be the
   attached payload, and Section 7 requires a Transparency Service to
   validate that payload as a receipt and to check sub against its
   scope.chain.  A hash-only statement fails both.  A deployment that
   needs to disclose less therefore cannot get it from this revision;
   defining a mapping -- what the hash covers, and what a service can
   still check -- is work for a future one.  CWT Claims in COSE headers
   are not encrypted ([RFC9597], Section 3), so iss and sub are visible
   to every party that can read the log.  A deployment SHOULD decide
   what may be published _before_ it registers: transparency rests on an
   append-only sequence, which [RFC9943], Section 5.1.3 requires the
   log's verifiable data structure to guarantee -- it cannot be
   modified, deleted or reordered -- so an entry cannot be un-
   registered, and this document defines no redaction mechanism.  What a
   service retains and serves beyond that history is its own policy,
   which this profile does not constrain.

   *Signer relationship reporting is a disclosure too.* The trust-
   configuration digests that Section 6.1 requires alongside a derived
   relationship commit to a policy and a registry snapshot; they do not
   disclose their contents, and a *Producer* SHOULD keep it that way
   rather than inlining registry material into a result a relying party
   may forward.

15.  Open questions for the working group

   _This section is to be removed by the RFC Editor before publication.
   It records what this revision deliberately did not settle, so that a
   reader does not mistake an open question for an oversight._

   *  *The verification equation is pinned in this revision, and the
      working group may revisit which one.* Section 4.2 pins the
      cofactorless check together with the canonical signature scalar,
      the canonical public-key encoding and the rejection of the eight
      small-order encodings; [RFC8032], Section 8.8 explains in its own
      words why the choice cannot be left open -- any signature meeting
      the non-multiplied equation satisfies the multiplied one, so
      implementations that choose differently disagree about the exact
      set of valid signatures, and in a hash chain that is a divergent
      accepted history.  This revision therefore chose, rather than
      leaving validity implementation-defined.  What remains genuinely

Toraman                 Expires 16 February 2027               [Page 78]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      open is _which_ of the two the working group wants.  The evidence,
      taken from this document's own measurements (Section 12, G20):
      four of the five shipped verifiers were measured cofactorless --
      Python, Rust and Go from their sources, and the TypeScript
      reference through the OpenSSL version it was measured against --
      and the fifth could not be measured.  So the equation chosen here
      is the one four of five already implement, and the argument for
      the other is not "it matches what ships".  Either can be made
      deterministic; neither can be left unmade.
   *  *The request signer is defined by example, which is why the text
      that needs it is not normative.* Section 6.1 derives a signer
      relationship against the _request signer_, and this document
      describes that party only by pointing at what the reference
      implementation signs with.  That is one of the reasons the
      relationship analysis there carries no requirement in this
      revision.  The question for the working group is what a definition
      would have to fix -- the party, the trust configuration it is
      derived from, and the digests that identify that configuration --
      before the analysis can become a requirement anywhere.
   *  *Bare or enveloped?* Section 4 admits both forms because both
      ship.  Whether a SCITT-native profile should require the envelope
      -- making every receipt registrable at the cost of forbidding the
      bare form every current implementation verifies -- is a genuine
      fork.
   *  *Duplicate sequence numbers, in a future revision.* This revision
      answers the question in the strict direction: a byte-identical
      duplicate is one of the six chain conditions, so the set fails and
      a verifier that de-duplicates and returns a positive result is not
      conformant (Section 5.1).  That is deliberately the safe answer
      rather than the obviously right one -- a retransmitted copy is an
      innocent event, and refusing it costs an operator something real.
      Whether a *future* revision should permit acceptance after de-
      duplication, and under what reporting requirement, is the open
      question; it is not open in this one.
   *  *Where the Evidence-Verifier layer belongs, now that this revision
      has stopped requiring it.* Section 6.1, Section 8.1, Section 8.2,
      Section 9 and Section 10 each mark the passages that run over
      artifacts Section 1.5 lists as undefined, and those passages carry
      no RFC 2119 requirement here: an implementation cannot fail them.
      That was the honest answer to an untestable obligation, and it
      leaves a real question rather than settling it.  Either the
      artifact formats come into this profile and the analysis becomes
      normative here, or the analysis moves into the companion documents
      that define them and becomes normative there.  What should not
      persist is the present state, where the reasoning is written in
      one document and enforceable in none.

Toraman                 Expires 16 February 2027               [Page 79]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Should the two untokenised results be named?* Section 1.5 lists
      them: the conflict result of Section 8.2 and the unproven-
      authorization result of Section 9.  Neither carries a requirement
      in this revision -- both live in passages marked non-normative --
      and neither has a token, so an implementation that reports them
      chooses its own name and two implementations reporting the same
      finding will not agree on it.  Defining the result and its token
      together is a small vocabulary decision with a real
      interoperability consequence, and it is the working group's to
      make rather than this author's.
   *  *"Issuer" is overloaded across three different parties.*
      Section 1.4 aliases the native Producer as the Issuer; Section 4.3
      uses iss for the authority the outer Signed Statement is emitted
      on behalf of; Section 6.1 calls the native signer the issuer; and
      a relay that wraps someone else's receipt is a fourth party using
      the same envelope position (Section 13).  Nothing here is
      contradictory, and an implementer can still build from it -- but a
      reader has to carry the disambiguation in their head, and the
      ambiguity invites exactly the native/outer collapse Section 6
      forbids.  Whether these should be distinct named roles, and which
      of them iss denotes when they differ, is a naming decision with
      security consequences and it belongs to the working group.
   *  *This profile forbids the leap-second representation, and that is
      a decision to review.* Section 3.3 requires a Producer not to emit
      a date-time whose seconds field reads 60, and a verifier to reject
      one.  The alternative this revision rejected was to admit 60 and
      require nobody to validate it, which is not implementable offline:
      [RFC3339], Section 5.7 admits 60 only at an actual leap-second
      position adjusted by the value's offset, and says future leap
      seconds cannot be predicted, so a verifier holding no table cannot
      decide whether such a value is a valid date-time -- and the
      requirement to reject what is not valid would have no determinate
      answer.  Pinning a table was rejected too: a table is state that
      ages, and offline verifiers acquire it at different times, so two
      conforming verifiers would still disagree about a historical
      instant.  Forbidding the representation is the only branch that
      leaves every verifier the same answer, and it costs a Producer
      nothing it needs.  The working group may prefer one of the
      branches this revision declined; the cost of each is stated here
      so the choice can be made on evidence.
   *  *Key rotation, and what it currently costs.* Section 5.1 requires
      one key per agent.id within a presented chain, which is what
      closes the chain-extension attack; the price is stated in
      Section 5.2: rotation is not expressible inside a chain, so a
      deployment that rotates a signing key starts a new one.  The
      reference implementation has gone further and refuses a receipt
      signed by a key its trust document marks retired, which this
      profile does not require (Section 12).  Whether a rotation or

Toraman                 Expires 16 February 2027               [Page 80]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      revocation mechanism belongs in the profile -- and if so, whether
      it may relax the one-key rule or must sit beside it -- is a
      genuine trade between an attack this revision closes and an
      operational need every deployment eventually has.
   *  *Standards Track with no IANA action, or Experimental?* The header
      of this revision reads Standards Track, which is itself a change
      from -00's Informational (Appendix A); it records the author's
      current intention, not a decision taken for the working group.
      Section 16 requests nothing, so there is no media type for the
      payload, and Section 4.3's content type cannot be interoperable
      across deployments.  Two answers are available and the document
      does not choose between them: register a media type and stay on
      the Standards Track, or publish as Experimental while the
      profile's open questions settle and register later.  What would be
      wrong is to ship a wire format on the Standards Track with
      neither.

16.  IANA Considerations

   _This section carries no normative requirement on any actor._

   This document has no IANA actions in this revision, and one of those
   absences is load-bearing: without a registered media type for the
   action-receipt payload, the content type of Section 4.3 cannot be
   interoperable across deployments.  A future revision ought to
   register one, and a Standards Track document that carries a wire
   format arguably should not ship without it -- this revision states
   the gap rather than papering over it.  It uses the existing IANA COSE
   Algorithms registry value -19 (Ed25519) and the existing COSE/CWT
   header parameters.  The vocabularies named in Section 6.1,
   Section 8.2, and Section 8.3 are shared spellings for _reporting_,
   not an interoperable output format -- this revision defines no result
   schema (Section 1.5), so two implementations using the same word
   still do not produce comparable output -- and they are not proposed
   for registration in this revision.  A future revision could request
   registration of a media type for the action-receipt payload and/or of
   CWT or COSE claims for the payload fields.

17.  References

17.1.  Normative References

   [FIPS180-4]
              National Institute of Standards and Technology, "Secure
              Hash Standard (SHS)", FIPS PUB 180-4, August 2015,
              <https://csrc.nist.gov/pubs/fips/180-4/upd1/final>.

Toraman                 Expires 16 February 2027               [Page 81]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   [RFC2104]  Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
              Hashing for Message Authentication", RFC 2104,
              DOI 10.17487/RFC2104, February 1997,
              <https://www.rfc-editor.org/info/rfc2104>.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

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

   [RFC4648]  Josefsson, S., "The Base16, Base32, and Base64 Data
              Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
              <https://www.rfc-editor.org/info/rfc4648>.

   [RFC8032]  Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
              Signature Algorithm (EdDSA)", RFC 8032,
              DOI 10.17487/RFC8032, January 2017,
              <https://www.rfc-editor.org/info/rfc8032>.

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

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

   [RFC8949]  Bormann, C. and P. Hoffman, "Concise Binary Object
              Representation (CBOR)", STD 94, RFC 8949,
              DOI 10.17487/RFC8949, December 2020,
              <https://www.rfc-editor.org/info/rfc8949>.

   [RFC9052]  Schaad, J., "CBOR Object Signing and Encryption (COSE):
              Structures and Process", STD 96, RFC 9052,
              DOI 10.17487/RFC9052, August 2022,
              <https://www.rfc-editor.org/info/rfc9052>.

   [RFC9053]  Schaad, J., "CBOR Object Signing and Encryption (COSE):
              Initial Algorithms", RFC 9053, DOI 10.17487/RFC9053,
              August 2022, <https://www.rfc-editor.org/info/rfc9053>.

Toraman                 Expires 16 February 2027               [Page 82]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   [RFC9360]  Schaad, J., "CBOR Object Signing and Encryption (COSE):
              Header Parameters for Carrying and Referencing X.509
              Certificates", RFC 9360, DOI 10.17487/RFC9360, February
              2023, <https://www.rfc-editor.org/info/rfc9360>.

   [RFC9597]  Looker, T. and M.B. Jones, "CBOR Web Token (CWT) Claims in
              COSE Headers", RFC 9597, DOI 10.17487/RFC9597, June 2024,
              <https://www.rfc-editor.org/info/rfc9597>.

   [RFC9864]  Jones, M.B. and O. Steele, "Fully-Specified Algorithms for
              JSON Object Signing and Encryption (JOSE) and CBOR Object
              Signing and Encryption (COSE)", RFC 9864,
              DOI 10.17487/RFC9864, October 2025,
              <https://www.rfc-editor.org/info/rfc9864>.

   [RFC9942]  Steele, O., Birkholz, H., Delignat-Lavaud, A., and C.
              Fournet, "CBOR Object Signing and Encryption (COSE)
              Receipts", RFC 9942, DOI 10.17487/RFC9942, June 2026,
              <https://www.rfc-editor.org/info/rfc9942>.

   [RFC9943]  Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande,
              Y., and S. Lasker, "An Architecture for Trustworthy and
              Transparent Digital Supply Chains", RFC 9943,
              DOI 10.17487/RFC9943, June 2026,
              <https://www.rfc-editor.org/info/rfc9943>.

   [UAX15]    The Unicode Consortium, "Unicode Standard Annex #15:
              Unicode Normalization Forms", 2025,
              <https://www.unicode.org/reports/tr15/>.

17.2.  Informative References

   [ACTA]     Farley, T., "Signed Decision Receipts for Machine-to-
              Machine Access Control", Work in Progress, Internet-Draft,
              draft-farley-acta-signed-receipts-02, June 2026,
              <https://datatracker.ietf.org/doc/draft-farley-acta-
              signed-receipts/>.

   [AGENTROA] Michalak, J., "Agent Route Origin Authorization
              (AgentROA): A Cryptographic Policy Enforcement Framework
              for AI Agent Actions", Work in Progress, Internet-Draft,
              draft-nivalto-agentroa-route-authorization-01, April 2026,
              <https://datatracker.ietf.org/doc/draft-nivalto-agentroa-
              route-authorization/>.

Toraman                 Expires 16 February 2027               [Page 83]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   [AI-ART50] Dawkins, V., "A SCITT Profile for EU AI Act Article 50
              Transparency Receipts", Work in Progress, Internet-Draft,
              draft-dawkins-scitt-ai-article50-00, May 2026,
              <https://datatracker.ietf.org/doc/draft-dawkins-scitt-ai-
              article50/>.

   [AIVS]     Stone, B., "AIVS: Agentic Integrity Verification
              Standard", Work in Progress, Internet-Draft, draft-stone-
              aivs-00, March 2026,
              <https://datatracker.ietf.org/doc/draft-stone-aivs/>.

   [ASQAV]    Gomes Marques, J. A., "Compliance Profile of Signed Action
              Receipts for AI Agents", Work in Progress, Internet-Draft,
              draft-marques-asqav-compliance-receipts-07, July 2026,
              <https://datatracker.ietf.org/doc/draft-marques-asqav-
              compliance-receipts/>.

   [I-D.hillier-scitt-arp]
              Hillier, J. D., "Attestation Reconciliation Protocol",
              Work in Progress, Internet-Draft, draft-hillier-scitt-arp-
              03, August 2026, <https://datatracker.ietf.org/doc/draft-
              hillier-scitt-arp/>.

   [I-D.schrock-action-evidence-boundary]
              Schrock, I., "The Action Evidence Boundary for
              Consequential Agent Effects", Work in Progress, Internet-
              Draft, draft-schrock-action-evidence-boundary-03, August
              2026, <https://datatracker.ietf.org/doc/draft-schrock-
              action-evidence-boundary/>.

   [I-D.toraman-noa-action-digest]
              Toraman, T., "The NOA Action Digest: a Domain-Separated
              Correlation Value for Human-Approved Agent Actions", Work
              in Progress, Internet-Draft, draft-toraman-noa-action-
              digest-01, August 2026, <https://datatracker.ietf.org/doc/
              draft-toraman-noa-action-digest/>.

   [I-D.toraman-noa-settlement-evidence]
              Toraman, T., "Settlement Evidence for Human-Approved Agent
              Payments", Work in Progress, Internet-Draft, draft-
              toraman-noa-settlement-evidence-01, August 2026,
              <https://datatracker.ietf.org/doc/draft-toraman-noa-
              settlement-evidence/>.

   [OWASP-MCP]
              OWASP, "OWASP MCP Top 10", Entry MCP08:2025, Lack of Audit
              and Telemetry, 2025,
              <https://owasp.org/www-project-mcp-top-10/>.

Toraman                 Expires 16 February 2027               [Page 84]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   [PSER]     Wilder, R., "A SCITT Profile for Physical-Site Engagement
              Receipts", Work in Progress, Internet-Draft, draft-wilder-
              scitt-physical-site-engage-receipt-00, July 2026,
              <https://datatracker.ietf.org/doc/draft-wilder-scitt-
              physical-site-engage-receipt/>.

   [RFC7942]  Sheffer, Y. and A. Farrel, "Improving Awareness of Running
              Code: The Implementation Status Section", BCP 205,
              RFC 7942, DOI 10.17487/RFC7942, July 2016,
              <https://www.rfc-editor.org/info/rfc7942>.

   [SCITT-VCP]
              Kamimura, T., "A SCITT Profile for Verifiable Audit Trails
              in Algorithmic Trading: The VeritasChain Protocol (VCP)",
              Work in Progress, Internet-Draft, draft-kamimura-scitt-
              vcp-03, July 2026, <https://datatracker.ietf.org/doc/
              draft-kamimura-scitt-vcp/>.

Appendix A.  Changes since -00

   _This section is to be removed by the RFC Editor before publication._

   This revision exists because of a public review thread.  What follows
   is that story in order: what was asked, what was built and measured
   in answer, and what this document now guarantees.  Every difference
   between the posted -00 and this text is accounted for here -- a
   reader diffing the two should find no change this section does not
   explain.

A.1.  Interface stability, and the two corrections a citing document
      must act on

   Section 5 keeps its number, its title and its XML anchor (hash-
   chaining-and-completeness), so both numeric and fragment references
   from [PSER] continue to resolve, and the construction it defines --
   chain.seq, prevHash, the linkage rule -- is unchanged.

   *Two sentences of its paragraph were wrong in -00 and are corrected
   in this revision.* A document that adopted Section 5 by reference
   inherited both, so the change is stated here in the terms an
   implementer needs:

   *  _Checkpoint authority._ -00 said the authority "is bound to the
      genesis key (the key authorized at seq == 0), so a foreign
      checkpoint produced by a re-heading attacker is rejected".  That
      binding does not exist on its own: it requires an identity
      manifest, and it binds to the _set_ of keys the manifest
      authorizes for the genesis receipt's agent.id. -01 says so, and

Toraman                 Expires 16 February 2027               [Page 85]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      says plainly that without a manifest the property does not hold.
      *An implementation that relied on -00's sentence believes it
      rejects a re-heading attacker and does not.*
   *  _Tail truncation._ -00 said the profile "detects in-band tampering
      and tail truncation _within_ a presented chain".  Tail truncation
      is not detectable from a presented set at all -- a prover who
      withholds the tail presents a set with nothing missing in it. -01
      says truncation is detectable only against an authenticated
      checkpoint. *An implementation that relied on -00's sentence
      believes a clean verification result means nothing was deleted
      from the end.  It does not.*

   Nothing else in the paragraph changed, and no receipt changes
   validity because of these two corrections: they describe what
   verification establishes, not how a receipt is built. *Subsections
   5.1 and 5.2 are NEW, and the principal requirements they add are:*

   *  detect all six chain conditions, each decided from the presented
      set alone (MUST), and report them distinguishably (MUST);
   *  report the checkpoint axis in exactly one of its three states --
      answered, unanswered, unusable (MUST) -- and never let any of them
      change the verdict the six conditions produced (MUST NOT);
   *  require the complete chain from seq == 0, refusing a presentation
      that begins elsewhere (MUST);
   *  distinguish a consistent extension past an older checkpoint from a
      head conflict (MUST), never report the former as the latter (MUST
      NOT), and never name a cause -- truncation, fork or signer error
      -- that the comparison did not establish (MUST NOT);
   *  refuse to let an unauthenticated checkpoint establish a head
      conflict (MUST NOT), reporting checkpoint-unverified instead;
   *  state whether the checkpoint behind any tail conclusion was
      authenticated (MUST);
   *  report every condition that holds rather than the first found
      (MUST);
   *  never report a chain-level condition as a per-receipt failure
      (MUST NOT);
   *  never infer completeness from the absence of these conditions
      (MUST NOT);
   *  (this one binds a *Deployment*, not a Chain Verifier) take
      temporal ordering from something other than ts (MUST), since no
      check constrains it;
   *  on a multi-agent chain, never report an unqualified tail check
      (MUST NOT) and state whose view the check covers (MUST);
   *  never treat a checkpoint's age as bounded by anything in the
      object (MUST NOT), since ts is signer-chosen and this profile
      defines no expiry;

Toraman                 Expires 16 February 2027               [Page 86]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  validate a supplied checkpoint's structure before authenticating
      it (MUST) -- closed object, spec, the four value shapes and the
      sig sub-object -- and never turn a malformed checkpoint into a
      finding about the chain (MUST NOT);
   *  compare a supplied checkpoint's chain to the presented scope.chain
      (MUST), report a mismatch as a finding about the checkpoint, and
      never let it fail an otherwise valid presented chain (MUST NOT);
   *  never return a positive result for a set on which any of the six
      chain conditions holds (MUST NOT), with no exception for a byte-
      identical duplicate;
   *  when an identity manifest is supplied, require a checkpoint's
      sig.kid to be authorized for the genesis receipt's agent.id and
      reject any other trusted key as UNTRUSTED (MUST);
   *  when no checkpoint is supplied, report the tail question as
      unanswered (MUST) rather than as an absence of truncation (MUST
      NOT);
   *  reject a presented chain in which two receipts share an agent.id
      and differ in sig.kid (MUST), reporting chain-key-discontinuity;
   *  where it _chooses_ to compare resolved key material as well (MAY),
      report that as a separate result rather than under the identifier
      comparison's name (MUST, conditional on the choice);
   *  report an unusable checkpoint as unusable and say which reason
      applies -- malformed, wrong chain, or unauthenticated -- and
      report the tail question as unanswered in every one of those cases
      (MUST);
   *  (*Deployment*) present a chain for verification from genesis
      (MUST), since a Chain Verifier refuses a presentation that begins
      elsewhere;
   *  (*Deployment*) never assume the outer envelope's kid is the
      identifier an identity manifest authorizes for a checkpoint (MUST
      NOT) -- a checkpoint is a native artifact and the two identifier
      spaces are separate;
   *  (*Deployment*) where freshness is needed, impose a maximum
      checkpoint age from its own clock and say so in its output (MUST),
      because nothing in the object bounds it.

   *This list is not exhaustive, and this revision no longer claims that
   it is.* Three earlier drafts made that claim and each was wrong: the
   list is written by hand, 5.1 and 5.2 are long, and a hand-written
   inventory of a long section rots the moment either changes.  It
   records the principal additions -- most binding a Chain Verifier,
   four binding a *Deployment* as marked, one conditional on an option a
   verifier need not take.  None constrains a Producer or changes how a
   chain is _built_, so a profile that adopts the convention to build
   receipts is unaffected.  A reader who needs the complete set has to
   read 5.1 and 5.2, which is the honest instruction.

Toraman                 Expires 16 February 2027               [Page 87]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *One documentation narrowing, disclosed rather than buried.* -00 said
   "a verifier checking a range of receipts MUST verify ..." and never
   said what a range may be. 5.1 now states that a conforming verifier
   requires the complete chain from seq == 0 and refuses a presentation
   that begins elsewhere.  That is a narrowing *of the text, not of any
   behaviour*: all five verifiers -- the reference implementation, the
   Python one compared directly to it, and the Go, Rust and C# ones
   compared to Python -- already hardcode 0..n-1, and a presentation of
   seq 1,2 has always been refused as a missing genesis.  So no receipt
   that verified under a -00 implementation fails under a -01
   implementation, and no implementation changes; what changed is that
   the requirement is now written down where an implementer can read it,
   and the capability nobody has -- verifying a mid-chain range against
   a trusted anchor -- is named as absent in Section 12 instead of being
   implied by silence.

   The same care applies to the gap condition itself: a correctly linked
   chain presenting 0 then 2 was underspecified in -00 and is a chain-
   sequence-gap failure under 5.1.  Any implementation of -00 already
   rejected it, so this is again documentation catching up to behaviour
   rather than a change of outcome -- but an implementer who read -00
   literally and built a permissive verifier would find their verifier
   non-conforming under -01, and that is worth saying plainly.

   *What happened to every -00 section, checked against the posted text
   rather than remembered.* Sections 1 through 7 keep their -00 numbers.
   The rest moved, and one was removed:

Toraman                 Expires 16 February 2027               [Page 88]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

       +======================+===================================+
       | In -00               | In -01                            |
       +======================+===================================+
       | 1-7                  | unchanged numbers                 |
       +----------------------+-----------------------------------+
       | 8 -- Relationship to | *removed.* It changed no          |
       | ACTA signed receipts | requirement, and a field-by-field |
       | (equivalence), with  | mapping to one other individual   |
       | its mapping table    | draft did not earn a section here |
       +----------------------+-----------------------------------+
       | 9 -- Policy-replay   | 11                                |
       | out of scope         |                                   |
       +----------------------+-----------------------------------+
       | 10 -- Security       | 13                                |
       | Considerations       |                                   |
       +----------------------+-----------------------------------+
       | 11 -- IANA           | 16                                |
       | Considerations       |                                   |
       +----------------------+-----------------------------------+
       | Appendix A --        | 12, promoted into the body where  |
       | Implementation       | RFC 7942 places it                |
       | status               |                                   |
       +----------------------+-----------------------------------+
       | Appendices B and C   | 17.1 and 17.2                     |
       | -- the two reference |                                   |
       | lists                |                                   |
       +----------------------+-----------------------------------+
       | --                   | 8, 9 and 10 are new (external-    |
       |                      | world non-claims, authorization   |
       |                      | vs evidence, the digest boundary) |
       +----------------------+-----------------------------------+
       | --                   | *14, Privacy Considerations, is   |
       |                      | new*, and -00 had no privacy      |
       |                      | section at all                    |
       +----------------------+-----------------------------------+
       | --                   | *15, Open questions for the       |
       |                      | working group, is new*            |
       +----------------------+-----------------------------------+
       | --                   | Appendix A (this change log) and  |
       |                      | Appendix B (acknowledgments) are  |
       |                      | new                               |
       +----------------------+-----------------------------------+

                                 Table 8

   The record format itself is untouched: no member of noa.receipt/0.1
   is added, removed, or re-typed.

Toraman                 Expires 16 February 2027               [Page 89]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

A.2.  What the author committed to on 23 July, item by item

   The author's reply to the thread
   (https://mailarchive.ietf.org/arch/msg/scitt/7QfK2KTD-
   WdRrPMnfZlwnDC3_NA/) listed ten things -01 would do.  Eight are done
   in this text; two -- items 3 and 4 -- are partly done, and the table
   says which part of each is outstanding.

    +=========================+=======================================+
    | Committed               | Where it landed                       |
    +=========================+=======================================+
    | 1.  Separate            | Section 8.1                           |
    | authorization,          |                                       |
    | controller-reported     |                                       |
    | outcome and physical    |                                       |
    | completion              |                                       |
    +-------------------------+---------------------------------------+
    | 2.  Define trust        | Section 8.2, Section 8.3              |
    | semantics and failure   |                                       |
    | behaviour for each      |                                       |
    | claim independently     |                                       |
    +-------------------------+---------------------------------------+
    | 3.  Make signer         | Section 6.1; derived and machine-     |
    | relationships machine-  | readable in the reconciler            |
    | readable when signed    | (Section 12), *not yet surfaced in    |
    | outcome evidence is     | bundle verdicts*, and never derivable |
    | present                 | as organizational independence today  |
    +-------------------------+---------------------------------------+
    | 4.  Add purpose-        | The attribution-substitution vector   |
    | specific negative       | landed at df777a6 (corpus 33 -> 34);  |
    | conformance vectors     | the rest are named and committed in   |
    |                         | Section 12 and *not yet written* --   |
    |                         | stated as open, not as done           |
    +-------------------------+---------------------------------------+
    | 5.  Define the shared   | Section 10, construction published    |
    | action-digest           | separately                            |
    | construction rather     | [I-D.toraman-noa-action-digest]       |
    | than assume equivalence |                                       |
    | with action.paramsHash  |                                       |
    +-------------------------+---------------------------------------+
    | 6.  Clarify the         | Section 4.2                           |
    | relation between the    |                                       |
    | native receipt          |                                       |
    | signature and the outer |                                       |
    | COSE envelope           |                                       |
    +-------------------------+---------------------------------------+
    | 7.  Resolve the policy- | Section 3.3                           |
    | identity inconsistency  |                                       |

Toraman                 Expires 16 February 2027               [Page 90]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

    | in the base payload     |                                       |
    +-------------------------+---------------------------------------+
    | 8.  Say clearly that a  | Section 5, Section 5.1 and Section 13 |
    | self-signed chain       |                                       |
    | cannot prove an unseen  |                                       |
    | tail does not exist     |                                       |
    +-------------------------+---------------------------------------+
    | 9.  Replace "non-       | Abstract and Section 1 now say        |
    | repudiable" with the    | issuer-authenticated / signature-     |
    | narrower wording        | verifiable                            |
    +-------------------------+---------------------------------------+
    | 10.  Update the stale   | Section 12: -19 is emitted, -8        |
    | algorithm-migration     | rejected under a genuine signature,   |
    | note                    | note corrected rather than carried    |
    |                         | forward -- and the stale _byte        |
    |                         | string_ an earlier revision quoted is |
    |                         | corrected in the same place           |
    +-------------------------+---------------------------------------+

                                  Table 9

A.3.  Corrections this revision makes to -00's own text

   *  *The protected-header key-identifier rule CHANGED, and this is a
      change rather than a correction.* -00 required the protected
      header to contain "a key identifier sufficient to resolve the
      verification key: kid (label 4), *or* a certificate reference (x5t
      label 34 / x5chain label 33) where a PKI is used" -- a
      disjunction, not a contradiction. -01 makes a resolvable kid
      mandatory and demotes the certificate references to additional-
      only, because a verifier conforming to this profile is required to
      resolve kid and is not required to process certificates.  A
      producer that satisfied -00 by carrying x5t alone is *not*
      conformant to -01.  Section 4 now says kid SHOULD be protected,
      MAY be unprotected, MUST be resolvable from either with the
      protected copy preferred, and that a verifier MUST report which
      bucket it used -- because attribution from an unprotected
      identifier is not covered by the signature, so an unprotected kid
      may resolve a key but never names an identity (Section 6).  It
      also states that additional registered headers MUST NOT cause
      rejection unless listed in crit.
   *  *Terminology defined a policyHash the payload never carried.*
      Section 3.3 resolves it in favour of what the wire format does:
      governance.ruleId is a label, the optional governance.compliance
      member is where a policy commitment lives, and neither makes a
      receipt replayable.

Toraman                 Expires 16 February 2027               [Page 91]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *scope.tenant was shown as always present.* It is optional, and
      Section 3.3 states the rule that matters: absence MUST NOT reset a
      tenancy comparison, or an optional field becomes a splice channel.
   *  *-00 said the commitment fields were not carried at all*, in the
      section that is now Section 11.  They may be; what remains
      unspecified is the replay _construction_. The prohibition on
      presenting a receipt as carrying a re-derivable verdict is
      unchanged.
   *  *The implementation-status byte string was wrong.* An earlier
      revision quoted a10132 as the protected header this implementation
      emits.  It is not: that encodes {1: -19} alone, and the emitted
      header is the two-member map {1: -19, 4: kid} -- the kid having
      been moved into the signed bucket, which the same document's own
      Section 4 says.  The identifier claim was right and the byte-level
      claim was not; Section 12 now states the map, and the paired
      a10127 claim about the deprecated identifier is dropped rather
      than repeated.  It was found by an adversarial pass that decoded a
      shipped vector -- one command, which is exactly how a reviewer
      would have found it.
   *  *The profile called its objects SCITT Signed Statements and called
      them registrable.* They are COSE_Sign1 objects; a Signed Statement
      additionally needs protected CWT Claims that a Transparency
      Service can apply a Registration Policy to, and the reference
      implementation emits none.  Section 4.3 is new and specifies the
      mapping normatively; Section 4 and Section 7 no longer assert
      registrability in the present tense; and the gap heads the not-
      implemented register in Section 12.  This was the round-1 review's
      categorical objection and it was right.
   *  *The payload figure omitted sig.* -00's figure ended at chain,
      which made its own "JCS(receipt WITHOUT chain.hash AND WITHOUT
      sig.value)" construction impossible to implement from the figure.
      sig (with alg, kid, value) is now shown as the mandatory member
      the schema has always required.
   *  *The optional-member contract listed two members; the schema has
      seven.* agent.model, action.rollbackRef, governance.ruleId,
      governance.approval and compliance.verdict join scope.tenant and
      governance.compliance, and the figure marks each.  The rule that
      present-as-null is not absence -- different bytes, different hash
      -- is stated with them.
   *  *Detached payloads were described backwards.* -00 said a detached
      payload's digest is bound through chain.hash.  COSE requires the
      detached bytes themselves for the Sig_structure, and chain.hash is
      a chain-linkage value computed over the receipt with chain.hash
      and sig.value removed.  The shipped parser refuses a non-byte-
      string payload.  Section 4.2 now defines the attached form only,
      and a detached mode is future work.

Toraman                 Expires 16 February 2027               [Page 92]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *The algorithm rule contradicted itself.* -00 said verifiers MUST
      reject every other alg and then that they SHOULD reject -8 unless
      a legacy mode was negotiated. -8 is not a special case, no such
      mode exists in any implementation, and the exception is deleted.
   *  *Certificate references were offered as a sufficient key
      identifier.* They are now additional and OPTIONAL, with kid
      required, matching a verifier that ignores x5t/x5chain.
   *  *The signer-relationship comparator named the wrong pair.* The
      relationship that decides independence is outcome signer versus
      request/authorization signer -- what both reviewers asked for, and
      what this document's own security prose already said.  An earlier
      draft compared against the receipt's issuer, which would report
      independence for an outcome signed by the requester.
   *  *The escaping row was wrong and the normalization row was too
      absolute.* JCS also escapes " and \; and a verifier MAY refuse a
      non-NFC receipt outright, which the shipped verifier offers as a
      mode.  What no verifier may do -- normalize before hashing -- is
      unchanged and is the rule that matters.
   *  *Timestamp validation was underspecified, and -01 makes the strict
      reading normative.* -00 required "RFC 3339" form without saying
      what a verifier must do with a string that matches the shape but
      is not a valid date-time.  Section 3.3 now requires rejection and
      pins the accepted grammar; Section 12 records that the shipped
      validator stops at the shape and why it will stay there.  An
      earlier -01 draft carried the opposite sentence here, which
      contradicted three other surfaces; this is the corrected one.
   *  *-00's NFC rule was rewritten, and that rewrite is itself a
      change.* -00 said flatly that all strings MUST be Unicode NFC,
      which reads as a validity condition on receipts. -01 splits it
      into a producer obligation and a verifier prohibition on
      normalizing, plus an optional refusal mode.  A receipt that -00
      called malformed may verify under -01 in the default mode, and
      vice versa under the refusal mode; implementers moving between
      revisions should read Section 3.2 and Section 3.3 together.
   *  *Nine -00 fragment anchors were broken and are restored.* A
      shortened anchor scheme in an earlier -01 draft would have broken
      deep links into introduction, relationship-to-other-work,
      identity-binding, policy-replay-is-out-of-scope-for-this-revision,
      security-considerations, implementation-status, hash-chaining-and-
      completeness, and the two reference sections.  Every one of the
      -00 anchors is restored in the published XML, so both numeric and
      fragment references from -00 continue to resolve.
   *  *Six references were reclassified or added.* RFC 9053 (the
      deprecated identifier named in a MUST, and the curve registry),
      RFC 3339, RFC 2104, RFC 9360 and Unicode Annex #15 are normative
      where the text depends on them; FIPS 180-4 is cited for SHA-256.

Toraman                 Expires 16 February 2027               [Page 93]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Requirements that existed only as code are now text.* Two reverse
      audits -- code read first, then the requirement it should have
      mapped to -- found rejection boundaries that every shipped
      verifier enforces and that no revision of this document required.
      They are requirements here, transcribed rather than invented: the
      128-code-point bound on id and the seven non-empty members, and
      the closed ALLOW/DENY set for governance.compliance.verdict
      (Section 3.1); the three JSON member names refused at the parse
      boundary (Section 3.2); the exact sig.alg literal, the Ed25519
      key-type rule, the canonical key encoding and the two public-point
      rejections (Section 4.2); the UTF-8 round trip before a kid is
      resolved (Section 4.1); and the checkpoint's closed object, value
      shapes and chain equality (Section 5.2).  One of them is not
      stated by one implementation, which Section 12 records.  The
      general rule of Section 8.3 -- that a verifier's own failure to
      authenticate or understand an input MUST NOT become a finding
      against the subject of the verification -- is new as a rule; the
      two requirements it generalizes were already in Section 5.1 and
      Section 5.2.
   *  *Conformance classes are new, and they change how every MUST is
      read.* -00 and earlier -01 drafts said "a verifier" and meant at
      least three different things, which made some requirements
      unsatisfiable by a single-receipt implementation and others
      meaningless to a chain one.  Section 1.4 defines Receipt, Chain
      and Evidence Verifier; each normative section states its class;
      and no class inherits another's obligations.  Two implementers can
      now build to the _same class_ and know they were asked for the
      same checks -- which is not the same as being able to interoperate
      from this document alone.  For the Receipt and Chain classes the
      inputs are defined here and agreement is testable on shared
      vectors.  For the Evidence class it is not: Section 1.5 lists the
      artifacts that layer runs over and this revision defines none of
      their wire formats, so two Evidence Verifiers cannot be given
      common inputs or compared on their outputs by reading this text
      (Section 15).
   *  *What this profile does not define is now a section rather than a
      scatter.* Section 1.5 lists the objects behind the Evidence-
      Verifier requirements -- identity manifest, approval and outcome
      artifacts, trust configuration, shared digest, result schema --
      and says plainly that their formats live in the companions and the
      reference implementation.  An unimplementable MUST is worse than
      none; the requirements that remain are the ones a reader can act
      on.
   *  *The non-equivocation claim is narrowed to what registration
      actually buys.* The Abstract, Section 7 and Section 13 previously
      asserted that registration supplies non-equivocation.  It supplies
      a third party's signed proof of registration.  Non-equivocation
      needs consistency proofs and monitoring, which this profile does

Toraman                 Expires 16 February 2027               [Page 94]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

      not specify and places no requirement on anyone to perform -- and
      a Transparency Receipt handed to an offline party _by the prover_
      is prover-supplied evidence, exactly as Section 5.1 says of a
      checkpoint.  The document's own argument now applies to its own
      escape hatch.
   *  *Registration binds more than the envelope.* Section 7 now
      requires a Transparency Service to verify the payload's own schema
      and native signature, and to check sub against scope.chain.
      Without the first, a trusted registrant can obtain a log entry for
      a receipt nobody in the chain signed; without the second, a
      chain-A receipt can be registered under chain-B.
   *  *Two further chain-level conditions are named.* The cross-tenant
      splice rule of Section 3.3 is a set property the axis table did
      not carry; it is now chain-tenant-split.  And every shipped
      verifier already rejects a mid-chain key change for one agent
      while no revision had ever named it: that is chain-key-
      discontinuity, the condition that stops a trusted-but-unrelated
      key from extending another party's chain.  The set of chain
      conditions is now six, and the two checkpoint-derived results that
      earlier drafts of this revision counted among them are on a
      separate axis: a checkpoint is a separate object answering a
      separate question, and nothing on that axis can fail a chain
      (Section 5.1).
   *  *An older checkpoint over a longer chain is no longer truncation.*
      Section 5.1 distinguishes a consistent extension from a
      truncation, and Section 12 records that the reference
      implementation reports one verdict for both.
   *  *The re-canonicalization requirement was impossible as written* --
      it demanded that a serialization omitting two members equal the
      bytes those members are in.  Section 4.2 now states the check the
      implementation actually performs: JCS(parse(bytes)) == bytes over
      the whole payload.
   *  *Field semantics are pinned* (Section 3.1): the notation legend,
      spec exactness, the absence of identifier namespaces, what ts
      means, and the cross-field rules that stop one record saying two
      things -- including the simulation-marker rule, which -00 left
      open.
   *  *Timestamps have a grammar* (Section 3.3): which spellings are
      accepted, why the spelling is signed, and why a verifier must not
      normalize one.
   *  *The relay attack is in the threat model* (Section 13).  The two-
      signature design permits any holder of a trusted key to re-wrap
      someone else's receipt; that was the one attack the design
      directly enables and the one the section omitted.
   *  *Parser resource bounds are named as the implementer's
      responsibility*, since this profile sets none and requires a
      complete chain from genesis.

Toraman                 Expires 16 February 2027               [Page 95]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Two RFC 9943 section pinpoints were wrong and are corrected.* An
      earlier -01 draft cited "Section 6.12" and "Section 6.13" for the
      kid and CWT Claims requirements.  RFC 9943 has no such subsections
      -- its Section 6 runs 6, 6.1, 6.2, 6.3 -- and both requirements
      live in the body of Section 6.  The citations now say Section 6.
      The error entered through a summarized reading of the RFC rather
      than its text; every external section pinpoint in this revision
      has since been checked against the RFC's own published text.
   *  *The deterministic-CBOR pin was too coarse.* "Section 4.2" named
      the whole Deterministically Encoded CBOR section; the requirement
      this profile depends on is the Core Deterministic Encoding
      Requirements of Section 4.2.1, which is now what it cites.
   *  *A quoted claim about another protocol's specification was
      removed.* The Introduction quoted a sentence about non-repudiation
      attributed to an agent protocol, with no primary citation to
      support it.  The surrounding point does not need it, and the
      paragraph now states the gap in neutral technical terms.  The
      OWASP entry is cited to its own project page, listing MCP08:2025
      by its published title; the severity rating an earlier draft
      asserted is not on that page and is gone.
   *  *The intended status CHANGED, and it is a change rather than an
      editorial detail.* The posted -00 carried "Intended status:
      Informational"; this revision carries "Intended status: Standards
      Track".  The document now defines wire-format acceptance rules
      that two implementations must agree on, which is why the header
      moved -- and the move is not settled: Section 15 states the case
      for Experimental instead, and the header records the current
      intention while the working group decides, not a conclusion the
      author reached alone.
   *  *The SCITT Architecture reference was a work-in-progress draft.*
      It was published as [RFC9943] in June 2026 and is cited as an RFC.
   *  *The equivalence section is gone, not edited.* -00 Section 8
      mapped this profile's fields onto another individual draft's field
      catalogue.  It changed no requirement in either document, so it is
      removed rather than carried forward; Section 1.2 still names that
      work and says a mapping is available to whoever needs to port one.

Appendix B.  Acknowledgments

   This revision is the product of a public review thread on the SCITT
   mailing list in July 2026, archived at
   https://mailarchive.ietf.org/arch/browse/scitt/?q=noa-scitt-ai-agent-
   receipt.  The reviewers named here disagreed usefully, contributed
   concrete text, and in one case ran their own implementation against
   this profile's adversarial corpus rather than arguing about it.
   Errors that remain are the author's.

Toraman                 Expires 16 February 2027               [Page 96]
Internet-Draft       SCITT AI-Agent Action Receipts          August 2026

   *  *Carlos Hernandez* separated a controller's report from the
      physical effect and asked for a machine-checkable non-claim rather
      than a caveat in prose: Section 8.1, Section 8.2 and Section 8.4.
   *  *Iman Schrock* (EMILIA Protocol) put pre-execution authorization
      in front of both other claims, supplied the substitution negative
      case, argued the signer relationship belongs in a field, and
      cautioned against treating two digest constructions as equal
      without a shared vector: Section 9, Section 6.1 and Section 10.
   *  *Steven Mih* held the thread to shared conformance vectors rather
      than shared vocabulary alone, which is the discipline Section 12
      commits to.
   *  *Joel Hillier* (Certisyn, Inc.) ran an independent reconciliation
      implementation against the published corpora and reported the
      numbers, including the failure no per-receipt verifier can reach:
      Section 5.1, Section 3.2 and the indeterminate-control discussion
      in Section 10.

Author's Address

   Tora Toraman
   NordenSoft
   Denmark
   Email: hello@ordeliya.com

Toraman                 Expires 16 February 2027               [Page 97]