@adcp/sdk 7.10.2 → 7.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/compliance/cache/3.1.0-rc.2/domains/brand/index.yaml +160 -0
  2. package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/distributed_brand_resolution.yaml +415 -0
  3. package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/single_side_trust_extension.yaml +454 -0
  4. package/compliance/cache/3.1.0-rc.2/domains/creative/index.yaml +339 -0
  5. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/billing_out_of_band.yaml +153 -0
  6. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/canonical_supported_formats.yaml +212 -0
  7. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
  8. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/native_in_feed.yaml +543 -0
  9. package/compliance/cache/3.1.0-rc.2/domains/governance/index.yaml +682 -0
  10. package/compliance/cache/3.1.0-rc.2/domains/media-buy/index.yaml +789 -0
  11. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/audience_buy_flow.yaml +380 -0
  12. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/available_actions.yaml +565 -0
  13. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
  14. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/canonical_formats.yaml +861 -0
  15. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
  16. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
  17. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/create_media_buy_async.yaml +234 -0
  18. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
  19. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_reception.yaml +247 -0
  20. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/delivery_reporting.yaml +357 -0
  21. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment.yaml +633 -0
  22. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
  23. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/event_dedup_flow.yaml +399 -0
  24. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
  25. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_approved.yaml +214 -0
  26. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_conditions.yaml +199 -0
  27. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied.yaml +204 -0
  28. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
  29. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/invalid_transitions.yaml +289 -0
  30. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
  31. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
  32. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_accountability.yaml +244 -0
  33. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
  34. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
  35. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
  36. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
  37. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow.yaml +428 -0
  38. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
  39. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/product_signal_targeting.yaml +373 -0
  40. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize.yaml +399 -0
  41. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
  42. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
  43. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
  44. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_enforcement.yaml +517 -0
  45. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
  46. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/reach_buy_flow.yaml +823 -0
  47. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
  48. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_products.yaml +148 -0
  49. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
  50. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
  51. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
  52. package/compliance/cache/3.1.0-rc.2/domains/media-buy/state-machine.yaml +442 -0
  53. package/compliance/cache/3.1.0-rc.2/domains/signals/index.yaml +266 -0
  54. package/compliance/cache/3.1.0-rc.2/domains/sponsored-intelligence/index.yaml +256 -0
  55. package/compliance/cache/3.1.0-rc.2/index.json +356 -0
  56. package/compliance/cache/3.1.0-rc.2/protocols/brand/index.yaml +160 -0
  57. package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/distributed_brand_resolution.yaml +415 -0
  58. package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/single_side_trust_extension.yaml +454 -0
  59. package/compliance/cache/3.1.0-rc.2/protocols/creative/index.yaml +339 -0
  60. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/billing_out_of_band.yaml +153 -0
  61. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/canonical_supported_formats.yaml +212 -0
  62. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
  63. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/native_in_feed.yaml +543 -0
  64. package/compliance/cache/3.1.0-rc.2/protocols/governance/index.yaml +682 -0
  65. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/index.yaml +789 -0
  66. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/audience_buy_flow.yaml +380 -0
  67. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/available_actions.yaml +565 -0
  68. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
  69. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/canonical_formats.yaml +861 -0
  70. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
  71. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
  72. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/create_media_buy_async.yaml +234 -0
  73. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
  74. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_reception.yaml +247 -0
  75. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/delivery_reporting.yaml +357 -0
  76. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment.yaml +633 -0
  77. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
  78. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/event_dedup_flow.yaml +399 -0
  79. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
  80. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_approved.yaml +214 -0
  81. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_conditions.yaml +199 -0
  82. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied.yaml +204 -0
  83. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
  84. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/invalid_transitions.yaml +289 -0
  85. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
  86. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
  87. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_accountability.yaml +244 -0
  88. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
  89. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
  90. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
  91. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
  92. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow.yaml +428 -0
  93. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
  94. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/product_signal_targeting.yaml +373 -0
  95. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize.yaml +399 -0
  96. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
  97. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
  98. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
  99. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_enforcement.yaml +517 -0
  100. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
  101. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/reach_buy_flow.yaml +823 -0
  102. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
  103. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_products.yaml +148 -0
  104. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
  105. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
  106. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
  107. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/state-machine.yaml +442 -0
  108. package/compliance/cache/3.1.0-rc.2/protocols/signals/index.yaml +266 -0
  109. package/compliance/cache/3.1.0-rc.2/protocols/sponsored-intelligence/index.yaml +256 -0
  110. package/compliance/cache/3.1.0-rc.2/specialisms/audience-sync/index.yaml +313 -0
  111. package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/index.yaml +350 -0
  112. package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/scenarios/governance_denied.yaml +226 -0
  113. package/compliance/cache/3.1.0-rc.2/specialisms/collection-lists/index.yaml +359 -0
  114. package/compliance/cache/3.1.0-rc.2/specialisms/content-standards/index.yaml +572 -0
  115. package/compliance/cache/3.1.0-rc.2/specialisms/creative-ad-server/index.yaml +409 -0
  116. package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/generative-seller.yaml +807 -0
  117. package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/index.yaml +758 -0
  118. package/compliance/cache/3.1.0-rc.2/specialisms/creative-template/index.yaml +510 -0
  119. package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/index.yaml +143 -0
  120. package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +117 -0
  121. package/compliance/cache/3.1.0-rc.2/specialisms/governance-delivery-monitor/index.yaml +441 -0
  122. package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/denied.yaml +221 -0
  123. package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/index.yaml +330 -0
  124. package/compliance/cache/3.1.0-rc.2/specialisms/property-lists/index.yaml +482 -0
  125. package/compliance/cache/3.1.0-rc.2/specialisms/sales-broadcast-tv/index.yaml +738 -0
  126. package/compliance/cache/3.1.0-rc.2/specialisms/sales-catalog-driven/index.yaml +840 -0
  127. package/compliance/cache/3.1.0-rc.2/specialisms/sales-guaranteed/index.yaml +601 -0
  128. package/compliance/cache/3.1.0-rc.2/specialisms/sales-non-guaranteed/index.yaml +546 -0
  129. package/compliance/cache/3.1.0-rc.2/specialisms/sales-proposal-mode/index.yaml +586 -0
  130. package/compliance/cache/3.1.0-rc.2/specialisms/sales-social/index.yaml +919 -0
  131. package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/index.yaml +424 -0
  132. package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/scenarios/governance_denied.yaml +210 -0
  133. package/compliance/cache/3.1.0-rc.2/specialisms/signal-owned/index.yaml +317 -0
  134. package/compliance/cache/3.1.0-rc.2/specialisms/sponsored-intelligence/index.yaml +59 -0
  135. package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor-live.yaml +78 -0
  136. package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor.yaml +223 -0
  137. package/compliance/cache/3.1.0-rc.2/test-kits/billing-gate-runner.yaml +115 -0
  138. package/compliance/cache/3.1.0-rc.2/test-kits/bistro-oranje.yaml +126 -0
  139. package/compliance/cache/3.1.0-rc.2/test-kits/distributed-brand-runner.yaml +281 -0
  140. package/compliance/cache/3.1.0-rc.2/test-kits/nova-motors.yaml +262 -0
  141. package/compliance/cache/3.1.0-rc.2/test-kits/osei-natural.yaml +126 -0
  142. package/compliance/cache/3.1.0-rc.2/test-kits/parallel-dispatch-runner.yaml +196 -0
  143. package/compliance/cache/3.1.0-rc.2/test-kits/rate-limit-trip-runner.yaml +172 -0
  144. package/compliance/cache/3.1.0-rc.2/test-kits/signed-requests-runner.yaml +155 -0
  145. package/compliance/cache/3.1.0-rc.2/test-kits/single-side-trust-runner.yaml +294 -0
  146. package/compliance/cache/3.1.0-rc.2/test-kits/substitution-observer-runner.yaml +688 -0
  147. package/compliance/cache/3.1.0-rc.2/test-kits/summit-foods.yaml +125 -0
  148. package/compliance/cache/3.1.0-rc.2/test-kits/webhook-receiver-runner.yaml +265 -0
  149. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/001-minimal-plan.json +43 -0
  150. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/002-full-plan.json +217 -0
  151. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
  152. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
  153. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
  154. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
  155. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
  156. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
  157. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
  158. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
  159. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
  160. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/README.md +220 -0
  161. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/canonicalization.json +241 -0
  162. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/keys.json +60 -0
  163. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
  164. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
  165. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
  166. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
  167. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
  168. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
  169. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
  170. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
  171. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
  172. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
  173. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
  174. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
  175. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
  176. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
  177. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
  178. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
  179. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
  180. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
  181. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
  182. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
  183. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
  184. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
  185. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
  186. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
  187. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
  188. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
  189. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
  190. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +26 -0
  191. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/001-basic-post.json +30 -0
  192. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
  193. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/003-es256-post.json +30 -0
  194. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
  195. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
  196. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
  197. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
  198. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
  199. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
  200. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
  201. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
  202. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
  203. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/README.md +211 -0
  204. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/keys.json +61 -0
  205. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
  206. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
  207. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
  208. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
  209. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
  210. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
  211. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
  212. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
  213. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
  214. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
  215. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
  216. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
  217. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
  218. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
  219. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
  220. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
  221. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
  222. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
  223. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
  224. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
  225. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
  226. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
  227. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
  228. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
  229. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
  230. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
  231. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
  232. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
  233. package/compliance/cache/3.1.0-rc.2/universal/billing-gate-dispatch.yaml +450 -0
  234. package/compliance/cache/3.1.0-rc.2/universal/canonical-format-validate-input.yaml +640 -0
  235. package/compliance/cache/3.1.0-rc.2/universal/capability-discovery.yaml +125 -0
  236. package/compliance/cache/3.1.0-rc.2/universal/collection-lists-pagination-integrity.yaml +306 -0
  237. package/compliance/cache/3.1.0-rc.2/universal/comply-controller-mode-gate.yaml +141 -0
  238. package/compliance/cache/3.1.0-rc.2/universal/content-standards-pagination-integrity.yaml +326 -0
  239. package/compliance/cache/3.1.0-rc.2/universal/deterministic-testing.yaml +1430 -0
  240. package/compliance/cache/3.1.0-rc.2/universal/error-compliance-signals.yaml +377 -0
  241. package/compliance/cache/3.1.0-rc.2/universal/error-compliance.yaml +528 -0
  242. package/compliance/cache/3.1.0-rc.2/universal/fictional-entities.yaml +307 -0
  243. package/compliance/cache/3.1.0-rc.2/universal/get-media-buys-pagination-integrity.yaml +160 -0
  244. package/compliance/cache/3.1.0-rc.2/universal/get-signals-pagination-integrity.yaml +210 -0
  245. package/compliance/cache/3.1.0-rc.2/universal/idempotency.yaml +861 -0
  246. package/compliance/cache/3.1.0-rc.2/universal/notification-config-event-scope.yaml +119 -0
  247. package/compliance/cache/3.1.0-rc.2/universal/notification-config-lifecycle.yaml +337 -0
  248. package/compliance/cache/3.1.0-rc.2/universal/notification-config-rejections.yaml +107 -0
  249. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-creative-formats.yaml +265 -0
  250. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-list-accounts.yaml +245 -0
  251. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity.yaml +263 -0
  252. package/compliance/cache/3.1.0-rc.2/universal/property-lists-pagination-integrity.yaml +307 -0
  253. package/compliance/cache/3.1.0-rc.2/universal/read-tool-idempotency.yaml +405 -0
  254. package/compliance/cache/3.1.0-rc.2/universal/runner-output-contract.yaml +1285 -0
  255. package/compliance/cache/3.1.0-rc.2/universal/schema-validation-signals.yaml +181 -0
  256. package/compliance/cache/3.1.0-rc.2/universal/schema-validation.yaml +548 -0
  257. package/compliance/cache/3.1.0-rc.2/universal/security.yaml +539 -0
  258. package/compliance/cache/3.1.0-rc.2/universal/signed-requests.yaml +217 -0
  259. package/compliance/cache/3.1.0-rc.2/universal/stale-response-advisory.yaml +295 -0
  260. package/compliance/cache/3.1.0-rc.2/universal/storyboard-schema.yaml +2194 -0
  261. package/compliance/cache/3.1.0-rc.2/universal/v3-envelope-integrity.yaml +117 -0
  262. package/compliance/cache/3.1.0-rc.2/universal/version-negotiation.yaml +130 -0
  263. package/compliance/cache/3.1.0-rc.2/universal/webhook-emission.yaml +411 -0
  264. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-bulk-webhooks.yaml +82 -0
  265. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-product-webhooks.yaml +83 -0
  266. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-products.yaml +151 -0
  267. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signal-webhooks.yaml +83 -0
  268. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signals.yaml +149 -0
  269. package/dist/lib/index.d.ts +1 -1
  270. package/dist/lib/index.d.ts.map +1 -1
  271. package/dist/lib/index.js +9 -5
  272. package/dist/lib/index.js.map +1 -1
  273. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  274. package/dist/lib/testing/storyboard/default-invariants.js +30 -1
  275. package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
  276. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  277. package/dist/lib/testing/storyboard/runner.js +84 -21
  278. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  279. package/dist/lib/testing/storyboard/types.d.ts +21 -0
  280. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  281. package/dist/lib/testing/storyboard/types.js.map +1 -1
  282. package/dist/lib/testing/types.d.ts +9 -0
  283. package/dist/lib/testing/types.d.ts.map +1 -1
  284. package/dist/lib/types/schemas.generated.d.ts +6707 -12040
  285. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  286. package/dist/lib/types/schemas.generated.js +1 -1
  287. package/dist/lib/types/schemas.generated.js.map +1 -1
  288. package/dist/lib/utils/signal-id-builders.d.ts +19 -0
  289. package/dist/lib/utils/signal-id-builders.d.ts.map +1 -1
  290. package/dist/lib/utils/signal-id-builders.js +30 -0
  291. package/dist/lib/utils/signal-id-builders.js.map +1 -1
  292. package/dist/lib/utils/tool-request-schemas.d.ts.map +1 -1
  293. package/dist/lib/utils/tool-request-schemas.js +3 -0
  294. package/dist/lib/utils/tool-request-schemas.js.map +1 -1
  295. package/dist/lib/v2/projection/constants.d.ts +28 -0
  296. package/dist/lib/v2/projection/constants.d.ts.map +1 -0
  297. package/dist/lib/v2/projection/constants.js +31 -0
  298. package/dist/lib/v2/projection/constants.js.map +1 -0
  299. package/dist/lib/v2/projection/registry.d.ts.map +1 -1
  300. package/dist/lib/v2/projection/registry.js +9 -4
  301. package/dist/lib/v2/projection/registry.js.map +1 -1
  302. package/dist/lib/version.d.ts +3 -3
  303. package/dist/lib/version.js +3 -3
  304. package/package.json +1 -1
  305. package/skills/SHAPE-GOTCHAS.md +5 -0
@@ -0,0 +1,360 @@
1
+ id: media_buy_seller/refine_finalize_exclusivity
2
+ version: "1.0.0"
3
+ title: "Seller enforces refine[] finalize-exclusivity and MULTI_FINALIZE_UNSUPPORTED"
4
+ category: media_buy_seller
5
+ summary: "Validates that sellers reject mixed-finalize requests (INVALID_REQUEST), structurally-invalid finalize entries, and handle multi-proposal finalize atomically or reject with MULTI_FINALIZE_UNSUPPORTED."
6
+ track: media_buy
7
+ required_tools:
8
+ - get_products
9
+
10
+ requires_capability:
11
+ path: media_buy.supports_proposals
12
+ equals: true
13
+
14
+ narrative: |
15
+ Issue #4107 clarified finalize-exclusivity semantics for refine[]: if any entry carries
16
+ action: "finalize", the entire array must consist exclusively of proposal-scoped finalize
17
+ entries. Mixing finalize with request- or product-scoped entries, or with include/omit
18
+ actions, is a business-rule violation. Current proposal storyboards exercise only the
19
+ happy-path finalize flow; this scenario covers the three normative negative cases.
20
+
21
+ 1. Mixed finalize + non-finalize — one proposal-scoped finalize entry combined with a
22
+ request-scoped entry in the same refine[] call. Each entry is individually schema-valid;
23
+ the combination violates the exclusivity rule. The seller must reject with INVALID_REQUEST
24
+ before any state changes and should populate error.field identifying the offending entry.
25
+
26
+ 2. Non-proposal-scoped finalize — a product-scoped entry carrying action: "finalize".
27
+ The schema's additionalProperties: false on the product variant makes this structurally
28
+ invalid (action: "finalize" is not in the product scope's action enum). The seller must
29
+ reject with INVALID_REQUEST.
30
+
31
+ 3. Multi-proposal finalize — two proposal-scoped finalize entries in one call. Sellers that
32
+ can guarantee atomic pre-commit validation handle this and commit all named proposals;
33
+ sellers that cannot MUST reject with MULTI_FINALIZE_UNSUPPORTED (preferred, distinguishes
34
+ capability gap from malformed request) or INVALID_REQUEST (acceptable fallback for
35
+ pre-3.1 error catalogs). This case uses a branch set: the storyboard accepts either
36
+ outcome from a conformant seller. Because both branches are optional and the runner
37
+ executes both, the branch that does not match the seller's behavior will fail its
38
+ validation step (tolerated as optional) while the matching branch contributes; the
39
+ gate asserts at least one contributed.
40
+
41
+ A second brief is attempted in the setup_second_proposal phase to capture a second
42
+ proposal_id. If the seller returns fewer than two proposals, all multi-finalize phases
43
+ skip gracefully via skip_if guards and the storyboard still passes on the two mandatory
44
+ cases.
45
+
46
+ agent:
47
+ interaction_model: media_buy_seller
48
+ capabilities:
49
+ - sells_media
50
+ - accepts_briefs
51
+ - generates_proposals
52
+ examples:
53
+ - "Full-service publisher with proposal engine"
54
+ - "Retail media network with curated packages"
55
+
56
+ caller:
57
+ role: buyer_agent
58
+ example: "Pinnacle Agency (buyer)"
59
+
60
+ prerequisites:
61
+ description: |
62
+ The seller must support proposal generation (media_buy.supports_proposals: true).
63
+ The Acme Outdoor test kit provides brand and operator credentials.
64
+ test_kit: "test-kits/acme-outdoor.yaml"
65
+
66
+ phases:
67
+ - id: setup
68
+ title: "Account setup and first proposal discovery"
69
+ steps:
70
+ - id: sync_accounts
71
+ title: "Establish account"
72
+ task: sync_accounts
73
+ schema_ref: "account/sync-accounts-request.json"
74
+ response_schema_ref: "account/sync-accounts-response.json"
75
+ doc_ref: "/accounts/tasks/sync_accounts"
76
+ stateful: true
77
+ expected: |
78
+ Return the account with account_id and status active.
79
+ sample_request:
80
+ accounts:
81
+ - brand:
82
+ domain: "acmeoutdoor.example"
83
+ operator: "pinnacle-agency.example"
84
+ billing: "operator"
85
+ payment_terms: "net_30"
86
+ idempotency_key: "$generate:uuid_v4#media_buy_seller_refine_finalize_exclusivity_setup_sync_accounts"
87
+ validations:
88
+ - check: response_schema
89
+ description: "Response matches sync-accounts-response.json schema"
90
+ - check: field_present
91
+ path: "accounts[0].account_id"
92
+ description: "Account has a platform-assigned ID"
93
+
94
+ - id: get_products_brief
95
+ title: "Request proposals — captures proposal_id_1 for mandatory error probes"
96
+ task: get_products
97
+ schema_ref: "media-buy/get-products-request.json"
98
+ response_schema_ref: "media-buy/get-products-response.json"
99
+ doc_ref: "/media-buy/task-reference/get_products"
100
+ comply_scenario: full_sales_flow
101
+ stateful: false
102
+ expected: |
103
+ Return at least one proposal with a proposal_id. proposal_id_1 is captured
104
+ here for the mandatory mixed-finalize and non-proposal-finalize error probes.
105
+ sample_request:
106
+ buying_mode: "brief"
107
+ brief: "Premium video and display across outdoor lifestyle and sports. Q2 flight, $50K budget. Adults 25-54, US and Canada."
108
+ account:
109
+ brand:
110
+ domain: "acmeoutdoor.example"
111
+ operator: "pinnacle-agency.example"
112
+ context_outputs:
113
+ - path: "proposals[0].proposal_id"
114
+ key: "proposal_id_1"
115
+ validations:
116
+ - check: response_schema
117
+ description: "Response matches get-products-response.json schema"
118
+ - check: field_present
119
+ path: "proposals[0].proposal_id"
120
+ description: "At least one proposal returned with an ID"
121
+
122
+ - id: setup_second_proposal
123
+ title: "Attempt second proposal capture for multi-finalize coverage"
124
+ optional: true
125
+ narrative: |
126
+ Sends a second brief to capture a second proposal_id for the multi-finalize branch
127
+ set. This phase is optional: if the seller returns fewer than two proposals, this
128
+ phase fails gracefully and all multi-finalize phases skip via skip_if guards. The
129
+ two mandatory error-probe phases (mixed_finalize_rejected, non_proposal_finalize_rejected)
130
+ are unaffected.
131
+ steps:
132
+ - id: get_products_brief_second
133
+ title: "Second brief to capture proposal_id_2"
134
+ task: get_products
135
+ schema_ref: "media-buy/get-products-request.json"
136
+ response_schema_ref: "media-buy/get-products-response.json"
137
+ doc_ref: "/media-buy/task-reference/get_products"
138
+ comply_scenario: full_sales_flow
139
+ stateful: false
140
+ expected: |
141
+ Return at least two proposals. proposals[1].proposal_id is captured as
142
+ proposal_id_2. If the seller returns only one proposal, this step fails
143
+ (tolerated — phase is optional), proposal_id_2 stays unset, and the
144
+ multi-finalize phases skip gracefully.
145
+ sample_request:
146
+ buying_mode: "brief"
147
+ brief: "Premium video and display across outdoor lifestyle and sports. Q2 flight, $50K budget. Adults 25-54, US and Canada."
148
+ account:
149
+ brand:
150
+ domain: "acmeoutdoor.example"
151
+ operator: "pinnacle-agency.example"
152
+ context_outputs:
153
+ - path: "proposals[1].proposal_id"
154
+ key: "proposal_id_2"
155
+ validations:
156
+ - check: field_present
157
+ path: "proposals[1].proposal_id"
158
+ description: "Second proposal present for multi-finalize test"
159
+
160
+ - id: mixed_finalize_rejected
161
+ title: "Mixed finalize rejected"
162
+ narrative: |
163
+ A refine[] array where one entry is a proposal-scoped finalize and another is a
164
+ request-scoped refinement. Each entry is individually schema-valid; their combination
165
+ violates the finalize-exclusivity rule. The seller must reject with INVALID_REQUEST
166
+ before any proposal state changes. Per issue #4107, the error response should include
167
+ error.field identifying which refine entry triggered the violation.
168
+
169
+ steps:
170
+ - id: get_products_mixed_finalize
171
+ title: "Finalize entry mixed with request-scoped entry"
172
+ task: get_products
173
+ schema_ref: "media-buy/get-products-request.json"
174
+ response_schema_ref: "media-buy/get-products-response.json"
175
+ doc_ref: "/media-buy/task-reference/get_products"
176
+ comply_scenario: full_sales_flow
177
+ expect_error: true
178
+ negative_path: payload_well_formed
179
+ stateful: true
180
+ expected: |
181
+ Reject with:
182
+ - code: INVALID_REQUEST
183
+ - error.field: pointing at the offending refine entry (e.g. "refine[0]",
184
+ "refine[1]", or "refine" — seller-chosen, any index that identifies
185
+ the violation is conformant)
186
+ No proposal state is changed; the finalize entry does not commit.
187
+ sample_request:
188
+ buying_mode: "refine"
189
+ refine:
190
+ - scope: "proposal"
191
+ proposal_id: "$context.proposal_id_1"
192
+ action: "finalize"
193
+ - scope: "request"
194
+ ask: "Also increase CTV budget allocation"
195
+ account:
196
+ brand:
197
+ domain: "acmeoutdoor.example"
198
+ operator: "pinnacle-agency.example"
199
+ validations:
200
+ - check: error_code
201
+ value: "INVALID_REQUEST"
202
+ description: "Mixed finalize + non-finalize refine[] rejected with INVALID_REQUEST"
203
+ - check: field_present
204
+ path: "errors[0].field"
205
+ description: "Seller populates error.field pointing at the offending refine entry"
206
+
207
+ - id: non_proposal_finalize_rejected
208
+ title: "Non-proposal finalize rejected"
209
+ narrative: |
210
+ A product-scoped refine entry carrying action: "finalize". The get-products-request
211
+ schema allows action: "finalize" only on the proposal-scoped variant; the product
212
+ variant defines action as "include" | "omit" | "more_like_this" with
213
+ additionalProperties: false. This is a structurally invalid payload — the runner
214
+ skips sample_request schema validation (negative_path: schema_invalid) and verifies
215
+ the seller returns INVALID_REQUEST rather than a 500 or silent acceptance.
216
+
217
+ The product_id value is a synthetic test sentinel; since the request fails at schema
218
+ validation before any product lookup, no fixture seeding is required.
219
+
220
+ steps:
221
+ - id: get_products_product_finalize
222
+ title: "Product-scoped entry with action: finalize"
223
+ task: get_products
224
+ schema_ref: "media-buy/get-products-request.json"
225
+ response_schema_ref: "media-buy/get-products-response.json"
226
+ doc_ref: "/media-buy/task-reference/get_products"
227
+ comply_scenario: full_sales_flow
228
+ expect_error: true
229
+ negative_path: schema_invalid
230
+ stateful: false
231
+ expected: |
232
+ Reject with INVALID_REQUEST. The schema prohibits action: "finalize" on
233
+ product-scoped entries; the seller must not silently ignore the field or
234
+ treat it as action: "include".
235
+ sample_request:
236
+ buying_mode: "refine"
237
+ refine:
238
+ - scope: "product"
239
+ product_id: "test-product-finalize-exclusivity-v1"
240
+ action: "finalize"
241
+ account:
242
+ brand:
243
+ domain: "acmeoutdoor.example"
244
+ operator: "pinnacle-agency.example"
245
+ validations:
246
+ - check: error_code
247
+ value: "INVALID_REQUEST"
248
+ description: "Product-scoped finalize entry rejected with INVALID_REQUEST"
249
+
250
+ - id: multi_finalize_atomic_path
251
+ title: "Multi-finalize handled atomically"
252
+ optional: true
253
+ branch_set:
254
+ id: multi_finalize_handled
255
+ semantics: any_of
256
+ skip_if: "!context.proposal_id_2"
257
+ narrative: |
258
+ The seller supports atomic multi-finalize: both proposals commit in a single call or
259
+ neither does. This branch passes when the seller returns a success response with both
260
+ proposals present. The spec requires atomicity at the observation point — the seller
261
+ must not return success unless every named proposal has been persisted as committed.
262
+
263
+ steps:
264
+ - id: get_products_multi_finalize_atomic
265
+ title: "Finalize two proposals in a single call — atomic success path"
266
+ task: get_products
267
+ schema_ref: "media-buy/get-products-request.json"
268
+ response_schema_ref: "media-buy/get-products-response.json"
269
+ doc_ref: "/media-buy/task-reference/get_products"
270
+ comply_scenario: full_sales_flow
271
+ stateful: true
272
+ contributes: true
273
+ expected: |
274
+ Return both proposals with committed status and expires_at hold windows.
275
+ Neither proposal is partially committed — the seller has run pre-commit
276
+ validation across all named proposals before returning success.
277
+ sample_request:
278
+ buying_mode: "refine"
279
+ refine:
280
+ - scope: "proposal"
281
+ proposal_id: "$context.proposal_id_1"
282
+ action: "finalize"
283
+ - scope: "proposal"
284
+ proposal_id: "$context.proposal_id_2"
285
+ action: "finalize"
286
+ account:
287
+ brand:
288
+ domain: "acmeoutdoor.example"
289
+ operator: "pinnacle-agency.example"
290
+ validations:
291
+ - check: response_schema
292
+ description: "Response matches get-products-response.json schema"
293
+ - check: field_present
294
+ path: "proposals"
295
+ description: "Response contains the finalized proposals"
296
+
297
+ - id: multi_finalize_unsupported_path
298
+ title: "Multi-finalize rejected with MULTI_FINALIZE_UNSUPPORTED"
299
+ optional: true
300
+ branch_set:
301
+ id: multi_finalize_handled
302
+ semantics: any_of
303
+ skip_if: "!context.proposal_id_2"
304
+ narrative: |
305
+ The seller cannot guarantee atomic pre-commit validation across multiple proposals.
306
+ Per the spec, such sellers MUST reject with MULTI_FINALIZE_UNSUPPORTED (preferred —
307
+ distinguishes seller-side capability gap from a malformed request) or INVALID_REQUEST
308
+ (acceptable fallback for sellers on a pre-3.1 error catalog). No proposal is committed.
309
+
310
+ Note: the runner executes both branch-set peers regardless of which succeeds. For
311
+ a seller that handled atomically in the sibling branch, this step will attempt to
312
+ finalize already-committed proposals and may receive a different error (e.g.
313
+ INVALID_STATE). That step failure is tolerated (optional branch); the atomic branch's
314
+ contribution is sufficient for the gate assertion.
315
+
316
+ steps:
317
+ - id: get_products_multi_finalize_unsupported
318
+ title: "Multi-finalize rejected by seller without atomic commit support"
319
+ task: get_products
320
+ schema_ref: "media-buy/get-products-request.json"
321
+ response_schema_ref: "media-buy/get-products-response.json"
322
+ doc_ref: "/media-buy/task-reference/get_products"
323
+ comply_scenario: full_sales_flow
324
+ expect_error: true
325
+ negative_path: payload_well_formed
326
+ stateful: true
327
+ contributes: true
328
+ expected: |
329
+ Reject with MULTI_FINALIZE_UNSUPPORTED (preferred) or INVALID_REQUEST
330
+ (acceptable fallback). No proposal is committed. Buyers receiving
331
+ MULTI_FINALIZE_UNSUPPORTED should sequence individual finalize calls.
332
+ sample_request:
333
+ buying_mode: "refine"
334
+ refine:
335
+ - scope: "proposal"
336
+ proposal_id: "$context.proposal_id_1"
337
+ action: "finalize"
338
+ - scope: "proposal"
339
+ proposal_id: "$context.proposal_id_2"
340
+ action: "finalize"
341
+ account:
342
+ brand:
343
+ domain: "acmeoutdoor.example"
344
+ operator: "pinnacle-agency.example"
345
+ validations:
346
+ - check: error_code
347
+ allowed_values: ["MULTI_FINALIZE_UNSUPPORTED", "INVALID_REQUEST"]
348
+ description: "Multi-finalize rejected with MULTI_FINALIZE_UNSUPPORTED or INVALID_REQUEST"
349
+
350
+ - id: multi_finalize_gate
351
+ title: "At least one multi-finalize path contributed"
352
+ skip_if: "!context.proposal_id_2"
353
+ steps:
354
+ - id: assert_multi_finalize
355
+ title: "Assert multi-finalize path contributed"
356
+ task: assert_contribution
357
+ validations:
358
+ - check: any_of
359
+ allowed_values: ["multi_finalize_handled"]
360
+ description: "Seller either handled multi-finalize atomically or rejected with MULTI_FINALIZE_UNSUPPORTED"
@@ -0,0 +1,148 @@
1
+ id: media_buy_seller/refine_products
2
+ version: "1.0.0"
3
+ title: "Seller handles product refinement"
4
+ category: media_buy_seller
5
+ summary: "Verifies that a media buy seller supports buying_mode: refine with product-level and request-level changes."
6
+ track: media_buy
7
+ required_tools:
8
+ - get_products
9
+
10
+ narrative: |
11
+ After a buyer receives products from a brief, they refine the results without starting
12
+ over. The buyer calls get_products with buying_mode: refine and a refine array describing
13
+ changes at the request level ("only guaranteed") or product level ("increase this product's
14
+ budget").
15
+
16
+ The seller must apply each refinement, return updated products, and include
17
+ refinement_applied showing how each request was handled. This is the standard negotiation
18
+ loop — brief, review, refine, repeat until satisfied.
19
+
20
+ Every media buy seller that supports negotiation (not just wholesale) must handle
21
+ product-level refinement.
22
+
23
+ agent:
24
+ interaction_model: media_buy_seller
25
+ capabilities:
26
+ - sells_media
27
+ - accepts_briefs
28
+ examples:
29
+ - "Any media buy seller that accepts briefs"
30
+
31
+ caller:
32
+ role: buyer_agent
33
+ example: "Pinnacle Agency (buyer)"
34
+
35
+ prerequisites:
36
+ description: |
37
+ The caller needs a brand identity and operator credentials.
38
+ test_kit: "test-kits/acme-outdoor.yaml"
39
+
40
+ phases:
41
+ - id: setup
42
+ title: "Account setup"
43
+ steps:
44
+ - id: sync_accounts
45
+ title: "Establish account"
46
+ task: sync_accounts
47
+ schema_ref: "account/sync-accounts-request.json"
48
+ response_schema_ref: "account/sync-accounts-response.json"
49
+ doc_ref: "/accounts/tasks/sync_accounts"
50
+ stateful: true
51
+ expected: |
52
+ Return the account with account_id and status active.
53
+
54
+ sample_request:
55
+ accounts:
56
+ - brand:
57
+ domain: "acmeoutdoor.example"
58
+ operator: "pinnacle-agency.example"
59
+ billing: "operator"
60
+ payment_terms: "net_30"
61
+
62
+ idempotency_key: "$generate:uuid_v4#media_buy_seller_refine_products_setup_sync_accounts"
63
+ validations:
64
+ - check: response_schema
65
+ description: "Response matches sync-accounts-response.json schema"
66
+ - check: field_present
67
+ path: "accounts[0].account_id"
68
+ description: "Account has a platform-assigned ID"
69
+
70
+ - id: brief
71
+ title: "Initial brief"
72
+ narrative: |
73
+ Send a brief to get the initial product set that the buyer will refine.
74
+
75
+ steps:
76
+ - id: get_products_brief
77
+ title: "Send a brief"
78
+ task: get_products
79
+ schema_ref: "media-buy/get-products-request.json"
80
+ response_schema_ref: "media-buy/get-products-response.json"
81
+ doc_ref: "/media-buy/task-reference/get_products"
82
+ comply_scenario: full_sales_flow
83
+ stateful: false
84
+ expected: |
85
+ Return products matching the brief. Each product should include product_id,
86
+ delivery_type, pricing_models, and forecast.
87
+
88
+ sample_request:
89
+ buying_mode: "brief"
90
+ brief: "Premium video and display on sports and outdoor lifestyle. Q2 flight, $50K budget. Adults 25-54, US and Canada."
91
+ account:
92
+ brand:
93
+ domain: "acmeoutdoor.example"
94
+ operator: "pinnacle-agency.example"
95
+
96
+ validations:
97
+ - check: response_schema
98
+ description: "Response matches get-products-response.json schema"
99
+ - check: field_present
100
+ path: "products"
101
+ description: "Response contains products"
102
+ - check: field_present
103
+ path: "products[0].product_id"
104
+ description: "Products have IDs"
105
+
106
+ - id: refine
107
+ title: "Refine products"
108
+ narrative: |
109
+ The buyer has reviewed the initial products and wants to narrow down. They call
110
+ get_products with buying_mode: refine and a refine array with request-level and
111
+ product-level changes. The seller applies each refinement and returns the updated
112
+ product set.
113
+
114
+ steps:
115
+ - id: get_products_refine
116
+ title: "Refine with request-level and product-level changes"
117
+ task: get_products
118
+ schema_ref: "media-buy/get-products-request.json"
119
+ response_schema_ref: "media-buy/get-products-response.json"
120
+ doc_ref: "/media-buy/task-reference/get_products"
121
+ comply_scenario: full_sales_flow
122
+ stateful: true
123
+ expected: |
124
+ Return updated products reflecting the refinements:
125
+ - Apply each refinement to the relevant scope (request or product)
126
+ - Include refinement_applied showing how each request was handled
127
+ - Preserve products that weren't targeted by refinements
128
+ - Update pricing and forecasts to reflect the changes
129
+
130
+ sample_request:
131
+ buying_mode: "refine"
132
+ refine:
133
+ - scope: "request"
134
+ ask: "Only guaranteed packages. Must include completion rate SLA above 80%."
135
+ - scope: "product"
136
+ product_id: "sports_preroll_q2"
137
+ ask: "Increase budget allocation to $30K"
138
+ account:
139
+ brand:
140
+ domain: "acmeoutdoor.example"
141
+ operator: "pinnacle-agency.example"
142
+
143
+ validations:
144
+ - check: response_schema
145
+ description: "Response matches get-products-response.json schema"
146
+ - check: field_present
147
+ path: "products"
148
+ description: "Response contains updated products"