Background
#4218 (closes #4219) switched the two create_media_buy steps in media_buy_seller/measurement_terms_rejected from hardcoded literal idempotency_key values to $generate:uuid_v4#… aliases. The motivation: hardcoded literals collide cross-run because the runner shifts dynamic start_time substitutions forward to keep the buy future-dated, so against a long-running seller each run produces same key + different canonical body → seller correctly arms IDEMPOTENCY_CONFLICT.
That fix solved the symptom in measurement_terms_rejected, but the same pattern exists in 15 other storyboard steps across 9 scenarios that still use hardcoded literals.
Concrete impact (production seller)
A live media_buy_seller storyboard run against a salesagent deployment that recently rolled out a fix to its CreateMediaBuyResponse shape (variant-1 vs variant-3 split for sync-create-with-pending-creatives) had ALL 5 of its create_buy* storyboard scenarios fail with stale-cache replay errors:
mcp_error: Output validation error: 'submitted' is not one of [...]
The pre-fix runs had populated the seller's IdempotencyStore with the OLD (now-spec-non-compliant) variant-3 responses under those static keys. Post-fix runs replay the stale cached payloads instead of writing fresh ones, blocking 5 stateful chains and cascading into ~43 dependent skipped steps.
Affected scenarios + keys (from compliance/cache/3.0.7/domains/media-buy/scenarios/*.yaml)
| Scenario |
Hardcoded idempotency_key |
creative_fate_after_cancellation |
creative-fate-setup-create-buy-v1 |
creative_fate_after_cancellation |
creative-fate-setup-sync-v1 |
creative_fate_after_cancellation |
creative-fate-cancel-v1 |
creative_fate_after_cancellation |
creative-fate-second-buy-v1 |
creative_fate_after_cancellation |
creative-fate-reassign-v1 |
governance_approved |
comply-gov-approved-sync-plans-v1 |
governance_conditions |
comply-gov-conditions-sync-plans-v1 |
governance_denied |
comply-gov-denied-sync-plans-v1 |
governance_denied_recovery |
comply-gov-recovery-sync-plans-v1 |
governance_denied_recovery |
gov-recovery-initial-denied-v1 |
governance_denied_recovery |
gov-recovery-retry-approved-v1 |
invalid_transitions |
invalid-transitions-setup-v1 |
inventory_list_no_match |
inventory-list-no-match-v1 |
inventory_list_targeting |
inventory-list-targeting-create-v1 |
pending_creatives_to_start |
pending-creatives-transition-v1 |
15 hardcoded keys total, all on create_media_buy / sync_creatives / update_media_buy steps that mutate state.
Proposed fix
Same pattern as #4218: replace each hardcoded literal with $generate:uuid_v4#<scenario>--<step> so each storyboard run mints fresh keys and never collides cross-run with stale cached state.
Why this matters beyond the symptom
The runner's stale-cache replay is correct seller behavior — the spec mandates that an idempotency_key replay returns the cached response. But in practice, any time the spec or seller's emit shape changes (which happens whenever AdCP versions roll forward), every storyboard scenario with a static key becomes a one-shot landmine: works on first run, breaks on every run after the seller updates. The $generate:uuid_v4 pattern is the systemic prevention.
Same reasoning #4218 used. Asking to extend the fix.
Related
Background
#4218 (closes #4219) switched the two
create_media_buysteps inmedia_buy_seller/measurement_terms_rejectedfrom hardcoded literalidempotency_keyvalues to$generate:uuid_v4#…aliases. The motivation: hardcoded literals collide cross-run because the runner shifts dynamicstart_timesubstitutions forward to keep the buy future-dated, so against a long-running seller each run produces same key + different canonical body → seller correctly armsIDEMPOTENCY_CONFLICT.That fix solved the symptom in
measurement_terms_rejected, but the same pattern exists in 15 other storyboard steps across 9 scenarios that still use hardcoded literals.Concrete impact (production seller)
A live
media_buy_sellerstoryboard run against a salesagent deployment that recently rolled out a fix to itsCreateMediaBuyResponseshape (variant-1 vs variant-3 split for sync-create-with-pending-creatives) had ALL 5 of itscreate_buy*storyboard scenarios fail with stale-cache replay errors:The pre-fix runs had populated the seller's
IdempotencyStorewith the OLD (now-spec-non-compliant) variant-3 responses under those static keys. Post-fix runs replay the stale cached payloads instead of writing fresh ones, blocking 5 stateful chains and cascading into ~43 dependent skipped steps.Affected scenarios + keys (from
compliance/cache/3.0.7/domains/media-buy/scenarios/*.yaml)creative_fate_after_cancellationcreative-fate-setup-create-buy-v1creative_fate_after_cancellationcreative-fate-setup-sync-v1creative_fate_after_cancellationcreative-fate-cancel-v1creative_fate_after_cancellationcreative-fate-second-buy-v1creative_fate_after_cancellationcreative-fate-reassign-v1governance_approvedcomply-gov-approved-sync-plans-v1governance_conditionscomply-gov-conditions-sync-plans-v1governance_deniedcomply-gov-denied-sync-plans-v1governance_denied_recoverycomply-gov-recovery-sync-plans-v1governance_denied_recoverygov-recovery-initial-denied-v1governance_denied_recoverygov-recovery-retry-approved-v1invalid_transitionsinvalid-transitions-setup-v1inventory_list_no_matchinventory-list-no-match-v1inventory_list_targetinginventory-list-targeting-create-v1pending_creatives_to_startpending-creatives-transition-v115 hardcoded keys total, all on
create_media_buy/sync_creatives/update_media_buysteps that mutate state.Proposed fix
Same pattern as #4218: replace each hardcoded literal with
$generate:uuid_v4#<scenario>--<step>so each storyboard run mints fresh keys and never collides cross-run with stale cached state.Why this matters beyond the symptom
The runner's stale-cache replay is correct seller behavior — the spec mandates that an idempotency_key replay returns the cached response. But in practice, any time the spec or seller's emit shape changes (which happens whenever AdCP versions roll forward), every storyboard scenario with a static key becomes a one-shot landmine: works on first run, breaks on every run after the seller updates. The
$generate:uuid_v4pattern is the systemic prevention.Same reasoning #4218 used. Asking to extend the fix.
Related
measurement_terms_rejected)