Agent Decision Commitments for Payments
draft-milan-agent-decision-commitment-00
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Author | Fernando Henrique D. Milan | ||
| Last updated | 2026-10-14 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Additional resources |
ORCID
|
||
| 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-milan-agent-decision-commitment-00
Network Working Group F. H. D. Milan
Internet-Draft 15 October 2026
Intended status: Experimental
Expires: 18 April 2027
Agent Decision Commitments for Payments
draft-milan-agent-decision-commitment-00
Abstract
Software agents increasingly select and initiate payments on behalf
of people and organizations. Existing agent payment protocols record
what a principal authorized and that value moved, but not what
information the agent relied on when it chose. This document defines
the Agent Decision Commitment (ADC): a salted hash commitment to a
decision record that identifies the content the agent provided to the
model interface (after any agent-side transformation), the model
calls made, and the resulting answer and action. The commitment is
carried as a single selectively disclosable claim in an existing
payment mandate or payment payload and is, by default, registered
with a transparency service before the payment is authorized. The
decision record and its content remain with the holder and are
disclosed only to dispute participants, who can verify them against
the mandate and the transparency service and can inspect the content
the agent provided to the model. This document defines the data
model, the commitment and anchoring procedures, a disclosure and
verification procedure that reports attestation levels rather than
verdicts, and bindings to three agent payment protocols and to
account-to-account credit transfers. It also defines a witnessed
reciprocal exchange by which two parties' agents evidence what passed
between them: the receiver signs over the committed bytes,
independent witnesses fix the time of each step, a failure to answer
by a deadline is recorded, and arbiters resolve stalled exchanges.
About This Document
This note is to be removed before publishing as an RFC.
This document is an individual submission. Discussion is invited on
the DISPATCH mailing list (dispatch@ietf.org), and on the SCITT
(scitt@ietf.org) and OAuth (oauth@ietf.org) working group lists,
since this document uses the SCITT architecture [RFC9943] and SD-JWT
[RFC9901].
Milan Expires 18 April 2027 [Page 1]
Internet-Draft Agent Decision Commitments October 2026
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 18 April 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 . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Scope . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2. Liability Neutrality . . . . . . . . . . . . . . . . . . 5
1.3. What ADC Does Not Establish . . . . . . . . . . . . . . . 5
1.4. Requirements Language . . . . . . . . . . . . . . . . . . 5
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5
3. Roles and Responsibilities . . . . . . . . . . . . . . . . . 7
4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5. Data Model . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.1. Conventions . . . . . . . . . . . . . . . . . . . . . . . 8
5.2. Context Items and the Context Receipt . . . . . . . . . . 9
5.3. Decision Record . . . . . . . . . . . . . . . . . . . . . 11
5.4. Commitment and Decision Context Claim . . . . . . . . . . 12
5.5. Holder Chain and Anchoring . . . . . . . . . . . . . . . 12
5.6. Outcome and Erasure Entries . . . . . . . . . . . . . . . 14
Milan Expires 18 April 2027 [Page 2]
Internet-Draft Agent Decision Commitments October 2026
5.7. CDDL . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6. Disclosure and Verification . . . . . . . . . . . . . . . . . 19
6.1. Disclosure Request . . . . . . . . . . . . . . . . . . . 19
6.2. Release . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.3. Transfer Confidentiality . . . . . . . . . . . . . . . . 20
6.4. Verification Procedure . . . . . . . . . . . . . . . . . 20
6.5. Attestation Levels . . . . . . . . . . . . . . . . . . . 21
6.6. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.7. Verification Reports and Their Audit . . . . . . . . . . 23
7. Bindings . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.1. Verifiable Intent . . . . . . . . . . . . . . . . . . . . 23
7.2. Agent Payments Protocol . . . . . . . . . . . . . . . . . 24
7.3. x402 . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7.4. Account-to-Account Credit Transfers . . . . . . . . . . . 25
7.5. Card Authorization Messages . . . . . . . . . . . . . . . 25
8. Witnessed Reciprocal Exchange . . . . . . . . . . . . . . . . 25
8.1. Common Rules . . . . . . . . . . . . . . . . . . . . . . 26
8.2. Objects . . . . . . . . . . . . . . . . . . . . . . . . . 26
8.3. Witnesses . . . . . . . . . . . . . . . . . . . . . . . . 29
8.4. State Machine . . . . . . . . . . . . . . . . . . . . . . 30
8.5. Arbiters . . . . . . . . . . . . . . . . . . . . . . . . 32
8.6. Binding to Decision Records . . . . . . . . . . . . . . . 33
8.7. Security and Privacy of the Exchange . . . . . . . . . . 33
9. Related Work . . . . . . . . . . . . . . . . . . . . . . . . 34
10. Security Considerations . . . . . . . . . . . . . . . . . . . 35
10.1. Trust Assumptions . . . . . . . . . . . . . . . . . . . 35
10.2. Threats and Mitigations . . . . . . . . . . . . . . . . 36
10.3. Replay and Attribution . . . . . . . . . . . . . . . . . 39
10.4. Cryptographic Considerations . . . . . . . . . . . . . . 39
11. Privacy Considerations . . . . . . . . . . . . . . . . . . . 39
12. Operational Considerations . . . . . . . . . . . . . . . . . 41
13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 41
13.1. JSON Web Token Claims Registration . . . . . . . . . . . 41
13.2. Media Type Registrations . . . . . . . . . . . . . . . . 42
14. Implementation Status . . . . . . . . . . . . . . . . . . . . 43
15. References . . . . . . . . . . . . . . . . . . . . . . . . . 43
15.1. Normative References . . . . . . . . . . . . . . . . . . 43
15.2. Informative References . . . . . . . . . . . . . . . . . 45
Appendix A. Test Vectors . . . . . . . . . . . . . . . . . . . . 51
Appendix B. Example Mapping to Dispute Evidence . . . . . . . . 55
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 56
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 56
Milan Expires 18 April 2027 [Page 3]
Internet-Draft Agent Decision Commitments October 2026
1. Introduction
Payment agents increasingly choose rather than merely execute: which
bill to pay, which merchant to buy from, whether a request is
legitimate. Mandate formats such as Verifiable Intent [VI] and the
Agent Payments Protocol [AP2] bind a principal's authorization to an
agent key. Merchant-signed checkout objects record what was bought,
and payment receipts and settlement record that value moved. None of
these records what the agent relied on when it chose.
That question matters in two recurring situations. The first is the
authorized but wrong purchase: a payment that satisfies the
principal's signed constraints but results from a misread invoice or
a fraudulent payee that fits the budget. The second is the
manipulated agent: content the agent read, including text embedded in
images, has been shown to redirect deployed agents [TOB] [BRAVE].
Media is a particular problem because model providers may resize
images or sample video frames before the model sees them, and an
attack can be constructed to appear only after such resampling [TOB].
A log of original files is therefore not a record of what the model
received. This document records the bytes the agent sent to the
model interface; transformations applied by a provider after receipt
are visible only through provider attestation (Section 6.5).
This document defines a minimal mechanism. The holder of the agent's
records computes a decision record that identifies, by salted
digests, every item provided to the deciding model, together with the
model calls, the answer and the action. The holder commits to the
record with a salted hash, places the commitment in the payment
mandate or payload, and, by default, registers it with a transparency
service [RFC9943] before the payment is authorized. In a dispute,
the holder discloses the record, the salts and the content to
authorized verifiers, who check them against the mandate and the
transparency service. Where the agent's decision depends on what a
counterparty sent, or a counterparty is to acknowledge what the agent
sent, the two parties use the witnessed reciprocal exchange
(Section 8), so that what passed between them is evidenced as well.
1.1. Scope
This document specifies the decision record, the context receipt, the
commitment, the holder chain and anchoring, outcome and erasure
entries, disclosure and verification, bindings, and the witnessed
reciprocal exchange between parties. It does not specify how an
agent decides, how content is selected for a model, how dispute
participants are credentialed, or what consequence follows from a
verification result.
Milan Expires 18 April 2027 [Page 4]
Internet-Draft Agent Decision Commitments October 2026
1.2. Liability Neutrality
ADC produces evidence. It does not allocate liability among
principals, holders, merchants, issuers, acquirers, networks, or
model providers, and it does not define the consequence of a missing,
withheld, or failed record. Those consequences are matters for the
applicable scheme rules, contracts, and law. Verifiers report the
attestation level and step results defined in Section 6.5, not a
verdict.
1.3. What ADC Does Not Establish
ADC establishes the integrity and timing of evidence, not its truth.
It does not establish that recorded inputs were authentic or
accurate, that the model's answer was correct, that the action
reflected the principal's intent beyond what the mandate states,
which item caused an outcome, that the context receipt is complete,
or that the holder recorded honestly at decision time. ADC imports
no facts about the world and therefore relies on no external oracle;
facts enter only as recorded content whose stated origin a verifier
can assess. Every verification step is a finite computation over
released data (hash recomputation, signature verification, and
comparison) and terminates. ADC does not evaluate properties of the
agent's program or behavior.
1.4. Requirements Language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
2. Terminology
Agent Decision Commitment (ADC): The mechanism defined in this
document, comprising the decision record, context receipt,
commitment, anchoring, and disclosure procedures.
Agent: Software that selects and initiates a payment on behalf of a
principal.
Principal: The person or organization on whose behalf the agent
acts.
Holder: The party that stores decision records and context and
responds to disclosure requests; typically the operator of the
agent.
Milan Expires 18 April 2027 [Page 5]
Internet-Draft Agent Decision Commitments October 2026
Verifier: A dispute participant (for example an issuer, acquirer,
merchant, network, or arbiter) that checks a disclosed record.
Context item: One byte sequence provided to a model for a decision,
after all agent-side transformation (rendering, resizing, frame
sampling, optical character recognition, transcription), or the
original from which such an item was derived.
Item descriptor: A JSON object that identifies a context item by
content digest and describes its media type, role, origin, and any
transformation.
Context receipt: A JSON object listing the salted digests of all
item descriptors for one decision. Not to be confused with a
mandate receipt or a transparency receipt.
Decision record: A JSON object binding a context receipt, the
question asked, the model calls, the answer, the action, and the
transaction.
Commitment: The salted hash of a decision record defined in
Section 5.4.
Decision context claim: The JSON object carrying a commitment inside
a mandate or payment payload, registered as the JWT claim
"decision_context".
Mandate receipt: A receipt defined by a payment protocol, such as
the AP2 Checkout Receipt.
Transparency service, signed statement: As defined in [RFC9943].
Transparency receipt: A Receipt as defined in [RFC9943], called
"transparency receipt" here to distinguish it from mandate
receipts and context receipts.
Exchange: The witnessed reciprocal exchange of a payload between a
sender and a recipient defined in Section 8.
Witness: A service, independent of the parties, that countersigns
the hash of an exchange object with its own time (Section 8.3).
Arbiter: One of the parties named in an offer that hold shares of
the exchange key and resolve stalled exchanges (Section 8.5). Not
to be confused with a dispute arbiter acting as verifier.
Rail: The payment protocol or scheme that carries the payment.
Milan Expires 18 April 2027 [Page 6]
Internet-Draft Agent Decision Commitments October 2026
Covered decision: A decision of a type that the holder's profile
designates as subject to this document.
Profile: A set of choices made by a community of holders and
verifiers (for example a payment scheme or a dispute program): the
decision types covered, the transparency services and their trust
anchors, the maximum anchoring interval, the credentials accepted
for disclosure requests, the request and release transport,
retention periods, and the attestation levels accepted for each
purpose. A claim or record identifies its profile by URI in the
"profile" member.
Abbreviations: JCS, JSON Canonicalization Scheme [RFC8785]; NFC,
Unicode Normalization Form C [UAX15]; SD-JWT, Selective Disclosure
for JWTs [RFC9901]; CDDL, Concise Data Definition Language [RFC8610].
3. Roles and Responsibilities
+==============+===================================================+
| Role | Responsibilities in this document |
+==============+===================================================+
| Holder | Records context items, computes receipts, records |
| | and commitments, maintains the holder chain, |
| | registers anchor and entry statements, stores |
| | content for the retention period, authenticates |
| | disclosure requests, releases evidence under the |
| | principal's authorization policy. |
+--------------+---------------------------------------------------+
| Agent | Places the decision context claim in the mandate |
| | or payload it signs or submits. |
+--------------+---------------------------------------------------+
| Principal | Sets the authorization policy that governs |
| | disclosure; may access its own records. |
+--------------+---------------------------------------------------+
| Transparency | Registers signed statements and issues |
| service | transparency receipts that bound when a |
| | commitment existed. |
+--------------+---------------------------------------------------+
| Model | Optionally attests to model calls (Section 6.5, |
| provider | level A3). |
+--------------+---------------------------------------------------+
| Verifier | Requests disclosure under a credential accepted |
| | by the holder's profile, runs the procedure in |
| | Section 6.4, and reports results. |
+--------------+---------------------------------------------------+
| Counterparty | In an exchange, signs held, key_received, |
| | received, mismatch, accepted, or refused over |
| | exactly the committed bytes (Section 8). |
Milan Expires 18 April 2027 [Page 7]
Internet-Draft Agent Decision Commitments October 2026
+--------------+---------------------------------------------------+
| Witness | Countersigns exchange object hashes with its own |
| | time; sees hashes only. |
+--------------+---------------------------------------------------+
| Arbiter | Holds an escrowed share of an exchange key and |
| | delivers the key when an exchange stalls; never |
| | acknowledges or accepts on the recipient's |
| | behalf. |
+--------------+---------------------------------------------------+
| Merchant, | Carry and present the mandate according to the |
| issuer, | rail's own rules; no new obligations are defined |
| acquirer, | for them. |
| network | |
+--------------+---------------------------------------------------+
Table 1: Roles
4. Overview
Holder/Agent Transparency Rail / Merchant
| Service |
1. record items, compute | |
receipt, record, | |
commitment C | |
2. register anchor(C) ------>| |
|<-- transparency receipt |
3. mandate/payload carrying decision_context(C) -->|
| | |
... later, a dispute ... | |
| | Verifier |
|<-------- 4. disclosure request (credential) |
5. release record, salts, | |
receipt, items ---------------------------------> 6. verify:
| | mandate, C,
|<---------------------- inclusion/time check - receipt,
| | items, level
Figure 1: Issuance and Dispute
5. Data Model
5.1. Conventions
* All objects are JSON [RFC8259]. Before hashing, every string
member name and value MUST be normalized to NFC [UAX15], and the
object MUST be serialized with JCS [RFC8785]. The result is
denoted CANON(object).
Milan Expires 18 April 2027 [Page 8]
Internet-Draft Agent Decision Commitments October 2026
* Digests are SHA-256 [SHS] unless the object's "alg" member states
otherwise, and are encoded as base64url without padding [RFC4648].
DIGEST(x) denotes BASE64URL(SHA-256(x)), where x is CANON(x) when
x is a JSON value and the octets themselves otherwise. Verifiers
MUST reject objects whose "alg" value they do not support.
* Every salt defined by this document is exactly 32 octets from a
cryptographically secure random number generator, fresh for each
use. (SD-JWT disclosure salts are governed by [RFC9901].) The
fixed length makes the concatenation salt || CANON(object)
unambiguous.
* Timestamps are strings in the format of [RFC3339] with a "Z"
offset.
* Each top-level object (receipt, record, statement payload,
release) carries "type" and "v"; the decision context claim
carries "v"; nested objects carry neither. This document defines
version 1. A verifier that does not support a version MUST report
the object as unsupported.
* Unknown members MUST be included when an object is canonicalized
and hashed, and MUST be ignored when interpreting it. An object
that contains duplicate member names, before or after NFC
normalization, MUST be rejected.
* Amounts are strings containing a non-negative decimal integer in
the smallest unit of the asset on the rail (minor units for fiat
currencies, base units for tokens), so that large values survive
JCS.
* Numbers are canonicalized by JCS, which can change their textual
form. Where the exact bytes returned by a model provider matter,
they are recorded as a context item with role "response"
(Section 5.2).
5.2. Context Items and the Context Receipt
For each context item i, in the order in which items were provided to
the model, the holder constructs an item descriptor D_i and a fresh
salt s_i, and computes the item digest:
item_digest_i = BASE64URL(SHA-256(s_i || CANON(D_i)))
An item descriptor has the following members:
content_digest (REQUIRED): BASE64URL(SHA-256(item bytes)).
Milan Expires 18 April 2027 [Page 9]
Internet-Draft Agent Decision Commitments October 2026
media_type (REQUIRED): The media type of the item bytes.
role (REQUIRED): One of "instructions", "tool_definition",
"prior_turn", "as_sent", "original", "request", "response",
"exchange", "witness", or an extension value in the form of a URI.
Role "request" denotes the complete request body as sent to the
provider. Roles "exchange" and "witness" denote an exchange
object body and a witness statement (Section 8.6).
calls (REQUIRED): The array of zero-based indexes, into the record's
"models" array, of the model calls to which the item was input or,
for role "response", from which it was returned; empty for an item
with role "original".
derived_from (OPTIONAL): The zero-based index of the item from which
this item was derived.
transform (OPTIONAL): A string identifying the transformation and
the implementation and version that performed it.
source (REQUIRED): An object with "kind" and, where applicable,
"uri" and "fetched_at".
The holder MUST list every input to every model call covered by the
decision, including instructions, tool definitions, prior turns,
retrieved content, and media, and MUST include the raw provider
response for each call with role "response". Where the agent
transformed an item, the item as provided to the model has role
"as_sent" and a "derived_from" member giving the index of its source
item. The source item SHOULD also be listed; it has role "original"
if it was not itself provided to the model, and role "as_sent"
otherwise. Agents SHOULD perform media transformations themselves
and stay within provider limits, so that the bytes recorded are the
bytes the model received.
The context receipt is:
type, v, alg (REQUIRED): "adc-receipt", 1, and the digest algorithm.
items (REQUIRED): The non-empty array of item digests, in model-
input order.
item_count (REQUIRED): The number of items, at least 1.
retention_until (REQUIRED): The time until which the holder commits
to retain the descriptors, salts, and items (Section 12).
selector (OPTIONAL): An object naming the component that selected
Milan Expires 18 April 2027 [Page 10]
Internet-Draft Agent Decision Commitments October 2026
the items and a digest of its configuration.
receipt_digest = BASE64URL(SHA-256(CANON(receipt))). Because each
descriptor is hidden behind its own salt, the receipt reveals neither
the content digests nor the origins of the items, and a descriptor
and its salt can later be deleted without changing receipt_digest
(Section 5.6).
5.3. Decision Record
type, v, alg (REQUIRED): "adc-record", 1, and the digest algorithm.
chain (REQUIRED): An object with "id", an opaque identifier of the
holder chain that is independent of any signing key; "seq", this
record's sequence number in the chain; and "prev", the commitment
of the record with sequence number seq - 1, or 32 zero octets
encoded in base64url for the first record of a chain
(Section 5.5).
receipt_digest (REQUIRED): As defined in Section 5.2.
question (REQUIRED): An object with "name", "kind" (for example
"choice", "score", "probability", or "freeform"), and
"schema_digest", DIGEST of the question definition (a JSON
object).
profile (OPTIONAL): The URI of the profile under which the record
was made.
models (REQUIRED): An array with one entry per model call, each with
"provider", "id" (a resolved model version, not an alias),
"request_id", "request_digest" (DIGEST of the request body as sent
to the provider), and optionally "params_digest" (digest of the
decoding parameters, if the interface exposes them) and
"attestation", a provider-issued attestation over the request and
response, for example an Attested Inference Receipt
[I-D.tsyrulnikov-rats-attested-inference-receipt], encoded as the
base64url encoding of the attestation token (Section 6.5).
answer (REQUIRED): The model output, as a JSON object.
action (REQUIRED): An object with "taken", the action decided:
"pay", "decline", or an extension value in the form of a URI. It
MUST NOT reference the mandate, which does not yet exist when the
record is committed.
transaction (REQUIRED when the action initiates a payment): An
Milan Expires 18 April 2027 [Page 11]
Internet-Draft Agent Decision Commitments October 2026
object with "rail", "payee", "amount", "currency", and, where the
rail defines one, "checkout_digest", each encoded and compared as
defined for the rail in Section 7. "currency" is an ISO 4217
[ISO4217] code for fiat currencies and a CAIP-19 asset identifier
[CAIP19] for tokens.
issued_at (REQUIRED): The time the record was completed.
One decision record MUST correspond to at most one transaction.
Outcomes and erasures are not part of the record; they are separate
entries (Section 5.6).
5.4. Commitment and Decision Context Claim
C = BASE64URL(SHA-256(salt || CANON(record)))
The decision context claim is:
{"v":1,"alg":"sha-256","commitment":"<C>","receipt_uri":"<uri>",
"profile":"<uri>"}
"receipt_uri" is an https URI at which disclosure requests for this
record are made; its path is an opaque value chosen by the holder.
It MUST NOT embed content, digests, or identifiers that link the
principal across transactions. "profile" (OPTIONAL) identifies the
profile; if it is absent, the verifier obtains the applicable profile
out of band, and without one reports no level above A1. Rails that
cannot carry the claim object carry only C, as defined in Section 7.
In JWT-based mandates, the claim is carried as an ordinary SD-JWT
disclosure [RFC9901]: it is not canonicalized, its member order is
whatever the issuer serialized, and its digest is computed over the
base64url-encoded disclosure string as RFC 9901 specifies. Verifiers
MUST use the received disclosure string and MUST NOT re-serialize the
claim. On rails that are not JWT-based, the claim is carried as a
plain JSON object or reduced to C, as defined in Section 7. The
commitment salt is distinct from any SD-JWT disclosure salt and is
released only under Section 6.
5.5. Holder Chain and Anchoring
The holder MUST create a decision record for every covered decision,
including decisions whose action is "decline", and MUST assign
consecutive sequence numbers per chain. The "prev" member links each
record to its predecessor, so that a missing record appears as a gap.
Hash chains are common in audit-log designs (Section 9); the chain
here is kept per chain id, independent of signing keys, and covers
declined decisions, so that a verifier can detect a withheld
decision, not only a withheld payment.
Milan Expires 18 April 2027 [Page 12]
Internet-Draft Agent Decision Commitments October 2026
A chain is not tied to a signing key. The key that signs a chain's
first anchor is the chain's initial key. To rotate, the holder
registers a rotation statement of type "adc-rotation", signed with
the current key, that names the chain and the successor key;
statements signed with the successor key then continue the same chain
id and sequence. Verifiers MUST consider only statements whose
signing key is the chain's initial key or a successor established by
such rotation statements; statements by any other issuer that use the
same "sub" are ignored. The holder MUST NOT start a new chain to
replace an existing one except under the profile's rules, and a new
chain's first anchor MUST be reported to verifiers on request. A
deletion at the tail of a chain, after the last anchor a verifier
sees, is not detectable by the chain alone.
Unless the profile permits late registration, the holder MUST
register an anchor statement with at least one transparency service
[RFC9943] before the mandate or payment payload that carries the
claim is signed. The anchor is a Signed Statement as defined in
[RFC9943]: a COSE_Sign1 message [RFC9052] whose protected header
carries a "kid" identifying the signing key (unless "x5t" or
"x5chain" is present) and CWT claims [RFC8392] with "iss" identifying
the holder and "sub" set to the chain id, and whose payload, of
content type application/adc-anchor+json, is:
{"type":"adc-anchor","v":1,"commitment":"<C>","chain":"<id>",
"seq":<n>,"prev":"<C(n-1)>","issued_at":"<time>"}
The holder MUST retain the transparency receipt. Level A2 requires
that the registration time can be established from the receipt or
from the transparency service under the profile; [RFC9943] does not
itself require receipts to carry a registration time. Profiles MAY
require registration with two transparency services operated by
different organizations, SHOULD prefer services that provide
consistency proofs, and MAY set the maximum interval between
issued_at and registration (300 seconds if unspecified). Where the
profile permits late registration, a holder that cannot reach a
transparency service registers as soon as it can, and the anchor is
reported as late (Section 6.5). Outcome, erasure, and rotation
statements (Section 5.6) use the same envelope and "sub" but carry no
sequence number. A batch format for anchors is out of scope.
Failure handling:
* Before registering an anchor, the holder MUST durably store the
record, the salts, the items, and the sequence number it consumes.
A sequence number MUST NOT be reused, including after recovery
from backup; the holder MUST determine the highest sequence number
already anchored before resuming a chain.
Milan Expires 18 April 2027 [Page 13]
Internet-Draft Agent Decision Commitments October 2026
* If registration times out, the holder retries with the identical
signed statement bytes. Verifiers treat byte-identical statements
as one. Re-signing a statement for the same chain and seq
produces different bytes and is reported as equivocation.
* If the agent does not complete an anchored action whose "taken" is
"pay", for example because the process failed before the mandate
was signed, the holder MUST register an outcome statement with
status "abandoned".
* A chain is a total order. A holder that makes concurrent
decisions SHOULD operate several chains; each covered decision
belongs to exactly one chain.
* Holders keep issued_at on a synchronized clock. Verifiers allow
the clock tolerance set by the profile (60 seconds if unspecified)
when comparing issued_at, registration times, and mandate issuance
times.
5.6. Outcome and Erasure Entries
After the decision, the holder can register further signed statements
that reference the commitment:
* "adc-outcome" (OPTIONAL), with "status" (for example "settled",
"disputed", "refunded", "reversed", or "abandoned"; see
Section 5.5) and, when known, "reference_digest", a digest of the
mandate or payment identifier. Rails and settlement-record
formats may already carry this information; profiles decide
whether outcome entries are used.
* "adc-erasure", which the holder MUST register when it deletes
evidence before retention_until, listing in "items" the zero-based
indexes of items whose descriptors, salts, and content were
deleted, in "erased_at" the time of deletion, and in "reason" one
of "principal_request", "legal_obligation", "lost", or an
extension value in the form of a URI. Loss of evidence before
retention_until is registered with reason "lost". Deleting a
descriptor and its salt leaves receipt_digest and the commitment
valid and makes the item digest unlinkable to the content, without
the per-record key management of cryptographic erasure. An
erasure entry records that evidence is no longer available; this
document attaches no consequence to it (Section 1.2).
Milan Expires 18 April 2027 [Page 14]
Internet-Draft Agent Decision Commitments October 2026
5.7. CDDL
The following CDDL [RFC8610] describes the objects. JSON encodings
apply; "digest" is a base64url string, "timestamp" is an RFC 3339
string, and salts, content, nonce_random, and statements are
base64url strings. Each entry of "statements" is a Transparent
Statement [RFC9943]: an anchor, entry, or rotation statement with its
transparency receipts. The exchange objects of Section 8 are
described by adc-exchange, adc-witness, and exchange-receipt.
adc-receipt = {
type: "adc-receipt", v: 1, alg: hash-alg,
items: [+ digest], item_count: uint .ge 1,
retention_until: timestamp,
? selector: { name: tstr, version: tstr, ? config_digest: digest },
* tstr => any
}
item-descriptor = {
content_digest: digest, media_type: tstr, role: item-role,
calls: [* uint], ? derived_from: uint, ? transform: tstr,
source: { kind: tstr, ? "uri": tstr, ? fetched_at: timestamp,
* tstr => any },
* tstr => any
}
item-role = "instructions" / "tool_definition" / "prior_turn" /
"as_sent" / "original" / "request" / "response" /
"exchange" / "witness" / tstr
adc-record = {
type: "adc-record", v: 1, alg: hash-alg,
chain: { id: tstr, seq: uint, prev: digest, * tstr => any },
? profile: tstr,
receipt_digest: digest,
question: { name: tstr, kind: tstr, schema_digest: digest,
* tstr => any },
models: [+ model-call],
answer: { * tstr => any },
action: { taken: tstr, * tstr => any },
? transaction: transaction,
issued_at: timestamp,
* tstr => any
}
model-call = {
provider: tstr, id: tstr, request_id: tstr, request_digest: digest,
? params_digest: digest, ? attestation: tstr,
* tstr => any
}
transaction = {
rail: "vi" / "ap2" / "x402" / "iso20022" / tstr,
Milan Expires 18 April 2027 [Page 15]
Internet-Draft Agent Decision Commitments October 2026
payee: tstr, amount: tstr, currency: tstr,
? checkout_digest: digest,
* tstr => any
}
decision-context-claim = {
v: 1, alg: hash-alg, commitment: digest, receipt_uri: tstr,
? profile: tstr,
* tstr => any
}
adc-anchor = {
type: "adc-anchor", v: 1, commitment: digest, chain: tstr,
seq: uint, prev: digest, issued_at: timestamp,
* tstr => any
}
adc-outcome = {
type: "adc-outcome", v: 1, commitment: digest, status: tstr,
? reference_digest: digest, issued_at: timestamp,
* tstr => any
}
adc-erasure = {
type: "adc-erasure", v: 1, commitment: digest,
items: [+ uint], erased_at: timestamp,
reason: "principal_request" / "legal_obligation" / "lost" / tstr,
* tstr => any
}
adc-rotation = {
type: "adc-rotation", v: 1, chain: tstr, successor_kid: tstr,
issued_at: timestamp,
* tstr => any
}
adc-request = {
type: "adc-request", v: 1, request_id: tstr, verifier: tstr,
presentation_digest: digest, issued_at: timestamp,
* tstr => any
}
adc-release = {
type: "adc-release", v: 1, request_id: tstr, verifier: tstr,
issued_at: timestamp, record: adc-record,
commitment_salt: tstr, receipt: adc-receipt,
statements: [* tstr],
items: [+ released-item / withheld-item],
? nonce_random: tstr,
* tstr => any
}
released-item = { index: uint, salt: tstr,
descriptor: item-descriptor, content: tstr }
withheld-item = { index: uint, status: "withheld" / "erased",
? erasure_reference: tstr }
Milan Expires 18 April 2027 [Page 16]
Internet-Draft Agent Decision Commitments October 2026
adc-error = {
type: "adc-error", v: 1, ? request_id: tstr,
code: "invalid_request" / "invalid_credential" /
"replayed_request" / "not_found" / "policy_denied" /
"too_large" / "temporarily_unavailable" / tstr,
? retry_after: uint, ? description: tstr,
* tstr => any
}
adc-report = {
type: "adc-report", v: 1, verifier: tstr, verified_at: timestamp,
? profile: tstr, level: "A0" / "A1" / "A2" / "A3" / "none",
signer: "agent" / "principal" / "payer" / "none",
steps: [8*8 step-result],
inputs: { presentation: digest, release: digest,
statements: [* digest], attestations: [* digest],
trust_anchors: [* digest], revocation: [* digest] },
? late_anchor_seconds: uint, ? equivocation: bool,
* tstr => any
}
adc-exchange = {
exchange-common, exchange-step,
* tstr => any
}
exchange-common = (
type: "adc-exchange", v: 1, exchange_id: tstr, seq: uint,
prev: digest, issued_at: timestamp
)
exchange-step = (
x-offer // x-held // x-key-release // x-key-received //
x-received // x-mismatch // x-answer // x-arbiter-delivery //
x-non-ack // x-close
)
x-offer = (
step: "offer", intent: "deliver" / "offer",
sender_key: tstr, recipient_key: tstr,
payload_commitment: digest, aead: tstr,
ciphertext_hash: digest, key_hash: digest,
? escrow: adc-escrow, response_window: uint,
expires_at: timestamp
)
x-held = (step: "held", envelope_hash: digest,
? arbiters_accepted: digest)
x-key-release = (
step: "key_release",
hpke: { kem_id: uint, kdf_id: uint, aead_id: uint },
wrapped_key: tstr
)
x-key-received = (step: "key_received", key_release_hash: digest)
Milan Expires 18 April 2027 [Page 17]
Internet-Draft Agent Decision Commitments October 2026
x-received = (step: "received", envelope_hash: digest)
x-mismatch = (
step: "mismatch", envelope_hash: digest,
check: "ciphertext_hash" / "unwrap" / "key_hash" / "decrypt" /
"payload_commitment"
)
x-answer = (step: "accepted" / "refused", envelope_hash: digest)
x-arbiter-delivery = (
step: "arbiter_delivery", envelope_hash: digest,
key_matched: bool, commitment_matched: bool,
? delivered_at: timestamp
)
x-non-ack = (
step: "non_ack", envelope_hash: digest, awaited: tstr,
attempts: [* delivery-attempt]
)
x-close = (step: "close", state: exchange-state, reason: tstr)
delivery-attempt = {
transport_digest: digest, witnesses: [+ witness-statement],
* tstr => any
}
adc-escrow = {
scheme: tstr, arbiters: [3* tstr], threshold: uint .ge 2,
shares: [3* tstr], proof: tstr,
* tstr => any
}
exchange-state = "NOT_ACKNOWLEDGED" / "VOID" /
"KEY_UNACKNOWLEDGED" / "DELIVERED_VIA_ARBITER" /
"CONTENT_UNACKNOWLEDGED" / "DELIVERED" /
"ACCEPTED" / "REFUSED" / "NOT_ACCEPTED" /
"FAULT_SENDER" / "FAULT_RECIPIENT" / "CLOSED"
exchange-receipt = {
object: tstr / { payload: tstr, signatures: [+ any] },
witnesses: [+ witness-statement],
* tstr => any
}
witness-statement = {
format: "rfc3161" / "scitt" / tstr, token: tstr,
* tstr => any
}
adc-witness = {
type: "adc-witness", v: 1, object_hash: digest,
* tstr => any
}
step-result = ("pass" / "fail" / "not_applicable" /
"not_checked" / "unsupported")
hash-alg = "sha-256" / tstr
digest = tstr
Milan Expires 18 April 2027 [Page 18]
Internet-Draft Agent Decision Commitments October 2026
timestamp = tstr
6. Disclosure and Verification
6.1. Disclosure Request
A verifier sends the holder, at "receipt_uri", the mandate
presentation that carries the claim and a credential issued by the
party administering the dispute. The credential types, their trust
anchors, and the request transport are defined by the profile; this
document defines the properties they need. The credential MUST be
audience-restricted to the holder, sender-constrained (for example
with DPoP [RFC9449]), short-lived, and bound to the transaction, for
example by including the "sd_hash" of the presentation, so that a
holder or an attacker controlling "receipt_uri" cannot replay it
elsewhere. The verifier MUST dereference only https URIs, MUST apply
request-forgery protections to "receipt_uri" (for example refusing
private and link-local addresses and redirects to other hosts), and
MUST NOT dereference "source.uri" values found in released
descriptors. The holder MUST authenticate the credential, MUST log
the request, and MUST limit release to the records bound to the
transaction in the request.
The request is an object of type "adc-request" (Section 5.7) carrying
"request_id", at least 16 octets from a cryptographically secure
random number generator encoded in base64url; "verifier", an
identifier of the verifier; "presentation_digest", the digest of the
mandate presentation; and "issued_at". The holder MUST reject a
request whose request_id it has already accepted within the lifetime
of the credential, and a request whose issued_at lies outside the
profile's tolerance (60 seconds if unspecified).
6.2. Release
Release is governed by an authorization policy that the principal
sets in advance. When the policy permits, the holder returns a
release object of type "adc-release" (Section 5.7) containing the
decision record, the commitment salt, the context receipt, the anchor
statement and any rotation statements needed to authorize its key,
each with its transparency receipts, and, for each item, either the
descriptor, its salt, and the item bytes, or a statement that the
item is withheld or was erased (with a reference to the erasure
entry). The release echoes the request's "request_id" and "verifier"
and carries its own "issued_at", so that it cannot be presented as
the answer to a different request. For the x402 binding, the release
also includes "nonce_random" (Section 7.3). The holder MUST sign the
release as a JWS [RFC7515] with a key that the profile associates
with the holder, so that what was released, and what was withheld, is
Milan Expires 18 April 2027 [Page 19]
Internet-Draft Agent Decision Commitments October 2026
attributable. Withheld items remain listed by digest, so the
omission is visible. Because the holder is typically the party whose
conduct is in question, profiles MAY require the holder to deposit an
encrypted copy of the release material with the principal or a
custodian at decision time.
6.3. Transfer Confidentiality
A release contains personal data and the salts that protect it. It
MUST be transferred over TLS 1.3 [RFC8446] or later, following
[RFC9325], with the holder authenticated for the host named in
"receipt_uri" and the verifier's credential presented within that
session. If any party other than the holder and the verifier relays,
queues, or stores the release, the release SHOULD additionally be
encrypted to the verifier as a JWE [RFC7516]; HPKE-based JWE
[I-D.ietf-jose-hpke-encrypt] and post-quantum or hybrid key
encapsulation [I-D.ietf-hpke-pq] are suitable as they become
available. Salts MUST NOT be sent in any message that is not
confidentiality-protected. A verifier MUST NOT retain released
content beyond the dispute and any retention obligation that applies
to it.
6.4. Verification Procedure
1. Verify the mandate or payload according to its own specification
and extract the decision context claim.
2. Verify the holder's signature on the release. Recompute C from
the record and salt; it MUST equal the claim's commitment.
3. Check that record.transaction matches the transaction in the
mandate or payload, field by field, using the mapping and
comparison rules for the rail (Section 7). For x402, check that
the signed nonce equals SHA-256(BASE64URL-DECODE(C) ||
nonce_random); if "nonce_random" is not released, the x402
binding is level A0.
4. Recompute receipt_digest; it MUST equal record.receipt_digest,
and item_count MUST equal the length of items.
5. For each released item, recompute its item digest from descriptor
and salt and check that it appears at the stated index, then
check content_digest against the bytes. For derived items, the
verifier MAY re-apply the transformation; a mismatch is reported,
and its significance depends on whether the transformation is
deterministic.
Milan Expires 18 April 2027 [Page 20]
Internet-Draft Agent Decision Commitments October 2026
6. Verify each transparency receipt against trust anchors for the
transparency service defined by the profile, and check that every
receipt covers the same anchor statement. Check that the
anchored commitment, chain, seq, and prev match the record, that
the registration time is not more than the profile's interval
after issued_at, and that it is not later than the issuance time
of the mandate or payload (for example its "iat") where the rail
provides one. Only statements signed by keys authorized for the
chain (Section 5.5) are considered. The verifier MAY request
from the holder the anchors for neighboring sequence numbers;
[RFC9943] defines no query interface for this, so the means are
set by the profile. Two different anchor statements for the same
chain and seq MUST be reported as equivocation.
7. For each model call with an attestation, verify the attestation
and check that it binds the call's request_digest and the
content_digest of the call's "response" item. If an item with
role "request" is released for the call, check that its
content_digest equals the call's request_digest.
8. Report the attestation level and the result of each step.
6.5. Attestation Levels
+=======+====================================================+
| Level | Conditions |
+=======+====================================================+
| A0 | The record matches a commitment carried in a field |
| | not signed by the agent, the principal, or the |
| | payer. |
+-------+----------------------------------------------------+
| A1 | The commitment is covered by the signature of the |
| | agent, the principal, or the payer (including the |
| | x402 nonce construction), and steps 2 to 5 |
| | succeed. The verifier reports which party signed. |
+-------+----------------------------------------------------+
| A2 | A1, and step 6 succeeds: the anchor was registered |
| | in time, and the anchored chain values are |
| | consistent with the record and with any |
| | neighboring anchors obtained. |
+-------+----------------------------------------------------+
| A3 | A2, every model call carries an attestation, and |
| | step 7 succeeds for every model call. |
+-------+----------------------------------------------------+
Table 2: Attestation Levels
Milan Expires 18 April 2027 [Page 21]
Internet-Draft Agent Decision Commitments October 2026
A late or missing anchor caps the level at A1, and the verifier
reports the delay; a timely anchor for an A0 commitment is reported
alongside A0. No level asserts that the receipt lists every input to
the model. At A3, a provider attestation binds what the provider
received and returned; if the holder also releases the item with role
"request", the verifier can check that the listed items are the parts
of that request. The strength of A3 depends on the attestation
format; some formats bind hashes of a request and response without
proving that the response was produced from that request. Profiles
define which levels they accept for which purposes.
6.6. Errors
A holder that does not release returns an error object of type "adc-
error" (Section 5.7) with one of the following codes; the profile
maps them to its transport.
invalid_request: The request is malformed or names an unsupported
version or algorithm.
invalid_credential: The credential is missing, expired, not sender-
bound, or not issued under a trust anchor of the profile.
replayed_request: The request_id was already used, or issued_at is
outside the tolerance.
not_found: No record is bound to the presented transaction.
policy_denied: The principal's authorization policy does not permit
release to this verifier.
too_large: The release would exceed the limits set by the profile;
the profile may define partial release.
temporarily_unavailable: The holder cannot serve the request now;
the error carries "retry_after" in seconds.
Where distinguishing not_found from policy_denied would reveal that a
record exists, the profile MAY require holders to return not_found
for both. An error is not evidence about the decision; verifiers
report it as received.
Verifiers fail closed. Each step in Section 6.4 yields one of
"pass", "fail", "not_applicable", "not_checked", or "unsupported".
If any of steps 1 to 5 yields "fail" or "unsupported", no level is
reported. A step that is not checked never counts as passed, and
partial results never raise the level.
Milan Expires 18 April 2027 [Page 22]
Internet-Draft Agent Decision Commitments October 2026
6.7. Verification Reports and Their Audit
The verifier records its result as a verification report of type
"adc-report" (Section 5.7). The report states the level or its
absence, the result of each step, the profile, the verifier, the time
of verification, and the digests of every input: the mandate
presentation, the signed release, each transparent statement, each
attestation, and the trust anchors and revocation information used.
The verifier MUST sign the report as a JWS [RFC7515].
Given the same inputs, every step except the evaluation of revocation
status is a deterministic computation, so any other party holding
those inputs can repeat the procedure and must obtain the same
result. Revocation status is evaluated as of the recorded time
against the recorded sources. A verifier is therefore checked by
repetition, not by another authority. Profiles MAY require
verification by more than one independent verifier for a given
purpose.
7. Bindings
The bindings below are based on the cited versions of each protocol
and will need revision as those protocols change. Verifiable Intent
and the Agent Payments Protocol have been contributed to the FIDO
Alliance, whose Payments Technical Working Group is developing them
further [FIDO-AGENTIC]. AP2 states that other properties may be
included in a mandate, based on the mandate type. Verifiable Intent
defines no general rule for additional claims in its Layer 3
payloads; it defines an "agent_attestation" extension container whose
attestation types are not yet specified and whose unrecognized types
are ignored, and a future attestation type for decision evidence
could carry the commitment instead of a separate claim. The bindings
rely on the JWT rule that claims not understood are ignored unless
the application requires otherwise (Section 4 of [RFC7519]), and on
verifying parties that choose to process the claim. Selective
disclosure does not prevent a presenter from omitting the claim's
disclosure; it prevents only alteration of a disclosure that is
presented.
7.1. Verifiable Intent
In Autonomous mode, the agent includes "decision_context" as an
additional selectively disclosable claim in both the Layer 3a payment
payload and the Layer 3b checkout payload [VI], with the same claim
value, so that its disclosure digest appears under the agent's
signature in what the network and the merchant each receive. Payee
and amount are compared against Layer 3a and checkout_digest against
Layer 3b. Verifiable Intent does not profile additional claims of
Milan Expires 18 April 2027 [Page 23]
Internet-Draft Agent Decision Commitments October 2026
this kind; a holder that presents the payload to a party that does
not process the claim can omit its disclosure. The claim MUST NOT be
expressed as a constraint, because unknown constraint types in open
mandates are rejected. In Immediate mode no agent-signed layer
exists and the principal confirms the final values; the claim MAY be
placed in the principal-signed Layer 2 mandate only if the signing
interface shows the principal that a decision commitment is included,
and the verifier reports the principal as signer. checkout_digest is
the Verifiable Intent "checkout_hash" value.
7.2. Agent Payments Protocol
The agent includes "decision_context" as a selectively disclosable
claim of the closed Checkout Mandate ("mandate.checkout.1") [AP2].
The merchant-signed Checkout Receipt's "reference" covers the
commitment only if the claim's disclosure is included in the
presentation the merchant receives. The claim MUST NOT appear in
open mandates or constraints. In human-present mode the principal
signs the closed mandate, and the claim SHOULD be included only if
the trusted surface shows the principal that a decision commitment is
included. The claim MAY also be included in the Payment Mandate,
which carries the payee, payment instrument, and amount to the
payment processor and issuer; payee, amount, and currency are
compared against the Payment Mandate where present and otherwise
against the checkout object bound by "checkout_hash".
Implementations MUST compute digests over the raw disclosure strings,
since some libraries discard unknown members when parsing.
checkout_digest is the closed mandate's "checkout_hash".
7.3. x402
The server advertises the extension "adc" in its payment-required
response with an empty "info" object and a schema; the client echoes
the extension in its payment payload and appends the claim as
"info.decision_context", which the x402 extension rules permit
(clients may append to, but not alter, the server's info) [X402].
The payer's EIP-3009 or Permit2 signature does not cover extensions.
To bring the commitment under the payer's signature, the client
SHOULD set the 32-octet nonce to SHA-256(BASE64URL-DECODE(C) || r),
where r is 16 random octets that the holder retains with the record
and returns, as "nonce_random", in the release (Section 6.2); the
32-octet value is encoded as the payment scheme requires (for example
as a decimal string for Permit2). Without this construction, the
binding is level A0. checkout_digest is BASE64URL(SHA-
256(CANON(accepted payment requirements))). Payee is the "payTo"
value and amount the authorized value in base units; currency is the
CAIP-19 identifier [CAIP19] of the asset, lowercased before use.
Hexadecimal addresses are compared case-insensitively. Because
Milan Expires 18 April 2027 [Page 24]
Internet-Draft Agent Decision Commitments October 2026
payment requirements can repeat, reuse of a claim is detected by the
nonce construction and the holder chain, not by step 3 alone.
7.4. Account-to-Account Credit Transfers
For ISO 20022 credit transfers [ISO20022], including instant schemes,
the holder places "ADC1:" followed by the lowercase hexadecimal
encoding of the 32 octets of the commitment in the unstructured
remittance information (69 characters), where the scheme and the
payer's provider permit payer-supplied remittance text. Hexadecimal
is used because some schemes restrict remittance text to a limited
character set. No receipt_uri is carried; the verifier obtains it
from the payer's provider or the principal under the profile. Payee
is the creditor account identifier, amount the instructed amount in
minor units, and currency its ISO 4217 code. checkout_digest is
BASE64URL(SHA-256(end-to-end identifier)) when that identifier is
known before submission and is otherwise absent. This field is not
signed by the agent, so the binding is level A0, anchoring
(Section 5.5) provides the time bound, and reuse is detected only
through the holder chain.
7.5. Card Authorization Messages
Card authorization and authentication messages do not carry the
claim. An issuer can obtain it only through a mandate presented by
the rail's agent program. This document defines no binding for
authorization messages.
8. Witnessed Reciprocal Exchange
A decision record proves what one party's agent relied on. This
section defines how two parties, for example an agent and a merchant,
two agents, or an agent and a person, evidence what passed between
them. The receiver signs over exactly the committed bytes.
Independent witnesses, procured and carried by each party's agent,
fix the time of every step with their own clocks. A failure to
answer by a deadline becomes evidence in its own right, and arbiters
resolve stalled exchanges.
The result is tamper-evident, not tamper-proof. Fair exchange
between two parties without a trusted third party is impossible
[PAGNIA], so this section follows the optimistic model [ASOKAN]:
witnesses take part in every exchange, and arbiters take part only in
stalled ones. The exchange is OPTIONAL; a holder that does not
exchange payloads with counterparties under this document need not
implement it.
Milan Expires 18 April 2027 [Page 25]
Internet-Draft Agent Decision Commitments October 2026
8.1. Common Rules
* Each exchange object has a body: a JSON object with "type" set to
"adc-exchange", "v" set to 1, and the members defined below. The
body is signed as a JWS [RFC7515] whose payload is CANON(body) and
whose protected header carries "alg", "kid", and "typ" set to
"adc-exchange+json". The object hash is object_hash =
DIGEST(CANON(body)); it does not depend on the signature.
* "alg" is "Ed25519" [RFC9864] or "ES256" [RFC7518]. ES256
signatures MUST be in low-S form, with s no greater than half the
order of the group; verifiers MUST reject ES256 signatures whose s
is greater. Verifiers MUST reject other algorithms unless the
profile permits them.
* Every body carries "exchange_id", an opaque string chosen by the
sender and unique for the pair of sender and recipient keys;
"seq", 0 for the offer and one more than the previous object
otherwise; "prev", the object_hash of the previous object, or 32
zero octets encoded in base64url for the offer; "step", the kind
of object; and "issued_at". One exchange is one linear chain.
* The offer identifies the parties by "sender_key" and
"recipient_key", the JWK Thumbprints [RFC7638] of their signing
keys. Objects signed by any other key are not part of the
exchange, except witness statements (Section 8.3) and
arbiter_delivery (Section 8.5).
* Equivocation is two different bodies signed by the same key with
the same exchange_id and seq. Different signatures over the same
body are not equivocation. A verifier that observes equivocation
reports it and attributes it to the holder of the signing key.
* Deadlines and ordering are judged by witness time (Section 8.3),
not by issued_at or by either party's clock. Where objects signed
by different parties carry the same seq, the one with the earlier
witness time is part of the chain and the other is void.
8.2. Objects
+==================+===========+====================================+
| step | Signed by | Members in addition to the |
| | | common members |
+==================+===========+====================================+
| offer | Sender | intent, sender_key, |
| | | recipient_key, |
| | | payload_commitment, aead, |
| | | ciphertext_hash, key_hash, |
Milan Expires 18 April 2027 [Page 26]
Internet-Draft Agent Decision Commitments October 2026
| | | escrow (conditional), |
| | | response_window, expires_at |
+------------------+-----------+------------------------------------+
| held | Recipient | envelope_hash, |
| | | arbiters_accepted (when |
| | | escrow is present) |
+------------------+-----------+------------------------------------+
| key_release | Sender | hpke, wrapped_key |
+------------------+-----------+------------------------------------+
| key_received | Recipient | key_release_hash |
+------------------+-----------+------------------------------------+
| received | Recipient | envelope_hash |
+------------------+-----------+------------------------------------+
| mismatch | Recipient | envelope_hash, check |
+------------------+-----------+------------------------------------+
| accepted, | Recipient | envelope_hash; valid only |
| refused | | after received for the same |
| | | envelope, and only when |
| | | intent is "offer" |
+------------------+-----------+------------------------------------+
| arbiter_delivery | M | envelope_hash, key_matched, |
| | arbiters | commitment_matched, |
| | | delivered_at |
+------------------+-----------+------------------------------------+
| non_ack | Sender | envelope_hash, awaited, |
| | | attempts |
+------------------+-----------+------------------------------------+
| close | Either | state, reason |
| | party | |
+------------------+-----------+------------------------------------+
Table 3: Exchange Objects
intent: "deliver", when the sender seeks proof of receipt, or
"offer", when the sender also seeks acceptance.
Payload and payload_commitment: The payload is a JSON value. The
sender chooses a fresh 32-octet salt s and computes
payload_commitment = BASE64URL(SHA-256(s || CANON(payload))), the
construction of Section 5.4. The plaintext is CANON({"payload":
payload, "salt": BASE64URL(s)}). A payload that is not JSON is
carried as an object with "media_type" and "content", the
base64url encoding of its octets.
Ciphertext, aead, ciphertext_hash, and key_hash: The sender chooses
a fresh 256-bit key K, used for one exchange only, and encrypts
the plaintext with the AEAD algorithm named in "aead" ("A256GCM"
[RFC7518] unless the profile permits others), a fresh random
Milan Expires 18 April 2027 [Page 27]
Internet-Draft Agent Decision Commitments October 2026
96-bit nonce, and, as associated data, the UTF-8 octets of
exchange_id. The ciphertext is the nonce followed by the AEAD
output. ciphertext_hash = DIGEST(ciphertext) and key_hash =
DIGEST(K).
Envelope and envelope_hash: The envelope is the signed offer
together with the ciphertext. envelope_hash is the object_hash of
the offer.
hpke and wrapped_key: K encrypted to the recipient with HPKE
[RFC9180] in base mode, with info set to the UTF-8 octets of "adc-
exchange" followed by the 32 octets of envelope_hash, and empty
associated data. wrapped_key is the base64url encoding of the
encapsulated key followed by the HPKE ciphertext; "hpke" carries
"kem_id", "kdf_id", and "aead_id". How the sender obtains the
recipient's HPKE public key is a matter for the profile.
key_release_hash: The object_hash of the key_release. key_received
acknowledges that the key_release arrived; it does not attest that
K is correct.
escrow: An object with "scheme", a URI identifying a publicly
verifiable secret sharing scheme and its encoding, for example one
based on [SCHOENMAKERS]; "arbiters", the array of N arbiter
identifiers; "threshold", M; "shares", the N encrypted shares in
base64url, each encrypted to one arbiter; and "proof", the
base64url encoding of the proof that the shares are consistent,
which any party can verify. Where the scheme shares a group
element rather than an octet string, K is derived from the shared
secret with HKDF [RFC5869] as the scheme specifies. escrow MUST
be present when intent is "offer" or when the exchange carries a
payment obligation, and then MUST have M at least 2 and N at least
3, with arbiters operated by different organizations.
arbiters_accepted: DIGEST(CANON(escrow)), sent only after the
recipient has verified the proof.
response_window and expires_at: response_window is a number of
seconds. The deadline for each expected object is the witness
time of the preceding object plus response_window, and is never
later than expires_at.
check: The check that failed: "ciphertext_hash", "unwrap",
"key_hash", "decrypt", or "payload_commitment".
awaited and attempts: awaited is the step that did not arrive by its
Milan Expires 18 April 2027 [Page 28]
Internet-Draft Agent Decision Commitments October 2026
deadline. attempts lists the delivery attempts, each with
"transport_digest", a digest of the transport receipt for the
attempt, and the witness statements obtained at the time of the
attempt.
key_matched, commitment_matched, and delivered_at: The results of
the arbiters' checks (Section 8.5) and, when K was delivered, the
time of delivery.
state and reason: The terminal state that the closing party asserts
(Section 8.4) and a human-readable reason.
8.3. Witnesses
A witness is an independent service that countersigns an object_hash
with its own time. Witnesses see hashes only, never content. A
witness statement takes one of two forms:
"rfc3161": A TimeStampToken [RFC3161] whose messageImprint uses
SHA-256 and whose hashedMessage is the 32 octets of object_hash,
that is, SHA-256(CANON(body)). Qualified electronic time stamps
issued by qualified trust service providers [EIDAS] take this
form.
"scitt": A Transparent Statement [RFC9943]: a Signed Statement, in
the envelope of Section 5.5, whose payload, of content type
application/adc-anchor+json, is the witness payload shown below,
with its transparency receipt. The witness time is the
registration time, established as for level A2 (Section 5.5). The
"sub" of such a statement MUST NOT link different exchanges.
{"type":"adc-witness","v":1,"object_hash":"<object_hash>"}
Each party's agent procures witness statements for every object it
signs and for every object it receives, and carries them with the
object as an exchange receipt: {"object": the signed object,
"witnesses": [{"format", "token"}, ...]}. A receipt for a step is
therefore three things together: the object, the counterparty's
signature on the object that answers it, and the witness statements.
Neither party needs to trust the other's clock or storage.
At least one witness MUST be independent of both parties. Exchanges
that carry a payment or other obligation SHOULD use two witnesses
operated by different organizations. The witness time of an object
is the earliest time among its valid witness statements from
witnesses accepted by the profile. Witness time is authoritative for
deadlines and for ordering across parties. The anchor of Section 5.5
is itself a witness statement over the decision commitment.
Milan Expires 18 April 2027 [Page 29]
Internet-Draft Agent Decision Commitments October 2026
A witness statement proves that an object existed at a time. It does
not prove delivery. Delivery is proven by the counterparty's
acknowledgement. Without one, a non_ack stands on delivery attempts
whose transport receipts were witnessed at the time of each attempt.
8.4. State Machine
A verifier determines the state of an exchange by verifying each
object's signature, its exchange_id, seq, and prev, and its witness
statements, and then applying the transitions below in order of
witness time.
Milan Expires 18 April 2027 [Page 30]
Internet-Draft Agent Decision Commitments October 2026
+==============+===============+=================================+
| State | Expected next | If the deadline passes |
+==============+===============+=================================+
| SENT (offer | held | NOT_ACKNOWLEDGED. The sender |
| witnessed) | | issues non_ack carrying the |
| | | witnessed delivery attempts. |
| | | The recipient is bound to |
| | | nothing, and a later held is |
| | | void. |
+--------------+---------------+---------------------------------+
| HELD | key_release | VOID. K was withheld and the |
| | | offer is void. The recipient |
| | | MAY close. |
+--------------+---------------+---------------------------------+
| KEY_RELEASED | key_received | Without escrow: |
| | | KEY_UNACKNOWLEDGED, and the |
| | | sender issues non_ack. With |
| | | escrow: the sender MAY request |
| | | arbiter delivery (Section 8.5); |
| | | on arbiter_delivery, |
| | | DELIVERED_VIA_ARBITER, and any |
| | | later received, accepted, or |
| | | refused is void. |
+--------------+---------------+---------------------------------+
| KEY_RECEIVED | received, or | CONTENT_UNACKNOWLEDGED. The |
| | mismatch | sender MAY issue non_ack. |
+--------------+---------------+---------------------------------+
| RECEIVED | accepted, or | NOT_ACCEPTED. The silence is |
| (intent | refused | recorded with non_ack. |
| "offer") | | |
+--------------+---------------+---------------------------------+
| MISMATCH | Recomputation | FAULT_SENDER if the failure is |
| | | confirmed; FAULT_RECIPIENT if |
| | | it is not. |
+--------------+---------------+---------------------------------+
Table 4: Exchange States
For intent "deliver", received moves the exchange directly to the
terminal state DELIVERED. For intent "offer", accepted and refused
move it to ACCEPTED and REFUSED. Either party MAY close an exchange
in a non-terminal state with a stated reason, which moves it to
CLOSED. The terminal states are NOT_ACKNOWLEDGED, VOID,
KEY_UNACKNOWLEDGED, DELIVERED_VIA_ARBITER, CONTENT_UNACKNOWLEDGED,
DELIVERED, ACCEPTED, REFUSED, NOT_ACCEPTED, FAULT_SENDER,
FAULT_RECIPIENT, and CLOSED.
Milan Expires 18 April 2027 [Page 31]
Internet-Draft Agent Decision Commitments October 2026
An object whose earliest witness time is after the deadline or expiry
that governs it, or after the exchange reached a terminal state, is
void. A state that results from a passed deadline is established
against the objects presented; a party rebuts it by presenting an
object of the awaited step whose witness time precedes the deadline.
Recomputation: because the sender signed both ciphertext_hash and
key_hash, any party given K and the ciphertext can repeat the
recipient's checks. If DIGEST(ciphertext) equals ciphertext_hash and
DIGEST(K) equals key_hash, but decryption fails or the decrypted
payload does not match payload_commitment, the failure is confirmed
and the state is FAULT_SENDER. If every check passes, the state is
FAULT_RECIPIENT. Where escrow is present, arbiters perform the
recomputation with the reconstructed K. A recipient that relies on
recomputation discloses K and the ciphertext to the party that
performs it, which can then read the payload. If the K or the
ciphertext presented does not match the hash the sender signed,
recomputation cannot attribute the failure, because HPKE decryption
and transport are not publicly verifiable. This covers the checks
"ciphertext_hash", "unwrap", and "key_hash"; where escrow is present,
the arbiters instead check the reconstructed K as described in
Section 8.5. Otherwise the verifier reports the cause as not
determinable, and the exchange remains in MISMATCH until it is
closed.
FAULT_SENDER and FAULT_RECIPIENT identify the party whose signed
values are inconsistent with the recomputation. Like every other
result of this document, they are evidence and not a verdict
(Section 1.2).
Implementations MUST present held, received, delivered via arbiter,
and accepted to users as distinct states. Treating delivery as
agreement is the most likely misuse of this mechanism.
8.5. Arbiters
Arbiters are named in the offer and bind only once the recipient
accepts them through arbiters_accepted in held. Publicly verifiable
secret sharing lets the recipient check the encrypted shares before
it sends held. A recipient MUST NOT send held with arbiters_accepted
unless the proof verifies; where escrow is required and the proof
does not verify, the recipient closes the exchange.
An arbiter MUST open its share only for an exchange whose chain and
witness statements show KEY_RELEASED past its deadline, or MISMATCH,
and MUST verify the chain before doing so. Every opening is itself
witnessed and registered with a transparency service.
Milan Expires 18 April 2027 [Page 32]
Internet-Draft Agent Decision Commitments October 2026
When M arbiters have opened their shares, they reconstruct K, check
it against key_hash, check that it decrypts the ciphertext to a
payload matching payload_commitment, deliver K to the recipient in
the manner of key_release, and each sign the same arbiter_delivery
body; the signatures are carried in the JWS JSON General
Serialization (Section 7.2.1 of [RFC7515]). arbiter_delivery never
implies received, acceptance, or refusal. Arbiters never issue
received, accepted, or refused on the recipient's behalf.
If the reconstructed K does not match key_hash, or does not decrypt
the ciphertext to a payload matching payload_commitment, the arbiters
sign arbiter_delivery with "key_matched" or "commitment_matched"
false and deliver nothing, and the inconsistency is attributed to the
sender, who signed both values (FAULT_SENDER).
8.6. Binding to Decision Records
When an agent decides on the basis of a received payload, its context
receipt (Section 5.2) lists, as items with role "exchange", the
bodies of the exchange objects up to and including received, each
with media type application/adc-exchange+json, and, as items with
role "witness", their witness statements, in addition to the payload
itself. The decision record therefore proves both what arrived and
what the agent did with it.
A counterparty MAY countersign a decision commitment: the holder
sends an exchange with intent "deliver" whose payload is the decision
context claim, and the counterparty's received object is the
countersignature. In the Agent Payments Protocol, the merchant-
signed Checkout Receipt has the same effect when the claim's
disclosure is included in the presentation the merchant receives
(Section 7.2).
8.7. Security and Privacy of the Exchange
Fairness:
Neither party can obtain the other's acknowledgement without
leaving evidence, but a party can still stop at any step. The
state machine turns stopping into a recorded state; it does not
prevent it [PAGNIA].
Metadata:
Witnesses see hashes only. Pairwise keys limit linking across
exchanges. Arbiters see the metadata of exchanges that name them
and SHOULD be rotated.
Milan Expires 18 April 2027 [Page 33]
Internet-Draft Agent Decision Commitments October 2026
Low-entropy payloads:
The 32-octet salt in the plaintext prevents a party that sees
payload_commitment from confirming a guessed payload.
Replay:
exchange_id, seq, prev, and expires_at together prevent a replayed
object from being accepted as new.
Key compromise:
Witness time bounds when a signature could have been made.
Witness collusion:
A party colluding with every witness it uses can misstate time.
The requirement for a witness independent of both parties, and two
witnesses for obligations, mitigates this.
Arbiter collusion:
M colluding arbiters can read the payload. Fewer than M learn
nothing about K.
Griefing:
A non_ack carries weight only through its witnessed delivery
attempts, not through the sender's assertion. A recipient MAY
answer with a signed close stating a reason.
Key and nonce reuse:
K is fresh for each exchange, so a random AEAD nonce is safe.
Reusing K across exchanges is prohibited.
Legal effect:
This section produces evidence. The legal presumption that
Article 43 of [EIDAS] gives to qualified electronic registered
delivery services requires a qualified provider. A qualified
trust service provider acting as both witness and delivery service
is the route to that effect and is outside the scope of this
document.
9. Related Work
Several individual Internet-Drafts define records of agent actions
for registration with transparency services. They include action
capsules with a selective-disclosure profile and two-party settlement
records that carry payment-protocol objects by digest
[I-D.mih-scitt-agent-action-capsule]
[I-D.mih-scitt-agent-action-capsule-sel-disc]
[I-D.mih-agent-settlement-records], execution records
[I-D.emirdag-scitt-ai-agent-execution], action receipts with hash
chains [I-D.noa-scitt-ai-agent-receipt], pre-execution authorization
Milan Expires 18 April 2027 [Page 34]
Internet-Draft Agent Decision Commitments October 2026
records [I-D.munoz-scitt-permit-profile], conversation records
[I-D.birkholz-verifiable-agent-conversations], an audit architecture
[I-D.kuehlewind-audit-architecture], an audit-trail format with a
pre-execution phase and deletion tombstones
[I-D.sharif-agent-audit-trail], a trading audit profile with
cryptographic erasure [I-D.kamimura-scitt-vcp], and a legal-AI
profile with salted prompt and response hashes
[I-D.ailex-vap-legal-ai-provenance]. Settlement receipts for AI
decisions that bind request, transformed-request, and response
digests and model identities [I-D.chang-delta1-settlement], spend
receipts with signed pre-payment trade manifests and payment-rail
reconciliation [I-D.dogru-cedulon-core], and signed authorization
verdicts [I-D.dias-agent-payment-verdicts] record decision outcomes
and payment-side facts. Attested inference receipts
[I-D.tsyrulnikov-rats-attested-inference-receipt] attest individual
model calls. A decision profile that reconciles signed allow, deny,
and defer records against observed effects
[I-D.dogru-cedulon-decision-profile] addresses decision outcomes
rather than model inputs. Bilateral attestation between two
organizations' agents, with mutual acknowledgment, recorded refusals,
and transparency anchoring [I-D.mih-agent-bilateral-attestation], is
the closest work to the witnessed reciprocal exchange (Section 8),
which adds independent witness time, deadline-based non-
acknowledgment, and escrowed key delivery by arbiters.
ADC uses established techniques: salted hashing, hash chains,
transparency-service registration, and selective disclosure. It
differs from the work above in three choices. First, the commitment
travels inside the payment mandate or payload as a selectively
disclosable claim covered by the agent's or principal's signature,
rather than in a separate record that refers to the mandate. Second,
registration with a transparency service is required, by default,
before the mandate is signed, and the verifier checks the
registration time against the mandate's issuance time. Third, the
commitment covers per-item salted descriptors of the bytes the agent
provided to the model, including transformed media and raw provider
responses, so that items can be disclosed, withheld, or erased
individually; existing selective-disclosure profiles apply salts to
record fields rather than to model inputs. ADC can use attested
inference receipts for level A3 and can reference conversation-record
formats for item content.
10. Security Considerations
10.1. Trust Assumptions
* The holder's signing key and the agent's signing key are not
compromised at decision time.
Milan Expires 18 April 2027 [Page 35]
Internet-Draft Agent Decision Commitments October 2026
* At least one transparency service used is append-only, presents a
consistent view, and records registration times honestly.
Collusion between a holder and every transparency service it uses
defeats the time bound.
* SHA-256 is collision-resistant and second-preimage-resistant.
* For level A3, the attesting model providers are honest.
* For exchanges, at least one witness used is independent of both
parties and records time honestly, and fewer than M arbiters
collude (Section 8.7).
10.2. Threats and Mitigations
Fabrication after the fact:
A record created after a dispute does not match the commitment in
the signed mandate or the anchored statement.
Fabrication at decision time:
Not prevented. A holder can commit to a misleading record before
signing. Level A3 narrows this by having providers attest to what
each model call received and returned.
Omission of records:
The holder chain and anchoring make a missing interior sequence
number detectable, and a verifier that obtains neighboring anchors
can detect equivocation. Deletion after the last anchor a
verifier sees, and abandonment of a chain, are not detectable from
the chain alone (Section 5.5).
Omission of items within a record:
A verifier cannot prove that the receipt lists every input; it can
prove only that the receipt has not changed since anchoring. At
A3 with a released "request" item, it can check that the listed
items are the parts of the attested request. Verifiers MUST NOT
report completeness.
Back-dating:
Bounded by the registration time, where it can be established
(Section 5.5).
Split view and service collusion:
A transparency service that presents different logs to different
parties can mislead a verifier that checks only the receipts the
holder presents. Profiles mitigate this with services that
provide consistency proofs, with registration at independent
services, and by distributing service trust anchors out of band.
Milan Expires 18 April 2027 [Page 36]
Internet-Draft Agent Decision Commitments October 2026
Malicious receipt_uri:
A holder can direct verifiers to a host it controls. The
credential properties in Section 6.1 prevent replay of the
verifier's credential, and the restriction on dereferencing limits
request forgery.
Reuse of a claim in another transaction:
Detected by step 3 where the record's transaction fields are
unique to the transaction (for example through checkout_digest);
on rails where they can repeat, detected through the x402 nonce
construction or the holder chain.
Stripping or substitution of the claim:
Substitution is prevented where the claim is covered by a
signature. Omission of the claim's disclosure from a presentation
is not prevented; a verifier that sees an undisclosed digest can
request the disclosure from the holder. Where no signature covers
the claim, the binding is level A0.
Guessing record contents:
Prevented by the 32-octet commitment salt and per-item salts.
Model substitution:
The record names a resolved model version; only level A3 proves
which model ran.
Canonicalization divergence:
Addressed by mandatory NFC normalization and JCS; numbers are
canonicalized by JCS, and raw provider output is a separate item.
Key compromise:
Anchoring bounds when a commitment existed, not when a signature
over it was made. Holders publish key validity periods and
revocations under their profile.
Replay of a disclosure request:
Prevented by the single-use request_id, the issued_at tolerance,
and the sender-constrained, transaction-bound credential
(Section 6.1).
Replay of a release:
A release echoes the request_id and verifier and is signed by the
holder, so it cannot be passed off as the answer to another
request. Anyone who holds a release can still show it to others;
verifiers MUST NOT pass releases to parties outside the dispute.
Milan Expires 18 April 2027 [Page 37]
Internet-Draft Agent Decision Commitments October 2026
Collusion:
A holder colluding with every transparency service it uses defeats
the time bound; independent services and consistency proofs
mitigate this. A holder colluding with a model provider defeats
level A3. A principal and holder acting together can still commit
to a misleading record before a payment, though not alter it
afterwards. A holder colluding with a verifier is exposed when
another party repeats the verification (Section 6.7). This
document does not address collusion among dispute participants
beyond that.
Hash collisions:
Binding depends on the collision resistance of SHA-256. A party
able to find collisions could open one commitment to two records.
Fixed-length salt prefixes and canonical serialization remove
ambiguity in how inputs are formed. Length extension does not
apply, because ADC uses no secret-prefix authentication and
verifiers recompute every digest over its complete input. The
"alg" member allows migration.
Canonicalization attacks:
Objects containing invalid Unicode (such as unpaired surrogates),
non-finite numbers, numbers outside the range JCS represents
exactly, or duplicate member names MUST be rejected before
hashing. Amounts are strings for this reason.
Weak randomness and salt reuse:
Predictable or reused salts allow guessing of hidden content and
linking of equal descriptors. Salts MUST come from a
cryptographically secure generator and MUST NOT be reused.
Malicious released content:
Released items are untrusted input and may contain malware, prompt
injection aimed at review tools, or decompression bombs.
Verifiers MUST treat items as data, MUST enforce the profile's
size and count limits before processing, and SHOULD isolate any
replay or automated review of item content.
Denial of service:
Holders rate-limit disclosure requests, which require credentials.
Unavailability of a transparency service is handled by alternate
services or late registration; unavailability of the holder is
reported as temporarily_unavailable and does not by itself change
any level.
Milan Expires 18 April 2027 [Page 38]
Internet-Draft Agent Decision Commitments October 2026
State rollback:
A holder restored from backup could reuse sequence numbers, which
verifiers report as equivocation. The failure-handling rules in
Section 5.5 prevent this for honest holders.
10.3. Replay and Attribution
Re-submitting recorded items to the named model shows what the model
received and how it may respond. It does not establish what caused
the original output, whether that output was correct, or that a given
item was responsible. Model outputs may vary between calls, and
models may be withdrawn. The committed answer is the record of what
happened.
10.4. Cryptographic Considerations
Salts have a fixed length so that concatenation is unambiguous. The
"alg" member allows other digest algorithms in future versions;
verifiers reject algorithms they do not support. Item digests and
commitments are salted with fixed-length salts, and receipts,
records, and statement payloads carry distinct "type" members; an
item descriptor carries no "type" but is always hashed with a salt,
whereas receipts are not. SD-JWT disclosure digests are computed as
specified in [RFC9901].
This document does not depend on the quantum resistance of any
signature. SHA-256 commitments retain their binding property against
known quantum attacks, and the 32-octet salts keep generic quantum
search for the hidden content impractical. The signatures on
mandates, signed statements, and transparency receipts are another
matter: a party able to forge them could fabricate evidence of when a
commitment existed. Holders SHOULD support ML-DSA for anchor
statements [RFC9964] as transparency services deploy it, MAY use
composite signatures [I-D.ietf-jose-pq-composite-sigs], and MAY re-
register earlier commitments under a stronger algorithm while
retaining the original receipts. Verifiers MUST report the signature
algorithm used at each step.
11. Privacy Considerations
This section follows the threat categories of [RFC6973].
Surveillance and correlation:
Mandates and transparency services see only commitments, chain
ids, and sequence numbers, but anchors are public and timestamped.
Because declined decisions are anchored too, the anchoring pattern
of a chain reveals how often its principal considers payments, and
the timing of an anchor can be joined with the time of an on-chain
Milan Expires 18 April 2027 [Page 39]
Internet-Draft Agent Decision Commitments October 2026
payment to link a chain to a wallet. Holders SHOULD operate
chains and signing keys that serve many principals rather than
one, MAY add a random delay within the profile's interval, and MAY
batch anchors where the profile allows. "receipt_uri" MUST NOT
contain stable principal identifiers or values derived from the
record.
Stored data compromise:
Stored context routinely contains personal data of the principal
and of third parties, such as the senders of emails. Holders MUST
encrypt stored items at rest and SHOULD use per-principal keys.
Identification:
Anchor and entry statements MUST NOT contain principal
identifiers.
Secondary use:
Context recorded under this document SHOULD NOT be used for
purposes other than dispute resolution, audit, and the principal's
own access. Replay by a verifier is itself processing and a
transfer to the model provider; it SHOULD occur only under an
agreement covering that processing or on infrastructure the
principal approves.
Disclosure:
Release is limited to the transaction in the request and governed
by the principal's policy. Withholding is visible.
Exclusion:
Principals SHOULD be able to obtain their own records and
receipts.
Data-protection law can apply to holders and verifiers, for example
[GDPR] and [LGPD]. Holders will typically need to determine their
role as controller or processor, a lawful basis, whether an impact
assessment is required, how notice is given to third parties whose
data appears in context, how access requests are met, and how cross-
border transfers are handled. Under such regimes, digests of
personal data can remain personal data. Deleting a descriptor's salt
prevents the digest from being linked to the content, but whether
that satisfies an erasure obligation is a legal question.
Requirements for logging by high-risk AI systems [EUAIA] apply only
where a system is classified as high-risk; this document does not by
itself satisfy them.
Milan Expires 18 April 2027 [Page 40]
Internet-Draft Agent Decision Commitments October 2026
12. Operational Considerations
Latency:
Anchoring before authorization adds a round trip to a transparency
service. Profiles that cannot accept this latency can allow late
anchoring, which caps the level at A1.
Availability:
Holders SHOULD be able to register with more than one transparency
service, and SHOULD replicate stored evidence so that a single
storage failure does not cause loss before retention_until.
Limits:
Profiles set maximum item counts, item sizes, and release sizes;
holders and verifiers enforce them.
Retention:
retention_until SHOULD cover the longest dispute window applicable
to the rail and any regulatory minimum. Profiles set the value.
Model deprecation:
Providers withdraw model versions, after which replay is
impossible. Level A3 attestations remain verifiable without the
model.
Storage:
As-sent media can be large. Holders can store each distinct item
once, keyed by content digest.
Keys:
Holder signing keys carry identifiers, validity periods, and
revocation status published under the profile. Sequence numbers
are per chain, not per key.
Registration cost:
Some transparency services may charge for or otherwise gate
registration. Because every covered decision, including a
decline, is anchored, holders need to account for the per-decision
cost when choosing services.
13. IANA Considerations
13.1. JSON Web Token Claims Registration
IANA is requested to register the following claim in the "JSON Web
Token Claims" registry established by [RFC7519]:
* Claim Name: decision_context
Milan Expires 18 April 2027 [Page 41]
Internet-Draft Agent Decision Commitments October 2026
* Claim Description: Commitment to the decision context of an agent-
initiated payment
* Change Controller: Author (to be changed to IETF if this document
is adopted in the IETF stream)
* Specification Document(s): Section 5.4 of this document
13.2. Media Type Registrations
IANA is requested to register the following media types [RFC6838],
all using the "+json" structured syntax suffix [RFC6839].
application/adc-anchor+json is the payload content type of anchor,
outcome, erasure, and witness statements (Section 5.5, Section 8.3);
application/adc-release+json is the payload of a signed release
(Section 6.2); application/adc-exchange+json is the body of an
exchange object (Section 8).
Type name: application
Subtype names: adc-anchor+json; adc-release+json; adc-exchange+json
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: binary; as for application/json
Security considerations: See Section 10 and Section 11 of this
document.
Interoperability considerations: Objects are canonicalized as
described in Section 5.1 before hashing.
Published specification: This document
Applications that use this media type: Agent platforms, payment
dispute systems, and agents exchanging payloads with
counterparties
Fragment identifier considerations: As for application/json
Additional information: Deprecated alias names for this type: N/A;
Magic number(s): N/A; File extension(s): N/A; Macintosh file type
code(s): N/A
Person and email address to contact for further information:
Fernando Henrique Damasceno Milan, milan@nordqubit.com
Milan Expires 18 April 2027 [Page 42]
Internet-Draft Agent Decision Commitments October 2026
Intended usage: COMMON
Restrictions on usage: None
Author: Fernando Henrique Damasceno Milan
Change controller: Author (to be changed to IETF if this document is
adopted in the IETF stream)
14. Implementation Status
This section is to be removed before publishing as an RFC.
This section records the status of known implementations at the time
of writing, following [RFC7942]. Description: the author is
developing a prototype holder implementation. Maturity: prototype;
not publicly available. Coverage: data model, commitment, and test
vectors; the exchange in Section 8 is not yet implemented, and its
state table has been checked mechanically for completeness and for
the absence of transitions out of terminal states. Contact: the
author. No interoperability testing has taken place. The test
vectors in Appendix A were reproduced by an independent
implementation written from the text of this document alone, and the
CDDL in Section 5.7 has been checked with a CDDL validator against
the objects in that appendix.
15. References
15.1. Normative References
[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>.
[RFC3161] Adams, C., Cain, P., Pinkas, D., and R. Zuccherato,
"Internet X.509 Public Key Infrastructure Time-Stamp
Protocol (TSP)", RFC 3161, DOI 10.17487/RFC3161, August
2001, <https://www.rfc-editor.org/info/rfc3161>.
[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>.
Milan Expires 18 April 2027 [Page 43]
Internet-Draft Agent Decision Commitments October 2026
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type
Specifications and Registration Procedures", BCP 13,
RFC 6838, DOI 10.17487/RFC6838, January 2013,
<https://www.rfc-editor.org/info/rfc6838>.
[RFC6839] Hansen, T. and A. Melnikov, "Additional Media Type
Structured Syntax Suffixes", RFC 6839,
DOI 10.17487/RFC6839, January 2013,
<https://www.rfc-editor.org/info/rfc6839>.
[RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web
Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May
2015, <https://www.rfc-editor.org/info/rfc7515>.
[RFC7516] Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)",
RFC 7516, DOI 10.17487/RFC7516, May 2015,
<https://www.rfc-editor.org/info/rfc7516>.
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
DOI 10.17487/RFC7518, May 2015,
<https://www.rfc-editor.org/info/rfc7518>.
[RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token
(JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,
<https://www.rfc-editor.org/info/rfc7519>.
[RFC7638] Jones, M. and N. Sakimura, "JSON Web Key (JWK)
Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September
2015, <https://www.rfc-editor.org/info/rfc7638>.
[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>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/info/rfc8446>.
[RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
Definition Language (CDDL): A Notational Convention to
Express Concise Binary Object Representation (CBOR) and
JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
June 2019, <https://www.rfc-editor.org/info/rfc8610>.
Milan Expires 18 April 2027 [Page 44]
Internet-Draft Agent Decision Commitments October 2026
[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>.
[RFC9180] Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid
Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180,
February 2022, <https://www.rfc-editor.org/info/rfc9180>.
[RFC9325] Sheffer, Y., Saint-Andre, P., and T. Fossati,
"Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", BCP 195, RFC 9325, DOI 10.17487/RFC9325, November
2022, <https://www.rfc-editor.org/info/rfc9325>.
[RFC9864] Jones, M. 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>.
[RFC9901] Fett, D., Yasuda, K., and B. Campbell, "Selective
Disclosure for JSON Web Tokens", RFC 9901,
DOI 10.17487/RFC9901, November 2025,
<https://www.rfc-editor.org/info/rfc9901>.
[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>.
[SHS] National Institute of Standards and Technology, "Secure
Hash Standard (SHS)", FIPS PUB 180-4, August 2015,
<https://doi.org/10.6028/NIST.FIPS.180-4>.
[UAX15] The Unicode Consortium, "Unicode Normalization Forms",
Unicode Standard Annex #15, September 2024,
<https://www.unicode.org/reports/tr15/>.
15.2. Informative References
[AP2] Google, "Agent Payments Protocol, version 0.2.0", April
2026, <https://github.com/google-agentic-commerce/AP2>.
Milan Expires 18 April 2027 [Page 45]
Internet-Draft Agent Decision Commitments October 2026
[ASOKAN] Asokan, N., Shoup, V., and M. Waidner, "Optimistic Fair
Exchange of Digital Signatures", Advances in Cryptology -
EUROCRYPT '98, LNCS 1403, pp. 591-606,
DOI 10.1007/BFb0054156, 1998,
<https://doi.org/10.1007/BFb0054156>.
[BRAVE] Brave, "Unseeable prompt injections in screenshots",
October 2025,
<https://brave.com/blog/unseeable-prompt-injections/>.
[CAIP19] Chain Agnostic Standards Alliance, "CAIP-19: Asset Type
and Asset ID Specification",
<https://chainagnostic.org/CAIPs/caip-19>.
[EIDAS] European Parliament and Council of the European Union,
"Regulation (EU) No 910/2014 on electronic identification
and trust services for electronic transactions in the
internal market, as amended by Regulation (EU) 2024/1183",
July 2014,
<https://eur-lex.europa.eu/eli/reg/2014/910/oj>.
[EUAIA] European Parliament and Council, "Regulation (EU)
2024/1689 (Artificial Intelligence Act), as amended by
Regulation (EU) 2026/1744", June 2024,
<https://eur-lex.europa.eu/eli/reg/2024/1689/oj>.
[FIDO-AGENTIC]
FIDO Alliance, "FIDO Alliance to Develop Standards for
Trusted AI Agent Interactions", 28 April 2026,
<https://fidoalliance.org/fido-alliance-to-develop-
standards-for-trusted-ai-agent-interactions/>.
[GDPR] European Parliament and Council, "Regulation (EU) 2016/679
(General Data Protection Regulation)", April 2016,
<https://eur-lex.europa.eu/eli/reg/2016/679/oj>.
[I-D.ailex-vap-legal-ai-provenance]
Yamakawa, S., "Verifiable AI Provenance (VAP) Framework
and Legal AI Profile (LAP)", Work in Progress, Internet-
Draft, draft-ailex-vap-legal-ai-provenance-04, 30
September 2026, <https://datatracker.ietf.org/doc/draft-
ailex-vap-legal-ai-provenance/04/>.
Milan Expires 18 April 2027 [Page 46]
Internet-Draft Agent Decision Commitments October 2026
[I-D.birkholz-verifiable-agent-conversations]
Birkholz, H., Heldt, T., and O. Steele, "Verifiable Agent
Conversation Records", Work in Progress, Internet-Draft,
draft-birkholz-verifiable-agent-conversations-01, 31
August 2026, <https://datatracker.ietf.org/doc/draft-
birkholz-verifiable-agent-conversations/01/>.
[I-D.chang-delta1-settlement]
Chang, Y. C., "Delta-1: A SCITT Profile for Binary
Settlement Receipts in Agentic AI Accountability", Work in
Progress, Internet-Draft, draft-chang-delta1-settlement-
00, 16 April 2026, <https://datatracker.ietf.org/doc/
draft-chang-delta1-settlement/00/>.
[I-D.dias-agent-payment-verdicts]
Dias, I., "Signed Authorization Verdicts for Agent-
Initiated Payments", Work in Progress, Internet-Draft,
draft-dias-agent-payment-verdicts-00, 9 October 2026,
<https://datatracker.ietf.org/doc/draft-dias-agent-
payment-verdicts/00/>.
[I-D.dogru-cedulon-core]
Doğru, E. C., "Spend Receipts and Payment Rail
Reconciliation for AI Agents", Work in Progress, Internet-
Draft, draft-dogru-cedulon-core-04, 7 October 2026,
<https://datatracker.ietf.org/doc/draft-dogru-cedulon-
core/04/>.
[I-D.dogru-cedulon-decision-profile]
Doğru, E. C., "Cedulon Decision Profile: Reconciling an
Agent's Decisions Against Its Effects", Work in Progress,
Internet-Draft, draft-dogru-cedulon-decision-profile-04, 5
October 2026, <https://datatracker.ietf.org/doc/draft-
dogru-cedulon-decision-profile/04/>.
[I-D.emirdag-scitt-ai-agent-execution]
Emirdag, P., "AI Agent Execution Profile of SCITT", Work
in Progress, Internet-Draft, draft-emirdag-scitt-ai-agent-
execution-00, 13 April 2026,
<https://datatracker.ietf.org/doc/draft-emirdag-scitt-ai-
agent-execution/00/>.
[I-D.ietf-hpke-pq]
Barnes, R. and D. Connolly, "Post-Quantum and Post-
Quantum/Traditional Hybrid Algorithms for HPKE", Work in
Progress, Internet-Draft, draft-ietf-hpke-pq-05, 6 July
2026,
<https://datatracker.ietf.org/doc/draft-ietf-hpke-pq/05/>.
Milan Expires 18 April 2027 [Page 47]
Internet-Draft Agent Decision Commitments October 2026
[I-D.ietf-jose-hpke-encrypt]
Reddy.K, T., Tschofenig, H., Banerjee, A., Steele, O., and
M. B. Jones, "Use of Hybrid Public Key Encryption (HPKE)
with JSON Web Encryption (JWE)", Work in Progress,
Internet-Draft, draft-ietf-jose-hpke-encrypt-22, 6 July
2026, <https://datatracker.ietf.org/doc/draft-ietf-jose-
hpke-encrypt/22/>.
[I-D.ietf-jose-pq-composite-sigs]
Prabel, L., Shuzhou, S., Gray, J., and T. Reddy.K, "PQ/T
Hybrid Composite Signatures for JOSE and COSE", Work in
Progress, Internet-Draft, draft-ietf-jose-pq-composite-
sigs-05, 8 October 2026,
<https://datatracker.ietf.org/doc/draft-ietf-jose-pq-
composite-sigs/05/>.
[I-D.kamimura-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, 21 July 2026, <https://datatracker.ietf.org/doc/
draft-kamimura-scitt-vcp/03/>.
[I-D.kuehlewind-audit-architecture]
Kühlewind, M. and H. Birkholz, "An Architecture for
Auditing Agent Delegation and Interactions", Work in
Progress, Internet-Draft, draft-kuehlewind-audit-
architecture-01, 7 September 2026,
<https://datatracker.ietf.org/doc/draft-kuehlewind-audit-
architecture/01/>.
[I-D.mih-agent-bilateral-attestation]
Mih, S., "Bilateral Attestation of Cross-Organization
Agent Actions", Work in Progress, Internet-Draft, draft-
mih-agent-bilateral-attestation-02, 13 September 2026,
<https://datatracker.ietf.org/doc/draft-mih-agent-
bilateral-attestation/02/>.
[I-D.mih-agent-settlement-records]
Mih, S., "Two-Party Settlement Records for Agent
Payments", Work in Progress, Internet-Draft, draft-mih-
agent-settlement-records-00, 1 October 2026,
<https://datatracker.ietf.org/doc/draft-mih-agent-
settlement-records/00/>.
[I-D.mih-scitt-agent-action-capsule]
Mih, S., "An Agent Action Capsule Profile for SCITT", Work
in Progress, Internet-Draft, draft-mih-scitt-agent-action-
Milan Expires 18 April 2027 [Page 48]
Internet-Draft Agent Decision Commitments October 2026
capsule-05, 26 September 2026,
<https://datatracker.ietf.org/doc/draft-mih-scitt-agent-
action-capsule/05/>.
[I-D.mih-scitt-agent-action-capsule-sel-disc]
Mih, S., "Selective Disclosure Profile for Agent Action
Capsules", Work in Progress, Internet-Draft, draft-mih-
scitt-agent-action-capsule-sel-disc-00, 19 June 2026,
<https://datatracker.ietf.org/doc/draft-mih-scitt-agent-
action-capsule-sel-disc/00/>.
[I-D.munoz-scitt-permit-profile]
Munoz, C., "A SCITT Profile for Pre-Execution AI Action
Authorization Records", Work in Progress, Internet-Draft,
draft-munoz-scitt-permit-profile-01, 18 July 2026,
<https://datatracker.ietf.org/doc/draft-munoz-scitt-
permit-profile/01/>.
[I-D.noa-scitt-ai-agent-receipt]
Toraman, T., "A SCITT Profile for AI-Agent Action
Receipts", Work in Progress, Internet-Draft, draft-noa-
scitt-ai-agent-receipt-01, 15 August 2026,
<https://datatracker.ietf.org/doc/draft-noa-scitt-ai-
agent-receipt/01/>.
[I-D.sharif-agent-audit-trail]
Sharif, R., "Agent Audit Trail: A Standard Logging Format
for Autonomous AI Systems", Work in Progress, Internet-
Draft, draft-sharif-agent-audit-trail-06, 29 September
2026, <https://datatracker.ietf.org/doc/draft-sharif-
agent-audit-trail/06/>.
[I-D.tsyrulnikov-rats-attested-inference-receipt]
Tsyrulnikov, B., "Attested Inference Receipt (AIR): A
COSE/CWT Profile for Confidential AI Inference", Work in
Progress, Internet-Draft, draft-tsyrulnikov-rats-attested-
inference-receipt-02, 5 July 2026,
<https://datatracker.ietf.org/doc/draft-tsyrulnikov-rats-
attested-inference-receipt/02/>.
[ISO4217] International Organization for Standardization, "Codes for
the representation of currencies", ISO 4217:2015, August
2015, <https://www.iso.org/iso-4217-currency-codes.html>.
[ISO20022] International Organization for Standardization, "Financial
services - Universal financial industry message scheme -
Part 1: Metamodel", ISO 20022-1:2013, May 2013,
<https://www.iso20022.org/>.
Milan Expires 18 April 2027 [Page 49]
Internet-Draft Agent Decision Commitments October 2026
[LGPD] Brazil, "Lei Geral de Proteção de Dados Pessoais (Lei
13.709/2018)", August 2018, <https://www.planalto.gov.br/
ccivil_03/_ato2015-2018/2018/lei/l13709.htm>.
[PAGNIA] Pagnia, H. and F. C. Gaertner, "On the Impossibility of
Fair Exchange without a Trusted Third Party", Technical
Report TUD-BS-1999-02, Darmstadt University of Technology,
March 1999.
[RFC5869] Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand
Key Derivation Function (HKDF)", RFC 5869,
DOI 10.17487/RFC5869, May 2010,
<https://www.rfc-editor.org/info/rfc5869>.
[RFC6973] Cooper, A., Tschofenig, H., Aboba, B., Peterson, J.,
Morris, J., Hansen, M., and R. Smith, "Privacy
Considerations for Internet Protocols", RFC 6973,
DOI 10.17487/RFC6973, July 2013,
<https://www.rfc-editor.org/info/rfc6973>.
[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>.
[RFC8392] Jones, M., Wahlstroem, E., Erdtman, S., and H. Tschofenig,
"CBOR Web Token (CWT)", RFC 8392, DOI 10.17487/RFC8392,
May 2018, <https://www.rfc-editor.org/info/rfc8392>.
[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>.
[RFC9449] Fett, D., Campbell, B., Bradley, J., Lodderstedt, T.,
Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of
Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449,
September 2023, <https://www.rfc-editor.org/info/rfc9449>.
[RFC9964] Prorock, M. and O. Steele, "ML-DSA for JSON Object Signing
and Encryption (JOSE) and CBOR Object Signing and
Encryption (COSE)", RFC 9964, DOI 10.17487/RFC9964, May
2026, <https://www.rfc-editor.org/info/rfc9964>.
Milan Expires 18 April 2027 [Page 50]
Internet-Draft Agent Decision Commitments October 2026
[SCHOENMAKERS]
Schoenmakers, B., "A Simple Publicly Verifiable Secret
Sharing Scheme and Its Application to Electronic Voting",
Advances in Cryptology - CRYPTO '99, LNCS 1666, pp.
148-164, DOI 10.1007/3-540-48405-1_10, 1999,
<https://doi.org/10.1007/3-540-48405-1_10>.
[TOB] Trail of Bits, "Weaponizing image scaling against
production AI systems", August 2025,
<https://blog.trailofbits.com/2025/08/21/weaponizing-
image-scaling-against-production-ai-systems/>.
[VI] Verifiable Intent Working Group, "Verifiable Intent:
Credential Format, version 0.1-draft",
https://github.com/agent-intent/verifiable-intent, 18
February 2026, <https://verifiableintent.dev>.
[X402] x402 Foundation, "x402 Protocol Specification, Protocol
Version 2", December 2025, <https://github.com/x402-
foundation/x402/blob/main/specs/x402-specification-v2.md>.
Appendix A. Test Vectors
All values were computed with SHA-256, NFC normalization, JCS, and
base64url without padding. Objects are shown formatted for
readability; their canonical forms follow from Section 5.1. Salts
are fixed, not random, so that results can be reproduced.
Item bytes (as US-ASCII strings) and salts:
item 0: "You are a payments assistant. Pay only bills the user
approved." (one line, single space after "user",
no trailing newline)
salt: 32 octets of 0xa0
item 1: "example invoice email body" salt: 32 octets of 0xa1
item 2: "example as-sent image bytes" salt: 32 octets of 0xa2
item 3: "{\"noul\":0.88}" salt: 32 octets of 0xa3
Item descriptors (content_digest values included) and item digests:
item 0
salt = oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKA
descriptor =
{
"calls": [
0
],
"content_digest": "rsu-z89tDjJoX3LK0DRrSIRz_EuYgWJ95Woi06yuRxg",
Milan Expires 18 April 2027 [Page 51]
Internet-Draft Agent Decision Commitments October 2026
"media_type": "text/plain",
"role": "instructions",
"source": {
"kind": "system"
}
}
item_digest = 9QV3ZRTxsG60bOe1e6gS5LL0q5XjkTivElxci0uqfqY
item 1
salt = oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaE
descriptor =
{
"calls": [
0
],
"content_digest": "BlW2UA5Du9SFrwm-NpRxeQsmL5C2lYT2GyJbZW3-BPU",
"media_type": "message/rfc822",
"role": "as_sent",
"source": {
"fetched_at": "2026-10-10T14:02:51Z",
"kind": "email",
"uri": "mid:invoice-0042@supplier.example"
}
}
item_digest = 8m7geGcZw1hWHKHjFFOpEpPe_MQ9IgxwyUaFALTdw4Y
item 2
salt = oqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqI
descriptor =
{
"calls": [
0
],
"content_digest": "2xHGVXsHZv2LW4y8n9Kl7juZ1Q1dfdfdL6s7P114tmQ",
"derived_from": 1,
"media_type": "image/png",
"role": "as_sent",
"source": {
"fetched_at": "2026-10-10T14:02:51Z",
"kind": "email_part",
"uri": "mid:invoice-0042@supplier.example"
},
"transform": "resize/example-lib-1.0/lanczos3/1024"
}
item_digest = nkT1qIfqXLMxVXtuqJvcRQtNaDbLxitRYFq329hcjrI
item 3
salt = o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6M
Milan Expires 18 April 2027 [Page 52]
Internet-Draft Agent Decision Commitments October 2026
descriptor =
{
"calls": [
0
],
"content_digest": "hGYLopth2mQvEvJW8AsgAyAuYcLFyHR5qcILCdeaqRk",
"media_type": "application/json",
"role": "response",
"source": {
"kind": "model",
"uri": "https://provider.example/v1/requests/req-0001"
}
}
item_digest = 2g8OXnhoGOAx3nkSIwTWsKYxkRuD5-sVOJAFUxh7uxA
Context receipt:
{
"alg": "sha-256",
"item_count": 4,
"items": [
"9QV3ZRTxsG60bOe1e6gS5LL0q5XjkTivElxci0uqfqY",
"8m7geGcZw1hWHKHjFFOpEpPe_MQ9IgxwyUaFALTdw4Y",
"nkT1qIfqXLMxVXtuqJvcRQtNaDbLxitRYFq329hcjrI",
"2g8OXnhoGOAx3nkSIwTWsKYxkRuD5-sVOJAFUxh7uxA"
],
"retention_until": "2028-04-10T00:00:00Z",
"type": "adc-receipt",
"v": 1
}
receipt_digest = _Ov_XzNXS4z1mVz9sb2CgIRLZbyUlSlN_G2lw080W0s
Decision record. Four members use stand-in values so that the vector
is self-contained: "prev" stands in for the commitment of record 40
and is DIGEST of the US-ASCII string "previous commitment
placeholder"; "checkout_digest" stands in for the AP2 "checkout_hash"
and is DIGEST of the US-ASCII string "example checkout_jwt";
"request_digest" is DIGEST of the US-ASCII string "example provider
request body". In this appendix, DIGEST of a string means DIGEST of
its octets, not of its JSON form. "schema_digest" is DIGEST of the
JSON object {"kind":"probability","name":"pay_invoice"}.
Milan Expires 18 April 2027 [Page 53]
Internet-Draft Agent Decision Commitments October 2026
{
"action": {
"taken": "pay"
},
"alg": "sha-256",
"answer": {
"probability": 0.88
},
"chain": {
"id": "ch-7f3a91",
"prev": "uuwyfPlzoD_kakG59boK4Ga0yJamhmuNq34CaV1WXMA",
"seq": 41
},
"issued_at": "2026-10-10T14:03:22Z",
"models": [
{
"id": "example-model-2026-09",
"provider": "provider.example",
"request_digest": "rLYUCRQ-un2g7mhK3wxADF_ud8Up-2bz66_UsWbCNOE",
"request_id": "req-0001"
}
],
"question": {
"kind": "probability",
"name": "pay_invoice",
"schema_digest": "e64ljzd9rTSr6AXA41WIigpstKOTVV82YIfxgxLidwY"
},
"receipt_digest": "_Ov_XzNXS4z1mVz9sb2CgIRLZbyUlSlN_G2lw080W0s",
"transaction": {
"amount": "48000",
"checkout_digest": "H6AT0BnDXRP7TfoMSOAdI7qs-u2D3Y99JeI7kKsQd2k",
"currency": "BRL",
"payee": "merchant.example",
"rail": "ap2"
},
"type": "adc-record",
"v": 1
}
commitment salt (octets 0x00..0x1f) =
AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8
C = iJbDuNj4EPEiCI_lVaAeT465fHTJn1qTDyDuBZSIIXA
Milan Expires 18 April 2027 [Page 54]
Internet-Draft Agent Decision Commitments October 2026
Decision context claim and SD-JWT disclosure. "receipt_uri" in this
example ends in an opaque value chosen by the holder. The disclosure
salt is the 16 octets 0x20..0x2f ("ICEiIyQlJicoKSorLC0uLw"). The
disclosure is the array [salt, "decision_context", claim] serialized
without whitespace, with the claim members in the order shown; the
disclosure digest is DIGEST of the US-ASCII disclosure string. Line
breaks in the encoded value are for display only:
{
"v": 1,
"alg": "sha-256",
"commitment": "iJbDuNj4EPEiCI_lVaAeT465fHTJn1qTDyDuBZSIIXA",
"receipt_uri": "https://holder.example/adc/r/q8Zk2LxV"
}
disclosure =
WyJJQ0VpSXlRbEppY29LU29yTEMwdUx3IiwiZGVjaXNpb25fY29udGV4dCIseyJ2
IjoxLCJhbGciOiJzaGEtMjU2IiwiY29tbWl0bWVudCI6ImlKYkR1Tmo0RVBFaUNJ
X2xWYUFlVDQ2NWZIVEpuMXFURHlEdUJaU0lJWEEiLCJyZWNlaXB0X3VyaSI6Imh0
dHBzOi8vaG9sZGVyLmV4YW1wbGUvYWRjL3IvcThaazJMeFYifV0
disclosure digest = sS4aHqmyXB7SM7eTSevd7HSwzvF2AuHi86hC_VH-BVU
x402 nonce, SHA-256(BASE64URL-DECODE(C) || r) in hexadecimal, with r
("nonce_random") = octets 0x30..0x3f:
nonce = 0xfeb329a3d9524e30640c71e39301af69
c63b7d54293eb1104a7d67e3765ad304
Negative vector: changing item 1's "fetched_at" to
"2026-10-10T14:02:52Z" yields item digest
_zVFztwZa20kMSsIdkhpwOq1UeSKLe8yygvC0O5_3Cs and receipt_digest
alHUluxRV0hr2pB-N82UZZPIJ5whPUSRm1oZeG2Hsh4, which does not match the
record.
ISO 20022 remittance information for this commitment:
ADC1:8896c3b8d8f810f122088fe555a01e4f8eb97c74c99f5a930f20ee0594882170
Normalization: the strings "Cafe" followed by U+0301 and "Caf"
followed by U+00E9 produce identical canonical forms after NFC
normalization.
Appendix B. Example Mapping to Dispute Evidence
This appendix is informative. It illustrates which questions in a
dispute about an agent-initiated payment the elements of this
document can help answer. It does not assert that any scheme accepts
them.
Milan Expires 18 April 2027 [Page 55]
Internet-Draft Agent Decision Commitments October 2026
+================================+=========================+
| Question | Element |
+================================+=========================+
| Was this payment the result of | Claim in the mandate; |
| a recorded decision, and when? | anchor; holder chain |
+--------------------------------+-------------------------+
| What did the model receive, | Context receipt and |
| including transformed media? | released items |
+--------------------------------+-------------------------+
| Which model decided, and with | models, answer; |
| what confidence? | attestation at level A3 |
+--------------------------------+-------------------------+
| Has the evidence changed since | Commitment and receipt |
| the decision? | digests |
+--------------------------------+-------------------------+
| Were any decisions omitted? | Sequence gaps in the |
| | holder chain |
+--------------------------------+-------------------------+
| Was evidence deleted, and | Erasure entries |
| when? | |
+--------------------------------+-------------------------+
Table 5: Dispute Questions and ADC Elements
Acknowledgments
The author thanks the reviewers of earlier versions of this document.
Author's Address
Fernando Henrique Damasceno Milan
Brazil
Email: milan@nordqubit.com
Milan Expires 18 April 2027 [Page 56]