@adcp/sdk 7.10.2 → 7.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/compliance/cache/3.1.0-rc.2/domains/brand/index.yaml +160 -0
  2. package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/distributed_brand_resolution.yaml +415 -0
  3. package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/single_side_trust_extension.yaml +454 -0
  4. package/compliance/cache/3.1.0-rc.2/domains/creative/index.yaml +339 -0
  5. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/billing_out_of_band.yaml +153 -0
  6. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/canonical_supported_formats.yaml +212 -0
  7. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
  8. package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/native_in_feed.yaml +543 -0
  9. package/compliance/cache/3.1.0-rc.2/domains/governance/index.yaml +682 -0
  10. package/compliance/cache/3.1.0-rc.2/domains/media-buy/index.yaml +789 -0
  11. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/audience_buy_flow.yaml +380 -0
  12. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/available_actions.yaml +565 -0
  13. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
  14. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/canonical_formats.yaml +861 -0
  15. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
  16. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
  17. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/create_media_buy_async.yaml +234 -0
  18. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
  19. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_reception.yaml +247 -0
  20. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/delivery_reporting.yaml +357 -0
  21. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment.yaml +633 -0
  22. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
  23. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/event_dedup_flow.yaml +399 -0
  24. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
  25. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_approved.yaml +214 -0
  26. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_conditions.yaml +199 -0
  27. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied.yaml +204 -0
  28. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
  29. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/invalid_transitions.yaml +289 -0
  30. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
  31. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
  32. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_accountability.yaml +244 -0
  33. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
  34. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
  35. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
  36. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
  37. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow.yaml +428 -0
  38. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
  39. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/product_signal_targeting.yaml +373 -0
  40. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize.yaml +399 -0
  41. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
  42. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
  43. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
  44. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_enforcement.yaml +517 -0
  45. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
  46. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/reach_buy_flow.yaml +823 -0
  47. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
  48. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_products.yaml +148 -0
  49. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
  50. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
  51. package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
  52. package/compliance/cache/3.1.0-rc.2/domains/media-buy/state-machine.yaml +442 -0
  53. package/compliance/cache/3.1.0-rc.2/domains/signals/index.yaml +266 -0
  54. package/compliance/cache/3.1.0-rc.2/domains/sponsored-intelligence/index.yaml +256 -0
  55. package/compliance/cache/3.1.0-rc.2/index.json +356 -0
  56. package/compliance/cache/3.1.0-rc.2/protocols/brand/index.yaml +160 -0
  57. package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/distributed_brand_resolution.yaml +415 -0
  58. package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/single_side_trust_extension.yaml +454 -0
  59. package/compliance/cache/3.1.0-rc.2/protocols/creative/index.yaml +339 -0
  60. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/billing_out_of_band.yaml +153 -0
  61. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/canonical_supported_formats.yaml +212 -0
  62. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
  63. package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/native_in_feed.yaml +543 -0
  64. package/compliance/cache/3.1.0-rc.2/protocols/governance/index.yaml +682 -0
  65. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/index.yaml +789 -0
  66. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/audience_buy_flow.yaml +380 -0
  67. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/available_actions.yaml +565 -0
  68. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
  69. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/canonical_formats.yaml +861 -0
  70. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
  71. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
  72. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/create_media_buy_async.yaml +234 -0
  73. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
  74. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_reception.yaml +247 -0
  75. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/delivery_reporting.yaml +357 -0
  76. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment.yaml +633 -0
  77. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
  78. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/event_dedup_flow.yaml +399 -0
  79. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
  80. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_approved.yaml +214 -0
  81. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_conditions.yaml +199 -0
  82. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied.yaml +204 -0
  83. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
  84. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/invalid_transitions.yaml +289 -0
  85. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
  86. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
  87. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_accountability.yaml +244 -0
  88. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
  89. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
  90. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
  91. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
  92. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow.yaml +428 -0
  93. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
  94. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/product_signal_targeting.yaml +373 -0
  95. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize.yaml +399 -0
  96. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
  97. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
  98. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
  99. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_enforcement.yaml +517 -0
  100. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
  101. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/reach_buy_flow.yaml +823 -0
  102. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
  103. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_products.yaml +148 -0
  104. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
  105. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
  106. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
  107. package/compliance/cache/3.1.0-rc.2/protocols/media-buy/state-machine.yaml +442 -0
  108. package/compliance/cache/3.1.0-rc.2/protocols/signals/index.yaml +266 -0
  109. package/compliance/cache/3.1.0-rc.2/protocols/sponsored-intelligence/index.yaml +256 -0
  110. package/compliance/cache/3.1.0-rc.2/specialisms/audience-sync/index.yaml +313 -0
  111. package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/index.yaml +350 -0
  112. package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/scenarios/governance_denied.yaml +226 -0
  113. package/compliance/cache/3.1.0-rc.2/specialisms/collection-lists/index.yaml +359 -0
  114. package/compliance/cache/3.1.0-rc.2/specialisms/content-standards/index.yaml +572 -0
  115. package/compliance/cache/3.1.0-rc.2/specialisms/creative-ad-server/index.yaml +409 -0
  116. package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/generative-seller.yaml +807 -0
  117. package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/index.yaml +758 -0
  118. package/compliance/cache/3.1.0-rc.2/specialisms/creative-template/index.yaml +510 -0
  119. package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/index.yaml +143 -0
  120. package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +117 -0
  121. package/compliance/cache/3.1.0-rc.2/specialisms/governance-delivery-monitor/index.yaml +441 -0
  122. package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/denied.yaml +221 -0
  123. package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/index.yaml +330 -0
  124. package/compliance/cache/3.1.0-rc.2/specialisms/property-lists/index.yaml +482 -0
  125. package/compliance/cache/3.1.0-rc.2/specialisms/sales-broadcast-tv/index.yaml +738 -0
  126. package/compliance/cache/3.1.0-rc.2/specialisms/sales-catalog-driven/index.yaml +840 -0
  127. package/compliance/cache/3.1.0-rc.2/specialisms/sales-guaranteed/index.yaml +601 -0
  128. package/compliance/cache/3.1.0-rc.2/specialisms/sales-non-guaranteed/index.yaml +546 -0
  129. package/compliance/cache/3.1.0-rc.2/specialisms/sales-proposal-mode/index.yaml +586 -0
  130. package/compliance/cache/3.1.0-rc.2/specialisms/sales-social/index.yaml +919 -0
  131. package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/index.yaml +424 -0
  132. package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/scenarios/governance_denied.yaml +210 -0
  133. package/compliance/cache/3.1.0-rc.2/specialisms/signal-owned/index.yaml +317 -0
  134. package/compliance/cache/3.1.0-rc.2/specialisms/sponsored-intelligence/index.yaml +59 -0
  135. package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor-live.yaml +78 -0
  136. package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor.yaml +223 -0
  137. package/compliance/cache/3.1.0-rc.2/test-kits/billing-gate-runner.yaml +115 -0
  138. package/compliance/cache/3.1.0-rc.2/test-kits/bistro-oranje.yaml +126 -0
  139. package/compliance/cache/3.1.0-rc.2/test-kits/distributed-brand-runner.yaml +281 -0
  140. package/compliance/cache/3.1.0-rc.2/test-kits/nova-motors.yaml +262 -0
  141. package/compliance/cache/3.1.0-rc.2/test-kits/osei-natural.yaml +126 -0
  142. package/compliance/cache/3.1.0-rc.2/test-kits/parallel-dispatch-runner.yaml +196 -0
  143. package/compliance/cache/3.1.0-rc.2/test-kits/rate-limit-trip-runner.yaml +172 -0
  144. package/compliance/cache/3.1.0-rc.2/test-kits/signed-requests-runner.yaml +155 -0
  145. package/compliance/cache/3.1.0-rc.2/test-kits/single-side-trust-runner.yaml +294 -0
  146. package/compliance/cache/3.1.0-rc.2/test-kits/substitution-observer-runner.yaml +688 -0
  147. package/compliance/cache/3.1.0-rc.2/test-kits/summit-foods.yaml +125 -0
  148. package/compliance/cache/3.1.0-rc.2/test-kits/webhook-receiver-runner.yaml +265 -0
  149. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/001-minimal-plan.json +43 -0
  150. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/002-full-plan.json +217 -0
  151. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
  152. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
  153. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
  154. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
  155. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
  156. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
  157. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
  158. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
  159. package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
  160. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/README.md +220 -0
  161. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/canonicalization.json +241 -0
  162. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/keys.json +60 -0
  163. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
  164. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
  165. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
  166. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
  167. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
  168. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
  169. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
  170. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
  171. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
  172. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
  173. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
  174. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
  175. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
  176. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
  177. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
  178. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
  179. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
  180. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
  181. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
  182. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
  183. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
  184. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
  185. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
  186. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
  187. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
  188. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
  189. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
  190. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +26 -0
  191. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/001-basic-post.json +30 -0
  192. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
  193. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/003-es256-post.json +30 -0
  194. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
  195. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
  196. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
  197. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
  198. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
  199. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
  200. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
  201. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
  202. package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
  203. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/README.md +211 -0
  204. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/keys.json +61 -0
  205. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
  206. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
  207. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
  208. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
  209. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
  210. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
  211. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
  212. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
  213. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
  214. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
  215. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
  216. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
  217. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
  218. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
  219. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
  220. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
  221. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
  222. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
  223. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
  224. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
  225. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
  226. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
  227. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
  228. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
  229. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
  230. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
  231. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
  232. package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
  233. package/compliance/cache/3.1.0-rc.2/universal/billing-gate-dispatch.yaml +450 -0
  234. package/compliance/cache/3.1.0-rc.2/universal/canonical-format-validate-input.yaml +640 -0
  235. package/compliance/cache/3.1.0-rc.2/universal/capability-discovery.yaml +125 -0
  236. package/compliance/cache/3.1.0-rc.2/universal/collection-lists-pagination-integrity.yaml +306 -0
  237. package/compliance/cache/3.1.0-rc.2/universal/comply-controller-mode-gate.yaml +141 -0
  238. package/compliance/cache/3.1.0-rc.2/universal/content-standards-pagination-integrity.yaml +326 -0
  239. package/compliance/cache/3.1.0-rc.2/universal/deterministic-testing.yaml +1430 -0
  240. package/compliance/cache/3.1.0-rc.2/universal/error-compliance-signals.yaml +377 -0
  241. package/compliance/cache/3.1.0-rc.2/universal/error-compliance.yaml +528 -0
  242. package/compliance/cache/3.1.0-rc.2/universal/fictional-entities.yaml +307 -0
  243. package/compliance/cache/3.1.0-rc.2/universal/get-media-buys-pagination-integrity.yaml +160 -0
  244. package/compliance/cache/3.1.0-rc.2/universal/get-signals-pagination-integrity.yaml +210 -0
  245. package/compliance/cache/3.1.0-rc.2/universal/idempotency.yaml +861 -0
  246. package/compliance/cache/3.1.0-rc.2/universal/notification-config-event-scope.yaml +119 -0
  247. package/compliance/cache/3.1.0-rc.2/universal/notification-config-lifecycle.yaml +337 -0
  248. package/compliance/cache/3.1.0-rc.2/universal/notification-config-rejections.yaml +107 -0
  249. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-creative-formats.yaml +265 -0
  250. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-list-accounts.yaml +245 -0
  251. package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity.yaml +263 -0
  252. package/compliance/cache/3.1.0-rc.2/universal/property-lists-pagination-integrity.yaml +307 -0
  253. package/compliance/cache/3.1.0-rc.2/universal/read-tool-idempotency.yaml +405 -0
  254. package/compliance/cache/3.1.0-rc.2/universal/runner-output-contract.yaml +1285 -0
  255. package/compliance/cache/3.1.0-rc.2/universal/schema-validation-signals.yaml +181 -0
  256. package/compliance/cache/3.1.0-rc.2/universal/schema-validation.yaml +548 -0
  257. package/compliance/cache/3.1.0-rc.2/universal/security.yaml +539 -0
  258. package/compliance/cache/3.1.0-rc.2/universal/signed-requests.yaml +217 -0
  259. package/compliance/cache/3.1.0-rc.2/universal/stale-response-advisory.yaml +295 -0
  260. package/compliance/cache/3.1.0-rc.2/universal/storyboard-schema.yaml +2194 -0
  261. package/compliance/cache/3.1.0-rc.2/universal/v3-envelope-integrity.yaml +117 -0
  262. package/compliance/cache/3.1.0-rc.2/universal/version-negotiation.yaml +130 -0
  263. package/compliance/cache/3.1.0-rc.2/universal/webhook-emission.yaml +411 -0
  264. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-bulk-webhooks.yaml +82 -0
  265. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-product-webhooks.yaml +83 -0
  266. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-products.yaml +151 -0
  267. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signal-webhooks.yaml +83 -0
  268. package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signals.yaml +149 -0
  269. package/dist/lib/index.d.ts +1 -1
  270. package/dist/lib/index.d.ts.map +1 -1
  271. package/dist/lib/index.js +9 -5
  272. package/dist/lib/index.js.map +1 -1
  273. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  274. package/dist/lib/testing/storyboard/default-invariants.js +30 -1
  275. package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
  276. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  277. package/dist/lib/testing/storyboard/runner.js +84 -21
  278. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  279. package/dist/lib/testing/storyboard/types.d.ts +21 -0
  280. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  281. package/dist/lib/testing/storyboard/types.js.map +1 -1
  282. package/dist/lib/testing/types.d.ts +9 -0
  283. package/dist/lib/testing/types.d.ts.map +1 -1
  284. package/dist/lib/types/schemas.generated.d.ts +6707 -12040
  285. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  286. package/dist/lib/types/schemas.generated.js +1 -1
  287. package/dist/lib/types/schemas.generated.js.map +1 -1
  288. package/dist/lib/utils/signal-id-builders.d.ts +19 -0
  289. package/dist/lib/utils/signal-id-builders.d.ts.map +1 -1
  290. package/dist/lib/utils/signal-id-builders.js +30 -0
  291. package/dist/lib/utils/signal-id-builders.js.map +1 -1
  292. package/dist/lib/utils/tool-request-schemas.d.ts.map +1 -1
  293. package/dist/lib/utils/tool-request-schemas.js +3 -0
  294. package/dist/lib/utils/tool-request-schemas.js.map +1 -1
  295. package/dist/lib/v2/projection/constants.d.ts +28 -0
  296. package/dist/lib/v2/projection/constants.d.ts.map +1 -0
  297. package/dist/lib/v2/projection/constants.js +31 -0
  298. package/dist/lib/v2/projection/constants.js.map +1 -0
  299. package/dist/lib/v2/projection/registry.d.ts.map +1 -1
  300. package/dist/lib/v2/projection/registry.js +9 -4
  301. package/dist/lib/v2/projection/registry.js.map +1 -1
  302. package/dist/lib/version.d.ts +3 -3
  303. package/dist/lib/version.js +3 -3
  304. package/package.json +1 -1
  305. package/skills/SHAPE-GOTCHAS.md +5 -0
@@ -0,0 +1,919 @@
1
+ id: sales_social
2
+ version: "1.0.0"
3
+ title: "Social platform"
4
+ protocol: media-buy
5
+ category: sales_social
6
+ summary: "Social media platform that accepts audience segments, native creatives, and conversion events from buyer agents."
7
+ track: audiences
8
+ required_tools:
9
+ - sync_governance
10
+ - sync_audiences
11
+ - sync_catalogs
12
+ - sync_creatives
13
+ - sync_event_sources
14
+ - preview_creative
15
+ requires_scenarios:
16
+ - governance_aware_seller/governance_multi_agent_rejected
17
+
18
+ # Cross-step assertion (adcp#2664). status.monotonic rejects resource
19
+ # status transitions observed across steps that aren't on the spec
20
+ # lifecycle graph — e.g. approved → processing on a creative asset or
21
+ # active → pending_creatives on a media_buy.
22
+ invariants:
23
+ - status.monotonic
24
+
25
+ narrative: |
26
+ You run a social media platform — Snap, Meta, TikTok, Pinterest, or any walled garden that
27
+ sells advertising through audience-based targeting and native creative formats. A buyer agent
28
+ connects to set up an account, push audience segments, sync native creatives, track conversion
29
+ events, and monitor spend.
30
+
31
+ Unlike open-web media buys, social platforms require the buyer to push assets into the
32
+ platform's environment. Audiences are activated via sync_audiences, creatives are pushed via
33
+ sync_creatives in platform-native formats, and conversion events flow back via log_event.
34
+
35
+ This storyboard covers the social platform integration from the buyer's perspective:
36
+ account setup, audience activation, native creative push, event tracking, and financial
37
+ monitoring.
38
+
39
+ context:
40
+ governance_agent_url: "https://test-agent.adcontextprotocol.org"
41
+
42
+ agent:
43
+ interaction_model: media_buy_seller
44
+ capabilities:
45
+ - sells_media
46
+ - accepts_briefs
47
+ - supports_non_guaranteed
48
+ examples:
49
+ - "Snap"
50
+ - "Meta"
51
+ - "TikTok"
52
+ - "Pinterest"
53
+
54
+ caller:
55
+ role: buyer_agent
56
+ example: "Scope3 (DSP)"
57
+
58
+ prerequisites:
59
+ description: |
60
+ The caller needs a brand identity, operator credentials, audience segment definitions,
61
+ and native creative assets. The test kit provides a sample brand with creative assets
62
+ suitable for social formats.
63
+ test_kit: "test-kits/acme-outdoor.yaml"
64
+
65
+ phases:
66
+ - id: capability_discovery
67
+ title: "Capability discovery"
68
+ narrative: |
69
+ The buyer calls get_adcp_capabilities to confirm the agent supports media buying before syncing audiences and native creatives.
70
+
71
+ steps:
72
+ - id: get_capabilities
73
+ title: "Check agent capabilities"
74
+ narrative: |
75
+ Verify that the agent declares the expected protocol support before
76
+ proceeding with domain-specific operations.
77
+ task: get_adcp_capabilities
78
+ schema_ref: "protocol/get-adcp-capabilities-request.json"
79
+ response_schema_ref: "protocol/get-adcp-capabilities-response.json"
80
+ doc_ref: "/protocol/get_adcp_capabilities"
81
+ comply_scenario: capability_discovery
82
+ stateful: false
83
+ expected: |
84
+ Return capabilities declaring media_buy in supported_protocols, confirming the agent sells media.
85
+ sample_request:
86
+ context:
87
+ correlation_id: "sales_social--get_capabilities"
88
+ validations:
89
+ - check: response_schema
90
+ description: "Response matches get-adcp-capabilities-response.json schema"
91
+ - check: field_present
92
+ path: "supported_protocols"
93
+ description: "Agent declares supported protocols"
94
+
95
+ - check: field_present
96
+ path: "context"
97
+ description: "Response echoes back the context object"
98
+ - check: field_value
99
+ path: "context.correlation_id"
100
+ value: "sales_social--get_capabilities"
101
+ description: "Context correlation_id returned unchanged"
102
+ - id: account_setup
103
+ title: "Account setup"
104
+ narrative: |
105
+ The buyer establishes an account with the social platform and verifies its status.
106
+ Social platforms often require advertiser verification before accepting ad spend.
107
+
108
+ steps:
109
+ - id: sync_accounts
110
+ title: "Register advertiser account"
111
+ narrative: |
112
+ The buyer registers their brand and operator with the social platform. The platform
113
+ provisions an advertiser account and returns its status. Social platforms may require
114
+ identity verification before the account goes active.
115
+ task: sync_accounts
116
+ schema_ref: "account/sync-accounts-request.json"
117
+ response_schema_ref: "account/sync-accounts-response.json"
118
+ doc_ref: "/accounts/tasks/sync_accounts"
119
+ stateful: true
120
+ expected: |
121
+ Return the advertiser account with:
122
+ - account_id: platform's identifier
123
+ - status: active or pending_approval (if verification required)
124
+ - account_scope: how the platform scopes this relationship
125
+
126
+ sample_request:
127
+ accounts:
128
+ - brand:
129
+ domain: "acmeoutdoor.example"
130
+ operator: "pinnacle-agency.example"
131
+ billing: "operator"
132
+
133
+ idempotency_key: "$generate:uuid_v4#sales_social_account_setup_sync_accounts"
134
+ context:
135
+ correlation_id: "sales_social--sync_accounts"
136
+ validations:
137
+ - check: response_schema
138
+ description: "Response matches sync-accounts-response.json schema"
139
+ - check: field_present
140
+ path: "accounts[0].account_id"
141
+ description: "Account has a platform-assigned ID"
142
+
143
+ - check: field_present
144
+ path: "context"
145
+ description: "Response echoes back the context object"
146
+ - check: field_value
147
+ path: "context.correlation_id"
148
+ value: "sales_social--sync_accounts"
149
+ description: "Context correlation_id returned unchanged"
150
+ - id: list_accounts
151
+ title: "Verify account status"
152
+ narrative: |
153
+ The buyer checks which accounts exist on the platform and their current status.
154
+ This confirms the account is active and shows any pending setup requirements.
155
+ task: list_accounts
156
+ schema_ref: "account/list-accounts-request.json"
157
+ response_schema_ref: "account/list-accounts-response.json"
158
+ doc_ref: "/accounts/tasks/list_accounts"
159
+ stateful: true
160
+ # Explicit-mode social platforms (Snap, Meta, TikTok) pre-provision
161
+ # advertiser accounts out-of-band — `sync_accounts` is intentionally
162
+ # missing_tool, with `list_accounts` as the canonical alternative.
163
+ # Declaring the substitution here lets the runner waive the
164
+ # downstream missing_tool cascade when list_accounts passes.
165
+ # See adcontextprotocol/adcp#3734.
166
+ provides_state_for: sync_accounts
167
+ expected: |
168
+ Return accounts matching the query:
169
+ - accounts array with status, account_id, brand, operator
170
+ - Active accounts ready for ad operations
171
+ - Pending accounts with accounts[].setup.url populated if verification is needed
172
+
173
+ sample_request:
174
+ context:
175
+ correlation_id: "sales_social--list_accounts"
176
+ validations:
177
+ - check: response_schema
178
+ description: "Response matches list-accounts-response.json schema"
179
+ - check: field_present
180
+ path: "accounts"
181
+ description: "Response contains accounts array"
182
+
183
+ - check: field_present
184
+ path: "context"
185
+ description: "Response echoes back the context object"
186
+ - check: field_value
187
+ path: "context.correlation_id"
188
+ value: "sales_social--list_accounts"
189
+ description: "Context correlation_id returned unchanged"
190
+ - id: sync_governance
191
+ title: "Register governance agent"
192
+ narrative: |
193
+ The buyer registers the configured governance agent on the advertiser
194
+ account before pushing audiences, creatives, catalogs, or conversion
195
+ events that can affect spend.
196
+ task: sync_governance
197
+ schema_ref: "account/sync-governance-request.json"
198
+ response_schema_ref: "account/sync-governance-response.json"
199
+ doc_ref: "/accounts/tasks/sync_governance"
200
+ stateful: true
201
+ expected: |
202
+ Acknowledge governance registration for the account:
203
+ - status: synced
204
+ - governance_agents[0].url echoes the configured governance agent
205
+
206
+ sample_request:
207
+ accounts:
208
+ - account:
209
+ brand:
210
+ domain: "acmeoutdoor.example"
211
+ operator: "pinnacle-agency.example"
212
+ governance_agents:
213
+ - url: "$context.governance_agent_url"
214
+ authentication:
215
+ schemes: ["Bearer"]
216
+ credentials: "gov-token-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
217
+
218
+ idempotency_key: "$generate:uuid_v4#sales_social_account_setup_sync_governance"
219
+ context:
220
+ correlation_id: "sales_social--sync_governance"
221
+ validations:
222
+ - check: response_schema
223
+ description: "Response matches sync-governance-response.json schema"
224
+ - check: field_value
225
+ path: "accounts[0].status"
226
+ value: "synced"
227
+ description: "Governance agent is registered on the advertiser account"
228
+ - check: field_present
229
+ path: "context"
230
+ description: "Response echoes back the context object"
231
+ - check: field_value
232
+ path: "context.correlation_id"
233
+ value: "sales_social--sync_governance"
234
+ description: "Context correlation_id returned unchanged"
235
+ - id: audience_sync
236
+ title: "Audience activation"
237
+ narrative: |
238
+ The buyer pushes audience segments to the platform. Social platforms use these segments
239
+ for targeting — the buyer defines who to reach, and the platform matches against its
240
+ user base.
241
+
242
+ steps:
243
+ - id: sync_audiences
244
+ title: "Push audience segments"
245
+ narrative: |
246
+ The buyer syncs audience segment definitions to the platform. Each segment includes
247
+ targeting criteria that the platform evaluates against its user graph. The platform
248
+ returns match rates and segment status.
249
+ task: sync_audiences
250
+ schema_ref: "media-buy/sync-audiences-request.json"
251
+ response_schema_ref: "media-buy/sync-audiences-response.json"
252
+ doc_ref: "/media-buy/task-reference/sync_audiences"
253
+ comply_scenario: sync_audiences
254
+ stateful: true
255
+ expected: |
256
+ Accept and process audience segments:
257
+ - Per-segment status: active, processing, or rejected
258
+ - Match rate estimates where available
259
+ - Platform-assigned segment IDs
260
+
261
+ sample_request:
262
+ account:
263
+ brand:
264
+ domain: "acmeoutdoor.example"
265
+ operator: "pinnacle-agency.example"
266
+ audiences:
267
+ - audience_id: "outdoor_enthusiasts_25_54"
268
+ name: "Outdoor enthusiasts 25-54"
269
+ description: "Adults 25-54 interested in hiking, camping, and outdoor gear"
270
+ # Realistic add[] payload forces adapters to call the upstream
271
+ # audience-upload endpoint rather than returning shape-valid
272
+ # responses from an empty-members branch. Hash values are
273
+ # fictional test vectors distinct from the audience_sync
274
+ # storyboard's fixtures to avoid cross-storyboard collision.
275
+ add:
276
+ - external_id: "acme-user-0001"
277
+ hashed_email: "a000000000000000000000000000000000000000000000000000000000000001"
278
+ - external_id: "acme-user-0002"
279
+ hashed_phone: "b000000000000000000000000000000000000000000000000000000000000002"
280
+
281
+ idempotency_key: "$generate:uuid_v4#sales_social_audience_sync_sync_audiences"
282
+ context:
283
+ correlation_id: "sales_social--sync_audiences"
284
+ validations:
285
+ - check: response_schema
286
+ description: "Response matches sync-audiences-response.json schema"
287
+
288
+ - check: field_present
289
+ path: "context"
290
+ description: "Response echoes back the context object"
291
+ - check: field_value
292
+ path: "context.correlation_id"
293
+ value: "sales_social--sync_audiences"
294
+ description: "Context correlation_id returned unchanged"
295
+ # Anti-façade: the adapter MUST forward the hashed identifiers to
296
+ # the upstream platform's audience-upload endpoint. Adopters who
297
+ # don't advertise query_upstream_traffic in list_scenarios grade
298
+ # this check not_applicable per the runner's forward-compat rule —
299
+ # opt-in by adopter capability.
300
+ - check: upstream_traffic
301
+ description: "sync_audiences caused upstream traffic carrying the supplied hashed identifiers"
302
+ min_count: 1
303
+ endpoint_pattern: "POST *"
304
+ identifier_paths:
305
+ - "audiences[*].add[*].hashed_email"
306
+ - "audiences[*].add[*].external_id"
307
+ - id: creative_push
308
+ title: "Native creative sync"
309
+ narrative: |
310
+ The buyer pushes native creative assets to the platform. Social platforms render ads
311
+ in their native format — the buyer provides assets (images, headlines, descriptions)
312
+ and the platform assembles them into the native ad unit.
313
+
314
+ steps:
315
+ - id: sync_creatives
316
+ title: "Push native creative assets"
317
+ narrative: |
318
+ The buyer syncs creative assets for native ad formats. The platform validates
319
+ each creative against its format requirements and returns per-creative status.
320
+ task: sync_creatives
321
+ schema_ref: "creative/sync-creatives-request.json"
322
+ response_schema_ref: "creative/sync-creatives-response.json"
323
+ doc_ref: "/creative/task-reference/sync_creatives"
324
+ comply_scenario: creative_sync
325
+ stateful: true
326
+ expected: |
327
+ Accept and validate native creatives:
328
+ - Per-creative action: created or updated
329
+ - Per-creative status: accepted, pending_review, or rejected
330
+ - Validation errors for rejected creatives
331
+
332
+ sample_request:
333
+ account:
334
+ brand:
335
+ domain: "acmeoutdoor.example"
336
+ operator: "pinnacle-agency.example"
337
+ creatives:
338
+ - creative_id: "native_trail_pro"
339
+ name: "Trail Pro 3000 - Native"
340
+ format_id:
341
+ agent_url: "https://social-platform.example.com"
342
+ id: "native_feed"
343
+ assets:
344
+ image:
345
+ asset_type: "image"
346
+ url: "https://cdn.pinnacle-agency.example/trail-pro-native.png"
347
+ width: 1200
348
+ height: 628
349
+ mime_type: "image/png"
350
+ headline:
351
+ asset_type: "text"
352
+ content: "Trail Pro 3000 — Built for the Summit"
353
+
354
+ idempotency_key: "$generate:uuid_v4#sales_social_creative_push_sync_creatives"
355
+ context:
356
+ correlation_id: "sales_social--sync_creatives"
357
+ validations:
358
+ - check: response_schema
359
+ description: "Response matches sync-creatives-response.json schema"
360
+
361
+ - check: field_present
362
+ path: "context"
363
+ description: "Response echoes back the context object"
364
+ - check: field_value
365
+ path: "context.correlation_id"
366
+ value: "sales_social--sync_creatives"
367
+ description: "Context correlation_id returned unchanged"
368
+ - id: catalog_driven_dynamic_ads
369
+ title: "Catalog-driven dynamic product ads"
370
+ narrative: |
371
+ Social platforms routinely ship dynamic product ads (Snap Dynamic Ads, Meta DPA,
372
+ TikTok Dynamic Showcase): the buyer pushes a product catalog and the platform
373
+ renders per-impression creative pulling product images, titles, and tracker URLs
374
+ from catalog items. The creative template references catalog-item macros
375
+ (`{SKU}`, `{GTIN}`) whose values resolve to the specific item shown at
376
+ impression time.
377
+
378
+ This phase exercises the catalog-acceptance leg of that flow: push a small inline
379
+ product catalog (with `content_id_type: "sku"` declared so macro resolution binds
380
+ to the right field), then push a DPA creative template using the AdCP-native
381
+ `product_carousel_3_to_10` format on `creative.adcontextprotocol.org`. Real
382
+ social-platform formats (Meta `native_carousel`, Snap dynamic ad set, TikTok
383
+ dynamic showcase) are platform-specific refinements tracked as follow-ups on
384
+ #2640; the AdCP-native format is the interop baseline.
385
+
386
+ Runtime substitution-safety — assertion that emitted tracker URLs percent-encode
387
+ catalog-item macro values per `docs/creative/universal-macros#substitution-safety-catalog-item-macros` —
388
+ runs in the separate `catalog_substitution_safety` phase below, gated on the
389
+ `substitution_observer_runner` test-kit contract.
390
+
391
+ steps:
392
+ - id: sync_product_catalog
393
+ title: "Push a product catalog"
394
+ narrative: |
395
+ The buyer pushes a small inline product catalog — the shape social platforms
396
+ accept for dynamic product ads. Your platform validates each item and
397
+ returns per-item approval status.
398
+ task: sync_catalogs
399
+ schema_ref: "media-buy/sync-catalogs-request.json"
400
+ response_schema_ref: "media-buy/sync-catalogs-response.json"
401
+ doc_ref: "/media-buy/task-reference/sync_catalogs"
402
+ stateful: true
403
+ expected: |
404
+ Return per-catalog results with catalog_id, action, item_count, and
405
+ items_approved counts.
406
+
407
+ sample_request:
408
+ account:
409
+ brand:
410
+ domain: "acmeoutdoor.example"
411
+ operator: "pinnacle-agency.example"
412
+ catalogs:
413
+ - catalog_id: "acme_gear_spring_2026"
414
+ type: "product"
415
+ content_id_type: "sku"
416
+ name: "Acme Outdoor — Spring 2026 Gear"
417
+ items:
418
+ - item_id: "trail_pro_3000"
419
+ title: "Trail Pro 3000 Backpack"
420
+ description: "65L expedition pack with torso-length adjustment."
421
+ url: "https://acmeoutdoor.example/gear/trail-pro-3000"
422
+ image_url: "https://cdn.acmeoutdoor.example/gear/trail-pro-3000.jpg"
423
+ price:
424
+ amount: 289.00
425
+ currency: "USD"
426
+ - item_id: "summit_tent_2p"
427
+ title: "Summit 2P Ultralight Tent"
428
+ description: "2-person four-season tent, 1.8kg packed."
429
+ url: "https://acmeoutdoor.example/gear/summit-tent-2p"
430
+ image_url: "https://cdn.acmeoutdoor.example/gear/summit-tent-2p.jpg"
431
+ price:
432
+ amount: 549.00
433
+ currency: "USD"
434
+
435
+ idempotency_key: "$generate:uuid_v4#sales_social_catalog_driven_dynamic_ads_sync_product_catalog"
436
+ context:
437
+ correlation_id: "sales_social--sync_product_catalog"
438
+ validations:
439
+ - check: response_schema
440
+ description: "Response matches sync-catalogs-response.json schema"
441
+ - check: field_present
442
+ path: "catalogs[0].catalog_id"
443
+ description: "Catalog has an ID"
444
+ - check: field_present
445
+ path: "catalogs[0].item_count"
446
+ description: "Catalog reports item count"
447
+ - check: field_present
448
+ path: "context"
449
+ description: "Response echoes back the context object"
450
+ - check: field_value
451
+ path: "context.correlation_id"
452
+ value: "sales_social--sync_product_catalog"
453
+ description: "Context correlation_id returned unchanged"
454
+
455
+ - id: sync_dpa_creative
456
+ title: "Push a dynamic product ad creative with catalog-item macros"
457
+ narrative: |
458
+ The buyer pushes a creative template whose tracker URLs reference
459
+ catalog-item macros (`{SKU}`, `{GTIN}`). At impression time, your platform
460
+ substitutes each catalog item's values into the template to render the
461
+ per-impression ad.
462
+
463
+ The template uses the AdCP-native `product_carousel_3_to_10` format
464
+ (see `docs/creative/channels/carousels.mdx`). Per #2620, values substituted
465
+ into URL contexts MUST be percent-encoded such that only RFC 3986 unreserved
466
+ characters remain unescaped; nested macro expansion is prohibited. This step
467
+ validates that the template is accepted into the library; runtime
468
+ substitution validation is tracked under #2638.
469
+ task: sync_creatives
470
+ schema_ref: "creative/sync-creatives-request.json"
471
+ response_schema_ref: "creative/sync-creatives-response.json"
472
+ doc_ref: "/creative/task-reference/sync_creatives"
473
+ comply_scenario: creative_sync
474
+ stateful: true
475
+ expected: |
476
+ Accept the DPA creative template. Per-creative action: created or updated.
477
+
478
+ sample_request:
479
+ account:
480
+ brand:
481
+ domain: "acmeoutdoor.example"
482
+ operator: "pinnacle-agency.example"
483
+ creatives:
484
+ - creative_id: "acme_dpa_spring_2026"
485
+ name: "Acme Outdoor — Spring DPA template"
486
+ format_id:
487
+ agent_url: "https://creative.adcontextprotocol.org"
488
+ id: "product_carousel_3_to_10"
489
+ assets:
490
+ impression_pixel:
491
+ asset_type: "url"
492
+ url: "https://track.acmeoutdoor.example/imp?sku={SKU}&gtin={GTIN}&mb={MEDIA_BUY_ID}"
493
+ click_url:
494
+ asset_type: "url"
495
+ url: "https://track.acmeoutdoor.example/click?sku={SKU}"
496
+
497
+ idempotency_key: "$generate:uuid_v4#sales_social_catalog_driven_dynamic_ads_sync_dpa_creative"
498
+ context:
499
+ correlation_id: "sales_social--sync_dpa_creative"
500
+ validations:
501
+ - check: response_schema
502
+ description: "Response matches sync-creatives-response.json schema"
503
+ - check: field_present
504
+ path: "context"
505
+ description: "Response echoes back the context object"
506
+ - check: field_value
507
+ path: "context.correlation_id"
508
+ value: "sales_social--sync_dpa_creative"
509
+ description: "Context correlation_id returned unchanged"
510
+ - id: catalog_substitution_safety
511
+ title: "Catalog-item macro substitution safety"
512
+ narrative: |
513
+ Per docs/creative/universal-macros#substitution-safety-catalog-item-macros,
514
+ sales agents MUST percent-encode catalog-item macro values such that only
515
+ RFC 3986 `unreserved` characters remain unescaped before substituting them
516
+ into a URL context. Nested macro expansion is prohibited.
517
+
518
+ This phase exercises the rule on the social-platform flow: push a probe
519
+ catalog whose items carry attacker-shaped `sku` values, push a DPA
520
+ creative template that binds to that catalog and references `{SKU}` in
521
+ its tracker URLs, then call `preview_creative` to render the bound
522
+ preview. The substitution-observer runner inspects `preview_html` from
523
+ the response and asserts each substituted `{SKU}` value is encoded per
524
+ the fixture at `static/test-vectors/catalog-macro-substitution.json`.
525
+
526
+ Scope note: this phase validates substitution on the PREVIEW surface
527
+ only. Social platforms with divergent preview vs impression-time
528
+ substitution paths MAY pass here while failing at serve time; serve-time
529
+ attestation is a known coverage limitation shared with creative-generative.
530
+ Real-impression observability for sales-social is deferred to a future
531
+ revision when platform attestation hooks become standardized.
532
+
533
+ The `expect_substitution_safe` step is gated on the
534
+ `substitution_observer_runner` test-kit contract (see
535
+ `test-kits/substitution-observer-runner.yaml`). Runners that do not
536
+ advertise the contract grade the step as `not_applicable` — the earlier
537
+ `sync_substitution_probe_catalog`, `sync_substitution_probe_creative`,
538
+ and `preview_substitution_probe_creative` steps still run (exercising
539
+ the catalog-acceptance, creative-push, and preview paths), but the
540
+ substituted-URL assertion is skipped.
541
+
542
+ steps:
543
+ - id: sync_substitution_probe_catalog
544
+ title: "Push a probe catalog with attacker-shaped values"
545
+ narrative: |
546
+ Push a small probe catalog whose `sku` fields contain five canonical
547
+ attacker-shaped values from the substitution-safety fixture. The
548
+ platform MUST accept the payload — the encoding rule applies at
549
+ substitution time, not at ingest — but the downstream `preview_creative`
550
+ output must percent-encode each value into tracker URLs.
551
+ task: sync_catalogs
552
+ schema_ref: "media-buy/sync-catalogs-request.json"
553
+ response_schema_ref: "media-buy/sync-catalogs-response.json"
554
+ doc_ref: "/media-buy/task-reference/sync_catalogs"
555
+ stateful: true
556
+ expected: |
557
+ Catalog accepted with per-item counts. Runner captures the
558
+ catalog_id + item_ids for the downstream assertion binding.
559
+
560
+ sample_request:
561
+ account:
562
+ brand:
563
+ domain: "acmeoutdoor.example"
564
+ operator: "pinnacle-agency.example"
565
+ catalogs:
566
+ - catalog_id: "sales_social_substitution_probe_v1"
567
+ type: "product"
568
+ content_id_type: "sku"
569
+ name: "Substitution safety probe"
570
+ items:
571
+ - item_id: "reserved_char_breakout"
572
+ sku: "00013&cmd=drop"
573
+ title: "Reserved-char breakout probe"
574
+ url: "https://acmeoutdoor.example/probe/reserved"
575
+ image_url: "https://cdn.acmeoutdoor.example/probe/reserved.jpg"
576
+ price: { amount: 1.00, currency: "USD" }
577
+ - item_id: "nested_expansion"
578
+ sku: "vacancy-{DEVICE_ID}-42"
579
+ title: "Nested-expansion probe"
580
+ url: "https://acmeoutdoor.example/probe/nested"
581
+ image_url: "https://cdn.acmeoutdoor.example/probe/nested.jpg"
582
+ price: { amount: 1.00, currency: "USD" }
583
+ - item_id: "non_ascii"
584
+ sku: "café-amsterdam"
585
+ title: "Non-ASCII UTF-8 probe"
586
+ url: "https://acmeoutdoor.example/probe/non-ascii"
587
+ image_url: "https://cdn.acmeoutdoor.example/probe/non-ascii.jpg"
588
+ price: { amount: 1.00, currency: "USD" }
589
+ - item_id: "crlf_injection"
590
+ sku: "abc\r\nHost: evil.example"
591
+ title: "CRLF injection probe"
592
+ url: "https://acmeoutdoor.example/probe/crlf"
593
+ image_url: "https://cdn.acmeoutdoor.example/probe/crlf.jpg"
594
+ price: { amount: 1.00, currency: "USD" }
595
+ - item_id: "bidi_override"
596
+ sku: "VIN-‮1234"
597
+ title: "Bidi-override probe"
598
+ url: "https://acmeoutdoor.example/probe/bidi"
599
+ image_url: "https://cdn.acmeoutdoor.example/probe/bidi.jpg"
600
+ price: { amount: 1.00, currency: "USD" }
601
+
602
+ idempotency_key: "$generate:uuid_v4#sales_social_catalog_substitution_safety_sync_substitution_probe_catalog"
603
+ context:
604
+ correlation_id: "sales_social--sync_substitution_probe_catalog"
605
+ validations:
606
+ - check: response_schema
607
+ description: "Response matches sync-catalogs-response.json schema"
608
+ - check: field_present
609
+ path: "catalogs[0].catalog_id"
610
+ description: "Probe catalog accepted"
611
+
612
+ - id: sync_substitution_probe_creative
613
+ title: "Push a DPA creative bound to the probe catalog"
614
+ narrative: |
615
+ Push a DPA creative template whose `product_catalog` asset binds to
616
+ the probe catalog from the previous step. Tracker URLs reference
617
+ `{SKU}` so the platform's substitution path resolves attacker-shaped
618
+ values into URL contexts at preview time.
619
+ task: sync_creatives
620
+ schema_ref: "creative/sync-creatives-request.json"
621
+ response_schema_ref: "creative/sync-creatives-response.json"
622
+ doc_ref: "/creative/task-reference/sync_creatives"
623
+ comply_scenario: creative_sync
624
+ stateful: true
625
+ expected: |
626
+ DPA creative template accepted. Per-creative action: created or updated.
627
+
628
+ sample_request:
629
+ account:
630
+ brand:
631
+ domain: "acmeoutdoor.example"
632
+ operator: "pinnacle-agency.example"
633
+ creatives:
634
+ - creative_id: "sales_social_substitution_probe_creative_v1"
635
+ name: "Substitution safety probe DPA"
636
+ format_id:
637
+ agent_url: "https://creative.adcontextprotocol.org"
638
+ id: "product_carousel_3_to_10"
639
+ assets:
640
+ product_catalog:
641
+ asset_type: "catalog"
642
+ type: "product"
643
+ catalog_id: "sales_social_substitution_probe_v1"
644
+ impression_pixel:
645
+ asset_type: "url"
646
+ url: "https://track.acmeoutdoor.example/imp?sku={SKU}"
647
+ click_url:
648
+ asset_type: "url"
649
+ url: "https://track.acmeoutdoor.example/click?sku={SKU}"
650
+
651
+ idempotency_key: "$generate:uuid_v4#sales_social_catalog_substitution_safety_sync_substitution_probe_creative"
652
+ context:
653
+ correlation_id: "sales_social--sync_substitution_probe_creative"
654
+ validations:
655
+ - check: response_schema
656
+ description: "Response matches sync-creatives-response.json schema"
657
+ - check: field_present
658
+ path: "context"
659
+ description: "Response echoes back the context object"
660
+
661
+ - id: preview_substitution_probe_creative
662
+ title: "Render a preview against the probe catalog"
663
+ narrative: |
664
+ Call `preview_creative` against the probe creative. The platform
665
+ renders the DPA template by binding `{SKU}` against the probe
666
+ catalog's items, returning `preview_html` whose tracker URLs carry
667
+ substituted SKU values. The substitution-observer runner uses this
668
+ response as its observation source in the next step.
669
+
670
+ `format: html` is requested so the response surfaces `preview_html`
671
+ directly; `item_limit: 5` ensures every probe catalog item is
672
+ rendered at least once so the observer can match every binding.
673
+ task: preview_creative
674
+ schema_ref: "creative/preview-creative-request.json"
675
+ response_schema_ref: "creative/preview-creative-response.json"
676
+ doc_ref: "/creative/task-reference/preview_creative"
677
+ stateful: true
678
+ expected: |
679
+ Preview returned with at least one render carrying preview_html
680
+ containing the substituted tracker URLs.
681
+
682
+ sample_request:
683
+ request_type: "single"
684
+ format: "html"
685
+ item_limit: 5
686
+ creative_manifest:
687
+ format_id:
688
+ agent_url: "https://creative.adcontextprotocol.org"
689
+ id: "product_carousel_3_to_10"
690
+ assets:
691
+ product_catalog:
692
+ asset_type: "catalog"
693
+ type: "product"
694
+ catalog_id: "sales_social_substitution_probe_v1"
695
+ impression_pixel:
696
+ asset_type: "url"
697
+ url: "https://track.acmeoutdoor.example/imp?sku={SKU}"
698
+ click_url:
699
+ asset_type: "url"
700
+ url: "https://track.acmeoutdoor.example/click?sku={SKU}"
701
+ account:
702
+ brand:
703
+ domain: "acmeoutdoor.example"
704
+ operator: "pinnacle-agency.example"
705
+
706
+ idempotency_key: "$generate:uuid_v4#sales_social_catalog_substitution_safety_preview_substitution_probe_creative"
707
+ context:
708
+ correlation_id: "sales_social--preview_substitution_probe_creative"
709
+ validations:
710
+ - check: response_schema
711
+ description: "Response matches preview-creative-response.json schema"
712
+ - check: field_present
713
+ path: "previews[0].renders[0].preview_html"
714
+ description: "Preview render carries preview_html"
715
+
716
+ - id: expect_substitution_safe
717
+ title: "Assert substituted tracker URLs percent-encode attacker shapes"
718
+ narrative: |
719
+ The runner inspects the `preview_html` from the previous step,
720
+ extracts tracker URLs that bind `{SKU}` to a probe catalog item,
721
+ and asserts each value is percent-encoded per RFC 3986
722
+ (unreserved-whitelist). Raw-byte leakage fails. Every declared
723
+ binding MUST be observed — a platform that silently strips `{SKU}`
724
+ rather than substituting it fails with `substitution_binding_missing`.
725
+ task: expect_substitution_safe
726
+ requires_contract: substitution_observer_runner
727
+ source: html_inline
728
+ source_path: "/previews/0/renders/0/preview_html"
729
+ macro_template: "https://track.acmeoutdoor.example/imp?sku={SKU}"
730
+ require_every_binding_observed: true
731
+ catalog_bindings:
732
+ - macro: "{SKU}"
733
+ catalog_item_id: "reserved_char_breakout"
734
+ vector_name: "reserved-character-breakout"
735
+ - macro: "{SKU}"
736
+ catalog_item_id: "nested_expansion"
737
+ vector_name: "nested-expansion-preserved-as-literal"
738
+ - macro: "{SKU}"
739
+ catalog_item_id: "non_ascii"
740
+ vector_name: "non-ascii-utf8-percent-encoding"
741
+ - macro: "{SKU}"
742
+ catalog_item_id: "crlf_injection"
743
+ vector_name: "crlf-injection-neutralized"
744
+ - macro: "{SKU}"
745
+ catalog_item_id: "bidi_override"
746
+ vector_name: "bidi-override-neutralized"
747
+ - id: event_setup
748
+ title: "Event source setup"
749
+ narrative: |
750
+ Before sending conversion events, the buyer registers the event sources the platform
751
+ should expect events from — a website pixel, a mobile SDK, or a server-to-server feed.
752
+ The platform returns setup instructions and binds the event_source_id that later
753
+ log_event calls will reference.
754
+
755
+ steps:
756
+ - id: sync_event_sources
757
+ title: "Register conversion event sources"
758
+ narrative: |
759
+ The buyer tells the platform where conversion events will come from. The
760
+ platform records each event_source_id, returns integration code, and will
761
+ accept log_event calls that reference it.
762
+ task: sync_event_sources
763
+ schema_ref: "media-buy/sync-event-sources-request.json"
764
+ response_schema_ref: "media-buy/sync-event-sources-response.json"
765
+ doc_ref: "/media-buy/task-reference/sync_event_sources"
766
+ stateful: true
767
+ expected: |
768
+ Return event sources with:
769
+ - event_source_id and seller_id
770
+ - setup.snippet: integration code (JavaScript pixel, HTML tag, or pixel URL)
771
+ - setup.instructions: human-readable integration guide
772
+ - action: created or updated
773
+
774
+ sample_request:
775
+ account:
776
+ brand:
777
+ domain: "acmeoutdoor.example"
778
+ operator: "pinnacle-agency.example"
779
+ event_sources:
780
+ - event_source_id: "acmeoutdoor_website"
781
+ name: "Acme Outdoor Website"
782
+ event_types: ["purchase", "add_to_cart", "page_view", "lead"]
783
+ allowed_domains: ["acmeoutdoor.example"]
784
+
785
+ idempotency_key: "$generate:uuid_v4#sales_social_event_setup_sync_event_sources"
786
+ context:
787
+ correlation_id: "sales_social--sync_event_sources"
788
+ validations:
789
+ - check: response_schema
790
+ description: "Response matches sync-event-sources-response.json schema"
791
+ - check: field_present
792
+ path: "event_sources[0].setup.snippet"
793
+ description: "Event source includes setup snippet"
794
+
795
+ - check: field_present
796
+ path: "context"
797
+ description: "Response echoes back the context object"
798
+ - check: field_value
799
+ path: "context.correlation_id"
800
+ value: "sales_social--sync_event_sources"
801
+ description: "Context correlation_id returned unchanged"
802
+ - id: event_logging
803
+ title: "Conversion event tracking"
804
+ narrative: |
805
+ The buyer sends conversion events back to the platform for measurement and optimization.
806
+ Events include purchases, signups, and other post-click actions that the platform uses
807
+ to optimize delivery and report on campaign performance.
808
+
809
+ steps:
810
+ - id: log_event
811
+ title: "Send conversion events"
812
+ narrative: |
813
+ The buyer logs conversion events that occurred after ad exposure. The platform
814
+ records these events for attribution, reporting, and delivery optimization.
815
+ task: log_event
816
+ schema_ref: "media-buy/log-event-request.json"
817
+ response_schema_ref: "media-buy/log-event-response.json"
818
+ doc_ref: "/media-buy/task-reference/log_event"
819
+ stateful: true
820
+ expected: |
821
+ Acknowledge the events:
822
+ - Per-event status: accepted or rejected
823
+ - Event IDs for deduplication
824
+ - Attribution window validation
825
+
826
+ sample_request:
827
+ account:
828
+ brand:
829
+ domain: "acmeoutdoor.example"
830
+ operator: "pinnacle-agency.example"
831
+ event_source_id: "acmeoutdoor_website"
832
+ events:
833
+ - event_type: "purchase"
834
+ event_id: "evt_trail_pro_001"
835
+ event_time: "2026-04-05T14:30:00Z"
836
+ # user_match prevents adapters from injecting synthetic placeholder
837
+ # identifiers to satisfy the upstream's required-field check.
838
+ # The hashed_email here matches the sync_audiences add[]
839
+ # member so an upstream_traffic identifier echo can confirm
840
+ # values were forwarded, not constants.
841
+ user_match:
842
+ hashed_email: "a000000000000000000000000000000000000000000000000000000000000001"
843
+ # value/currency belong inside custom_data per event-custom-data.json;
844
+ # additionalProperties: true on the parent silently swallowed them
845
+ # at the wrong nesting level, meaning real upstreams never saw
846
+ # the purchase value.
847
+ custom_data:
848
+ value: 149.99
849
+ currency: "USD"
850
+
851
+ idempotency_key: "$generate:uuid_v4#sales_social_event_logging_log_event"
852
+ context:
853
+ correlation_id: "sales_social--log_event"
854
+ validations:
855
+ - check: response_schema
856
+ description: "Response matches log-event-response.json schema"
857
+
858
+ - check: field_present
859
+ path: "context"
860
+ description: "Response echoes back the context object"
861
+ - check: field_value
862
+ path: "context.correlation_id"
863
+ value: "sales_social--log_event"
864
+ description: "Context correlation_id returned unchanged"
865
+ # Anti-façade: the adapter MUST forward the conversion event to the
866
+ # upstream platform's event-tracking endpoint, carrying the supplied
867
+ # user_match identifier. A façade that injects a constant placeholder
868
+ # hash to satisfy the upstream's required-field check fails the
869
+ # identifier_paths echo — the constant won't match the storyboard's
870
+ # supplied value.
871
+ - check: upstream_traffic
872
+ description: "log_event caused upstream traffic carrying the supplied user_match identifier"
873
+ min_count: 1
874
+ endpoint_pattern: "POST *"
875
+ identifier_paths:
876
+ - "events[*].user_match.hashed_email"
877
+ - id: financials
878
+ title: "Account financials"
879
+ narrative: |
880
+ The buyer checks account financials — spending, balance, and payment status. This is
881
+ essential for budget monitoring across multiple social platforms.
882
+
883
+ steps:
884
+ - id: get_account_financials
885
+ title: "Check account spending and balance"
886
+ narrative: |
887
+ The buyer retrieves financial information for the advertiser account. The platform
888
+ returns current spend, remaining balance, and payment status.
889
+ task: get_account_financials
890
+ schema_ref: "account/get-account-financials-request.json"
891
+ response_schema_ref: "account/get-account-financials-response.json"
892
+ doc_ref: "/accounts/tasks/get_account_financials"
893
+ stateful: true
894
+ expected: |
895
+ Return account financial data:
896
+ - Current spend to date
897
+ - Remaining balance or credit
898
+ - Payment status and terms
899
+ - Budget utilization metrics
900
+
901
+ sample_request:
902
+ account:
903
+ brand:
904
+ domain: "acmeoutdoor.example"
905
+ operator: "pinnacle-agency.example"
906
+
907
+ context:
908
+ correlation_id: "sales_social--get_account_financials"
909
+ validations:
910
+ - check: response_schema
911
+ description: "Response matches get-account-financials-response.json schema"
912
+
913
+ - check: field_present
914
+ path: "context"
915
+ description: "Response echoes back the context object"
916
+ - check: field_value
917
+ path: "context.correlation_id"
918
+ value: "sales_social--get_account_financials"
919
+ description: "Context correlation_id returned unchanged"