Deferred half of #632. PR #635 recovers stranded approved executions by failing them (safe-fail), because commitment creation has no idempotency token: EC2 PurchaseReservedInstancesOffering sets no ClientToken and CreateSavingsPlan has no idempotency field. Auto-re-driving a row interrupted after AWS created the commitment but before the row persisted would double-purchase.
To upgrade the recovery sweep from fail to idempotent auto-re-drive (so a stranded approval completes automatically instead of needing operator Retry):
- Thread a deterministic
ClientToken through the EC2 RI purchase path (derive from execution_id + rec index so a re-drive reuses the same token).
- Add a dedupe guard for Savings Plans (no native idempotency): before
CreateSavingsPlan, check for an existing SP matching the execution's intent within a recent window, or persist an intent marker keyed by execution_id.
- Once both exist, change
RecoverStrandedApprovals to re-drive (idempotently) rather than fail.
Until then, #635's safe-fail + Retry is the correct conservative behaviour.
Deferred half of #632. PR #635 recovers stranded
approvedexecutions by failing them (safe-fail), because commitment creation has no idempotency token: EC2PurchaseReservedInstancesOfferingsets noClientTokenandCreateSavingsPlanhas no idempotency field. Auto-re-driving a row interrupted after AWS created the commitment but before the row persisted would double-purchase.To upgrade the recovery sweep from fail to idempotent auto-re-drive (so a stranded approval completes automatically instead of needing operator Retry):
ClientTokenthrough the EC2 RI purchase path (derive from execution_id + rec index so a re-drive reuses the same token).CreateSavingsPlan, check for an existing SP matching the execution's intent within a recent window, or persist an intent marker keyed by execution_id.RecoverStrandedApprovalsto re-drive (idempotently) rather than fail.Until then, #635's safe-fail + Retry is the correct conservative behaviour.