Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/measurement-terms-rejected-narrative.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"adcontextprotocol": patch
---

fix(compliance): `measurement_terms_rejected` — UUID-aliased idempotency_keys + spec-aligned narrative

The `media_buy_seller/measurement_terms_rejected` storyboard shipped hardcoded `idempotency_key` literals on both `create_media_buy` steps. Combined with runner-side dynamic `start_time` substitution (the runner shifts stale dates forward to keep the buy future-dated), this produced **same key + different body** on every run against a long-running seller deployment, arming the spec-mandated `IDEMPOTENCY_CONFLICT` on the seller side. Switch to `$generate:uuid_v4#…` aliases so each run mints fresh keys (matches the established pattern across the storyboard suite).

Also rewrites the narrative, which previously told implementers the buyer "retries the same `create_media_buy` `idempotency_key` with an adjusted payload" — a direct spec violation — to describe minting a fresh key for the retry.

Closes #4219. Refs adcontextprotocol/adcp-client#1586.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ narrative: |
measurement_terms negotiation is a round-trip. The buyer proposes a measurement vendor,
window, and variance tolerance on each package; the seller either accepts (returning
measurement_terms echoed in the response) or rejects with TERMS_REJECTED and a message
explaining what is unacceptable. The buyer corrects the terms and retries the same
create_media_buy idempotency_key with an adjusted payload.
explaining what is unacceptable. The buyer mints a fresh idempotency_key and retries
create_media_buy with the adjusted payload — reusing the prior key against a different
body MUST be rejected with IDEMPOTENCY_CONFLICT per spec.

This scenario sends an intentionally aggressive first proposal (max_variance_percent: 0
with a window the seller does not guarantee), verifies the seller rejects with
Expand Down Expand Up @@ -105,7 +106,7 @@ phases:
brand:
domain: "acmeoutdoor.example"
operator: "pinnacle-agency.example"
idempotency_key: "measurement-terms-probe-aggressive-v1"
idempotency_key: "$generate:uuid_v4#measurement_terms_rejected_aggressive_terms"
start_time: "2026-05-01T00:00:00Z"
end_time: "2026-05-31T23:59:59Z"
packages:
Expand Down Expand Up @@ -162,7 +163,7 @@ phases:
brand:
domain: "acmeoutdoor.example"
operator: "pinnacle-agency.example"
idempotency_key: "measurement-terms-probe-relaxed-v1"
idempotency_key: "$generate:uuid_v4#measurement_terms_rejected_relaxed_terms"
start_time: "2026-05-01T00:00:00Z"
end_time: "2026-05-31T23:59:59Z"
packages:
Expand Down
Loading