@aibtc/tx-schemas 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/core/enums.d.ts +161 -0
- package/dist/core/enums.d.ts.map +1 -0
- package/dist/core/enums.js +98 -0
- package/dist/core/enums.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/payment.d.ts +267 -0
- package/dist/core/payment.d.ts.map +1 -0
- package/dist/core/payment.js +85 -0
- package/dist/core/payment.js.map +1 -0
- package/dist/core/primitives.d.ts +11 -0
- package/dist/core/primitives.d.ts.map +1 -0
- package/dist/core/primitives.js +29 -0
- package/dist/core/primitives.js.map +1 -0
- package/dist/core/schemas.d.ts +2 -0
- package/dist/core/schemas.d.ts.map +1 -0
- package/dist/core/schemas.js +2 -0
- package/dist/core/schemas.js.map +1 -0
- package/dist/core/terminal-reasons.d.ts +154 -0
- package/dist/core/terminal-reasons.d.ts.map +1 -0
- package/dist/core/terminal-reasons.js +82 -0
- package/dist/core/terminal-reasons.js.map +1 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +2 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/schemas.d.ts +424 -0
- package/dist/http/schemas.d.ts.map +1 -0
- package/dist/http/schemas.js +171 -0
- package/dist/http/schemas.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/rpc/index.d.ts +2 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +2 -0
- package/dist/rpc/index.js.map +1 -0
- package/dist/rpc/schemas.d.ts +339 -0
- package/dist/rpc/schemas.d.ts.map +1 -0
- package/dist/rpc/schemas.js +91 -0
- package/dist/rpc/schemas.js.map +1 -0
- package/docs/package-schemas.md +52 -0
- package/docs/x402-approval-spec.md +530 -0
- package/docs/x402-state-machines.md +241 -0
- package/package.json +101 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
# x402 Approval Spec: Reduce Before We Polish
|
|
2
|
+
|
|
3
|
+
This document defines what "approvable" means for the current x402 payment architecture across:
|
|
4
|
+
|
|
5
|
+
- `aibtcdev/skills`
|
|
6
|
+
- `aibtcdev/aibtc-mcp-server`
|
|
7
|
+
- `aibtcdev/landing-page` (`aibtc.com`)
|
|
8
|
+
- `aibtcdev/agent-news` (`aibtc.news`)
|
|
9
|
+
- `aibtcdev/x402-sponsor-relay`
|
|
10
|
+
- `aibtcdev/x402-api`
|
|
11
|
+
|
|
12
|
+
It applies the SpaceX engineering principles as follows:
|
|
13
|
+
|
|
14
|
+
1. Make the requirements less dumb.
|
|
15
|
+
2. Delete duplicated decision-making.
|
|
16
|
+
3. Simplify the system around one payment truth.
|
|
17
|
+
4. Accelerate by fixing one vertical slice at a time.
|
|
18
|
+
5. Automate the approval bar so regressions are blocked.
|
|
19
|
+
|
|
20
|
+
## 1. What We Are Keeping
|
|
21
|
+
|
|
22
|
+
We are not collapsing `HTTP` and `RPC` into one endpoint.
|
|
23
|
+
|
|
24
|
+
They serve different trust boundaries:
|
|
25
|
+
|
|
26
|
+
- `HTTP` is the external consumer interface for general agents and tools such as `skills`, `aibtc-mcp-server`, and other third-party x402 clients.
|
|
27
|
+
- `RPC` is the internal first-party interface for services such as `landing-page` and `agent-news`.
|
|
28
|
+
|
|
29
|
+
`x402-api` should be treated as an internal first-party service target for migration purposes, even if some current flows still use `HTTP`.
|
|
30
|
+
|
|
31
|
+
Transport duplication is acceptable.
|
|
32
|
+
|
|
33
|
+
Semantic duplication is not acceptable.
|
|
34
|
+
|
|
35
|
+
The approval target is:
|
|
36
|
+
|
|
37
|
+
- keep both `HTTP` and `RPC`
|
|
38
|
+
- enforce one canonical payment state model
|
|
39
|
+
- make transports thin adapters over a shared settlement core
|
|
40
|
+
|
|
41
|
+
## 2. Core Diagnosis
|
|
42
|
+
|
|
43
|
+
The current design feels like spaghetti because the same business decision is made in too many places:
|
|
44
|
+
|
|
45
|
+
- client code decides which relay errors are retryable and when to rebuild transactions
|
|
46
|
+
- service code decides whether `pending` still delivers the resource
|
|
47
|
+
- relay code owns the actual payment lifecycle and final chain-observed truth
|
|
48
|
+
- some route- or product-specific recovery logic compensates for gaps instead of consuming a narrow contract
|
|
49
|
+
|
|
50
|
+
There is also an important wallet-boundary constraint:
|
|
51
|
+
|
|
52
|
+
- clients control sender-wallet state and sender nonces
|
|
53
|
+
- relay controls sponsor-wallet state and sponsor nonces
|
|
54
|
+
|
|
55
|
+
That boundary is real and should be reflected in the approval model rather than abstracted away.
|
|
56
|
+
|
|
57
|
+
This creates three failure modes:
|
|
58
|
+
|
|
59
|
+
- status drift: `pending`, `confirmed`, `mempool`, `failed`, and `replaced` are interpreted differently depending on repo
|
|
60
|
+
- retry drift: client-specific retries and service-specific polling diverge from relay truth
|
|
61
|
+
- warning debt: errors and warnings are reduced by adding branches instead of deleting ambiguity
|
|
62
|
+
|
|
63
|
+
## 3. Canonical Domain Model
|
|
64
|
+
|
|
65
|
+
The relay must own the canonical payment state machine for the settlement domain it actually controls.
|
|
66
|
+
|
|
67
|
+
All other repos consume that model. They do not redefine it.
|
|
68
|
+
|
|
69
|
+
### Canonical Payment States
|
|
70
|
+
|
|
71
|
+
The shared payment lifecycle is:
|
|
72
|
+
|
|
73
|
+
`requires_payment -> submitted -> queued -> broadcasting -> mempool -> confirmed | failed | replaced | not_found`
|
|
74
|
+
|
|
75
|
+
These states mean:
|
|
76
|
+
|
|
77
|
+
- `requires_payment`: protected resource requires proof of payment
|
|
78
|
+
- `submitted`: relay accepted a submission request and assigned identity
|
|
79
|
+
- `queued`: accepted but not yet broadcasting
|
|
80
|
+
- `broadcasting`: relay is actively attempting sponsor/broadcast work
|
|
81
|
+
- `mempool`: transaction accepted by node/network and awaiting finality
|
|
82
|
+
- `confirmed`: chain-observed success
|
|
83
|
+
- `failed`: terminal failure
|
|
84
|
+
- `replaced`: terminal failure caused by nonce replacement or supersession
|
|
85
|
+
- `not_found`: missing, expired, or unknown payment identity
|
|
86
|
+
|
|
87
|
+
### Canonical State Categories
|
|
88
|
+
|
|
89
|
+
Every state must fit one category:
|
|
90
|
+
|
|
91
|
+
- pre-payment: `requires_payment`
|
|
92
|
+
- in-flight: `submitted`, `queued`, `broadcasting`, `mempool`
|
|
93
|
+
- terminal-success: `confirmed`
|
|
94
|
+
- terminal-failure: `failed`, `replaced`, `not_found`
|
|
95
|
+
|
|
96
|
+
No repo may invent a separate terminal category.
|
|
97
|
+
|
|
98
|
+
### Canonical Response Contract
|
|
99
|
+
|
|
100
|
+
All adapters must map onto the same domain contract:
|
|
101
|
+
|
|
102
|
+
- success response: resource may be delivered only for `confirmed`
|
|
103
|
+
- in-flight response: caller receives payment status and payment identity, but resource delivery depends on product policy
|
|
104
|
+
- failure response: no resource delivery
|
|
105
|
+
|
|
106
|
+
### Wallet Responsibility Boundary
|
|
107
|
+
|
|
108
|
+
The shared architecture must preserve blockchain reality:
|
|
109
|
+
|
|
110
|
+
- client wallet owner is responsible for sender nonce correctness and sender-side recovery
|
|
111
|
+
- relay is responsible for sponsor nonce correctness, sponsor-side ordering, and sponsor-side recovery
|
|
112
|
+
|
|
113
|
+
This means:
|
|
114
|
+
|
|
115
|
+
- the relay must not pretend it can fully repair sender-wallet nonce state
|
|
116
|
+
- clients must not pretend they can interpret sponsor-wallet contention better than the relay
|
|
117
|
+
- cross-boundary errors should be surfaced explicitly instead of hidden behind generic retry loops
|
|
118
|
+
|
|
119
|
+
The `gin rummy` style ordering logic is a sponsor-wallet concern and belongs in relay-owned domain behavior.
|
|
120
|
+
|
|
121
|
+
Sender-wallet recovery mechanisms such as replacing or flushing a stuck transaction are client concerns, even if first-party clients provide helpers for them.
|
|
122
|
+
|
|
123
|
+
### Approval Invariant on Resource Delivery
|
|
124
|
+
|
|
125
|
+
For internal services and paid protected resources, the default invariant is:
|
|
126
|
+
|
|
127
|
+
- do not deliver the protected resource on `pending` or any in-flight state
|
|
128
|
+
|
|
129
|
+
If a product intentionally wants "deliver while payment is still in-flight", that behavior must be treated as an explicit exception, documented per route, and justified as safe. It must not be the hidden default semantics of `pending`.
|
|
130
|
+
|
|
131
|
+
The approval preference is to remove "pending but delivered" wherever possible.
|
|
132
|
+
|
|
133
|
+
## 4. Domain Ownership
|
|
134
|
+
|
|
135
|
+
The architecture is approvable only if domain ownership is narrow.
|
|
136
|
+
|
|
137
|
+
### Relay Owns
|
|
138
|
+
|
|
139
|
+
`x402-sponsor-relay` is the domain owner for:
|
|
140
|
+
|
|
141
|
+
- payment state transitions
|
|
142
|
+
- settlement truth
|
|
143
|
+
- retryable versus terminal settlement outcomes
|
|
144
|
+
- payment identity lifecycle
|
|
145
|
+
- nonce conflict and replacement semantics
|
|
146
|
+
- chain-observed finalization
|
|
147
|
+
- sponsor-wallet ordering and sponsor-wallet healing
|
|
148
|
+
|
|
149
|
+
The relay may expose this through both `RPC` and `HTTP`, but the transport layer must not fork the state model.
|
|
150
|
+
|
|
151
|
+
### External Client Adapters Own
|
|
152
|
+
|
|
153
|
+
`skills`, `aibtc-mcp-server`, and external `HTTP` consumers own:
|
|
154
|
+
|
|
155
|
+
- offer validation
|
|
156
|
+
- wallet readiness checks
|
|
157
|
+
- transaction construction and signing
|
|
158
|
+
- transport submission
|
|
159
|
+
- bounded client retries for transport failures only
|
|
160
|
+
- sender-wallet nonce hygiene and sender-side recovery actions
|
|
161
|
+
|
|
162
|
+
They do not own:
|
|
163
|
+
|
|
164
|
+
- interpreting chain finality independently of relay truth
|
|
165
|
+
- route-specific payment state enums
|
|
166
|
+
- business-specific terminal status invention
|
|
167
|
+
- sponsor-wallet ordering policy
|
|
168
|
+
|
|
169
|
+
### Internal Service Adapters Own
|
|
170
|
+
|
|
171
|
+
`landing-page` and `agent-news` own:
|
|
172
|
+
|
|
173
|
+
- enforcing route-level payment requirement
|
|
174
|
+
- calling relay over `RPC`
|
|
175
|
+
- converting relay status into route responses
|
|
176
|
+
- exposing `payment-status` polling endpoints where needed
|
|
177
|
+
|
|
178
|
+
They do not own:
|
|
179
|
+
|
|
180
|
+
- custom payment lifecycle logic
|
|
181
|
+
- product-specific redefinition of `confirmed`, `failed`, `replaced`, or `not_found`
|
|
182
|
+
- special-case settlement behavior that bypasses shared semantics
|
|
183
|
+
|
|
184
|
+
### x402-api
|
|
185
|
+
|
|
186
|
+
`x402-api` is our service and should be treated as an internal first-party consumer.
|
|
187
|
+
|
|
188
|
+
The target direction is to migrate it toward the same `RPC`-backed internal contract used by other first-party services, while preserving external `HTTP` support for true third-party consumers.
|
|
189
|
+
|
|
190
|
+
It must not become a second settlement brain.
|
|
191
|
+
|
|
192
|
+
## 5. Transport Rules
|
|
193
|
+
|
|
194
|
+
Transport-specific behavior is allowed only at the adapter boundary.
|
|
195
|
+
|
|
196
|
+
### Allowed `HTTP` Differences
|
|
197
|
+
|
|
198
|
+
- auth shape
|
|
199
|
+
- header shape
|
|
200
|
+
- external error formatting
|
|
201
|
+
- polling ergonomics for external consumers
|
|
202
|
+
|
|
203
|
+
### Allowed `RPC` Differences
|
|
204
|
+
|
|
205
|
+
- service binding mechanics
|
|
206
|
+
- internal auth and circuit-breaker behavior
|
|
207
|
+
- internal error transport format
|
|
208
|
+
|
|
209
|
+
### Forbidden Differences
|
|
210
|
+
|
|
211
|
+
- a different payment state enum
|
|
212
|
+
- a different definition of terminal success
|
|
213
|
+
- a different definition of retryable settlement failure
|
|
214
|
+
- a different meaning of `not_found` or `replaced`
|
|
215
|
+
- a different resource-delivery rule for the same protected resource type without explicit route documentation
|
|
216
|
+
|
|
217
|
+
## 6. Retry Policy
|
|
218
|
+
|
|
219
|
+
The current system will not become approvable by layering more recovery branches into clients and services.
|
|
220
|
+
|
|
221
|
+
Retry policy must be reduced and made explicit.
|
|
222
|
+
|
|
223
|
+
### Client Retry Policy
|
|
224
|
+
|
|
225
|
+
Clients may retry only for:
|
|
226
|
+
|
|
227
|
+
- transient network/transport failures
|
|
228
|
+
- explicit relay retryable responses
|
|
229
|
+
- bounded transaction rebuild when relay says sender nonce is stale or gapped
|
|
230
|
+
- sender-wallet recovery actions that are clearly client-owned
|
|
231
|
+
|
|
232
|
+
Clients may not:
|
|
233
|
+
|
|
234
|
+
- infer confirmation from side channels as a normal control path
|
|
235
|
+
- carry product-specific auto-recovery logic that bypasses shared relay status APIs unless it is a temporary migration shim
|
|
236
|
+
- assume responsibility for sponsor-wallet healing
|
|
237
|
+
|
|
238
|
+
### Service Retry Policy
|
|
239
|
+
|
|
240
|
+
Services may:
|
|
241
|
+
|
|
242
|
+
- poll the relay for bounded in-flight resolution
|
|
243
|
+
- return a stable `paymentId` for caller polling when budget is exhausted
|
|
244
|
+
|
|
245
|
+
Services may not:
|
|
246
|
+
|
|
247
|
+
- implement settlement-specific state transitions outside relay contracts
|
|
248
|
+
- swallow terminal relay failures and convert them into ambiguous route behavior
|
|
249
|
+
|
|
250
|
+
### Relay Retry Policy
|
|
251
|
+
|
|
252
|
+
The relay owns:
|
|
253
|
+
|
|
254
|
+
- sponsor contention retries
|
|
255
|
+
- queue rescheduling
|
|
256
|
+
- nonce conflict handling
|
|
257
|
+
- mempool observation and chain finalization
|
|
258
|
+
- sponsor-wallet healing such as gap-fill, reset, and ordering strategies
|
|
259
|
+
|
|
260
|
+
If retry semantics are needed, they should move toward the relay, not outward toward every consumer.
|
|
261
|
+
|
|
262
|
+
## 7. Shared Types and Contracts
|
|
263
|
+
|
|
264
|
+
Approval requires a shared contract package or equivalent shared source of truth.
|
|
265
|
+
|
|
266
|
+
At minimum, all consumers must converge on:
|
|
267
|
+
|
|
268
|
+
- one `PaymentState` enum
|
|
269
|
+
- one `PaymentStateCategory` mapping
|
|
270
|
+
- one `PaymentTerminalReason` or equivalent error taxonomy
|
|
271
|
+
- one settlement response shape for `HTTP`
|
|
272
|
+
- one settlement response shape for `RPC`
|
|
273
|
+
- one rule set for which states permit resource delivery
|
|
274
|
+
|
|
275
|
+
For first-party production apps, this shared source of truth should start small:
|
|
276
|
+
|
|
277
|
+
- shared types and schemas first
|
|
278
|
+
- shared transport/domain adapters second if they clearly reduce drift
|
|
279
|
+
|
|
280
|
+
The goal is alignment, not framework overhead.
|
|
281
|
+
|
|
282
|
+
The initial rollout should be first-party focused:
|
|
283
|
+
|
|
284
|
+
- `x402-sponsor-relay`
|
|
285
|
+
- `landing-page`
|
|
286
|
+
- `agent-news`
|
|
287
|
+
- `x402-api`
|
|
288
|
+
|
|
289
|
+
But it must be designed with `skills` and `aibtc-mcp-server` in mind from the start, because the external `HTTP` contract is primarily for those clients and likely overlaps heavily with the first-party response model.
|
|
290
|
+
|
|
291
|
+
That means:
|
|
292
|
+
|
|
293
|
+
- do not build an internal package that ignores external client needs
|
|
294
|
+
- define `HTTP` response shapes once, with external clients as first-class consumers
|
|
295
|
+
- allow first-party apps to adopt shared internal types first without forcing immediate runtime changes in all clients
|
|
296
|
+
|
|
297
|
+
The recommended sequence is:
|
|
298
|
+
|
|
299
|
+
- define shared domain enums and schemas used by all repos
|
|
300
|
+
- define shared first-party `RPC` response types for internal apps
|
|
301
|
+
- define shared `HTTP` response types with `skills` and `aibtc-mcp-server` compatibility in mind
|
|
302
|
+
- migrate first-party apps first
|
|
303
|
+
- let client repos follow on the same schemas rather than inventing a second contract later
|
|
304
|
+
|
|
305
|
+
This can be implemented as:
|
|
306
|
+
|
|
307
|
+
- a shared package, or
|
|
308
|
+
- copied generated types from relay-owned schemas, or
|
|
309
|
+
- a contract repo consumed by all relevant projects
|
|
310
|
+
|
|
311
|
+
What is not acceptable is hand-maintained parallel type definitions drifting across repos.
|
|
312
|
+
|
|
313
|
+
## 8. Repo-by-Repo Approval Expectations
|
|
314
|
+
|
|
315
|
+
### `x402-sponsor-relay`
|
|
316
|
+
|
|
317
|
+
This repo is approvable when:
|
|
318
|
+
|
|
319
|
+
- state transitions are explicit and testable
|
|
320
|
+
- `RPC` and `HTTP` adapters both map to the same domain model
|
|
321
|
+
- impossible transitions are rejected
|
|
322
|
+
- terminal reasons are enumerable and stable
|
|
323
|
+
- settlement warnings are either actionable or removed
|
|
324
|
+
|
|
325
|
+
This repo is not approvable if transport adapters contain divergent business semantics.
|
|
326
|
+
|
|
327
|
+
### `landing-page`
|
|
328
|
+
|
|
329
|
+
This repo is approvable when:
|
|
330
|
+
|
|
331
|
+
- payment verification is adapter-only
|
|
332
|
+
- route handlers use shared payment states
|
|
333
|
+
- pending handling is explicit and documented per route
|
|
334
|
+
- route-specific compensation logic is reduced or deleted
|
|
335
|
+
|
|
336
|
+
This repo is not approvable if inbox or protected-route flows redefine relay truth.
|
|
337
|
+
|
|
338
|
+
### `agent-news`
|
|
339
|
+
|
|
340
|
+
This repo is approvable when:
|
|
341
|
+
|
|
342
|
+
- it consumes the same adapter contract as `landing-page`
|
|
343
|
+
- route behavior matches shared invariants
|
|
344
|
+
- any divergence from `landing-page` is intentional and documented at the product layer
|
|
345
|
+
|
|
346
|
+
This repo is not approvable if it independently hardens around relay edge cases with custom semantics.
|
|
347
|
+
|
|
348
|
+
### `skills`
|
|
349
|
+
|
|
350
|
+
This repo is approvable when:
|
|
351
|
+
|
|
352
|
+
- it performs signing and bounded submit/retry work only
|
|
353
|
+
- recovery logic is generic and contract-driven
|
|
354
|
+
- product-specific inbox logic is removed or isolated behind shared utilities with tests
|
|
355
|
+
- its `HTTP` contract usage stays compatible with the shared response schemas adopted by first-party apps
|
|
356
|
+
|
|
357
|
+
This repo is not approvable if external client code becomes a second settlement coordinator.
|
|
358
|
+
|
|
359
|
+
### `aibtc-mcp-server`
|
|
360
|
+
|
|
361
|
+
This repo is approvable when:
|
|
362
|
+
|
|
363
|
+
- it uses the same external client adapter rules as `skills`
|
|
364
|
+
- tool-specific behavior is isolated from payment semantics
|
|
365
|
+
- inbox tools do not carry private interpretations of relay outcomes
|
|
366
|
+
- its `HTTP` contract usage stays compatible with the shared response schemas adopted by first-party apps
|
|
367
|
+
|
|
368
|
+
This repo is not approvable if MCP tools grow their own state machine variants.
|
|
369
|
+
|
|
370
|
+
### `x402-api`
|
|
371
|
+
|
|
372
|
+
This repo is approvable when:
|
|
373
|
+
|
|
374
|
+
- it is moved toward the same first-party internal contract as `landing-page` and `agent-news`
|
|
375
|
+
- it consumes shared payment types instead of inventing local settlement semantics
|
|
376
|
+
- it does not normalize relay failures into new ad hoc statuses
|
|
377
|
+
|
|
378
|
+
This repo is not approvable if it accumulates special-case settlement behavior separate from the first-party contract.
|
|
379
|
+
|
|
380
|
+
## 9. Approval Checklist
|
|
381
|
+
|
|
382
|
+
The application is approvable only when all of the following are true:
|
|
383
|
+
|
|
384
|
+
- `HTTP` and `RPC` are documented as separate transports over the same payment domain model.
|
|
385
|
+
- One canonical payment state enum exists and is used across all participating repos.
|
|
386
|
+
- One canonical terminal error taxonomy exists and is used across all participating repos.
|
|
387
|
+
- Shared `HTTP` response schemas are defined with `skills` and `aibtc-mcp-server` as intended consumers.
|
|
388
|
+
- Relay is the sole owner of settlement truth and state transitions.
|
|
389
|
+
- Relay is the sole owner of sponsor-wallet ordering and sponsor-wallet healing behavior.
|
|
390
|
+
- Client adapters clearly own sender-wallet nonce hygiene and sender-side recovery.
|
|
391
|
+
- Client repos are adapter-only and perform only bounded retries.
|
|
392
|
+
- Internal services are adapter-only and do not redefine payment semantics.
|
|
393
|
+
- `pending` delivery behavior is either removed or explicitly documented as a route-level exception.
|
|
394
|
+
- `paymentId` polling semantics are consistent across internal and external consumers.
|
|
395
|
+
- Route- or product-specific recovery logic is either deleted or justified as a temporary migration shim.
|
|
396
|
+
- Warnings in touched x402 code paths are reduced to zero or explicitly waived with rationale.
|
|
397
|
+
- Contract tests verify the same outcomes for `HTTP` and `RPC`.
|
|
398
|
+
- End-to-end tests cover `confirmed`, `failed`, `replaced`, and `not_found`.
|
|
399
|
+
|
|
400
|
+
If any of those are false, the system is not ready for approval and more branch-level cleanup will mostly add entropy.
|
|
401
|
+
|
|
402
|
+
## 10. Required Test Matrix
|
|
403
|
+
|
|
404
|
+
Approval requires automated tests that enforce the architecture, not just the implementation.
|
|
405
|
+
|
|
406
|
+
### Contract Tests
|
|
407
|
+
|
|
408
|
+
- `HTTP` and `RPC` return equivalent domain statuses for equivalent relay outcomes.
|
|
409
|
+
- `confirmed` is the only default state that authorizes protected resource delivery.
|
|
410
|
+
- `failed`, `replaced`, and `not_found` are always terminal failures.
|
|
411
|
+
- in-flight states serialize consistently with payment identity and polling instructions.
|
|
412
|
+
- `HTTP` response schemas satisfy both first-party service callers and external client consumers such as `skills` and `aibtc-mcp-server`.
|
|
413
|
+
|
|
414
|
+
### State Transition Tests
|
|
415
|
+
|
|
416
|
+
- invalid transitions are rejected
|
|
417
|
+
- `submitted -> queued -> broadcasting -> mempool -> confirmed` is accepted
|
|
418
|
+
- `mempool -> replaced` is accepted
|
|
419
|
+
- `failed -> confirmed` is rejected
|
|
420
|
+
- `replaced -> confirmed` is rejected
|
|
421
|
+
|
|
422
|
+
### Adapter Tests
|
|
423
|
+
|
|
424
|
+
- `skills` and `aibtc-mcp-server` use shared external payment types
|
|
425
|
+
- `landing-page`, `agent-news`, and `x402-api` use shared internal payment types
|
|
426
|
+
- route handlers do not deliver resources on terminal failure
|
|
427
|
+
- sender-wallet errors and sponsor-wallet errors are surfaced as distinct contract categories where applicable
|
|
428
|
+
|
|
429
|
+
### End-to-End Tests
|
|
430
|
+
|
|
431
|
+
- external HTTP client can pay and receive confirmed result
|
|
432
|
+
- internal RPC service can pay and receive confirmed result
|
|
433
|
+
- in-flight payment returns stable polling identity
|
|
434
|
+
- terminal failure remains terminal across repeated polls
|
|
435
|
+
|
|
436
|
+
## 11. Migration Sequence
|
|
437
|
+
|
|
438
|
+
This should not be attacked as a broad cleanup.
|
|
439
|
+
|
|
440
|
+
Use a reduction-first sequence.
|
|
441
|
+
|
|
442
|
+
### Phase 1: Freeze the Contract
|
|
443
|
+
|
|
444
|
+
- define canonical states and terminal reasons
|
|
445
|
+
- define shared response schemas
|
|
446
|
+
- document delivery invariants
|
|
447
|
+
- validate `HTTP` schema shape against `skills` and `aibtc-mcp-server` usage before broad migration
|
|
448
|
+
|
|
449
|
+
No new payment branches should be added until this exists.
|
|
450
|
+
|
|
451
|
+
### Phase 2: Collapse Adapters
|
|
452
|
+
|
|
453
|
+
- make `landing-page` and `agent-news` consume the same internal adapter contract
|
|
454
|
+
- migrate `x402-api` toward the same internal adapter contract
|
|
455
|
+
- make `skills` and `aibtc-mcp-server` consume the same external adapter contract
|
|
456
|
+
- move retry semantics inward toward relay where possible
|
|
457
|
+
|
|
458
|
+
### Phase 3: Delete Compensating Logic
|
|
459
|
+
|
|
460
|
+
- remove route-specific recovery branches
|
|
461
|
+
- remove product-specific status reinterpretation
|
|
462
|
+
- remove dead warnings after the branches disappear
|
|
463
|
+
|
|
464
|
+
### Phase 4: Enforce in CI
|
|
465
|
+
|
|
466
|
+
- shared type drift checks
|
|
467
|
+
- contract tests
|
|
468
|
+
- end-to-end state coverage
|
|
469
|
+
- warning budget for touched x402 paths
|
|
470
|
+
|
|
471
|
+
## 12. SpaceX Principles Applied Concretely
|
|
472
|
+
|
|
473
|
+
### 1. Make the requirements less dumb
|
|
474
|
+
|
|
475
|
+
The requirement is not "handle all weird cases everywhere."
|
|
476
|
+
|
|
477
|
+
The requirement is:
|
|
478
|
+
|
|
479
|
+
- one payment truth
|
|
480
|
+
- two transports
|
|
481
|
+
- narrow adapters
|
|
482
|
+
- explicit delivery invariants
|
|
483
|
+
|
|
484
|
+
### 2. Delete the part or process
|
|
485
|
+
|
|
486
|
+
Delete duplicate semantics before fixing more warnings.
|
|
487
|
+
|
|
488
|
+
Candidate deletions:
|
|
489
|
+
|
|
490
|
+
- route-specific payment state reinterpretation
|
|
491
|
+
- inbox-specific payment recovery that should live in shared client code
|
|
492
|
+
- product-specific fallback branches that exist only because contracts are vague
|
|
493
|
+
|
|
494
|
+
Candidate clarifications that should remain explicit:
|
|
495
|
+
|
|
496
|
+
- sender-wallet recovery is client-owned
|
|
497
|
+
- sponsor-wallet healing is relay-owned
|
|
498
|
+
- first-party app alignment can begin with shared types before shared runtime helpers
|
|
499
|
+
|
|
500
|
+
### 3. Simplify or optimize
|
|
501
|
+
|
|
502
|
+
Simplify around one relay-owned lifecycle.
|
|
503
|
+
|
|
504
|
+
Do not optimize local branches that should disappear after contract reduction.
|
|
505
|
+
|
|
506
|
+
### 4. Accelerate cycle time
|
|
507
|
+
|
|
508
|
+
Prove one vertical slice at a time:
|
|
509
|
+
|
|
510
|
+
- external HTTP consumer slice
|
|
511
|
+
- internal RPC consumer slice
|
|
512
|
+
|
|
513
|
+
Only after both converge on the same domain truth should broad warning cleanup continue.
|
|
514
|
+
|
|
515
|
+
### 5. Automate
|
|
516
|
+
|
|
517
|
+
Approval must be enforced by tests, schemas, and CI checks.
|
|
518
|
+
|
|
519
|
+
Without automation, the system will drift back into per-repo semantics.
|
|
520
|
+
|
|
521
|
+
## 13. Decision
|
|
522
|
+
|
|
523
|
+
The current system should be reviewed against this standard:
|
|
524
|
+
|
|
525
|
+
- approve transport plurality
|
|
526
|
+
- reject semantic plurality
|
|
527
|
+
|
|
528
|
+
If the team can show one relay-owned state model, thin transport adapters, explicit delivery invariants, and automated contract coverage, the application is approvable.
|
|
529
|
+
|
|
530
|
+
If not, more warning and error cleanup will likely make the system harder to reason about instead of easier.
|