@adcp/sdk 7.11.0 → 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 (282) 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/schemas-data/v2.5/_provenance.json +1 -1
  270. package/dist/lib/testing/storyboard/default-invariants.js +23 -0
  271. package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
  272. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  273. package/dist/lib/testing/storyboard/runner.js +84 -21
  274. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  275. package/dist/lib/testing/storyboard/types.d.ts +21 -0
  276. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  277. package/dist/lib/testing/storyboard/types.js.map +1 -1
  278. package/dist/lib/testing/types.d.ts +9 -0
  279. package/dist/lib/testing/types.d.ts.map +1 -1
  280. package/dist/lib/version.d.ts +3 -3
  281. package/dist/lib/version.js +3 -3
  282. package/package.json +1 -1
@@ -0,0 +1,470 @@
1
+ id: media_buy_seller/performance_buy_flow_roas
2
+ version: "1.0.0"
3
+ title: "Seller fulfills a performance (event-kind goal) media buy with a ROAS target"
4
+ category: media_buy_seller
5
+ summary: "Verifies that a seller advertising conversion_tracking with per_ad_spend in supported_targets can accept a media buy whose event-kind optimization_goal carries a ROAS (per_ad_spend) target bound to an event source with value_field, reject ROAS goals that omit value_field on every event-source entry, ingest valued purchase events, and report conversion_value + roas alongside conversions and cost_per_acquisition. Sibling to media_buy_seller/performance_buy_flow gated on the supported_targets sub-capability: sellers that don't advertise per_ad_spend (most broadcast TV, upper-funnel video, signal-only) grade not_applicable."
6
+ track: media_buy
7
+
8
+ # Gate: scenario runs only when the seller declares per_ad_spend in
9
+ # conversion_tracking.supported_targets. Sellers that compute conversions
10
+ # but not return-on-ad-spend (broadcast TV, upper-funnel video, signal-only,
11
+ # many MMP-mediated mobile pipelines) grade `not_applicable`, not failing.
12
+ # supported_targets is a per-target-kind enumeration of the target kinds the
13
+ # seller can actually optimize toward (proposed in #4639). Gating on the
14
+ # explicit kind rather than on conversion_tracking presence is what keeps
15
+ # honest CPA-only implementations from failing. Requires runner support for
16
+ # the `contains:` matcher (adcp-client >= 7.70).
17
+ requires_capability:
18
+ path: media_buy.conversion_tracking.supported_targets
19
+ contains: "per_ad_spend"
20
+
21
+ required_tools:
22
+ - get_products
23
+ - sync_event_sources
24
+ - create_media_buy
25
+ - log_event
26
+ - get_media_buy_delivery
27
+ - comply_test_controller
28
+
29
+ invariants:
30
+ - status.monotonic
31
+
32
+ narrative: |
33
+ A "ROAS buy" is a performance media buy whose optimization_goal targets
34
+ return-on-ad-spend rather than cost-per-acquisition. The buyer commits to
35
+ a target_roas (per_ad_spend) and binds the buy to one or more conversion
36
+ event sources whose events carry monetary value. value_field on the
37
+ event-source entry tells the seller which custom_data field carries the
38
+ per-event value to aggregate; without value_field there is nothing to
39
+ divide by spend, so the seller MUST reject the goal.
40
+
41
+ This scenario is a sibling to media_buy_seller/performance_buy_flow, gated
42
+ on a separate sub-capability bit (conversion_tracking.supported_targets
43
+ contains per_ad_spend). The CPA scenario is gated on conversion_tracking
44
+ presence — every seller that tracks conversions can compute CPA. ROAS is
45
+ narrower: many performance sellers honestly track conversions but don't
46
+ compute return-on-ad-spend because their attribution doesn't carry value.
47
+ Gating ROAS on the explicit per_ad_spend kind in supported_targets is what
48
+ prevents that population from being marked failing instead of
49
+ not_applicable.
50
+
51
+ Discriminating behaviors this scenario verifies:
52
+ 1. sync_event_sources returns an event_source_id that is valid as the
53
+ binding target on a per_ad_spend optimization_goal.
54
+ 2. create_media_buy with an event-kind goal whose target.kind is
55
+ per_ad_spend AND whose event_sources[k].value_field is populated is
56
+ accepted.
57
+ 3. create_media_buy with target.kind = per_ad_spend AND NO value_field on
58
+ any event_sources[] entry is rejected with INVALID_REQUEST. The seller
59
+ cannot compute ROAS without a value field; silent acceptance would mean
60
+ reporting roas: 0 for the life of the buy. error.field points at the
61
+ offending value_field absence at packages[0].optimization_goals[0].event_sources[0].value_field.
62
+ 4. log_event flows valued conversions back, scoped to the registered
63
+ event_source_id with order_total in custom_data.
64
+ 5. get_media_buy_delivery returns first-class ROAS metrics — conversion_value
65
+ and roas — alongside conversions and cost_per_acquisition. CPA is still
66
+ computed (spend / conversions is well-defined for any conversion source);
67
+ roas is the field this scenario exists to assert.
68
+
69
+ Per-creative ROAS breakdown is deliberately NOT asserted here for the
70
+ same reason per-creative attribution is deferred in performance_buy_flow:
71
+ honest adopters report at differing granularities (social per-ad, retail-
72
+ media per-line, MMP-mediated per-campaign, broadcast/CTV per-placement).
73
+ A follow-up scenario gated on a sub-capability bit will land per-creative
74
+ value attribution once the breakdown shape is settled.
75
+
76
+ agent:
77
+ interaction_model: media_buy_seller
78
+ capabilities:
79
+ - sells_media
80
+ - supports_non_guaranteed
81
+ - conversion_tracking
82
+ examples:
83
+ - "Performance-mode DSPs with value-aware bidding"
84
+ - "Retail-media networks (Amazon Ads, Criteo, Walmart Connect)"
85
+ - "Social platforms with value optimization (Meta VBO, TikTok VBO)"
86
+ - "Agentic optimizers that pass value into upstream attribution"
87
+
88
+ caller:
89
+ role: buyer_agent
90
+ example: "Pinnacle Agency (buyer)"
91
+
92
+ prerequisites:
93
+ description: |
94
+ The seller must implement comply_test_controller with simulate_delivery
95
+ (already required for delivery_reporting). simulate_delivery's
96
+ `conversions` param injects attributed conversion counts and the seller
97
+ is expected to compute conversion_value from logged events with
98
+ order_total. Sellers whose attribution pipeline cannot ingest a value
99
+ field do not advertise per_ad_spend in supported_targets and grade
100
+ not_applicable.
101
+
102
+ The buyer fixture supplies a brand, an operator, a conversion event
103
+ source definition, and a valued purchase event sufficient to exercise
104
+ the ROAS reporting contract.
105
+ test_kit: "test-kits/acme-outdoor.yaml"
106
+ controller_seeding: true
107
+
108
+ fixtures:
109
+ products:
110
+ - product_id: "performance_roas_native_q2"
111
+ delivery_type: "non_guaranteed"
112
+ channels: ["display", "native"]
113
+ format_ids:
114
+ - id: "native_feed_1x1"
115
+ - id: "display_300x250"
116
+ pricing_options:
117
+ - product_id: "performance_roas_native_q2"
118
+ pricing_option_id: "auction_cpm"
119
+ pricing_model: "cpm"
120
+ currency: "USD"
121
+ floor_price: 1.50
122
+
123
+ phases:
124
+
125
+ - id: setup
126
+ title: "Establish account and discover products"
127
+ steps:
128
+ - id: sync_accounts
129
+ title: "Establish account"
130
+ task: sync_accounts
131
+ schema_ref: "account/sync-accounts-request.json"
132
+ response_schema_ref: "account/sync-accounts-response.json"
133
+ doc_ref: "/accounts/tasks/sync_accounts"
134
+ stateful: true
135
+ expected: |
136
+ Return the account with account_id and status active.
137
+ sample_request:
138
+ accounts:
139
+ - brand:
140
+ domain: "acmeoutdoor.example"
141
+ operator: "pinnacle-agency.example"
142
+ billing: "operator"
143
+ idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_setup_sync_accounts"
144
+ validations:
145
+ - check: response_schema
146
+ description: "Response matches sync-accounts-response.json schema"
147
+ - check: field_present
148
+ path: "accounts[0].account_id"
149
+ description: "Account has a platform-assigned ID"
150
+
151
+ - id: get_products_for_roas
152
+ title: "Discover products that support ROAS optimization"
153
+ task: get_products
154
+ schema_ref: "media-buy/get-products-request.json"
155
+ response_schema_ref: "media-buy/get-products-response.json"
156
+ doc_ref: "/media-buy/task-reference/get_products"
157
+ stateful: false
158
+ expected: |
159
+ Return at least one product whose conversion_tracking capabilities
160
+ accept per_ad_spend event-kind targets.
161
+ sample_request:
162
+ buying_mode: "brief"
163
+ brief: "Performance native + display, US, adults 25-54. Target ROAS 4.0 on purchase events with order_total from acmeoutdoor.example."
164
+ required_capabilities:
165
+ - "conversion_tracking"
166
+ account:
167
+ brand:
168
+ domain: "acmeoutdoor.example"
169
+ operator: "pinnacle-agency.example"
170
+ validations:
171
+ - check: response_schema
172
+ description: "Response matches get-products-response.json schema"
173
+ - check: field_present
174
+ path: "products"
175
+ description: "Response contains products"
176
+
177
+ - id: event_source_binding
178
+ title: "Register the conversion event source"
179
+ narrative: |
180
+ The ROAS buy cannot be created without a registered event source whose
181
+ entry carries value_field. This phase exercises the binding —
182
+ sync_event_sources returns an event_source_id that the next phase
183
+ references on a per_ad_spend optimization_goal.
184
+
185
+ steps:
186
+ - id: sync_event_sources
187
+ title: "Register a website conversion source"
188
+ task: sync_event_sources
189
+ schema_ref: "media-buy/sync-event-sources-request.json"
190
+ response_schema_ref: "media-buy/sync-event-sources-response.json"
191
+ doc_ref: "/media-buy/task-reference/sync_event_sources"
192
+ stateful: true
193
+ expected: |
194
+ Return event_sources with event_source_id, setup.snippet, and
195
+ action: created. The id is captured for the ROAS create_media_buy
196
+ phase.
197
+ sample_request:
198
+ account:
199
+ brand:
200
+ domain: "acmeoutdoor.example"
201
+ operator: "pinnacle-agency.example"
202
+ event_sources:
203
+ - event_source_id: "acmeoutdoor_website"
204
+ name: "Acme Outdoor Website"
205
+ event_types: ["purchase"]
206
+ allowed_domains: ["acmeoutdoor.example"]
207
+ idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_event_source_binding_sync_event_sources"
208
+ validations:
209
+ - check: response_schema
210
+ description: "Response matches sync-event-sources-response.json schema"
211
+ - check: field_present
212
+ path: "event_sources[0].event_source_id"
213
+ description: "Event source has a platform-assigned ID"
214
+ - check: field_present
215
+ path: "event_sources[0].setup.snippet"
216
+ description: "Event source returns integration code"
217
+ # Anti-façade: an adapter that returns a shape-valid
218
+ # sync_event_sources response without forwarding the source
219
+ # definition upstream fails this check. Adopters who don't
220
+ # advertise query_upstream_traffic grade not_applicable.
221
+ - check: upstream_traffic
222
+ description: "sync_event_sources caused upstream traffic registering the event source"
223
+ min_count: 1
224
+ endpoint_pattern: "POST *"
225
+
226
+ - id: create_performance_buy_roas
227
+ title: "Create a performance buy with a ROAS goal"
228
+ narrative: |
229
+ The buyer creates a media buy whose package carries an event-kind
230
+ optimization_goal binding to the registered event source. The target
231
+ is per_ad_spend (ROAS) 4.0 on purchase events, with value_field
232
+ "order_total" telling the seller which custom_data field to aggregate.
233
+
234
+ steps:
235
+ - id: create_media_buy_roas
236
+ title: "Create media buy with event-kind goal (per_ad_spend target)"
237
+ task: create_media_buy
238
+ schema_ref: "media-buy/create-media-buy-request.json"
239
+ response_schema_ref: "media-buy/create-media-buy-response.json"
240
+ doc_ref: "/media-buy/task-reference/create_media_buy"
241
+ stateful: true
242
+ expected: |
243
+ Create the media buy. Response carries a media_buy_id used for
244
+ subsequent log_event and get_media_buy_delivery calls.
245
+ sample_request:
246
+ brand:
247
+ domain: "acmeoutdoor.example"
248
+ account:
249
+ brand:
250
+ domain: "acmeoutdoor.example"
251
+ operator: "pinnacle-agency.example"
252
+ start_time: "2026-06-01T00:00:00Z"
253
+ end_time: "2026-06-30T23:59:59Z"
254
+ packages:
255
+ - product_id: "performance_roas_native_q2"
256
+ budget: 25000
257
+ pricing_option_id: "auction_cpm"
258
+ optimization_goals:
259
+ - kind: "event"
260
+ event_sources:
261
+ - event_source_id: "acmeoutdoor_website"
262
+ event_type: "purchase"
263
+ value_field: "order_total"
264
+ target:
265
+ kind: "per_ad_spend"
266
+ value: 4.0
267
+ priority: 1
268
+ idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_create_performance_buy_roas_create_media_buy"
269
+ context_outputs:
270
+ - name: media_buy_id
271
+ path: "media_buy_id"
272
+ validations:
273
+ - check: response_schema
274
+ description: "Response matches create-media-buy-response.json schema"
275
+ - check: field_present
276
+ path: "media_buy_id"
277
+ description: "Media buy has a platform-assigned ID"
278
+
279
+ - id: rejection_per_ad_spend_no_value_field
280
+ title: "Reject a per_ad_spend goal that omits value_field"
281
+ narrative: |
282
+ Silent acceptance of a per_ad_spend target with no value_field on any
283
+ event_sources[] entry is a façade — the seller cannot compute ROAS
284
+ without a value to divide by spend, so the buy would silently report
285
+ roas: 0 (or absent) for the life of the flight. The seller MUST reject
286
+ with INVALID_REQUEST and set error.field to the offending value_field
287
+ absence on the first event_sources entry. This mirrors the unbound
288
+ event_source_id rejection in performance_buy_flow on the value side.
289
+
290
+ optimization-goal.json:148-156 makes the requirement explicit: target
291
+ kinds per_ad_spend and maximize_value require value_field on at least
292
+ one entry. Sellers MUST reject when the requirement is unmet.
293
+
294
+ steps:
295
+ - id: create_media_buy_per_ad_spend_no_value_field
296
+ title: "Submit a per_ad_spend goal with no value_field on any source"
297
+ task: create_media_buy
298
+ schema_ref: "media-buy/create-media-buy-request.json"
299
+ response_schema_ref: "media-buy/create-media-buy-response.json"
300
+ doc_ref: "/media-buy/task-reference/create_media_buy"
301
+ expect_error: true
302
+ negative_path: payload_well_formed
303
+ stateful: false
304
+ expected: |
305
+ Reject with INVALID_REQUEST. error.field points at the missing
306
+ value_field on the event_sources entry. media_buy_id is not
307
+ allocated.
308
+ sample_request:
309
+ brand:
310
+ domain: "acmeoutdoor.example"
311
+ account:
312
+ brand:
313
+ domain: "acmeoutdoor.example"
314
+ operator: "pinnacle-agency.example"
315
+ start_time: "2026-06-01T00:00:00Z"
316
+ end_time: "2026-06-30T23:59:59Z"
317
+ packages:
318
+ - product_id: "performance_roas_native_q2"
319
+ budget: 5000
320
+ pricing_option_id: "auction_cpm"
321
+ optimization_goals:
322
+ - kind: "event"
323
+ event_sources:
324
+ - event_source_id: "acmeoutdoor_website"
325
+ event_type: "purchase"
326
+ target:
327
+ kind: "per_ad_spend"
328
+ value: 4.0
329
+ idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_rejection_per_ad_spend_no_value_field"
330
+ validations:
331
+ - check: error_code
332
+ allowed_values: ["INVALID_REQUEST"]
333
+ description: "Seller rejects the per_ad_spend goal with no value_field with INVALID_REQUEST"
334
+ - check: field_value
335
+ path: "errors[0].field"
336
+ value: "packages[0].optimization_goals[0].event_sources[0].value_field"
337
+ description: "Error.field points at the missing value_field on the first event_sources entry (core/error.json defines field as deterministic JSONPath-lite — literal equality; the value_field path is more buyer-actionable than pointing at target.kind because it tells the buyer what to add, not what to remove)"
338
+
339
+ - id: log_purchase_event
340
+ title: "Log a valued purchase event against the bound source"
341
+ narrative: |
342
+ The buyer logs a purchase event with order_total in custom_data tied
343
+ to the registered event_source_id. The seller's attribution pipeline
344
+ ingests order_total via the value_field declared on the goal and
345
+ aggregates it into conversion_value, surfaced in delivery in the next
346
+ phase.
347
+
348
+ steps:
349
+ - id: log_purchase_event
350
+ title: "Log a purchase event with order_total"
351
+ task: log_event
352
+ schema_ref: "media-buy/log-event-request.json"
353
+ response_schema_ref: "media-buy/log-event-response.json"
354
+ doc_ref: "/media-buy/task-reference/log_event"
355
+ stateful: true
356
+ expected: |
357
+ Acknowledge the event with accepted status.
358
+ sample_request:
359
+ account:
360
+ brand:
361
+ domain: "acmeoutdoor.example"
362
+ operator: "pinnacle-agency.example"
363
+ event_source_id: "acmeoutdoor_website"
364
+ events:
365
+ - event_type: "purchase"
366
+ event_id: "evt_perf_buy_flow_roas_001"
367
+ event_time: "2026-06-05T14:30:00Z"
368
+ user_match:
369
+ hashed_email: "a000000000000000000000000000000000000000000000000000000000000020"
370
+ custom_data:
371
+ order_total: 149.99
372
+ currency: "USD"
373
+ idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_log_purchase_event_log_event"
374
+ validations:
375
+ - check: response_schema
376
+ description: "Response matches log-event-response.json schema"
377
+ - check: upstream_traffic
378
+ description: "log_event forwards the event to the seller's upstream conversion endpoint with the order_total value"
379
+ min_count: 1
380
+ endpoint_pattern: "POST *"
381
+ identifier_paths:
382
+ - "events[*].user_match.hashed_email"
383
+
384
+ - id: attributed_roas_delivery
385
+ title: "Delivery reporting carries ROAS, conversion_value, conversions, and CPA"
386
+ narrative: |
387
+ The discriminating assertion of the ROAS buy mode: delivery reporting
388
+ MUST surface conversion_value and roas — not just conversions and CPA.
389
+ The runner injects simulated impressions, conversions, and spend via
390
+ the test controller, then verifies get_media_buy_delivery returns all
391
+ four first-class metrics at the buy level.
392
+
393
+ CPA is still computed (spend / conversions is well-defined whenever
394
+ the seller tracks conversions); ROAS is the addition this scenario
395
+ exists to certify. Sellers that advertise per_ad_spend in
396
+ supported_targets are committing to populate conversion_value and roas
397
+ on delivery responses.
398
+
399
+ Per-creative ROAS breakdown is deliberately NOT asserted here for the
400
+ same reason performance_buy_flow defers per-creative attribution:
401
+ honest adopters report at differing granularities and gating
402
+ per-creative value attribution on a sub-capability bit lands as a
403
+ follow-up scenario.
404
+
405
+ steps:
406
+ - id: simulate_roas_delivery
407
+ title: "Inject impressions + conversions + spend"
408
+ task: comply_test_controller
409
+ requires_tool: comply_test_controller
410
+ stateful: true
411
+ expected: |
412
+ The test controller acknowledges the simulated delivery.
413
+ sample_request:
414
+ account:
415
+ sandbox: true
416
+ scenario: "simulate_delivery"
417
+ params:
418
+ media_buy_id: "$context.media_buy_id"
419
+ impressions: 200000
420
+ clicks: 4500
421
+ conversions: 90
422
+ reported_spend:
423
+ amount: 3000.00
424
+ currency: "USD"
425
+ validations:
426
+ - check: field_value
427
+ path: "success"
428
+ allowed_values: [true]
429
+ description: "Delivery simulation succeeds"
430
+
431
+ - id: get_attributed_roas_delivery
432
+ title: "Get delivery and verify ROAS-attributed metrics"
433
+ task: get_media_buy_delivery
434
+ schema_ref: "media-buy/get-media-buy-delivery-request.json"
435
+ response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
436
+ doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
437
+ stateful: true
438
+ expected: |
439
+ Delivery response includes:
440
+ - conversions (the count of attributed conversions)
441
+ - conversion_value (the sum of order_total across attributed conversions)
442
+ - roas (conversion_value / spend — the discriminating assertion for this scenario)
443
+ - cost_per_acquisition (still computed; ROAS is in addition, not instead)
444
+
445
+ Per-creative value attribution is intentionally NOT asserted here
446
+ (see phase narrative). A follow-up scenario gated on a sub-capability
447
+ bit will land per-creative ROAS once the breakdown shape is settled.
448
+ sample_request:
449
+ account:
450
+ brand:
451
+ domain: "acmeoutdoor.example"
452
+ operator: "pinnacle-agency.example"
453
+ media_buy_ids:
454
+ - "$context.media_buy_id"
455
+ include_package_daily_breakdown: true
456
+ validations:
457
+ - check: response_schema
458
+ description: "Response matches get-media-buy-delivery-response.json schema"
459
+ - check: field_present
460
+ path: "media_buy_deliveries[0].totals.conversions"
461
+ description: "Conversion count surfaced at the buy level"
462
+ - check: field_present
463
+ path: "media_buy_deliveries[0].totals.conversion_value"
464
+ description: "Aggregated conversion_value surfaced at the buy level (sum of order_total across attributed conversions)"
465
+ - check: field_present
466
+ path: "media_buy_deliveries[0].totals.roas"
467
+ description: "ROAS surfaced at the buy level — the discriminating assertion of per_ad_spend optimization (conversion_value / spend)"
468
+ - check: field_present
469
+ path: "media_buy_deliveries[0].totals.cost_per_acquisition"
470
+ description: "CPA still computed alongside ROAS (spend / conversions)"