fix(cli): resume pending settlement safely#73
Conversation
GPT review — changes requestedReviewed head
The normal retry path otherwise preserves the exact signature/request, bounds retries and replacement signing, and reapplies |
- carry the do-not-repay guidance across network and 5xx failures that follow an observed pending settlement, so a lost retry can no longer read as a plain error inviting a fresh key - require the x-h402-previous-idempotency-key binding (presence and match) before signing a replacement challenge Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-upAddressed both GPT findings in commit
Verification: |
…tlement-resume Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Final reviewVerdict: REJECT — blocking money-safety gap Reviewed head Blocker
I added a disposable regression with this sequence:
It failed as follows:
A signed request is settlement-risk-bearing as soon as it is sent, not only after the backend manages to return the explicit pending code. Please preserve the risk guidance across every non-definitive exit after any signed send; optionally retry the byte-identical signed request/key in-process on bounded network failures as well. Add regressions for the first signed request returning a network error and a generic 5xx. Verification performed
No paid, wallet-signing, production, or provider call was made; signing and HTTP were mocked. |
Review follow-upAddressed the final first-signed-request money-safety blocker in commit
Verification:
No real wallet signing, provider call, payment, or production request was made; HTTP and signing remained mocked. |
GPT ReviewerVerdict: REJECT Reviewed head An initial replacement-marked 402 bypasses the pending-settlement gate and can cause a fresh authorization to be signed under the original idempotency key. All shared deterministic checks passed. Findings
Shared exact-snapshot validation
|
Opus ReviewerVerdict: PASS Reviewed head This PR makes the CLI resume a I traced the full
stdout/stderr contract preserved (only final success to stdout; all failures thrown to the error envelope). The api.ts money-sensitive code-set expansion is mirrored in api.test.ts; docs edits match implementation and the new docs.test assertions. The refactor does not worsen the pre-existing (unchanged) absence of the auth header on the paid retry. Shared validation passes: typecheck, lint, build, and 172 CLI + 14 core tests. Items considered and dismissed as non-actionable: the deliberate double FindingsNone. Shared exact-snapshot validation
|
Summary
payment_settlement_pendingresponses in-process with the byte-identicalPAYMENT-SIGNATURE, idempotency key, method, path, body, and provider path--max-usdbefore signing a replacement challenge and extend money-sensitive guidance to pending, reconciled, and authorization-conflict responsesSafety properties
x-h402-replacement-idempotency-keyand a valid replacement challengeVerification
npm run test -w @h402/cli -- tests/docs.test.ts tests/api.test.ts tests/call-settlement-retry.test.ts tests/call-max-usd.test.tsgit diff --checknpm run typechecknpm run lintnpm testnpm run buildCloses #43