#1713 gates the user-facing Retry at creation time, which stops new duplicate Azure savings-plan purchases. It does not defuse successors created before that fix landed.
An execution with RetryAttemptN > 0 for an Azure savings-plans recommendation, already sitting in pending, notified or approved, will still purchase when approved. Neither executor consults re-drive safety:
claimAndExecute (internal/purchase/manager.go:179)
ApproveAndExecute (internal/purchase/approvals.go:332)
That is correct as general behaviour — both must allow a first savings-plan purchase, and a blanket re-drive gate there would block legitimate buys. The gap is specifically the successor rows that a pre-fix retry already created.
Why this is not a defect in #1713
#1713 stops the ongoing bleed and is the right scope for #1668. This issue covers the rows already in flight, which no creation-time gate can reach.
Suggested fix
Gate at the executor on the conjunction, not on re-drive safety alone:
RetryAttemptN > 0 && RedriveRefusalReason(exec) != ""
The RetryAttemptN > 0 term is what preserves first-purchase behaviour: a fresh execution has no retry lineage, so it is unaffected. Reuse purchase.RedriveRefusalReason introduced by #1713 — do not add a second predicate.
Apply it at both executors, since either can reach a successor row.
Operational check, worth doing before the code fix
Determine whether any such rows exist right now. Something equivalent to:
SELECT execution_id, plan_id, status, retry_attempt_n, scheduled_date
FROM purchase_executions
WHERE retry_attempt_n > 0
AND status IN ('pending','notified','approved')
AND recommendations::text ILIKE '%savingsplans%';
Confirm the column names against the current schema before running; the intent is retried, not-yet-executed rows whose recommendations include an Azure savings plan. If any exist, they are armed to buy a second uncancellable commitment on approval, and that is worth handling directly rather than waiting for the code fix.
Regression test
An Azure savings-plans execution with RetryAttemptN > 0 in approved, driven through ApproveAndExecute, asserting no provider purchase call. Plus the negative control: the same recommendation with RetryAttemptN == 0 must still purchase exactly once, so the fix cannot be mistaken for blocking first buys.
Found during the independent adversarial review of #1713. Not verified against production data: whether any matching rows actually exist is unknown from here.
#1713 gates the user-facing Retry at creation time, which stops new duplicate Azure savings-plan purchases. It does not defuse successors created before that fix landed.
An execution with
RetryAttemptN > 0for an Azure savings-plans recommendation, already sitting inpending,notifiedorapproved, will still purchase when approved. Neither executor consults re-drive safety:claimAndExecute(internal/purchase/manager.go:179)ApproveAndExecute(internal/purchase/approvals.go:332)That is correct as general behaviour — both must allow a first savings-plan purchase, and a blanket re-drive gate there would block legitimate buys. The gap is specifically the successor rows that a pre-fix retry already created.
Why this is not a defect in #1713
#1713 stops the ongoing bleed and is the right scope for #1668. This issue covers the rows already in flight, which no creation-time gate can reach.
Suggested fix
Gate at the executor on the conjunction, not on re-drive safety alone:
The
RetryAttemptN > 0term is what preserves first-purchase behaviour: a fresh execution has no retry lineage, so it is unaffected. Reusepurchase.RedriveRefusalReasonintroduced by #1713 — do not add a second predicate.Apply it at both executors, since either can reach a successor row.
Operational check, worth doing before the code fix
Determine whether any such rows exist right now. Something equivalent to:
Confirm the column names against the current schema before running; the intent is retried, not-yet-executed rows whose recommendations include an Azure savings plan. If any exist, they are armed to buy a second uncancellable commitment on approval, and that is worth handling directly rather than waiting for the code fix.
Regression test
An Azure savings-plans execution with
RetryAttemptN > 0inapproved, driven throughApproveAndExecute, asserting no provider purchase call. Plus the negative control: the same recommendation withRetryAttemptN == 0must still purchase exactly once, so the fix cannot be mistaken for blocking first buys.Found during the independent adversarial review of #1713. Not verified against production data: whether any matching rows actually exist is unknown from here.