@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,840 @@
1
+ id: sales_catalog_driven
2
+ version: "1.0.0"
3
+ title: "Catalog-driven creative and conversion tracking"
4
+ protocol: media-buy
5
+ category: sales_catalog_driven
6
+ summary: "Seller that renders dynamic ads from product catalogs, tracks conversions, and optimizes delivery based on performance feedback."
7
+ track: media_buy
8
+ required_tools:
9
+ - sync_governance
10
+ - get_products
11
+ - create_media_buy
12
+ requires_scenarios:
13
+ - media_buy_seller/refine_products
14
+ - media_buy_seller/delivery_reporting
15
+ - media_buy_seller/pending_creatives_to_start
16
+ - media_buy_seller/invalid_transitions
17
+ - governance_aware_seller/governance_multi_agent_rejected
18
+
19
+ # Cross-step assertion (adcp#2664). status.monotonic rejects resource
20
+ # status transitions observed across steps that aren't on the spec
21
+ # lifecycle graph — e.g. active → pending_creatives on a media_buy or
22
+ # approved → pending on a catalog_item.
23
+ #
24
+ # Cross-resource assertion (adcp#2859). impairment.coherence verifies that
25
+ # catalog_item.withdrawn transitions propagate to any non-terminal media buy
26
+ # that references the item: the buy's impairments[] MUST list an entry for
27
+ # the withdrawn catalog item, and the buy's health MUST be `impaired`.
28
+ # Inverse direction is also enforced — a buy reporting an impairment whose
29
+ # referenced catalog_item is no longer offline fails the check. Out of
30
+ # scope: terminal-status buys MAY remain unreported; materiality
31
+ # (package_ids minItems:1) is enforced at the schema layer (#2855), not
32
+ # here. Grades not_applicable until the storyboard exercises both a
33
+ # catalog-item transition AND a media-buy snapshot read (#2860).
34
+ invariants:
35
+ - status.monotonic
36
+ - impairment.coherence
37
+
38
+ narrative: |
39
+ You run a platform that supports catalog-driven advertising — think Snap Dynamic Ads,
40
+ Meta Product Catalogs, or retail media product listing ads. The buyer pushes a product
41
+ catalog (menu items, retail products, hotel listings), and your platform renders ads
42
+ dynamically from that feed. When a user converts, events are logged back and attributed
43
+ to catalog items, closing the optimization loop.
44
+
45
+ This storyboard walks through the full catalog-to-conversion flow: account setup,
46
+ catalog sync, creative formats for catalog items, media buy with catalog packages,
47
+ event source configuration, conversion logging, and performance feedback.
48
+
49
+ The key difference from the standard media buy flow is that creatives are catalog-driven —
50
+ the buyer doesn't build individual ads. They push a feed, and your platform renders
51
+ the right item to the right user at the right time.
52
+
53
+ context:
54
+ governance_agent_url: "https://test-agent.adcontextprotocol.org"
55
+
56
+ agent:
57
+ interaction_model: media_buy_seller
58
+ capabilities:
59
+ - sells_media
60
+ - accepts_catalogs
61
+ - supports_conversion_tracking
62
+ - catalog_driven_creative
63
+ examples:
64
+ - "Snap (Dynamic Ads)"
65
+ - "Retail media networks"
66
+ - "Travel platforms"
67
+ - "Local commerce platforms"
68
+
69
+ caller:
70
+ role: buyer_agent
71
+ example: "Scope3 (DSP)"
72
+
73
+ prerequisites:
74
+ description: |
75
+ The caller needs a product catalog (feed URL or inline items) and an event source
76
+ for conversion tracking. The test kit provides a sample brand with catalog-compatible
77
+ assets.
78
+ test_kit: "test-kits/acme-outdoor.yaml"
79
+
80
+ phases:
81
+ - id: capability_discovery
82
+ title: "Capability discovery"
83
+ narrative: |
84
+ The buyer calls get_adcp_capabilities to confirm the agent supports media buying before sending briefs or creating buys.
85
+
86
+ steps:
87
+ - id: get_capabilities
88
+ title: "Check agent capabilities"
89
+ narrative: |
90
+ Verify that the agent declares the expected protocol support before
91
+ proceeding with domain-specific operations.
92
+ task: get_adcp_capabilities
93
+ schema_ref: "protocol/get-adcp-capabilities-request.json"
94
+ response_schema_ref: "protocol/get-adcp-capabilities-response.json"
95
+ doc_ref: "/protocol/get_adcp_capabilities"
96
+ comply_scenario: capability_discovery
97
+ stateful: false
98
+ expected: |
99
+ Return capabilities declaring media_buy in supported_protocols, confirming the agent sells media.
100
+ sample_request:
101
+ context:
102
+ correlation_id: "sales_catalog_driven--get_capabilities"
103
+ validations:
104
+ - check: response_schema
105
+ description: "Response matches get-adcp-capabilities-response.json schema"
106
+ - check: field_present
107
+ path: "supported_protocols"
108
+ description: "Agent declares supported protocols"
109
+
110
+ - check: field_present
111
+ path: "context"
112
+ description: "Response echoes back the context object"
113
+ - check: field_value
114
+ path: "context.correlation_id"
115
+ value: "sales_catalog_driven--get_capabilities"
116
+ description: "Context correlation_id returned unchanged"
117
+ - id: account_setup
118
+ title: "Account setup"
119
+ narrative: |
120
+ The buyer establishes an account relationship with your platform. For catalog-driven
121
+ campaigns, the account must be active before any catalog sync can happen.
122
+
123
+ steps:
124
+ - id: sync_accounts
125
+ title: "Establish account"
126
+ narrative: |
127
+ The buyer registers their brand and operator. Sandbox accounts are provisioned
128
+ instantly for testing catalog flows.
129
+ task: sync_accounts
130
+ schema_ref: "account/sync-accounts-request.json"
131
+ response_schema_ref: "account/sync-accounts-response.json"
132
+ doc_ref: "/accounts/tasks/sync_accounts"
133
+ stateful: true
134
+ expected: |
135
+ Return the account with account_id, status (active for sandbox), and billing terms.
136
+
137
+ sample_request:
138
+ accounts:
139
+ - brand:
140
+ domain: "amsterdam-steakhouse.example"
141
+ operator: "pinnacle-agency.example"
142
+ billing: "operator"
143
+ sandbox: true
144
+
145
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_account_setup_sync_accounts"
146
+ context:
147
+ correlation_id: "sales_catalog_driven--sync_accounts"
148
+ validations:
149
+ - check: response_schema
150
+ description: "Response matches sync-accounts-response.json schema"
151
+ - check: field_present
152
+ path: "accounts[0].account_id"
153
+ description: "Account has a platform-assigned ID"
154
+
155
+ - check: field_present
156
+ path: "context"
157
+ description: "Response echoes back the context object"
158
+ - check: field_value
159
+ path: "context.correlation_id"
160
+ value: "sales_catalog_driven--sync_accounts"
161
+ description: "Context correlation_id returned unchanged"
162
+ - id: sync_governance
163
+ title: "Register governance agent"
164
+ narrative: |
165
+ The buyer registers the configured governance agent on the account before
166
+ catalog sync and catalog-driven media-buy creation.
167
+ task: sync_governance
168
+ schema_ref: "account/sync-governance-request.json"
169
+ response_schema_ref: "account/sync-governance-response.json"
170
+ doc_ref: "/accounts/tasks/sync_governance"
171
+ stateful: true
172
+ expected: |
173
+ Acknowledge governance registration for the account:
174
+ - status: synced
175
+ - governance_agents[0].url echoes the configured governance agent
176
+
177
+ sample_request:
178
+ accounts:
179
+ - account:
180
+ brand:
181
+ domain: "amsterdam-steakhouse.example"
182
+ operator: "pinnacle-agency.example"
183
+ governance_agents:
184
+ - url: "$context.governance_agent_url"
185
+ authentication:
186
+ schemes: ["Bearer"]
187
+ credentials: "gov-token-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
188
+
189
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_account_setup_sync_governance"
190
+ context:
191
+ correlation_id: "sales_catalog_driven--sync_governance"
192
+ validations:
193
+ - check: response_schema
194
+ description: "Response matches sync-governance-response.json schema"
195
+ - check: field_value
196
+ path: "accounts[0].status"
197
+ value: "synced"
198
+ description: "Governance agent is registered on the account"
199
+ - check: field_present
200
+ path: "context"
201
+ description: "Response echoes back the context object"
202
+ - check: field_value
203
+ path: "context.correlation_id"
204
+ value: "sales_catalog_driven--sync_governance"
205
+ description: "Context correlation_id returned unchanged"
206
+ - id: catalog_sync
207
+ title: "Product catalog sync"
208
+ narrative: |
209
+ The buyer pushes their product catalog to your platform. This is the foundation of
210
+ catalog-driven advertising — every ad your platform renders comes from this feed.
211
+
212
+ For a restaurant, this is the menu. For retail, it is the product feed. For travel,
213
+ it is hotel or flight listings. Your platform validates each item against your
214
+ format requirements (image dimensions, required fields, pricing format) and returns
215
+ per-item approval status.
216
+
217
+ Large feeds may go async — the buyer gets back a submitted status and waits for
218
+ your platform to finish processing. Small feeds (inline items) are processed
219
+ synchronously.
220
+
221
+ steps:
222
+ - id: discover_catalog_formats
223
+ title: "Check catalog format requirements"
224
+ narrative: |
225
+ Before pushing catalog items, the buyer checks what creative formats your
226
+ platform supports for catalog-driven ads. This tells the buyer what image
227
+ dimensions, text lengths, and required fields each catalog item needs.
228
+ task: list_creative_formats
229
+ schema_ref: "creative/list-creative-formats-request.json"
230
+ response_schema_ref: "creative/list-creative-formats-response.json"
231
+ doc_ref: "/creative/task-reference/list_creative_formats"
232
+ comply_scenario: creative_lifecycle
233
+ stateful: false
234
+ expected: |
235
+ Return creative formats that accept catalog assets. Look for formats with
236
+ catalog-specific asset slots (product_image, product_title, price, description).
237
+
238
+ sample_request:
239
+ channels: ["display", "native"]
240
+
241
+ context:
242
+ correlation_id: "sales_catalog_driven--discover_catalog_formats"
243
+ validations:
244
+ - check: response_schema
245
+ description: "Response matches list-creative-formats-response.json schema"
246
+ - check: field_present
247
+ path: "formats"
248
+ description: "Response contains formats array"
249
+
250
+ - check: field_present
251
+ path: "context"
252
+ description: "Response echoes back the context object"
253
+ - check: field_value
254
+ path: "context.correlation_id"
255
+ value: "sales_catalog_driven--discover_catalog_formats"
256
+ description: "Context correlation_id returned unchanged"
257
+ - check: field_present
258
+ path: "formats[0].format_id.agent_url"
259
+ description: "Format IDs include agent_url"
260
+ - check: field_present
261
+ path: "formats[0].format_id.id"
262
+ description: "Format IDs include id — must match those in get_products"
263
+ - id: sync_catalogs
264
+ title: "Push product catalog"
265
+ narrative: |
266
+ The buyer pushes their product feed. This can be a URL to an existing feed
267
+ (your platform fetches and re-fetches on a schedule) or inline items for
268
+ small catalogs.
269
+
270
+ Your platform validates each item: images meet minimum dimensions, required
271
+ fields are present, prices are formatted correctly. Items that fail validation
272
+ are rejected with specific reasons. Items that pass are approved and available
273
+ for dynamic creative rendering.
274
+ task: sync_catalogs
275
+ schema_ref: "media-buy/sync-catalogs-request.json"
276
+ response_schema_ref: "media-buy/sync-catalogs-response.json"
277
+ doc_ref: "/media-buy/task-reference/sync_catalogs"
278
+ stateful: true
279
+ expected: |
280
+ Return per-catalog results with:
281
+ - catalog_id and action (created/updated)
282
+ - item_count, items_approved, items_pending, items_rejected
283
+ - item_issues for rejected items with specific reasons
284
+ - next_fetch_at for URL-based feeds
285
+
286
+ sample_request:
287
+ account:
288
+ brand:
289
+ domain: "amsterdam-steakhouse.example"
290
+ operator: "pinnacle-agency.example"
291
+ catalogs:
292
+ - catalog_id: "menu_spring_2026"
293
+ type: "product"
294
+ name: "Spring 2026 Menu"
295
+ items:
296
+ - item_id: "ribeye_36oz"
297
+ title: "36oz Tomahawk Ribeye"
298
+ description: "Dry-aged 45 days, served with truffle butter and roasted bone marrow"
299
+ url: "https://amsterdam-steakhouse.example/menu/ribeye-36oz"
300
+ image_url: "https://cdn.amsterdam-steakhouse.example/menu/ribeye-36oz-hero.jpg"
301
+ price:
302
+ amount: 89.00
303
+ currency: "USD"
304
+ - item_id: "seafood_tower"
305
+ title: "Grand Seafood Tower"
306
+ description: "Oysters, king crab, lobster tail, shrimp cocktail, tuna tartare"
307
+ url: "https://amsterdam-steakhouse.example/menu/seafood-tower"
308
+ image_url: "https://cdn.amsterdam-steakhouse.example/menu/seafood-tower-hero.jpg"
309
+ price:
310
+ amount: 145.00
311
+ currency: "USD"
312
+ - item_id: "wagyu_flight"
313
+ title: "A5 Wagyu Tasting Flight"
314
+ description: "Three cuts of Japanese A5 Wagyu — striploin, ribeye cap, tenderloin"
315
+ url: "https://amsterdam-steakhouse.example/menu/wagyu-flight"
316
+ image_url: "https://cdn.amsterdam-steakhouse.example/menu/wagyu-flight-hero.jpg"
317
+ price:
318
+ amount: 195.00
319
+ currency: "USD"
320
+
321
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_catalog_sync_sync_catalogs"
322
+ context:
323
+ correlation_id: "sales_catalog_driven--sync_catalogs"
324
+ validations:
325
+ - check: response_schema
326
+ description: "Response matches sync-catalogs-response.json schema"
327
+ - check: field_present
328
+ path: "catalogs[0].catalog_id"
329
+ description: "Catalog has an ID"
330
+ - check: field_present
331
+ path: "catalogs[0].item_count"
332
+ description: "Catalog reports item count"
333
+ - check: field_present
334
+ path: "catalogs[0].items_approved"
335
+ description: "Catalog reports approved item count"
336
+
337
+ - check: field_present
338
+ path: "context"
339
+ description: "Response echoes back the context object"
340
+ - check: field_value
341
+ path: "context.correlation_id"
342
+ value: "sales_catalog_driven--sync_catalogs"
343
+ description: "Context correlation_id returned unchanged"
344
+ - id: substitution_safety
345
+ title: "Catalog-item macro substitution safety"
346
+ narrative: |
347
+ Per docs/creative/universal-macros#substitution-safety-catalog-item-macros,
348
+ sales agents MUST percent-encode catalog-item macro values such that only
349
+ RFC 3986 `unreserved` characters remain unescaped before substituting them
350
+ into a URL context. Nested macro expansion is prohibited.
351
+
352
+ This phase exercises the rule with three attacker-shaped catalog values
353
+ drawn from the unit-test fixture at `static/test-vectors/catalog-macro-substitution.json`:
354
+ reserved-char breakout, nested-expansion preservation, and non-ASCII
355
+ UTF-8. The remaining canonical vectors (CRLF injection, bidi-override,
356
+ mixed path/query, url-scheme injection) are exercised at the unit-test
357
+ layer and, where a specialism's template shape supports them, in
358
+ specialism-specific substitution-safety phases (see
359
+ `creative-generative/index.yaml` for CRLF + bidi coverage).
360
+
361
+ The `expect_substitution_safe` step is gated on the
362
+ `substitution_observer_runner` test-kit contract (see
363
+ `test-kits/substitution-observer-runner.yaml`). Runners that do not
364
+ advertise the contract grade the step as `not_applicable` — the earlier
365
+ `sync_attacker_shaped_catalog` and `build_catalog_aware_creative` steps
366
+ still run (they exercise the catalog-acceptance and build paths), but
367
+ the substituted-URL assertion is skipped.
368
+
369
+ steps:
370
+ - id: sync_attacker_shaped_catalog
371
+ title: "Push a catalog with attacker-shaped values"
372
+ narrative: |
373
+ Push a small catalog whose fields contain the six canonical
374
+ attacker-shaped values from the substitution-safety fixture. The
375
+ seller MUST accept the payload at sync_catalogs (the rule applies at
376
+ substitution time, not at ingest — the seller is free to pass values
377
+ through, then encode them at serve time).
378
+ task: sync_catalogs
379
+ schema_ref: "media-buy/sync-catalogs-request.json"
380
+ response_schema_ref: "media-buy/sync-catalogs-response.json"
381
+ doc_ref: "/media-buy/task-reference/sync_catalogs"
382
+ stateful: true
383
+ expected: |
384
+ Catalog accepted with per-item counts. Runner captures the item_ids
385
+ for downstream assertion binding.
386
+
387
+ sample_request:
388
+ account:
389
+ brand:
390
+ domain: "amsterdam-steakhouse.example"
391
+ operator: "pinnacle-agency.example"
392
+ catalogs:
393
+ - catalog_id: "substitution_safety_probe_v1"
394
+ type: "product"
395
+ content_id_type: "sku"
396
+ name: "Substitution safety probe"
397
+ items:
398
+ # item_id is the vector name; the `sku` field carries the
399
+ # attacker-shaped value that substitution must encode.
400
+ - item_id: "reserved_char_breakout"
401
+ sku: "00013&cmd=drop"
402
+ title: "Reserved-char breakout probe"
403
+ url: "https://amsterdam-steakhouse.example/probe/reserved"
404
+ image_url: "https://cdn.amsterdam-steakhouse.example/probe/reserved.jpg"
405
+ price: { amount: 1.00, currency: "USD" }
406
+ - item_id: "nested_expansion"
407
+ sku: "vacancy-{DEVICE_ID}-42"
408
+ title: "Nested-expansion probe"
409
+ url: "https://amsterdam-steakhouse.example/probe/nested"
410
+ image_url: "https://cdn.amsterdam-steakhouse.example/probe/nested.jpg"
411
+ price: { amount: 1.00, currency: "USD" }
412
+ - item_id: "non_ascii"
413
+ sku: "café-amsterdam"
414
+ title: "Non-ASCII UTF-8 probe"
415
+ url: "https://amsterdam-steakhouse.example/probe/non-ascii"
416
+ image_url: "https://cdn.amsterdam-steakhouse.example/probe/non-ascii.jpg"
417
+ price: { amount: 1.00, currency: "USD" }
418
+
419
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_substitution_safety_sync_attacker_shaped_catalog"
420
+ context:
421
+ correlation_id: "sales_catalog_driven--sync_attacker_shaped_catalog"
422
+ validations:
423
+ - check: response_schema
424
+ description: "Response matches sync-catalogs-response.json schema"
425
+ - check: field_present
426
+ path: "catalogs[0].catalog_id"
427
+ description: "Catalog accepted"
428
+
429
+ - id: build_catalog_aware_creative
430
+ title: "Build a creative with catalog-item macros in tracker URLs"
431
+ narrative: |
432
+ Build a creative whose impression and click trackers include
433
+ catalog-item macros bound to the `sku` field of the attacker-shaped
434
+ catalog items above. Request `include_preview: true` so the
435
+ substitution-observer runner has a preview surface to inspect.
436
+ task: build_creative
437
+ schema_ref: "media-buy/build-creative-request.json"
438
+ response_schema_ref: "media-buy/build-creative-response.json"
439
+ doc_ref: "/creative/task-reference/build_creative"
440
+ comply_scenario: creative_flow
441
+ stateful: true
442
+ expected: |
443
+ Creative manifest returned with preview_html or preview_url populated.
444
+
445
+ sample_request:
446
+ message: "Build a catalog-driven display ad for the substitution_safety_probe_v1 catalog. Use {SKU} in impression and click tracker URLs."
447
+ target_format_id:
448
+ agent_url: "https://your-agent.example.com"
449
+ id: "display_300x250_catalog"
450
+ account:
451
+ brand:
452
+ domain: "amsterdam-steakhouse.example"
453
+ operator: "pinnacle-agency.example"
454
+ quality: "draft"
455
+ include_preview: true
456
+
457
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_substitution_safety_build_catalog_aware_creative"
458
+ context:
459
+ correlation_id: "sales_catalog_driven--build_catalog_aware_creative"
460
+ validations:
461
+ - check: response_schema
462
+ description: "Response matches build-creative-response.json schema"
463
+ - check: field_present
464
+ path: "creative_manifest.format_id"
465
+ description: "Creative manifest returned"
466
+
467
+ - id: expect_substitution_safe
468
+ title: "Assert substituted tracker URLs percent-encode attacker shapes"
469
+ narrative: |
470
+ The runner inspects the preview artifact from the previous step,
471
+ extracts tracker URLs that bind `{SKU}` to a catalog item from the
472
+ attacker-shaped catalog, and asserts each value is percent-encoded
473
+ per RFC 3986 (unreserved-whitelist). Raw-byte leakage fails. Every
474
+ declared binding MUST be observed — a seller that silently strips
475
+ `{SKU}` rather than substituting it fails with
476
+ `substitution_binding_missing`.
477
+ task: expect_substitution_safe
478
+ requires_contract: substitution_observer_runner
479
+ source: html_inline
480
+ source_path: "/creative_manifest/preview_html"
481
+ macro_template: "https://track.example/imp?sku={SKU}"
482
+ require_every_binding_observed: true
483
+ catalog_bindings:
484
+ # Each binding: `catalog_item_id` is the item_id in the synced
485
+ # catalog; `vector_name` is the fixture entry whose raw_value and
486
+ # expected_encoded the runner loads from
487
+ # static/test-vectors/catalog-macro-substitution.json.
488
+ - macro: "{SKU}"
489
+ catalog_item_id: "reserved_char_breakout"
490
+ vector_name: "reserved-character-breakout"
491
+ - macro: "{SKU}"
492
+ catalog_item_id: "nested_expansion"
493
+ vector_name: "nested-expansion-preserved-as-literal"
494
+ - macro: "{SKU}"
495
+ catalog_item_id: "non_ascii"
496
+ vector_name: "non-ascii-utf8-percent-encoding"
497
+ - id: create_buy
498
+ title: "Create catalog-driven media buy"
499
+ narrative: |
500
+ The buyer creates a media buy with catalog-driven packages. Instead of assigning
501
+ individual creatives, the buyer references the synced catalog. Your platform
502
+ renders the right catalog items dynamically based on user context, intent signals,
503
+ and inventory availability.
504
+
505
+ The key schema difference: packages include a catalogs[] array instead of (or
506
+ alongside) creative_assignments[].
507
+
508
+ steps:
509
+ - id: get_products
510
+ title: "Discover catalog-compatible products"
511
+ narrative: |
512
+ The buyer finds products that support catalog-driven delivery. These products
513
+ accept catalog references and render dynamic ads from the feed.
514
+ task: get_products
515
+ schema_ref: "media-buy/get-products-request.json"
516
+ response_schema_ref: "media-buy/get-products-response.json"
517
+ doc_ref: "/media-buy/task-reference/get_products"
518
+ comply_scenario: full_sales_flow
519
+ stateful: false
520
+ expected: |
521
+ Return products that support catalog-driven creative. Products should indicate
522
+ catalog compatibility in their format requirements.
523
+
524
+ sample_request:
525
+ buying_mode: "brief"
526
+ brief: "Dynamic product ads for a high-end steakhouse. Geo-targeted to 10 miles around Amsterdam location. Drive reservations and foot traffic."
527
+ account:
528
+ brand:
529
+ domain: "amsterdam-steakhouse.example"
530
+ operator: "pinnacle-agency.example"
531
+
532
+ context:
533
+ correlation_id: "sales_catalog_driven--get_products"
534
+ validations:
535
+ - check: response_schema
536
+ description: "Response matches get-products-response.json schema"
537
+ - check: field_present
538
+ path: "products"
539
+ description: "Response contains products"
540
+
541
+ - check: field_present
542
+ path: "context"
543
+ description: "Response echoes back the context object"
544
+ - check: field_value
545
+ path: "context.correlation_id"
546
+ value: "sales_catalog_driven--get_products"
547
+ description: "Context correlation_id returned unchanged"
548
+ - check: field_present
549
+ path: "products[0].format_ids"
550
+ description: "Products include format_ids for creative requirements"
551
+ - check: field_present
552
+ path: "products[0].format_ids[0].agent_url"
553
+ description: "Format IDs include agent_url — must match this agent's URL"
554
+ - check: field_present
555
+ path: "products[0].format_ids[0].id"
556
+ description: "Format IDs include id — must be accepted back in sync_creatives"
557
+ - id: create_media_buy
558
+ title: "Create media buy with catalog packages"
559
+ narrative: |
560
+ The buyer creates the media buy with packages that reference the synced catalog.
561
+ Each package has a catalogs[] array specifying which catalog feeds drive the
562
+ dynamic creative for that line item.
563
+
564
+ Your platform optimizes across catalog items within each package's budget
565
+ envelope — showing the ribeye to steak lovers and the seafood tower to
566
+ seafood enthusiasts.
567
+ task: create_media_buy
568
+ schema_ref: "media-buy/create-media-buy-request.json"
569
+ response_schema_ref: "media-buy/create-media-buy-response.json"
570
+ doc_ref: "/media-buy/task-reference/create_media_buy"
571
+ comply_scenario: create_media_buy
572
+ stateful: true
573
+ expected: |
574
+ Create the media buy with catalog-driven packages. Return:
575
+ - media_buy_id
576
+ - status: active
577
+ - packages with catalog references preserved
578
+
579
+ sample_request:
580
+ brand:
581
+ domain: "amsterdam-steakhouse.example"
582
+ account:
583
+ brand:
584
+ domain: "amsterdam-steakhouse.example"
585
+ operator: "pinnacle-agency.example"
586
+ start_time: "2026-04-07T00:00:00Z"
587
+ end_time: "2026-06-30T23:59:59Z"
588
+ packages:
589
+ - product_id: "local_display_dynamic"
590
+ pricing_option_id: "cpm_standard"
591
+ budget: 5000
592
+ catalogs:
593
+ - catalog_id: "menu_spring_2026"
594
+ type: "product"
595
+
596
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_create_buy_create_media_buy"
597
+ context:
598
+ correlation_id: "sales_catalog_driven--create_media_buy"
599
+ context_outputs:
600
+ - name: media_buy_id
601
+ path: "media_buy_id"
602
+ validations:
603
+ - check: response_schema
604
+ description: "Response matches create-media-buy-response.json schema"
605
+
606
+ - check: field_present
607
+ path: "context"
608
+ description: "Response echoes back the context object"
609
+ - check: field_value
610
+ path: "context.correlation_id"
611
+ value: "sales_catalog_driven--create_media_buy"
612
+ description: "Context correlation_id returned unchanged"
613
+ - id: event_setup
614
+ title: "Conversion tracking setup"
615
+ narrative: |
616
+ The buyer configures event sources so your platform can attribute conversions to
617
+ catalog items. For a restaurant, the events are reservations and walk-ins. For
618
+ retail, they are purchases and add-to-carts.
619
+
620
+ Your platform returns setup snippets (pixel code, SDK instructions) that the
621
+ buyer installs on their conversion surfaces.
622
+
623
+ steps:
624
+ - id: sync_event_sources
625
+ title: "Configure event sources"
626
+ narrative: |
627
+ The buyer tells your platform where conversion events will come from —
628
+ a website pixel, a mobile SDK, or a server-to-server integration. Your
629
+ platform returns the integration code.
630
+ task: sync_event_sources
631
+ schema_ref: "media-buy/sync-event-sources-request.json"
632
+ response_schema_ref: "media-buy/sync-event-sources-response.json"
633
+ doc_ref: "/media-buy/task-reference/sync_event_sources"
634
+ stateful: true
635
+ expected: |
636
+ Return event sources with:
637
+ - event_source_id and seller_id
638
+ - setup.snippet: integration code (JavaScript pixel, HTML tag, or pixel URL)
639
+ - setup.instructions: human-readable integration guide
640
+ - action: created or updated
641
+
642
+ sample_request:
643
+ account:
644
+ brand:
645
+ domain: "amsterdam-steakhouse.example"
646
+ operator: "pinnacle-agency.example"
647
+ event_sources:
648
+ - event_source_id: "amsterdam_website"
649
+ name: "Amsterdam Steakhouse Website"
650
+ event_types: ["purchase", "add_to_cart", "page_view", "lead"]
651
+ allowed_domains: ["amsterdam-steakhouse.example", "book.amsterdam-steakhouse.example"]
652
+
653
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_event_setup_sync_event_sources"
654
+ context:
655
+ correlation_id: "sales_catalog_driven--sync_event_sources"
656
+ ext:
657
+ test_platform:
658
+ test_run: true
659
+ validations:
660
+ - check: response_schema
661
+ description: "Response matches sync-event-sources-response.json schema"
662
+ - check: field_present
663
+ path: "event_sources[0].setup.snippet"
664
+ description: "Event source includes setup snippet"
665
+
666
+ - check: field_present
667
+ path: "context"
668
+ description: "Response echoes back the context object"
669
+ - check: field_value
670
+ path: "context.correlation_id"
671
+ value: "sales_catalog_driven--sync_event_sources"
672
+ description: "Context correlation_id returned unchanged"
673
+ - id: conversion_tracking
674
+ title: "Log conversions"
675
+ narrative: |
676
+ The campaign is running and customers are converting. The buyer logs conversion
677
+ events back to your platform, attributing them to catalog items via content_ids.
678
+
679
+ When someone books a reservation after seeing the ribeye ad, the event includes
680
+ content_ids: ["ribeye_36oz"] — linking the conversion to the catalog item that
681
+ drove it. Your platform uses this signal to optimize which items to show.
682
+
683
+ steps:
684
+ - id: log_events
685
+ title: "Send conversion events"
686
+ narrative: |
687
+ The buyer sends a batch of conversion events. Each event includes the event
688
+ type, value, and content_ids linking to catalog items. Your platform processes
689
+ these for attribution and optimization.
690
+ task: log_event
691
+ schema_ref: "media-buy/log-event-request.json"
692
+ response_schema_ref: "media-buy/log-event-response.json"
693
+ doc_ref: "/media-buy/task-reference/log_event"
694
+ stateful: true
695
+ expected: |
696
+ Process the events and return:
697
+ - events_received and events_processed counts
698
+ - partial_failures for events that failed validation
699
+ - match_quality: how well events matched to ad exposures (0.0-1.0)
700
+
701
+ sample_request:
702
+ account:
703
+ brand:
704
+ domain: "amsterdam-steakhouse.example"
705
+ operator: "pinnacle-agency.example"
706
+ event_source_id: "amsterdam_website"
707
+ events:
708
+ - event_id: "evt_001"
709
+ event_type: "purchase"
710
+ event_time: "2026-04-15T19:30:00Z"
711
+ content_ids: ["ribeye_36oz"]
712
+ value: 89.00
713
+ currency: "USD"
714
+ - event_id: "evt_002"
715
+ event_type: "lead"
716
+ event_time: "2026-04-15T20:15:00Z"
717
+ content_ids: ["wagyu_flight"]
718
+ value: 195.00
719
+ currency: "USD"
720
+ - event_id: "evt_003"
721
+ event_type: "page_view"
722
+ event_time: "2026-04-15T20:45:00Z"
723
+ content_ids: ["seafood_tower"]
724
+
725
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_conversion_tracking_log_events"
726
+ context:
727
+ correlation_id: "sales_catalog_driven--log_events"
728
+ validations:
729
+ - check: response_schema
730
+ description: "Response matches log-event-response.json schema"
731
+ - check: field_present
732
+ path: "events_received"
733
+ description: "Response reports events received"
734
+ - check: field_present
735
+ path: "match_quality"
736
+ description: "Response includes match quality score"
737
+
738
+ - check: field_present
739
+ path: "context"
740
+ description: "Response echoes back the context object"
741
+ - check: field_value
742
+ path: "context.correlation_id"
743
+ value: "sales_catalog_driven--log_events"
744
+ description: "Context correlation_id returned unchanged"
745
+ - id: optimization_loop
746
+ title: "Performance feedback and optimization"
747
+ narrative: |
748
+ The buyer closes the optimization loop by telling your platform how the campaign
749
+ is performing against their goals. A performance_index above 1.0 means the
750
+ campaign is exceeding expectations — your platform should maintain or increase
751
+ delivery. Below 1.0 means underperforming — your platform should adjust targeting,
752
+ item selection, or pacing.
753
+
754
+ steps:
755
+ - id: provide_feedback
756
+ title: "Submit performance feedback"
757
+ narrative: |
758
+ The buyer reports that the campaign is driving 1.4x the expected reservation
759
+ rate. Your platform uses this signal to optimize delivery — showing more of
760
+ the high-performing catalog items and adjusting bid strategies.
761
+ task: provide_performance_feedback
762
+ schema_ref: "media-buy/provide-performance-feedback-request.json"
763
+ response_schema_ref: "media-buy/provide-performance-feedback-response.json"
764
+ doc_ref: "/media-buy/task-reference/provide_performance_feedback"
765
+ stateful: true
766
+ expected: |
767
+ Acknowledge the feedback. The seller should adjust delivery optimization
768
+ based on the performance_index signal.
769
+
770
+ sample_request:
771
+ account:
772
+ brand:
773
+ domain: "amsterdam-steakhouse.example"
774
+ operator: "pinnacle-agency.example"
775
+ media_buy_id: "$context.media_buy_id"
776
+ measurement_period:
777
+ start: "2026-04-07T00:00:00Z"
778
+ end: "2026-04-14T23:59:59Z"
779
+ performance_index: 1.4
780
+ metric_type: "conversion_rate"
781
+ feedback_source: "buyer_attribution"
782
+
783
+ idempotency_key: "$generate:uuid_v4#sales_catalog_driven_optimization_loop_provide_feedback"
784
+ context:
785
+ correlation_id: "sales_catalog_driven--provide_feedback"
786
+ ext:
787
+ test_platform:
788
+ test_run: true
789
+ validations:
790
+ - check: response_schema
791
+ description: "Response matches provide-performance-feedback-response.json schema"
792
+ - check: field_value
793
+ path: "success"
794
+ value: true
795
+ description: "Feedback accepted"
796
+
797
+ - check: field_present
798
+ path: "context"
799
+ description: "Response echoes back the context object"
800
+ - check: field_value
801
+ path: "context.correlation_id"
802
+ value: "sales_catalog_driven--provide_feedback"
803
+ description: "Context correlation_id returned unchanged"
804
+ - id: check_delivery
805
+ title: "Monitor delivery with catalog attribution"
806
+ narrative: |
807
+ The buyer checks delivery metrics to see which catalog items are driving
808
+ performance and how spend is allocated across the product feed.
809
+ task: get_media_buy_delivery
810
+ schema_ref: "media-buy/get-media-buy-delivery-request.json"
811
+ response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
812
+ doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
813
+ comply_scenario: reporting_flow
814
+ stateful: true
815
+ expected: |
816
+ Return delivery metrics including impressions, clicks, spend, and
817
+ conversion data attributed to catalog items.
818
+
819
+ sample_request:
820
+ account:
821
+ brand:
822
+ domain: "amsterdam-steakhouse.example"
823
+ operator: "pinnacle-agency.example"
824
+ media_buy_ids:
825
+ - "$context.media_buy_id"
826
+ include_package_daily_breakdown: true
827
+
828
+ context:
829
+ correlation_id: "sales_catalog_driven--check_delivery"
830
+ validations:
831
+ - check: response_schema
832
+ description: "Response matches get-media-buy-delivery-response.json schema"
833
+
834
+ - check: field_present
835
+ path: "context"
836
+ description: "Response echoes back the context object"
837
+ - check: field_value
838
+ path: "context.correlation_id"
839
+ value: "sales_catalog_driven--check_delivery"
840
+ description: "Context correlation_id returned unchanged"