Internet-Draft Cedulon August 2026
Dogru Expires 27 February 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-dogru-cedulon-01
Published:
Intended Status:
Informational
Expires:
Author:
E. C. Dogru
VERAX TEKNOLOJI LIMITED SIRKETI

Cedulon: An Audit Layer for Agent-to-Agent Commerce

Abstract

This document defines the Cedulon Protocol, an audit layer for agent-to-agent commerce. Payment rails such as HTTP 402 flows (x402) and mandate protocols (AP2) already move value. They do not, by themselves, produce a fail-closed policy check and a signed spend receipt that a verifier can reconcile against a rail extract. Cedulon specifies a Trade Manifest (signed offer before payment), a Policy Decision Point with default deny, a Spend Receipt (COSE/CWT claim set after a gated payment), epoch checkpoints, and rail-extract reconciliation. The reconciliation shows that no settlement on the extract lacks a receipt and no settled receipt is absent from the extract. That result is unconditional only when the verifier pins the rail key out of band and states the period under audit; otherwise the document requires it to be reported as conditional. It also defines a Dispute Evidence Bundle (evidence, not an award) and optional SCITT anchoring. Cedulon is not a competitor to x402 or AP2; it sits above them.

Status of This Memo

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

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 27 February 2027.

Table of Contents

1. Introduction

Note to Readers: This document is submitted as Informational. The author's eventual intended track, if the work is taken up, is a Standards Track profile of COSE [RFC9052] and CWT [RFC8392] for agent-spend receipts. This -01 does not claim IETF consensus.

Agents can now pay. Open HTTP 402 protocols [X402] attach stablecoin settlement to ordinary requests. Card networks and processors issue agent-scoped tokens. Google's Agent Payments Protocol (AP2) [AP2] binds user intent to signed mandates.

What is missing is an interoperable audit layer: a machine-checkable answer to "was this spend allowed by policy, against which offer, and what bytes were delivered?" Without that layer, a prompt-injected or looping agent can drain a rail that has already accepted a valid signature. A counterparty can ship the wrong artifact. A transparency log, if used at all, is proprietary.

Cedulon fills that gap. It does not clear funds, hold custody, or operate a payment facilitator. An optional escrow actor is defined only as a third-party role interface (Section 14.13). Implementations of this specification MUST NOT take custody of funds or operate escrow (MUST-T8-custody).

The control is an old one. Reconciling an internal ledger against an external statement is what double-entry bookkeeping [PACIOLI] made routine, and signing the artifacts on both sides is Grigg's triple-entry idea [GRIGG]. Neither is claimed here. What this document contributes is an open wire profile for that control in a setting where the parties are software: a COSE receipt shape, an extract shape, a checkpoint chain, and a verification algorithm precise enough that two implementations reach the same finding on the same evidence. The novelty is interoperability, not the idea.

Neighbor drafts are complementary, not substitutes. draft-bates-atp [BATES-ATP] covers tamper-evident causal lineage as a signed DAG. Cedulon is the completeness layer: a spend that never produced a receipt is visible when an authenticated rail extract is reconciled (MUST-T10-1).

2. Terminology

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.

The following terms are used:

Trade Manifest:

A signed statement produced before payment. It binds a description of goods or service, price, currency, acceptance-criteria hash, cancel condition, expiry, and an optional AP2 mandate reference.

Policy Decision Point (PDP):

The function that evaluates a structured spend request against stored policy. The default is deny.

Spend Receipt:

A signed statement produced after a gated payment attempt. It binds payer, payee, amount, currency, policy hash, manifestHash or an explicit noManifest flag, rail payment reference, timestampMs, nonce, prevReceiptHash, and outcome.

Receipt Issuer:

The party that signs Spend Receipts.

Anchor:

An optional SCITT Transparency Service [RFC9943] that registers a signed statement and returns a COSE receipt [RFC9942].

Dispute Evidence Bundle:

A package of the Trade Manifest, the Spend Receipt, and a delivery hash. It is evidence for a later human or legal process. It is not an arbitral award and not an escrow release.

Decision Token:

A portable, single-use PDP allow encoded as COSE_Sign1. The claim set binds requestHash, policyHash, expiryMs, nonce, and singleUseId. See Section 7.

Rail Extract:

An authenticated list of settlement records for one account, one rail, and one time window. See Section 8.

3. Architecture

Cedulon has three control-plane objects and one optional log:

  Principal --policy--> PDP --allow/deny--> x402/AP2 rail
                              |
                              v
                      Receipt Issuer --> Spend Receipt
                              |
                              v
                      Anchor / SCITT (optional)

The payer agent never talks to the rail except through an adapter that calls the PDP first (MUST-T5-1).

3.1. Policy Decision Point

The PDP evaluates structured fields only (MUST-T1-1): amount, currency, payee, tool identifier, nonce, optional manifest hash, and evaluation time. It applies limit, velocity, and scope checks (MUST-T2-1, MUST-T2-2). If the PDP is unreachable, uninitialized, or throws, the result is deny (MUST-T2-3). Denied attempts do not increment success counters (MUST-T2-4).

An allow produces a Decision Token whose requestHash covers six fields: amount, currency, payee, tool, nonce, and manifestHash (MUST-T3-4, MUST-T6-1). The token is a COSE_Sign1 object (MUST-T6-4), is single-use (MUST-T6-2), and MAY be carried to the adapter that performs settlement.

3.2. Receipt Issuer

After the adapter attempts settlement (success or a recorded deny that still needs an audit trail for an allowed-then-aborted path), the Receipt Issuer signs a Spend Receipt over a canonical encoding (MUST-T4-1). Verifiers reject bad signatures and byte mismatch (MUST-T4-2).

3.3. Anchor / SCITT

Parties MAY register the signed receipt (or a privacy-preserving hash encoding) as a SCITT Signed Statement [RFC9943] and attach the COSE receipt (MAY-T4-6). This document does not operate a Transparency Service.

4. Trade Manifest

A Trade Manifest is the commerce analogue of a promise: it is issued before value moves. It is conceptually symmetric to a later Spend Receipt (promise then proof), and it MAY carry an AP2 mandate hash so that user intent and the Cedulon offer stay linked (SHOULD-T8-5).

A Trade Manifest MUST bind all of the following (MUST-T8-1):

It MAY include ap2MandateHash. The corresponding CBOR label is always present; a missing mandate is encoded as CBOR null.

The manifest is COSE_Sign1 [RFC9052] over a deterministic CBOR claim map (Section 6). manifestHash is the SHA-256 of the signed COSE bytes (MUST-T8-7). A spend bound to a manifest MUST be denied if the requested amount or currency differs from the manifest (MUST-T8-2) or if the manifest is expired (MUST-T3-3).

A spend that is not bound to a verified manifest MUST be marked noManifest on the receipt and MUST still pass limit, velocity, and scope checks (MUST-T1-2). An implementation MAY refuse all noManifest spend (MAY-T1-4).

5. Spend Receipt

The Spend Receipt claim set is carried in COSE_Sign1 [RFC9052] wrapping a CWT-compatible map [RFC8392]. New receipts MUST use the COSE profile (Section 6).

Claims (MUST-T4-3, MUST-T4-4, MUST-T4-7):

Table 1
Claim Description
payer Payer agent identifier
payee Payee identifier
amount Minor units as a decimal string 0|[1-9][0-9]*
currency Currency identifier
policyHash SHA-256 of the canonical policy document (lowercase hex)
manifestHash SHA-256 of the signed manifest COSE bytes, or null when noManifest is true
noManifest Boolean; MUST be true if and only if manifestHash is null
x402PaymentRef Rail payment reference, or null
timestampMs POSIX milliseconds
nonce Unique spend nonce; at least 128 bits of randomness; unique in the issuer scope
prevReceiptHash Previous receipt hash, or null for the first receipt (SHOULD-T4-5)
outcome settled or aborted

A receipt with outcome = settled MUST have a non-null x402PaymentRef (MUST-T4-7). An aborted receipt MUST NOT be added into checkpoint totals.

All twelve labels in Section 6.1 are always present. An empty optional value is encoded as CBOR null, never by omitting the label.

receiptHash is the SHA-256 of the receipt's signed COSE bytes, encoded as lowercase hex.

Verifiers MUST reject a receipt if the signature fails or if the decoded claim map does not match the presented claims (MUST-T4-2).

5.1. Optional payee countersignature

A payee MAY attach a countersignature over the issuer's signed Spend Receipt (MAY-T8-9). The profile uses a detached COSE_Sign1 [RFC9052] whose payload is a CBOR map with a single private-use label:

Table 2
Label Claim CBOR type
-70401 receiptCose bstr (exact issuer COSE_Sign1 bytes)

The countersignature uses the header profile in Section 6 and content type application/cedulon-countersign+cbor.

This is a second Sign1 object, not RFC 9052 Countersignature0 (unprotected-header label 11). Countersignature0 would write into the issuer object and change receiptHash after issue, breaking the receipt chain. A detached Sign1 keeps the issuer bytes stable, reuses kid and content-type, and is absent by simply omitting the sibling object.

Absence of a countersignature MUST NOT invalidate the issuer receipt (MAY-T8-9). If a countersignature is present, a verifier MUST reject it when the signature fails, when kid or content type does not match the configured payee key, or when label -70401 is not the issuer COSE bytes (MUST-T8-8). A Dispute Evidence Bundle that includes a verified countersignature has stronger evidence that the payee accepted those bytes; the bundle is still not an award (MUST-T8-4).

6. COSE Profile

This profile uses deterministic CBOR [RFC8949] Section 4.2.1 (definite lengths, shortest integer form, map keys sorted in bytewise lexicographic order of their encoded keys). Implementations MUST encode only the types used by Cedulon claim maps: null, bool, unsigned and negative integers, UTF-8 text, byte strings, arrays, and maps (MUST-T4-1).

6.1. Claim labels

Registered CWT claims [RFC8392] are not required in -01. Cedulon uses CWT private-use integer labels less than -65536 so that the profile does not occupy the 100-110 registry range.

Receipt labels (MUST-T4-3, MUST-T4-4, MUST-T4-7):

Table 3
Label Claim CBOR type
-70001 payer tstr
-70002 payee tstr
-70003 amount tstr
-70004 currency tstr
-70005 policyHash tstr (lowercase hex SHA-256)
-70006 manifestHash tstr / null
-70007 noManifest bool
-70008 x402PaymentRef tstr / null
-70009 timestampMs uint
-70010 nonce tstr
-70011 prevReceiptHash tstr / null
-70012 outcome tstr (settled / aborted)

Checkpoint labels (MUST-T11-1):

Table 4
Label Claim CBOR type
-70101 epoch uint
-70102 startMs uint
-70103 endMs uint
-70104 receiptCount uint
-70105 chainHeadHash tstr / null
-70106 totals map tstr -> tstr
-70107 prevCheckpointHash tstr / null

Manifest labels (MUST-T8-1):

Table 5
Label Claim CBOR type
-70201 description tstr
-70202 amount tstr
-70203 currency tstr
-70204 acceptanceCriteriaHash tstr
-70205 cancelCondition tstr
-70206 expiresAtMs uint
-70207 ap2MandateHash tstr / null

Decision Token labels (MUST-T6-4):

Table 6
Label Claim CBOR type
-70301 requestHash tstr
-70302 policyHash tstr (lowercase hex SHA-256)
-70303 expiryMs uint
-70304 nonce tstr
-70305 singleUseId tstr

6.2. COSE_Sign1 headers

The protected header MUST be a deterministic CBOR map containing (MUST-T4-1, MUST-T4-8):

  • 1 (alg) = -19 (Ed25519, [RFC9864]; the generic EdDSA value -8 from [RFC9053] is deprecated for this profile)

  • 3 (content type) = a tstr that distinguishes the payload: application/cedulon-receipt+cbor, application/cedulon-checkpoint+cbor, application/cedulon-manifest+cbor, application/cedulon-decision+cbor, or application/cedulon-countersign+cbor

  • 4 (kid) = bstr, mandatory. The profile computes kid as the first eight bytes of SHA-256 over the issuer's SubjectPublicKeyInfo DER. A verifier MUST obtain the public key from an authenticated channel (preconfigured issuer set, directory, or transparency statement) and MUST reject a message whose kid does not match that key.

The unprotected header MUST be empty. The payload MUST be the CBOR encoding of the claim map. The signature is Ed25519 [RFC8032] over the COSE Sig_structure ["Signature1", protected, h'', payload].

7. Decision Token

A Decision Token is the portable encoding of a PDP allow. It is COSE_Sign1 with the header profile in Section 6 and the labels in Section 6.1. All five labels are always present (MUST-T6-4).

requestHash MUST be the six-field hash defined for the PDP (MUST-T6-1). policyHash MUST be the SHA-256 of the canonical policy document the PDP evaluated. expiryMs is a Unix time in milliseconds after which the token MUST be treated as expired (SHOULD-T6-3). nonce is the request nonce. singleUseId is the identifier consumed on the first settlement attempt (MUST-T6-2).

A party that accepts a Decision Token MUST reject it if the signature fails, if kid does not match a configured PDP key, if the content type is not application/cedulon-decision+cbor, if the decoded claim map does not match the presented claims, or if expiryMs is in the past (MUST-T6-5).

8. Rail Extract Profile

A verifier checks completeness against a rail extract, not against the issuer's own receipts alone (MUST-T10-7).

8.1. Record schema

Each settlement record MUST contain:

Table 7
Field Type
ref tstr (rail payment reference)
amount tstr matching 0|[1-9][0-9]*
currency tstr
timestampMs uint

8.2. Scope

An extract is scoped to one account identifier, one rail identifier, and one half-open time window [windowStartMs, windowEndMs).

8.3. Authentication

The mock rail in the companion implementation signs the extract with Ed25519 over a canonical encoding of the scoped body. A verifier MUST obtain the extract from the rail or from a signature the rail published (MUST-T10-7). A deployment that cannot do so is running the reconciliation against evidence it did not obtain independently, and MUST report the guarantee as conditional.

A signature on an extract proves internal consistency, not origin: a key generated by whoever produced the object verifies against itself. The verifier therefore MUST obtain the rail's public key out of band and MUST verify the extract signature against that key rather than against any key the extract carries (MUST-T10-8). A verifier that holds no such key MUST treat the guarantee as conditional.

Keys are compared as bytes. A verifier MUST compare the pinned key and the key that signed the extract by their SubjectPublicKeyInfo DER encoding, not by any text encoding of it, so that the same key presented in a different envelope still compares equal (MUST-T10-9). A pinned key the verifier cannot decode is a fault in the verifier's own configuration, not evidence about the extract, and MUST be reported as trust-key-unreadable rather than as a key mismatch.

What a verifier emits for an extract it cannot authenticate depends on whether it stated an expectation. With no pinned key the verifier has asserted nothing, so an extract that does not carry a verifiable signature is unauthenticated-extract, a warning: completeness findings may still be computed, but the guarantee is conditional on the extract being authentic. With a pinned key the verifier has asserted what it requires, and an extract that fails to meet it is a failure rather than a caveat; see the verification algorithm for which finding applies. -00 defined only the first case, and readers of -00 should note that this revision makes the pinned case fail closed. See Section 14.

8.4. Scope agreement

An extract declares a window and carries settlement records. The two MUST agree: a verifier MUST report every settlement record whose timestampMs falls outside [windowStartMs, windowEndMs) as extract-scope-mismatch, identified by that record's ref (MUST-T10-10). This check is about the extract's internal consistency and MUST be performed whether or not a rail key is pinned.

A verifier that knows which account, rail, and window it is auditing MUST also check the extract against that expectation and MUST fail closed when the extract does not cover it (MUST-T10-11). An extract for another account or rail, or one whose window does not span the period under audit, cannot support a completeness claim about that period.

A verifier that states no period leaves the extract free to define one, and an extract that reports on a millisecond balances as easily as one that reports on a month. Pinning a key establishes who signed; only a stated period establishes what the signature had to cover. A verifier that has not stated the period under audit therefore MUST emit unstated-audit-window and MUST treat the guarantee as conditional (MUST-T10-15), whatever else verifies.

9. Reconciliation and Epoch Checkpoints

Completeness is the property that, given an authenticated rail extract, every settlement in the extract has a matching settled Spend Receipt, every settled receipt has a matching settlement, receipt and checkpoint hash chains verify, and checkpoint totals equal the sum of settled receipts in the checkpoint window. If a spend occurred without a receipt, the missing receipt is itself the evidence (MUST-T10-2).

9.1. Checkpoint claims

An epoch checkpoint MUST be COSE_Sign1-signed with the header profile in Section 6 and MUST bind all of the following (MUST-T11-1):

epoch, startMs, endMs, receiptCount, chainHeadHash, totals, and prevCheckpointHash.

The checkpoint window is half-open [startMs, endMs) (MUST-T11-7). receiptCount MUST equal the number of receipts (settled and aborted) whose timestampMs falls in that window. chainHeadHash MUST equal receiptHash of the last receipt in that window, or null if the window is empty (MUST-T11-2). totals MUST sum only receipts with outcome = settled.

9.2. Genesis and continuity

The first checkpoint in a presented chain is the genesis checkpoint of that chain. Its prevCheckpointHash MUST be null. Epoch numbers MUST be consecutive integers. Adjacent windows MUST satisfy next.startMs = prev.endMs (MUST-T11-8).

A later checkpoint that omits a prefix of earlier epochs (prefix deletion) is detectable only if an external witness (transparency log) has recorded the missing prefix (MUST-T11-9). Without that witness, T11 guarantees about suppression are conditional.

9.3. Verification algorithm

A verifier MUST perform all of these steps and MUST report every finding they produce (MUST-T10-1, MUST-T11-2). They are numbered for reference, not to require an evaluation order: no step short-circuits another, and an implementation may evaluate them in any order that produces the same set of findings.

When a step names an identifier in backticks, that identifier SHOULD be used for the condition in diagnostic output. The normative requirement is the behaviour: report the condition, identified by the ref or other handle given in the step. The identifiers are not an interoperability surface.

  1. Establish the subject of the audit. When an extract is supplied, the settlement records it carries are the ones reconciled; a settlement list from any other source MUST NOT be substituted for them (MUST-T10-12). If the caller supplies both and they differ, the verifier MUST report that the caller-supplied list disagrees with the extract, and MUST still reconcile the extract. The identifier extract-settlement-mismatch SHOULD be used for this condition in diagnostic output.

  2. Verify the extract signature against the out-of-band rail key (MUST-T10-8, MUST-T10-9). If no key is pinned, the verifier MUST treat the completeness guarantee as conditional (MUST-T10-7). The identifier unauthenticated-extract SHOULD be used for this condition in diagnostic output. If a key is pinned and cannot be decoded, the verifier MUST report that the pinned key is unreadable. The identifier trust-key-unreadable SHOULD be used for this condition. If a key is pinned and the signature does not verify against it, or verifies against a different key, the verifier MUST report that the extract is not signed by the pinned key. The identifier extract-key-mismatch SHOULD be used for this condition. A finding that puts the extract itself in doubt MUST prevent an unconditional guarantee.

  3. Check scope. The verifier MUST report each settlement record whose timestampMs falls outside the declared window, identified by that record's ref (MUST-T10-10). When the verifier states an expected account, rail, or window, it MUST report an extract that does not cover it (MUST-T10-11). The identifier extract-scope-mismatch SHOULD be used for both conditions. If the verifier stated no period, it MUST treat the guarantee as conditional (MUST-T10-15). The identifier unstated-audit-window SHOULD be used for this condition.

  4. Decode each Spend Receipt COSE_Sign1. Reject if Ed25519 verify fails, if kid does not match the configured issuer key, if the content type is not the receipt type, or if the decoded claim map does not match the presented claims (MUST-T4-2, MUST-T4-8).

  5. Scope the receipts. When an extract is supplied, only receipts whose timestampMs falls in the extract's declared window are reconciled against it (MUST-T10-16). A receipt outside that window is not a completeness failure against this extract; auditing a longer period requires extracts that cover it. Receipts remain subject to every other check regardless of window.

  6. Walk receipts in issuer order. The first prevReceiptHash MUST be null. Each later prevReceiptHash MUST equal receiptHash of the previous receipt. A miss MUST be reported as a break in the receipt chain. The identifier receipt-chain-break SHOULD be used for this condition.

  7. Index settled receipts and extract records by ref. A ref that appears more than once on either side MUST be reported as a repeated reference (MUST-T10-6). The identifier duplicate-ref SHOULD be used for this condition.

  8. For each ref that appears exactly once on each side, require a one-to-one match on ref AND amount AND currency (MUST-T10-1). Amount or currency mismatch MUST be reported as a settlement that does not match its receipt, identified by that ref. The identifier settlement-mismatch SHOULD be used for this condition. A settlement with no receipt MUST be reported as lacking a receipt, identified by its ref (MUST-T10-2). The identifier settlement-without-receipt SHOULD be used for this condition. A settled receipt with no extract row MUST be reported as a completeness failure (MUST-T10-3). The identifier receipt-without-settlement SHOULD be used for this condition. A settled receipt with a null rail ref MUST be reported as settled without a rail reference. The identifier settled-without-ref SHOULD be used for this condition.

  9. A ref already reported as repeating MUST still be reconciled by amount rather than dropped from the comparison (MUST-T10-13). For each currency under that ref, compare the total settled against the total receipted. A settled total that exceeds the receipted total MUST be reported as a settlement lacking a receipt, and the finding MUST state the unaccounted amount. The identifier settlement-without-receipt SHOULD be used for this condition. A settled total that is less than the receipted total MUST be reported as a settlement that does not match its receipt, identified by that ref. The identifier settlement-mismatch SHOULD be used for this condition. An amount on that repeating ref that cannot be parsed as an integer MUST be reported without abandoning the audit; the identifier malformed-amount SHOULD be used for this condition. A verifier MUST still report findings for the remaining records.

  10. Aborted receipts are not matched to extract rows and are not added to totals.

  11. Decode each checkpoint. Reject a failed signature. Require receiptCount, chainHeadHash, and totals to match the receipts in [startMs, endMs) as defined above (MUST-T11-2).

  12. Every chained receipt MUST fall in exactly one checkpoint window. A gap or double count MUST be reported as a window coverage failure (MUST-T11-7, MUST-T11-8). The identifier window-coverage SHOULD be used for this condition.

  13. Walk checkpoints in epoch order. prevCheckpointHash MUST equal the SHA-256 of the previous checkpoint COSE bytes, or null for genesis (MUST-T11-4).

  14. If two successfully verified checkpoints share an epoch number and have different hashes, the verifier MUST report equivocation (MUST-T11-3). The identifier equivocation SHOULD be used for this condition.

  15. If any finding remains that is not a warning (a warning is a condition that only makes the completeness guarantee conditional), the audit MUST fail (MUST-T10-4).

9.4. Finding codes

The identifiers below are for diagnostic output. They are not an interoperability surface. A finding object that can be carried on the wire is outside the scope of this document and may be defined later. Two implementations interoperate when they accept the same inputs and fail or warn on the same conditions, not when they print the same strings.

A condition that makes the audit fail is a finding. A condition that only makes the completeness guarantee conditional is a warning. Warnings MUST still appear in operator-facing output (MUST-T10-14).

Table 8
Code Effect Meaning
settlement-without-receipt audit fails Extract row has no matching settled receipt, or a repeating ref settled more than it receipted
receipt-without-settlement audit fails Settled receipt ref is not on the extract
settlement-mismatch audit fails Same ref, different amount or currency, including a repeating ref that settled less than it receipted
duplicate-ref audit fails Ref appears more than once on one side
settled-without-ref audit fails outcome is settled and x402PaymentRef is null
receipt-chain-break audit fails Signature or prevReceiptHash failed
checkpoint-total-mismatch audit fails Totals, count, signature, or checkpoint chain failed
checkpoint-head-mismatch audit fails chainHeadHash is not the last in-window receipt
equivocation audit fails Two distinct hashes for one epoch
window-coverage audit fails Gap, overlap, or non-adjacent / non-consecutive windows
unauthenticated-extract guarantee conditional No pinned rail key, or the extract has no verifiable signature
extract-key-mismatch audit fails Extract is signed by a key other than the pinned rail key, or does not verify against it
trust-key-unreadable audit fails The pinned rail key could not be decoded; the verifier's configuration is at fault
extract-scope-mismatch audit fails A record falls outside the declared window, or the extract does not cover the expected account, rail, or window
extract-settlement-mismatch audit fails A caller-supplied settlement list disagrees with the extract; the extract is authoritative
malformed-amount audit fails An amount on a ref already reported as repeating that could not be parsed as an integer
unstated-audit-window guarantee conditional The verifier stated no period, so the extract defined its own
countersign-bad audit fails Present payee countersignature failed verify

A finding that puts the extract itself in doubt (extract-key-mismatch, trust-key-unreadable, extract-scope-mismatch, or extract-settlement-mismatch) MUST also prevent an unconditional guarantee, not merely fail the audit.

An unconditional guarantee therefore requires all of: an extract, a pinned rail key the extract's signature verifies against, a stated period the extract covers, and no finding that puts the extract in doubt. Anything less is conditional, and the report MUST say so.

An implementation MUST make the guarantee and any warnings visible in whatever human-readable audit report it produces under this document, not only in a returned structure (MUST-T10-14). A report that says the books balance while withholding that the balance is conditional invites the reader to take a conditional result for an unconditional one.

Checkpoints SHOULD be registered with a Transparency Service (SHOULD-T11-5). A test deployment MAY use an in-process append-only log as the witness (MAY-T11-6). Cedulon still MUST NOT take custody.

10. Lifecycle

  1. Manifest. Parties sign a Trade Manifest (optional for metered API spend; required for goods with acceptance criteria).

  2. Policy check. The adapter submits a structured request to the PDP. Default is deny. An allow is a Decision Token (MUST-T6-4).

  3. Payment. On allow, the adapter performs the x402 (or other rail) exchange using exactly the decision fields (MUST-T6-1). The Decision Token is consumed (MUST-T6-2). A reused nonce is denied (MUST-T3-1, MUST-T3-2). A tampered or expired token is denied (MUST-T6-5).

  4. Receipt. The Receipt Issuer signs a Spend Receipt. Rail credentials MUST NOT appear in the receipt, logs, or tool results (MUST-T5-2, MUST-T7-1).

  5. Dispute Evidence Bundle. If delivery bytes do not match the acceptance-criteria hash, an implementation MUST be able to emit a bundle of manifest + receipt + delivery hash (MUST-T8-3). The bundle MUST NOT be described as an arbitral award or escrow release (MUST-T8-4).

11. Policy Semantics

Policy is default deny. The engine understands three families of rule:

Fail-closed: missing engine, crash, or exception yields deny (MUST-T2-3). Implementations SHOULD emit stable reason codes (SHOULD-T2-5). Decision tokens SHOULD expire after a short TTL (SHOULD-T6-3).

The agent-facing spend interface MUST invoke the PDP and MUST NOT expose a parallel ungated rail call to the model (MUST-T5-1).

12. SCITT Anchoring

A Receipt Issuer or relying party MAY construct a SCITT Signed Statement whose payload is either the Spend Receipt COSE object or a privacy profile (Section 13) and register it with a Transparency Service [RFC9943]. The service returns a COSE receipt [RFC9942]. Embedding that receipt yields a Transparent Statement. Cedulon does not define a new transparency algorithm.

13. Privacy Considerations

A public transparency encoding MUST support omitting or hashing payer and payee identifiers and MUST support amount redaction or bucket encoding (MUST-T9-1). Implementations MUST NOT write government-ID numbers, payment-instrument PAN, or street address into a public statement (MUST-T9-2). Default public anchors SHOULD publish policyHash, manifestHash, receiptHash, and timestampMs rather than full claims (SHOULD-T9-3). A private auditor MAY receive an unredacted receipt out of band (MAY-T9-4).

14. Security Considerations

This section is authoritative for the protocol requirements in this document. The companion repository file THREAT_MODEL.md is informative and MUST NOT be read as overriding this section.

Requirement identifiers take the form KEYWORD-Tn-k, where KEYWORD is MUST, SHOULD, or MAY, n is the threat number in this section, and k is a sequence number within that threat. MUST-T8-custody is the custody prohibition under T8. The tables below define the requirement text those citations refer to.

14.1. T1: Prompt injection leads to unauthorized spend

Table 9
ID Requirement
MUST-T1-1 The PDP MUST decide from structured request fields and stored policy, not from model-generated prose.
MUST-T1-2 A spend that is not bound to a verified Trade Manifest MUST be marked no-manifest on the Spend Receipt and MUST still be subject to limit, velocity, and scope policy.
SHOULD-T1-3 Hosts SHOULD require a human confirmation channel for first-use payees.
MAY-T1-4 An implementation MAY refuse all no-manifest spend.

14.2. T2: Runaway agent (loop spend)

Table 10
ID Requirement
MUST-T2-1 Policy MUST express a maximum payment count per configured time window (velocity).
MUST-T2-2 Policy MUST express a maximum amount per payment and a maximum cumulative amount per window.
MUST-T2-3 If the PDP is unreachable, uninitialized, or throws during evaluation, the spend MUST be denied (fail-closed, default deny).
MUST-T2-4 A denied attempt MUST NOT increment the allowed-spend counters as if it had succeeded.
SHOULD-T2-5 Implementations SHOULD emit a stable reason code for velocity and limit denials.

14.3. T3: Replay of payment authority

Table 11
ID Requirement
MUST-T3-1 Every spend attempt that the PDP allows MUST include a nonce that the implementation has not accepted before.
MUST-T3-2 A second attempt that reuses a nonce MUST be denied.
MUST-T3-3 A Trade Manifest MUST carry an expiry; a spend against an expired manifest MUST be denied.
MUST-T3-4 A PDP allow decision MUST be bound to a hash of the request fields it evaluated and MUST be single-use.
SHOULD-T3-5 Nonce stores SHOULD persist across process restart when the deployment is not a test fixture.

14.4. T4: Receipt forgery or repudiation

Table 12
ID Requirement
MUST-T4-1 A Spend Receipt MUST be signed by the Receipt Issuer over a canonical encoding of its claims.
MUST-T4-2 Verifiers MUST reject a receipt whose signature does not validate or whose canonical bytes do not match the signed payload.
MUST-T4-3 A Spend Receipt MUST include payer, payee, amount, currency, policyHash, timestampMs, and nonce.
MUST-T4-4 A Spend Receipt MUST include manifestHash or an explicit noManifest flag, never an ambiguous empty hash. Empty optional values are CBOR null; labels are never absent.
SHOULD-T4-5 Receipts SHOULD form a hash chain (prevReceiptHash) so omission is detectable within one issuer stream.
MAY-T4-6 Parties MAY register the signed receipt as a SCITT statement to obtain a COSE receipt.
MUST-T4-7 A Spend Receipt MUST include outcome (settled or aborted). A settled receipt MUST have a non-null rail ref. Aborted receipts MUST NOT enter checkpoint totals.
MUST-T4-8 COSE_Sign1 protected headers MUST use alg -19 (Ed25519), a mandatory kid, and a payload-specific content type. Verifiers MUST reject a kid that does not match the configured issuer key.

14.5. T5: Policy bypass via direct rail access

Table 13
ID Requirement
MUST-T5-1 The agent-facing spend interface MUST invoke the PDP and MUST NOT expose a parallel ungated rail call to the model.
MUST-T5-2 Rail credentials, wallet handles, and facilitator tokens MUST NOT be placed in tool results or prompts.
SHOULD-T5-3 Hosts SHOULD run the PDP and signing keys in a process the model runtime cannot write.
MAY-T5-4 A deployment MAY use OS or hardware isolation between the model and the PDP.

14.6. T6: TOCTOU between policy check and payment

Table 14
ID Requirement
MUST-T6-1 Payment settlement MUST use the same six requestHash fields the PDP evaluated: amount, currency, payee, tool, nonce, and manifestHash.
MUST-T6-2 An allow decision MUST be consumed on the first settlement attempt, success or fail-closed abort, and MUST NOT authorize a later different request.
SHOULD-T6-3 Implementations SHOULD treat a decision older than a short TTL as expired.
MUST-T6-4 An allow Decision Token MUST be COSE_Sign1 with CWT private-use labels -70301..-70305 (requestHash, policyHash, expiryMs, nonce, singleUseId) and content type application/cedulon-decision+cbor.
MUST-T6-5 A party that accepts a Decision Token MUST reject a failed signature, a kid or content-type mismatch, a claim-map mismatch, or an expired expiryMs.

14.7. T7: Signing-key leakage

Table 15
ID Requirement
MUST-T7-1 Secret key material MUST NOT appear in receipts, manifests, logs, or example output.
MUST-T7-2 Example and test keys MUST be generated at runtime or stored as clearly fake fixtures, never as production secrets.
SHOULD-T7-3 Production deployments SHOULD use an HSM or OS key store and SHOULD rotate keys.
MAY-T7-4 Implementations MAY encrypt keys at rest.

14.8. T8: Counterparty price gouging or defective delivery

Table 16
ID Requirement
MUST-T8-1 A Trade Manifest MUST bind goods or service description, price, currency, acceptance-criteria hash, cancel condition, and expiry.
MUST-T8-2 A spend bound to a manifest MUST be denied if the requested amount or currency differs from the manifest.
MUST-T8-3 If delivery bytes do not hash to the acceptance-criteria hash, the implementation MUST be able to produce a Dispute Evidence Bundle containing the manifest, the spend receipt, and the delivery hash.
MUST-T8-4 The Dispute Evidence Bundle MUST NOT be described as an arbitral award or escrow release.
MUST-T8-7 manifestHash MUST be the SHA-256 of the signed Trade Manifest COSE bytes and MUST NOT include the issuer public key encoding.
SHOULD-T8-5 Manifests SHOULD reference an AP2 mandate hash when one exists.
MAY-T8-6 Parties MAY add an optional escrow actor as a third-party role interface; this project MUST NOT implement custody.
MUST-T8-custody Implementations of this specification MUST NOT take custody of funds or operate escrow.
MUST-T8-8 If a payee countersignature is present, a verifier MUST reject it when the signature fails, when kid or content type does not match the configured payee key, or when the payload is not the issuer COSE_Sign1 bytes.
MAY-T8-9 A payee MAY attach a detached COSE_Sign1 countersignature over the issuer receipt bytes. Absence MUST NOT invalidate the issuer receipt.

14.9. MUST-T8-custody

Implementations of this specification MUST NOT take custody of funds or operate escrow. See also Section 14.13.

14.10. T9: PII leakage into the transparency log

See also Section 13.

Table 17
ID Requirement
MUST-T9-1 A transparency encoding MUST support omitting or hashing payer/payee identifiers and MUST support amount redaction or range/bucket encoding.
MUST-T9-2 Implementations MUST NOT write raw government-ID, payment-instrument PAN, or street address fields into a public transparency statement.
SHOULD-T9-3 Default public anchors SHOULD publish policyHash, manifestHash, receiptHash, and timestamp rather than full claim sets.
MAY-T9-4 A private auditor MAY receive an unredacted receipt out of band.

14.11. T10: Secret spend via rail bypass

See Section 9.

Table 18
ID Requirement
MUST-T10-1 A verifier MUST match each extract settlement to a settled receipt on ref AND amount AND currency.
MUST-T10-2 A settlement with no matching receipt MUST be reported as a completeness failure identified by that settlement ref.
MUST-T10-3 A settled Spend Receipt whose x402PaymentRef is not on the extract MUST be reported as a completeness failure.
MUST-T10-4 An audit that has any fail-severity completeness finding MUST fail (non-zero status in the companion tool).
SHOULD-T10-5 Hosts SHOULD still apply T5 (no ungated rail in the model process). Completeness does not replace prevention.
MUST-T10-6 A ref that appears more than once among settled receipts or among extract rows MUST be reported as duplicate-ref.
MUST-T10-7 A verifier MUST obtain the extract from the rail or from a rail signature. With no pinned rail key, an unverifiable extract MUST be reported as unauthenticated-extract and makes the completeness guarantee conditional. With a pinned key, see MUST-T10-8: the extract MUST fail closed rather than warn.
MUST-T10-8 A verifier MUST obtain the rail public key out of band and MUST verify the extract signature against that key, not against a key the extract carries. Without such a key the guarantee is conditional.
MUST-T10-9 Keys MUST be compared by SubjectPublicKeyInfo DER encoding rather than by any text encoding. A pinned key that cannot be decoded MUST be reported as trust-key-unreadable, not as a key mismatch.
MUST-T10-10 Every settlement record whose timestampMs falls outside the extract's declared window MUST be reported as extract-scope-mismatch, identified by that record's ref. This check MUST run whether or not a key is pinned.
MUST-T10-11 When the verifier states an expected account, rail, or window, an extract that does not cover it MUST fail closed as extract-scope-mismatch.
MUST-T10-12 When an extract is supplied, the records it carries are the subject of reconciliation. A settlement list from another source MUST NOT be substituted; a disagreeing list MUST be reported as extract-settlement-mismatch.
MUST-T10-13 A ref reported as duplicate-ref MUST still be reconciled by aggregate amount per currency, and a shortfall MUST state the unaccounted amount. An unparseable amount MUST be reported as malformed-amount without aborting the audit.
MUST-T10-14 An implementation MUST surface the guarantee and any warnings in any human-readable audit report it produces, not only in a returned structure.
MUST-T10-15 A verifier that has not stated the period under audit MUST emit unstated-audit-window and MUST treat the guarantee as conditional, because an unstated period leaves the extract free to define its own.
MUST-T10-16 When an extract is supplied, only receipts whose timestampMs falls in its declared window are reconciled against it. A receipt outside that window MUST NOT be reported as a completeness failure against that extract.

In MUST-T10-4, a completeness finding that makes the audit fail is distinct from a warning that only makes the guarantee conditional. The verification algorithm states that distinction by behaviour (Section 9).

14.12. T11: Checkpoint suppression or rollback

Table 19
ID Requirement
MUST-T11-1 An epoch checkpoint MUST be COSE-signed and MUST bind epoch number, time window, receipt count, chain-head hash, per-currency totals, and the previous checkpoint hash.
MUST-T11-2 Verifiers MUST reject a checkpoint whose signature fails, whose totals do not match settled receipts in the declared window, whose receiptCount is wrong, or whose chainHeadHash is not the last in-window receipt hash.
MUST-T11-3 Two verified checkpoints for the same epoch with different hashes MUST be reported as equivocation.
MUST-T11-4 A broken checkpoint hash chain MUST fail verification.
SHOULD-T11-5 Checkpoints SHOULD be registered with a Transparency Service when one is configured.
MAY-T11-6 A test deployment MAY use an in-process append-only log as the witness.
MUST-T11-7 Checkpoint windows MUST be half-open [startMs, endMs). Every chained receipt MUST fall in exactly one window.
MUST-T11-8 Presented checkpoint epochs MUST be consecutive and adjacent windows MUST meet at endMs = next.startMs.
MUST-T11-9 Prefix-deletion and suppression claims that go beyond the presented chain are conditional on an external transparency witness.
Issuer self-attestation:

A Receipt Issuer that also produces the only copy of the extract can omit settlements. Completeness holds only against an extract the verifier obtained from the rail or from a rail signature.

Key rotation and revocation:

kid identifies the verification key. This -01 does not specify a revocation list. Verifiers MUST pin the issuer keys they accept and MUST stop accepting a kid after an authenticated revocation signal.

Timestamp trust:

timestampMs is issuer-asserted. Window assignment uses that field. A lying issuer can slide a receipt between windows. External timestamping or a transparency log is out of scope for -01.

Collusion:

If the rail operator and the issuer collude, they can publish a matching extract and receipt set that hides a real-world settlement. Cedulon does not detect extract-external agreement.

Reversal, refund, and partial settlement:

State machines for reversal, refund, and partial settlement are out of scope for this revision.

14.13. Optional escrow role

Parties MAY name an escrow actor in a Trade Manifest as a third-party role that holds funds under rules outside this protocol (MAY-T8-6). Implementations of this specification MUST NOT take custody or operate escrow (MUST-T8-custody).

15. IANA Considerations

CWT claim labels need no assignment: this profile uses private-use integer labels below -65536.

Media types do. This document defines five and makes their values a normative check inside a protected COSE header (MUST-T4-8, MUST-T6-5), so they cannot stay unregistered while that check stands. If this work is taken up, the following should be registered in the Standards Tree per [RFC6838]:

Table 20
Media type Carries
application/cedulon-receipt+cbor Spend Receipt claim set
application/cedulon-checkpoint+cbor Epoch checkpoint claim set
application/cedulon-manifest+cbor Trade Manifest claim set
application/cedulon-decision+cbor Decision Token claim set
application/cedulon-countersign+cbor Payee countersignature

For each: encoding is binary CBOR [RFC8949]; security considerations are those in Section 14; the change controller would be the IETF; the contact is the author of this document. Until registration, an implementation outside a closed deployment should expect these names to change, and readers should treat them as placeholders rather than as stable identifiers.

16. Implementation Status

This section is to be removed before publishing as an RFC.

RFC 7942 [RFC7942] note.

Implementation:

A companion implementation with a runnable verification suite at https://github.com/dogrucanemek-alt/cedulon. The code is a profile of this document, not a second specification. This -01 is not an IETF working-group item.

Maturity:

Research code by a single implementer. Interoperability with an independent implementation has not been demonstrated; no second implementation is known to the author.

Coverage:

The receipt, checkpoint, extract, reconciliation, and verification algorithm are implemented. Every requirement added in this revision is implemented and covered by a red-then-green case before appearing in this text. The escrow role, reversal, refund, and partial settlement are not implemented.

Licensing:

Apache-2.0.

Contact:

The author of this document.

Experience:

Two independent readers ran an earlier revision and reported defects, one of which was a bypass of the completeness claim. Both are fixed and the fixes are recorded in the repository. That review is the reason for most of this revision.

Note on distribution: the requirements in this document are implemented in the @cedulon packages at version 0.2.0 on npm, and in the repository at the commit named in the release notes. Package versions before 0.2.0 predate these requirements, so a reader checking a claim against an installed package should confirm the version first.

16.1. Changes from -00

Two independent readers ran the -00 implementation and reported defects. One was a bypass of the completeness claim: the implementation verified an extract and then reconciled a separate settlement list, so a validly signed extract could carry an off-book settlement while the caller supplied an empty list, and the audit reported balanced books. That was the implementation contradicting -00, which already required reconciling against the extract; this revision states the requirement in the verification algorithm so it cannot be read as optional (MUST-T10-12).

The second was a gap in this document rather than in the code. -00 required an authenticated extract but never said which key the signature is checked against, so an implementation could satisfy the text while verifying a signature against a key the extract itself carried. Such a key verifies against itself. -01 requires the rail key out of band and compares keys as DER (MUST-T10-8, MUST-T10-9).

The remaining changes close narrower holes found while repairing those two: an extract whose declared window disagrees with the records it carries (MUST-T10-10), an extract that does not cover the period under audit (MUST-T10-11), a repeated ref dropping out of the comparison and hiding the unaccounted amount (MUST-T10-13), and a report that states a balance in operator-facing output while withholding that the balance is conditional (MUST-T10-14).

Three changes are not repairs and are recorded here so a reader of -00 is not surprised:

  • A failed extract signature was a warning in -00 and stays one when no key is pinned. Once a key is pinned it now fails the audit. -00 did not contemplate a pinned key, so this is new behaviour rather than a clarification.

  • Requiring that a disagreeing caller-supplied list be reported as extract-settlement-mismatch is new normative content. -00 required reconciling the extract; it did not require saying anything about a list that contradicted it.

  • -00 said reversal, refund, and partial settlement were "expected in -01", and said reserved extensions belonged in "-01 or -02". Neither arrived in this revision. They are now stated as out of scope for this revision and expected later, with no date.

The reporters are named in the Acknowledgments.

17. Evolution and Future Work (Informative)

This section is a direction, not a commitment. The structures below are reserved in name only. Normative wire formats, tests, and threat-model MUST lines for them belong in later revisions (-02 or -03), written with the same discipline as this -01.

17.1. Re-attestation profile

Algorithms retire. A Spend Receipt or checkpoint signed under Ed25519 today may need a later verifier that no longer accepts -19. A companion seed [REATTEST] sketches re-attestation: register the original COSE bytes as a SCITT Signed Statement and have a current algorithm countersign or receipt them. The principle is that structures outlive ciphers. The first concrete example is the profile's own move from generic EdDSA (-8) to Ed25519 (-19) in [RFC9864].

17.2. Streaming reconciliation

Epoch checkpoints in this document are batch windows. A later revision (-02) may define a continuous, second-scale profile [STREAMING] in which the same completeness relation is evaluated as settlements arrive, without waiting for an epoch close. That work does not change the matching rules in this document.

17.3. Generalization

Payment is the special case that this -01 implements. The same completeness calculus (an authenticated extract of consumed units reconciled to signed receipts) can apply to other consumable resources such as compute, data, or energy. This document does not specify those profiles.

18. Informative Notes on Adjacent Protocols

x402 [X402] uses HTTP 402 [RFC9110] to negotiate stablecoin payment. AP2 [AP2] uses signed mandates as verifiable credentials. Cedulon does not replace either protocol. Profiles built on HTTP Message Signatures [RFC9421] authenticate bots; they are not a spend receipt. draft-bates-atp [BATES-ATP] is a lineage neighbor. It does not define rail-extract completeness.

draft-vauban-x402-stark-receipts [VAUBAN] specifies complementary x402 receipt-format variants that a Cedulon Spend Receipt MAY carry as a rail proof; it does not define rail-extract completeness. draft-schrock-ep-outcome-binding [SCHROCK] compares authorized action bytes to independently observed effects; it does not define rail-extract completeness. draft-marques-asqav-compliance-receipts [MARQUES] profiles access-control action receipts (the broader Acta family includes [ACTA]); it does not define rail-extract completeness. draft-hopley-x402-compliance-receipt [HOPLEY] records an admission-time compliance decision; it does not define rail-extract completeness.

19. References

19.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC6234]
Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, , <https://www.rfc-editor.org/rfc/rfc6234>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/rfc/rfc6838>.
[RFC8032]
Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, , <https://www.rfc-editor.org/rfc/rfc8032>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC8392]
Jones, M., Wahlstroem, E., Erdtman, S., and H. Tschofenig, "CBOR Web Token (CWT)", RFC 8392, DOI 10.17487/RFC8392, , <https://www.rfc-editor.org/rfc/rfc8392>.
[RFC8949]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, , <https://www.rfc-editor.org/rfc/rfc8949>.
[RFC9052]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, , <https://www.rfc-editor.org/rfc/rfc9052>.
[RFC9053]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Initial Algorithms", RFC 9053, DOI 10.17487/RFC9053, , <https://www.rfc-editor.org/rfc/rfc9053>.
[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, , <https://www.rfc-editor.org/rfc/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, , <https://www.rfc-editor.org/rfc/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, , <https://www.rfc-editor.org/rfc/rfc9943>.

19.2. Informative References

[ACTA]
Farley, T., "Signed Decision Receipts for Machine-to-Machine Access Control", , <https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/>.
[AP2]
Google Agentic Commerce, "Agent Payments Protocol (AP2)", , <https://ap2-protocol.org/ap2/specification/>.
[BATES-ATP]
Bates, D., "Agent Transaction Protocol (ATP)", , <https://datatracker.ietf.org/doc/html/draft-bates-atp>.
[GRIGG]
Grigg, I., "Triple Entry Accounting", , <https://iang.org/papers/triple_entry.html>.
[HOPLEY]
Hopley, C., "Categorical Compliance Screening Receipt Format for Agentic-Payment Flows", , <https://datatracker.ietf.org/doc/draft-hopley-x402-compliance-receipt/>.
[MARQUES]
Gomes Marques, J. A., "Compliance Profile of Signed Action Receipts for AI Agents", , <https://datatracker.ietf.org/doc/draft-marques-asqav-compliance-receipts/>.
[PACIOLI]
Pacioli, L., "Summa de arithmetica, geometria, proportioni et proportionalita", .
[REATTEST]
Dogru, E. C., "Cedulon Re-Attestation: Carrying Spend Evidence Across Algorithm Retirement", , <https://github.com/dogrucanemek-alt/cedulon/blob/e681e24d1b29912d8c190259c2ea9f4f9538c29d/spec/draft-dogru-cedulon-reattestation-00.md>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, , <https://www.rfc-editor.org/rfc/rfc7942>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/rfc/rfc9110>.
[RFC9421]
Backman, A., Ed., Richer, J., Ed., and M. Sporny, "HTTP Message Signatures", RFC 9421, DOI 10.17487/RFC9421, , <https://www.rfc-editor.org/rfc/rfc9421>.
[SCHROCK]
Schrock, I., "Outcome Binding for Authorized Actions and Independently Observed Effects", , <https://datatracker.ietf.org/doc/draft-schrock-ep-outcome-binding/>.
[STREAMING]
Dogru, E. C., "Cedulon Streaming Reconciliation: Continuous Completeness for Agent Spend", , <https://github.com/dogrucanemek-alt/cedulon/blob/e681e24d1b29912d8c190259c2ea9f4f9538c29d/spec/draft-dogru-cedulon-streaming-00.md>.
[VAUBAN]
Vauban Research, "x402 STARK Receipt Format Extension", , <https://datatracker.ietf.org/doc/draft-vauban-x402-stark-receipts/>.
[X402]
x402 Foundation, "x402: An Open Standard for Internet-Native Payments", , <https://www.x402.org/>.

Acknowledgments

Iman Schrock and Pablo Play ran the -00 implementation against the pinned commit and reported the defects that produced this revision. Iman Schrock found the two extract-binding defects, proposed the repair this document adopts, and is also the author of [SCHROCK], cited here as adjacent work. Pablo Play found that a repeated reference hid the unaccounted amount, and filed a written reproduction. Neither reviewed this text, and any error in it is the author's.

Field survey notes and the informative threat-model narrative in the companion repository helped shape the requirement identifiers used here. Those identifiers are defined in Section 14.

Appendix A. Test Vectors

These vectors use RFC 8032 Ed25519 secret scalar #1 (fixture only; never a production key). Hex is lowercase. They MUST match the locked tests in the companion implementation.

Receipt COSE_Sign1:

Claims: payer=payer-1, payee=payee-1, amount=1, currency=USD, policyHash=aa, manifestHash=null, noManifest=true, x402PaymentRef=null, timestampMs=1700000000000, nonce=n100000000000000, prevReceiptHash=null, outcome=aborted.

COSE_Sign1 hex (whitespace ignored; identical to the locked test):

845830a301320378206170706c69636174696f6e2f636564756c6f6e2d
726563656970742b63626f72044806e3fd8fda29bb60a0587cac3a0001
11706770617965722d313a000111716770617965652d313a0001117261
313a00011173635553443a000111746261613a00011175f63a00011176
f53a00011177f63a000111781b0000018bcfe568003a00011179706e31
30303030303030303030303030303a0001117af63a0001117b6761626f
727465645840685c01aa778a850b9d35250406f092b6f5cb03fb359593
0422533e28ac620ad439f5e7bd8ed1fa5ded90d4421a2de34f94d1d78d
38a65812cb5315ee7f1cf403

Manifest COSE_Sign1:

Body: description=fixture-goods, amount=1, currency=USD, acceptanceCriteriaHash=00, cancelCondition=none, expiresAtMs=1700000000000, ap2MandateHash=null.

COSE_Sign1 hex (whitespace ignored; identical to the locked test):

845831a301320378216170706c69636174696f6e2f636564756c6f6e2d
6d616e69666573742b63626f72044806e3fd8fda29bb60a0584aa73a00
0112386d666978747572652d676f6f64733a0001123961313a0001123a
635553443a0001123b6230303a0001123c646e6f6e653a0001123d1b00
00018bcfe568003a0001123ef65840898628b1524a44ca641b5058c7a4
7e71bd4ce1ca0782e03b511c23e0819c3771407d627216d0b104224ee8
2cacffbd21e66fe035ed5ce4ee85b7bcd9c560ad02

Author's Address

Emek Can Dogru
VERAX TEKNOLOJI LIMITED SIRKETI