From 9c5ef74825837bb54bb31b7a684d25e0aa5c5397 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sat, 17 Oct 2026 19:49:31 +0200 Subject: [PATCH] feat(common): add PurchaseOptions.RequestedAt for token-less idempotency lookups Redshift reserved nodes are not taggable and PurchaseReservedNodeOffering takes no client token, so the tag-based duplicate guard cannot work (#509, platform#702 option C). The replacement matches an existing owned node by offering, count and start time, which needs a lower bound: the first-dispatch time of the purchase lineage. Add RequestedAt to PurchaseOptions. It is stable across re-drives; zero means unknown and a provider that requires it must refuse rather than guess. Additive only: no behavior change here, and every PurchaseOptions literal in this repo and the cli, mcp and platform checkouts is keyed. The Redshift client consumes it in a follow-up PR. Refs #509 Co-Authored-By: Claude Opus 5.5 --- pkg/common/types.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/common/types.go b/pkg/common/types.go index 120f2811..203c399d 100644 --- a/pkg/common/types.go +++ b/pkg/common/types.go @@ -423,6 +423,12 @@ type PurchaseOptions struct { // defaults to "convertible" to preserve pre-694 behavior. // Only meaningful for EC2 RI purchases; ignored by other providers. OfferingClass string + // RequestedAt is the first-dispatch time of this purchase lineage, stable + // across re-drives of the same IdempotencyToken. Providers use it to bound + // idempotency lookups for services that have no client token (Redshift + // reserved nodes). A zero value means unknown; a provider that requires it + // must refuse the purchase rather than guess. + RequestedAt time.Time } // NormalizeSource lowercases s and returns it when it matches an allowed