You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(purchase): allow Retry of proven-NoSubmission rows for EC2, Redshift and Azure savings plans #1803
RedriveRefusalReason (internal/purchase/manager.go) refuses Retry for EC2, Redshift and Azure savings-plan purchases whatever the row's NoSubmission says. That is right when a request may have reached the provider. But some failed rows prove nothing was submitted, for example the per-account skip rows from #1798 (#1672) and pre-execution refusals. For those providers, the user has to start a new purchase instead of retrying.
Proposal
Let Retry (checkRetryEligibilityGates) and the execution-time re-drive check accept a failed row with NoSubmission set for those providers.
This is a money path, so it needs its own double-buy review:
prove every writer of NoSubmission=true runs strictly before any provider call;
prove a Retry of such a row cannot race an in-flight attempt of the same lineage;
test that a NoSubmission EC2 row is retryable and a submitted one stays refused.
When this lands, the skip row's wording in skippedAccountNote can drop its "start a new purchase" branch.
Claimed by claude-ui-fix-1 (coordinator-assigned). This is a money path, so I'm planning first: map every writer of NoSubmission=true and its ordering relative to provider calls, and the lineage race with in-flight attempts, before any code.
Scope note from planning (no code yet). The proposal as written is unsafe in one case, so the plan narrows it:
NoSubmission proves one row, not a lineage. Retry successors reuse the lineage's idempotency key. A successor can fail with NoSubmission set (for example when a plan step is failed before it runs), but that says nothing about attempt 0, which may have bought. EC2 has no provider-side dedupe. So the rule is "failed, NoSubmission, and first attempt" (the existing NeverSubmitted), not "failed and NoSubmission".
The execution-time check runs on the successor, whose own NoSubmission is always false. It will read the predecessor instead and require it to be failed, NoSubmission and attempt 0. A lookup error or a missing predecessor refuses.
Under the Retry transaction's row lock, the same condition is re-checked before linking the successor.
RedriveRefusalReason stays unchanged for the reaper. A Retry-only predicate lifts just the EC2, Redshift and Azure savings-plan reasons. Unknown providers keep refusing.
Defaults taken, to be overridden here if wanted:
first attempt only, no chain walk;
fan-out root rows with NoSubmission at attempt 0 are eligible;
no new idempotency-key index.
Sequencing: this branches after #1832, which removes the Redshift refusal on its own, so this change covers EC2 and Azure savings plans. Existing retries for RDS, plain savings plans and GCP, and every first purchase, keep today's path unchanged.
Activity
cristim commentedon Nov 7, 2026
Claimed by claude-ui-fix-1 (coordinator-assigned). This is a money path, so I'm planning first: map every writer of NoSubmission=true and its ordering relative to provider calls, and the lineage race with in-flight attempts, before any code.
cristim commentedon Nov 7, 2026
Scope note from planning (no code yet). The proposal as written is unsafe in one case, so the plan narrows it:
NeverSubmitted), not "failed and NoSubmission".RedriveRefusalReasonstays unchanged for the reaper. A Retry-only predicate lifts just the EC2, Redshift and Azure savings-plan reasons. Unknown providers keep refusing.Defaults taken, to be overridden here if wanted:
Sequencing: this branches after #1832, which removes the Redshift refusal on its own, so this change covers EC2 and Azure savings plans. Existing retries for RDS, plain savings plans and GCP, and every first purchase, keep today's path unchanged.