diff --git a/.changeset/restore-replayed-assertion-fresh-create-media-buy.md b/.changeset/restore-replayed-assertion-fresh-create-media-buy.md new file mode 100644 index 0000000000..e42dee599b --- /dev/null +++ b/.changeset/restore-replayed-assertion-fresh-create-media-buy.md @@ -0,0 +1,4 @@ +--- +--- + +Restore positive `replayed` assertion on the fresh-path `create_media_buy_initial` step in `universal/idempotency.yaml`, now using the `field_value_or_absent` matcher (documented in #3032, shipped in `@adcp/client` 5.16.0). Fresh execution MAY omit `replayed` per `protocol-envelope.json`, but if present it MUST be `false` — this closes the coverage gap opened in #3013 without penalizing spec-correct agents that omit the field. diff --git a/static/compliance/source/universal/idempotency.yaml b/static/compliance/source/universal/idempotency.yaml index 2f97e4b3c0..9bed60fdb6 100644 --- a/static/compliance/source/universal/idempotency.yaml +++ b/static/compliance/source/universal/idempotency.yaml @@ -270,14 +270,10 @@ phases: - check: field_present path: "media_buy_id" description: "Agent returns a media_buy_id for the initial request" - # NOTE: intentionally NO assertion on `replayed` here. Per - # `protocol-envelope.json`, fresh execution MAY omit the field, - # and `@adcp/client` >= 5.14 omits it (see adcp-client#859). - # The replay step below asserts `replayed: true` on the - # cached replay, which is the real regression surface. A - # fresh-path `field_value allowed_values: [false]` assertion - # has no `field_absent`-tolerant form today and would fail - # spec-correct agents. + - check: field_value_or_absent + path: "replayed" + allowed_values: [false] + description: "If replayed is present on fresh execution, it MUST be false (protocol-envelope.json)" - check: field_present path: "context"