Skip to content

feat(specs): add diagnostic extension for payment failure signaling#1875

Open
jonathanbulkeley wants to merge 3 commits intocoinbase:mainfrom
jonathanbulkeley:feat/diagnostic-extension
Open

feat(specs): add diagnostic extension for payment failure signaling#1875
jonathanbulkeley wants to merge 3 commits intocoinbase:mainfrom
jonathanbulkeley:feat/diagnostic-extension

Conversation

@jonathanbulkeley
Copy link
Copy Markdown
Contributor

x402 Diagnostic Extension

PR Description

Adds specs/extensions/diagnostic.md — a machine-readable diagnostic vocabulary for x402 402 responses.

Closes #1860.

This spec was developed from production experience operating a pay-per-query oracle receiving 8,000+ daily failed payment requests from a broken client over 18 days, with no protocol mechanism to signal the issue. It was refined through discussion in #1860 incorporating contributions from @hermesnousagent (receipt trail, correlation_id), @up2itnow0822 / agentwallet-sdk (code-to-behavior mapping, committed to shipping client-side implementation when spec stabilizes), and builds on the implementation foundation laid by @0xAxiom in #1866.

What this adds:

  • 6 standard diagnostic codes with clear retriable/escalate semantics
  • escalate: true flag for broken payment logic detection
  • Client SDK implementation guidance with escalation event schema
  • Server implementation guidance with attempt tracking thresholds
  • Python and TypeScript reference implementations
  • Out-of-band operator contact scoped as a future extension
  • Fully backward compatible — existing clients ignore extensions

cc @hermesnousagent @up2itnow0822 @0xAxiom


@cb-heimdall
Copy link
Copy Markdown

cb-heimdall commented Mar 30, 2026

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@github-actions github-actions bot added the specs Spec changes or additions label Mar 30, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

@jonathanbulkeley is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@up2itnow0822
Copy link
Copy Markdown
Contributor

Clean spec. The code-to-behavior mapping table in Client Implementation is exactly what SDK authors need. A few notes from the implementation side:

Code-to-SpendingPolicy mapping (what we will build in agentwallet-sdk):

The six diagnostic codes map cleanly to three distinct behaviors in a client SDK spending policy:

  • PAYMENT_REQUIRED + INVOICE_EXPIRED -> normal flow, handled by existing retry logic
  • PAYMENT_UNVERIFIED -> route to operator approval queue (DraftThenApprove mode), do not auto-retry. Broken signature likely means broken config, not transient failure.
  • PAYMENT_ATTEMPTS_EXCEEDED + WALLET_INSUFFICIENT_FUNDS + OPERATOR_ALERT -> halt, block endpoint, emit escalation event with full diagnostic payload

The escalate: true flag being independent of code is the right call. It lets servers express urgency without being constrained to a specific code, and gives SDK authors a single boolean to key behavioral decisions on.

One implementation detail worth specifying: When a client blocks an endpoint after escalate: true, should the block be per-endpoint or per-server? If myceliasignal.com has /price/BTC and /price/ETH, does an escalation on one block all endpoints on that origin, or just the specific path? For the 144k-request case the answer is probably per-origin (the whole payment stack is broken), but for a server with mixed free/paid endpoints the answer might be per-path.

Suggest adding a scope note in the Client Implementation section — something like "endpoint blocking SHOULD default to per-origin unless the diagnostic includes path-specific context."

Will implement the client-side parsing in agentwallet-sdk once the spec stabilizes.

@jonathanbulkeley
Copy link
Copy Markdown
Contributor Author

Excellent! The three-bucket distillation is much cleaner than the six-code table for SDK authors — I'll add that framing to the Client Implementation section alongside the full code table.

On scope: the per-origin vs per-path question is a really good one. My instinct is (same as yours) — default per-origin, but with an opt-in to per-path scope. The 144k-request case is a broken payment stack, not a broken endpoint, so blocking the origin is correct. But a server with mixed free/paid endpoints (like mine — /dlc/oracle/threshold is paid, /dlc/oracle/pubkey is free) shouldn't have its free endpoints blocked because the payment stack failed on a paid one.

Proposed addition to the spec:

Endpoint blocking scope: When blocking after escalate: true, clients SHOULD default to per-origin blocking (block all paid endpoints on the same hostname). Clients MAY implement per-path blocking if the server context makes mixed free/paid endpoints likely. Servers MAY include a scope hint in the diagnostic ("endpoint" or "origin") to signal the appropriate blocking granularity.

I'll add this to the spec. Does the scope hint approach work for the agentwallet-sdk implementation? Or would you suggest a different signal?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

specs Spec changes or additions

Development

Successfully merging this pull request may close these issues.

RFC: Diagnostic extension for 402 responses — payment failure signaling for agents

3 participants