| Internet-Draft | Payment-Dispute Receipt Profile | October 2026 |
| Goshi | Expires 15 April 2027 | [Page] |
This document profiles draft-farley-acta-signed-receipts, "Signed Decision Receipts for Machine-to-Machine Access Control", for use as card-scheme dispute evidence. It defines how a conforming decision receipt is populated for payment disputes, and specifies four additional evidence layers bound to that receipt: card-scheme dispute-evidence categories (Visa Compelling Evidence 3.0, Mastercard First-Party Trust), agent-native anchors with no scheme-defined slot, a settlement anchor recording what money actually moved, and an evidentiary-custody wrapper aligned with U.S. Federal Rules of Evidence 901/902. This is a vendor profile documenting one implementation (ActaSeal's DisputeEvidencePacket); it does not define a new protocol and makes no claim of IETF consensus or standardization.¶
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 15 April 2027.¶
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.¶
This document is a vendor implementation profile, submitted as an Independent Submission. It is not a product of an IETF working group and does not represent IETF consensus.¶
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] when, and only when, they appear in all capitals, as shown here.¶
These key words bind only conformance to this profile as implemented by ActaSeal's DisputeEvidencePacket -- they do not bind any other implementation of the base draft.¶
[FARLEY] defines a portable, cryptographically
signed receipt for machine-to-machine access-control decisions:
Ed25519 ([RFC8032]) over an [RFC8785]
(JCS) canonicalized payload, in an envelope of the form
{payload, signature{alg, kid, sig}},
with namespaced type values as the
extension mechanism, verifiable offline with keys resolved out of
band.¶
Agent payment disputes need more than the decision receipt itself. Card-scheme representment (Visa Compelling Evidence 3.0, Mastercard First-Party Trust) asks for specific evidence categories; adjudication turns on whether the agent exceeded its delegated scope; the money that actually moved must be anchored to an independent artifact; and a court asks who captured the evidence, when, and how ([FRE901], [FRE902]). This profile binds those four layers to the base receipt.¶
A conforming dispute receipt is a base-draft receipt with:¶
type:
actaseal:policy_decision (namespaced
per the base draft's extension mechanism).¶
PolicyDecisionReceipt
canonical dict -- decision, reason_code, action_hash,
evidence_set_hash, ledger_entry_hash, timestamp, mandate_hash,
rail_anchors_hash, scope_conformance, key_id,
signer_pubkey_hash.¶
alg = EdDSA).¶
receipt_public_key_hex; verifiers
decide whether to trust it -- the base draft's rule that the
envelope itself cannot authenticate its own key applies
unchanged).¶
Conformance, verified: the reference implementation ships two canonicalizers. The v2 canonicalizer is full RFC 8785 JCS -- ECMAScript Number::toString formatting and UTF-16 code-unit key ordering per [RFC8785] section 3.2, checked against the RFC's own Appendix / cyberphone json-canonicalization test vectors (French, structures, values, weird). The v1 canonicalizer -- unchanged, and what every already-signed receipt was hashed and signed with -- sorts keys by codepoint rather than UTF-16 code unit and defers number formatting to the host language's default JSON serializer. Both diverge from JCS only outside this payload's value domain (no receipt field is a non-decimal number or a non-BMP key), and produce byte-identical output to v2 for every field this profile actually emits: the receipt dict is strings, null, and nested objects/arrays of the same, with amounts pre-converted to decimal strings before canonicalization. Interop claims for this profile's receipt payload MAY say "JCS" ([RFC8785]) without qualification; a general-purpose caller outside this value domain SHOULD use the JCS-conformant canonicalizer explicitly rather than assume the legacy path is conformant for arbitrary input.¶
The reference implementation's CE 3.0 view emits the three scheme categories -- device identity, delivery information, additional identity factor -- each populated only from fields the packet actually holds. At the time of writing the packet genuinely holds one identity data point (the actor login identifier confirmed by an ActorValidated ledger event); device identity and delivery information are emitted unpopulated with explicit gap notes. A missing dispute reason code MUST cause the mapper to raise rather than pass silently. The mapper MUST NOT invent evidence.¶
Agent-native facts with no scheme-defined slot ride in a
distinct agent_anchors block: AP2
mandate_hash, TAP
agent_id, approval event hash,
receipt signature. Network token id and 3DS/ACS result are part
of the block's shape but null when the implementation has no
source for them. The receipt's
scope_conformance field (the
intent-scope vs. executed-action diff) is the adjudication
headline -- one of
in_scope,
BREACH:<field>, or
not_evaluated -- and MUST be
re-derived by the verifier from recorded inputs, never asserted
without re-derivation.¶
The manifest's settlement_anchor
block records what money actually moved:
{rail, txn_ref, finality_status,
amount_minor, currency, captured_at, network, payer},
plus unanchored_fields naming what
the settlement rail's public artifact did not witness (for
example, an x402 v2 settlement response carries no amount). The
block is bound by an anchor_hash (a
canonical hash of the anchor content). Absence MUST be stated as
SETTLEMENT_UNANCHORED; a manifest
without the block MUST fail verification.¶
The packet carries an acquisition record (who captured the evidence, when, with what tool and clock source -- gaps declared, custodian never invented), a custody record (each custody event bound to a ledger event hash), and an authentication statement naming exactly what a challenger can independently re-derive, aligned with [FRE901](b)(9) and [FRE902](13)-(14).¶
Verification is re-derivation, not trust: the packet ships a
verifier with no non-standard-library dependency beyond a
cryptographic primitives library, which recomputes event hashes
and chain links, the receipt signature over canonical bytes, the
scope verdict from the recorded intent scope and executed action,
the settlement anchor hash, and headline consistency across
manifest, receipt, and ledger slice. Every failure MUST be named
(for example, SCOPE_HEADLINE_MISMATCH,
SETTLEMENT_ANCHOR_HASH_MISMATCH). This
satisfies the base draft's offline-verifiability requirement and
extends it to the dispute layers defined here.¶
All of the base draft's security considerations apply. In addition: the settlement anchor is only as strong as its source. A reference implementation that plugs a test-only fixture into the settlement-anchor seam witnesses nothing; production deployments MUST plug a real acquirer or facilitator feed into that seam -- for example, a facilitator implementing [X402] or an equivalent settlement rail. Independent time requires an external anchor proof ([RFC3161] or a transparency log per [RFC6962]); absent that, the host clock MUST be declared untrusted in the acquisition record.¶
The dispute-evidence categories in Section 4.1 are named for, but not endorsed or specified by, the card schemes: see [CE3] and [FPT] for the scheme-owned program requirements this profile's category names reference. [LCP] is an unrelated but complementary mechanism for binding the terms of service in force at transaction time; it is out of scope for this profile but referenced here for implementers who need both.¶
This document has no IANA actions.¶
This profile documents ActaSeal's DisputeEvidencePacket implementation of [FARLEY].¶