fix(cli): retry pending settlements without replacement signing#80
Conversation
GPT ReviewerVerdict: REJECT Reviewed head A reused idempotency key can receive an ambiguous historical settlement failure before this process signs, bypassing the new do-not-repay protection and risking another charge. Findings
Shared exact-snapshot validation
|
Opus ReviewerVerdict: PASS Reviewed head This PR replaces the (superseded #73) behavior of re-signing a fresh authorization on settlement uncertainty with in-process reconciliation that resends the byte-identical signed request and refuses server-issued replacement challenges. The implementation is correct, security-conscious, and comprehensively tested. Key verifications:
Deterministic validation (typecheck, lint, build, 175+14 tests) all pass, with no regressions. I found no actionable blocker, major, or minor issues. FindingsNone. Shared exact-snapshot validation
|
GPT ReviewerVerdict: PASS Reviewed head The updated implementation safely performs bounded reconciliation using the byte-identical signed request, creates no replacement authorization, and now conservatively handles historical settlement failures unless all non-payment proof fields match the invocation. Error guidance, documentation, and focused regression tests align with the intended payment-safety contract. Deterministic validation passes. FindingsNone. Shared exact-snapshot validation
|
Opus ReviewerVerdict: PASS Reviewed head This PR replaces the superseded #73 behavior (re-signing a fresh authorization with a new idempotency key on settlement uncertainty) with in-process reconciliation that resends the byte-identical signed request and refuses server-issued replacement challenges. The implementation is correct, security-conscious, and comprehensively tested. Key verifications:
All deterministic validation passes (typecheck, lint, build, 177 CLI + 14 core tests) with no regressions. I found no actionable blocker, major, or minor issue. FindingsNone. Shared exact-snapshot validation
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7646146ebd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!isPaymentSettlementFailure(error) || !error.detail || typeof error.detail !== "object") { | ||
| return false; | ||
| } | ||
| const backendError = (error.detail as { error?: unknown }).error; |
There was a problem hiding this comment.
Accept flat settlement failure proofs
When the backend returns the flat error shape that backendErrorCode already accepts, e.g. { code: "payment_settlement_failed", idempotencyKey, paid: false, safeToStartNewCall: true }, this line ignores the proof because there is no nested error object. isConclusiveSettlementFailure then returns false, so the catch path appends the do-not-repay warning even though the server has confirmed the original authorization was not paid, leaving callers unable to tell that it is safe to start the replacement call.
Useful? React with 👍 / 👎.
Summary
payment_settlement_pendingin-process with the byte-identical signature, idempotency key, method, path, provider, and body.callinvocation.payment_settlement_failedas terminal only when it matches the invocation key and includespaid: falseplussafeToStartNewCall: true.Why
PR #73 could turn settlement uncertainty into a second purchase by signing a fresh authorization with a new idempotency key. This pivot limits recovery to bounded reconciliation of the original authorization and prevents automatic replacement payments.
Companion backend change: Steemhunt/h402-web#609.
Supersedes #73.
Closes #43.
Validation
npm test: 175 CLI tests and 14 core tests passednpm run typechecknpm run lintnpm run buildnpm run verify:packnpm run smoke:packgit diff --check