@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,117 @@
1
+ id: v3_envelope_integrity
2
+ version: "1.0.0"
3
+ title: "v3 envelope integrity — no legacy status fields"
4
+ category: schema_validation
5
+ summary: "v3 protocol envelopes MUST NOT carry task_status or response_status — v2 legacy field names that have no semantics in v3."
6
+ track: core
7
+ required_tools: [] # protocol-level: get_adcp_capabilities is mandatory for all agents
8
+
9
+ narrative: |
10
+ AdCP 3.0 normalises all task lifecycle state onto a single `status` field (values
11
+ defined in the task-status enum). The v2 `task_status` and `response_status` field
12
+ names have no semantics in v3 — carrying them on a v3 envelope is a normative
13
+ MUST NOT per the migration guide, task-lifecycle.mdx, and the protocol-envelope
14
+ schema. See docs/reference/migration/index.mdx and
15
+ docs/building/implementation/task-lifecycle.mdx.
16
+
17
+ This storyboard documents the machine-check assertion and asserts the canonical v3
18
+ `status` field is present using the `envelope_field_present` check type, which
19
+ walks the protocol envelope rather than the inner response schema. The explicit
20
+ envelope-root field-absence checks assert that task_status and response_status are
21
+ absent using `envelope_field_absent`; protocol-envelope.json carries the matching
22
+ top-level `not: { anyOf: [{ required: [task_status] }, { required:
23
+ [response_status] }] }` schema constraint.
24
+
25
+ Scope: envelope top-level only. Domain data inside `payload` (e.g., a reporting
26
+ row carrying a field named task_status) is outside this prohibition and is not
27
+ checked here.
28
+
29
+ agent:
30
+ interaction_model: "*" # applies to every agent regardless of protocol or specialism
31
+ examples:
32
+ - "Any AdCP agent (seller, signals, creative, retail media, SI, governance)"
33
+
34
+ caller:
35
+ role: buyer_agent
36
+ example: "Compliance test harness"
37
+
38
+ prerequisites:
39
+ description: |
40
+ No test-kit credentials required. get_adcp_capabilities is a public operation
41
+ that every AdCP agent must expose without authentication.
42
+
43
+ phases:
44
+ - id: envelope_integrity_check
45
+ title: "v3 envelope must not carry legacy v2 status field names"
46
+ narrative: |
47
+ Call get_adcp_capabilities and verify the response envelope carries the
48
+ canonical v3 status field and omits the legacy v2 field names
49
+ task_status and response_status.
50
+
51
+ steps:
52
+ - id: no_legacy_status_fields
53
+ title: "Envelope carries canonical v3 status; no legacy v2 status field names"
54
+ narrative: |
55
+ get_adcp_capabilities is the lightest call every agent supports and
56
+ requires no credentials. The response envelope must carry the canonical
57
+ v3 `status` field and must not carry task_status or response_status.
58
+ The protocol-envelope.json schema's top-level `not: { anyOf: [...] }`
59
+ constraint forbids either field, making this constraint detectable by
60
+ any schema-aware validator without runner-specific primitives.
61
+
62
+ MCP transport note: the `status` field must appear at the top level of
63
+ `structuredContent` (or the first parseable `content[].text` JSON object
64
+ for older MCP servers) — it is NOT a JSON-RPC result-level field. The extracted AdCP
65
+ response IS the protocol envelope: `status` lives alongside task-specific
66
+ payload fields in the same flat object. The `get-adcp-capabilities-response.json`
67
+ schema validates only the task-specific fields (capabilities, context echo,
68
+ etc.) and does not cover protocol envelope fields like `status` — an agent
69
+ whose MCP response passes response_schema validation but omits `status` is
70
+ still non-conformant. See docs/building/implementation/mcp-response-extraction
71
+ for the normative MCP extraction algorithm and the expected structuredContent
72
+ shape, including the required `status` field at the top level.
73
+ task: get_adcp_capabilities
74
+ schema_ref: "protocol/get-adcp-capabilities-request.json"
75
+ response_schema_ref: "protocol/get-adcp-capabilities-response.json"
76
+ doc_ref: "/protocol/get_adcp_capabilities"
77
+ comply_scenario: envelope_integrity
78
+ stateful: false
79
+ expected: |
80
+ Response envelope (all transports):
81
+ - MUST contain status (the v3 canonical field)
82
+ - MUST NOT contain task_status (v2 legacy, no v3 semantics)
83
+ - MUST NOT contain response_status (v2 legacy, no v3 semantics)
84
+ Both forbidden fields are blocked by the top-level `not: { anyOf: [...] }`
85
+ constraint in protocol-envelope.json, so any schema-aware validator that
86
+ validates the full protocol envelope will detect violations.
87
+
88
+ For MCP agents specifically: `status` MUST be present at the top level of
89
+ structuredContent (or the first parseable content[].text JSON object). It is not a JSON-RPC sibling
90
+ field — it lives inside the content payload, at the same level as the
91
+ task-specific response fields. An agent returning only the task payload
92
+ without `status` fails this check regardless of whether the payload itself
93
+ validates against the task response schema.
94
+
95
+ sample_request:
96
+ context:
97
+ correlation_id: "v3_envelope_integrity--no_legacy_status"
98
+
99
+ validations:
100
+ - check: response_schema
101
+ description: "Response matches get-adcp-capabilities-response.json schema"
102
+ - check: envelope_field_present
103
+ path: "status"
104
+ description: "Envelope carries the canonical v3 status field"
105
+ - check: envelope_field_absent
106
+ path: "task_status"
107
+ description: "Envelope root MUST NOT carry task_status (v2 legacy; no v3 semantics)"
108
+ - check: envelope_field_absent
109
+ path: "response_status"
110
+ description: "Envelope root MUST NOT carry response_status (v2 legacy; no v3 semantics)"
111
+ - check: field_present
112
+ path: "context"
113
+ description: "Response echoes back the context object"
114
+ - check: field_value
115
+ path: "context.correlation_id"
116
+ value: "v3_envelope_integrity--no_legacy_status"
117
+ description: "Context correlation_id returned unchanged"
@@ -0,0 +1,130 @@
1
+ id: version_negotiation
2
+ version: "1.0.0"
3
+ title: "Release-precision version negotiation"
4
+ category: version_negotiation
5
+ summary: "Sellers advertise supported releases on capabilities and echo the served release on every response."
6
+ track: core
7
+ required_tools: [] # protocol-level: get_adcp_capabilities is mandatory for all agents
8
+
9
+ narrative: |
10
+ AdCP 3.1 introduces release-precision (VERSION.RELEASE, e.g. "3.1") version
11
+ negotiation alongside the legacy major-precision (`adcp_major_version` integer)
12
+ carried since 3.0. Both directions of the negotiation are SHOULD-level through
13
+ 3.x and graduate to MUST at 4.0 — this storyboard exercises both halves so
14
+ sellers can discover gaps before the 3.2 grader cutover flips advisory results
15
+ to blocking failures.
16
+
17
+ Two checks ride on a single get_adcp_capabilities call:
18
+
19
+ 1. **Seller advertises** `adcp.supported_versions` — an array of release-precision
20
+ strings the seller speaks. Authoritative for buyer-side pinning; the legacy
21
+ `adcp.major_versions` integer array remains required through 3.x for
22
+ backwards compatibility.
23
+
24
+ 2. **Seller echoes** `adcp_version` at the envelope root — the release the seller
25
+ actually served. Buyers SHOULD validate the response against the echoed
26
+ release's schema, not against their own pin. Legacy 3.0 sellers that don't
27
+ read the field omit the echo (`additionalProperties: true` makes the field
28
+ invisible to them) — buyers fall back to their constructor pin.
29
+
30
+ Per the [migration table](/docs/reference/versioning#migration-timeline), both
31
+ surfaces are advisory at 3.1 and become blocking failure at 3.2. The advisory
32
+ marker on each validation makes that promotion a single-PR change at 3.2 cut
33
+ rather than a per-adopter compliance break at the boundary.
34
+
35
+ Scope: protocol envelope and capabilities advertisement only. The
36
+ `VERSION_UNSUPPORTED` error path (buyer pins a release outside the seller's
37
+ `supported_versions`) is exercised separately by error_compliance — running it
38
+ here requires the runner to send a deliberately-mismatched pin and is left to
39
+ follow-up.
40
+
41
+ agent:
42
+ interaction_model: "*" # applies to every agent regardless of protocol or specialism
43
+ examples:
44
+ - "Any AdCP agent (seller, signals, creative, retail media, SI, governance)"
45
+
46
+ caller:
47
+ role: buyer_agent
48
+ example: "Compliance test harness"
49
+
50
+ prerequisites:
51
+ description: |
52
+ No test-kit credentials required. get_adcp_capabilities is a public operation
53
+ that every AdCP agent must expose without authentication.
54
+
55
+ phases:
56
+ - id: capabilities_advertise_and_echo
57
+ title: "Capabilities advertise supported_versions; response echoes adcp_version"
58
+ narrative: |
59
+ Call get_adcp_capabilities. The single response carries both halves of the
60
+ negotiation contract — `adcp.supported_versions` in the body (seller's
61
+ advertisement) and `adcp_version` on the envelope (seller's echo of what
62
+ it served). Sellers SHOULD populate both at 3.1; the grader reports
63
+ missing entries as advisory findings without failing certification.
64
+
65
+ steps:
66
+ - id: get_capabilities_with_version
67
+ title: "Verify seller advertises supported_versions and echoes adcp_version"
68
+ narrative: |
69
+ The runner emits `adcp_version` on the request envelope based on its
70
+ configured pin (the SDK's release-precision constructor option). The
71
+ seller honors the pin within the resolution algorithm in
72
+ docs/reference/versioning.mdx, echoes the served release on the response
73
+ envelope, and lists every release it speaks under
74
+ `adcp.supported_versions` in the response body.
75
+
76
+ A seller serving only 3.0 (no awareness of the new fields) passes the
77
+ request schema unchanged — `adcp_version` rides on the envelope and is
78
+ invisible to readers that don't look for it. The advisory checks below
79
+ will report missing `supported_versions` advertisement and missing
80
+ envelope echo without failing the step.
81
+ task: get_adcp_capabilities
82
+ schema_ref: "protocol/get-adcp-capabilities-request.json"
83
+ response_schema_ref: "protocol/get-adcp-capabilities-response.json"
84
+ doc_ref: "/protocol/get_adcp_capabilities"
85
+ comply_scenario: version_negotiation
86
+ stateful: false
87
+ expected: |
88
+ Response carries both halves of the negotiation contract:
89
+ - Body: adcp.supported_versions (array of release-precision strings, e.g.
90
+ ["3.0", "3.1"]) declaring every release the seller speaks. Authoritative
91
+ for buyer-side pinning. SHOULD at 3.1, MUST at 4.0.
92
+ - Envelope: adcp_version (release-precision string) echoing the release
93
+ the seller actually served. SHOULD at 3.1, MUST at 4.0. Buyers SHOULD
94
+ validate the response against the echoed release's schema.
95
+
96
+ Legacy `adcp.major_versions` (integer array) remains required through 3.x.
97
+
98
+ sample_request:
99
+ context:
100
+ correlation_id: "version_negotiation--get_capabilities_with_version"
101
+
102
+ validations:
103
+ - check: response_schema
104
+ description: "Response matches get-adcp-capabilities-response.json schema"
105
+
106
+ - check: field_present
107
+ path: "adcp.major_versions"
108
+ description: "Legacy major-precision advertisement present (required through 3.x)"
109
+
110
+ - check: field_present
111
+ path: "adcp.supported_versions"
112
+ severity: advisory
113
+ permanent_advisory:
114
+ reason: "Per docs/reference/versioning.mdx > Migration timeline, sellers SHOULD declare supported_versions at 3.1 and the compliance grader reports presence as advisory. At 3.2 the storyboard cut promotes this validation to required (manual flip — not gated on runner_capability_version because the 3.2 boundary is a protocol-spec cutover, not a runner-capability cutover). 4.0 promotes to MUST per the spec. Marking permanent_advisory here is a deliberate use of the field to defer promotion to the 3.2 storyboard PR rather than relying on the expires_after_version semver gate."
115
+ description: "Seller advertises release-precision supported_versions (advisory at 3.1, required at 3.2)"
116
+
117
+ - check: field_present
118
+ path: "adcp_version"
119
+ severity: advisory
120
+ permanent_advisory:
121
+ reason: "Per docs/reference/versioning.mdx > Migration timeline, sellers SHOULD echo adcp_version at 3.1 and the compliance grader reports presence as advisory. At 3.2 the storyboard cut promotes this validation to required (manual flip — see the supported_versions check above for the same rationale). 4.0 promotes to MUST per the spec."
122
+ description: "Seller echoes adcp_version on the response envelope (advisory at 3.1, required at 3.2)"
123
+
124
+ - check: field_present
125
+ path: "context"
126
+ description: "Response echoes back the context object"
127
+ - check: field_value
128
+ path: "context.correlation_id"
129
+ value: "version_negotiation--get_capabilities_with_version"
130
+ description: "Context correlation_id returned unchanged"
@@ -0,0 +1,411 @@
1
+ id: webhook_emission
2
+ version: "1.0.0"
3
+ title: "Webhook emission — outbound webhook conformance (signing + idempotency)"
4
+ category: core
5
+ summary: "Any agent that emits webhooks MUST carry a stable idempotency_key across retries and — when the buyer has not opted into the deprecated HMAC fallback — MUST sign deliveries under the RFC 9421 webhook profile. Graded by a runner hosting a webhook receiver during storyboard execution."
6
+ track: core
7
+
8
+ narrative: |
9
+ Webhook emission is a cross-cutting capability, not a specialism. Sellers emit
10
+ webhooks on `create_media_buy` status changes. Rights agents emit revocation
11
+ notifications. Governance agents emit `collection_list_changed` and
12
+ `property_list_changed`. Content-standards agents emit artifact webhooks.
13
+ Every agent that accepts `push_notification_config` on any operation is in
14
+ scope for this universal — no capability flag, no opt-in.
15
+
16
+ Two load-bearing conformance requirements apply to every outbound webhook:
17
+
18
+ 1. **`idempotency_key` is present on every payload and stable across retries.**
19
+ Required by adcontextprotocol/adcp#2417. Receivers dedupe on this field;
20
+ a sender that regenerates the key on retry breaks at-least-once delivery
21
+ semantics and creates duplicate side effects downstream.
22
+
23
+ 2. **RFC 9421 webhook signing is baseline in 3.0** unless the buyer opts into
24
+ the deprecated HMAC fallback via `push_notification_config.authentication`.
25
+ Required by adcontextprotocol/adcp#2423. Signatures carry
26
+ `tag="adcp/webhook-signing/v1"`, cover `content-digest`, and verify
27
+ against the seller's brand.json-published JWKS.
28
+
29
+ Grading is observable-behavior only. The runner hosts a webhook receiver per
30
+ the contract at `test-kits/webhook-receiver-runner.yaml`, drives storyboards
31
+ that trigger webhooks from whatever operations the agent advertises, and
32
+ asserts on what the agent sends back.
33
+
34
+ This universal grades not_applicable when the runner does not host a webhook
35
+ receiver (e.g., lint-only runs against an agent that has no webhook-emitting
36
+ operations, or runs where the operator has not configured the receiver
37
+ contract).
38
+
39
+ **9421 is the on-ramp.** Any agent advertising webhook-emitting operations
40
+ MUST publish a `webhook-signing` JWKS at its `brand.json` `agents[].jwks_uri`
41
+ and MUST emit valid 9421 signatures when triggered with no `authentication`
42
+ block on `push_notification_config`. Agents without published signing keys
43
+ fail the `signing_keys_published` precheck before the signature phase runs;
44
+ agents with keys but invalid signatures fail `signature_validity`. The
45
+ deprecated HMAC fallback remains a buyer-side registration option in 3.x
46
+ (`push_notification_config.authentication`), but it is not a path that
47
+ exempts the agent from publishing 9421 keys — the runner registers as a
48
+ 9421-default buyer, and the agent is graded on what it does in that mode.
49
+ This closes the on-ramp loophole that previously let agents self-declare
50
+ themselves out of the signing phase via `webhook_auth_mode == 'hmac_legacy'`.
51
+
52
+ **Clean seam**: the runner does NOT reimplement signature verification or
53
+ idempotency dedup. It delegates to `@adcp/client` primitives —
54
+ `AsyncHandlerConfig.webhookDedup`, `WebhookMetadata.idempotency_key`, and
55
+ the 9421 webhook verifier once that lands in the client library. The same
56
+ code that production receivers rely on is what the conformance runner
57
+ exercises; a single bug fix in the library covers both surfaces.
58
+
59
+ agent:
60
+ interaction_model: webhook_emitter
61
+ capabilities:
62
+ - emits_webhooks
63
+ examples:
64
+ - "Any AdCP seller that accepts push_notification_config on create_media_buy, update_media_buy, or equivalent async operations"
65
+ - "Rights agents that post revocation notifications"
66
+ - "Governance agents that emit collection_list_changed or property_list_changed webhooks"
67
+ - "Content-standards agents that emit artifact webhooks"
68
+
69
+ caller:
70
+ role: compliance_runner
71
+ example: "AdCP Verified runner with webhook receiver capability"
72
+
73
+ prerequisites:
74
+ description: |
75
+ The runner MUST be configured with a webhook receiver per the contract at
76
+ `test-kits/webhook-receiver-runner.yaml`. The receiver operates in one of
77
+ two modes: `loopback_mock` (intercepts at the `@adcp/client` AsyncHandler
78
+ layer — zero network deps, used for lint runs) or `proxy_url` (operator-
79
+ supplied HTTPS URL routing into the runner — used for AdCP Verified
80
+ grading). Runners without a receiver grade this universal as
81
+ not_applicable.
82
+
83
+ The agent under test MUST advertise the operations it supports in
84
+ `get_adcp_capabilities`. The runner drives whichever webhook-emitting
85
+ operations are advertised; operations the agent does not support are
86
+ skipped cleanly, not graded as failures.
87
+
88
+ Agents advertising webhook-emitting operations MUST publish a JWKS at the
89
+ `jwks_uri` on their brand.json `agents[]` entry containing a key with
90
+ `adcp_use: "webhook-signing"`. The `signing_keys_published` precheck
91
+ asserts this directly; agents without published signing keys fail
92
+ `webhook_signing_keys_unpublished` before the signature phase runs.
93
+ test_kit: "test-kits/webhook-receiver-runner.yaml"
94
+
95
+ phases:
96
+ - id: capability_discovery
97
+ title: "Capability discovery"
98
+ narrative: |
99
+ Discover which async operations the agent supports so the runner knows
100
+ which to drive for webhook emission.
101
+
102
+ steps:
103
+ - id: get_capabilities
104
+ title: "Discover webhook-emitting operations"
105
+ narrative: |
106
+ The runner calls `get_adcp_capabilities` and inspects which async
107
+ operations the agent supports. If the agent advertises none that
108
+ accept `push_notification_config`, this universal does not apply
109
+ and grading returns not_applicable (not a failure).
110
+ task: get_adcp_capabilities
111
+ schema_ref: "protocol/get-adcp-capabilities-request.json"
112
+ response_schema_ref: "protocol/get-adcp-capabilities-response.json"
113
+ doc_ref: "/protocol/get_adcp_capabilities"
114
+ comply_scenario: capability_discovery
115
+ stateful: false
116
+ expected: |
117
+ Return a capabilities block including supported_protocols. Webhook-
118
+ emitting operations are discovered via the transport handshake
119
+ (MCP tools/list, A2A skills), not the capabilities body; grading
120
+ returns a stable not_applicable marker downstream when no webhook-
121
+ emitting operation resolves through
122
+ $test_kit.operations.primary_webhook_emitter.
123
+ sample_request:
124
+ context:
125
+ correlation_id: "webhook_emission--get_capabilities"
126
+ validations:
127
+ - check: field_present
128
+ path: "supported_protocols"
129
+ description: "Agent declares its supported AdCP protocols"
130
+
131
+ - id: idempotency_key_presence
132
+ title: "Every webhook payload carries idempotency_key"
133
+ narrative: |
134
+ The runner triggers a webhook-emitting operation with a
135
+ push_notification_config pointed at the runner's per-step receiver. The
136
+ first inbound webhook MUST carry an `idempotency_key` matching the
137
+ required pattern (`^[A-Za-z0-9_.:-]{16,255}$`). Absence of the field or
138
+ a pattern mismatch fails the phase.
139
+
140
+ This is the baseline conformance with adcontextprotocol/adcp#2417 —
141
+ receivers cannot dedupe without it, so "I forgot to emit the field" is
142
+ the single highest-impact publisher bug the universal catches.
143
+
144
+ steps:
145
+ - id: trigger_webhook_operation
146
+ title: "Trigger an operation that emits a webhook"
147
+ narrative: |
148
+ Runner calls the first operation the capability block advertises as
149
+ webhook-emitting (typically `create_media_buy` for sales agents,
150
+ `acquire_rights` for rights agents, etc.), passing
151
+ `push_notification_config.url = {{runner.webhook_url:trigger_webhook_operation}}`
152
+ — no `authentication` block (9421 is the baseline for conformance).
153
+ task: "$test_kit.operations.primary_webhook_emitter"
154
+ task_default: create_media_buy
155
+ schema_ref: "$test_kit.schemas.primary_request"
156
+ response_schema_ref: "$test_kit.schemas.primary_response"
157
+ doc_ref: "/building/implementation/webhooks"
158
+ comply_scenario: webhook_trigger
159
+ stateful: false
160
+ sample_request:
161
+ push_notification_config:
162
+ url: "{{runner.webhook_url:trigger_webhook_operation}}"
163
+ idempotency_key: "$generate:uuid_v4#webhook_emission_trigger"
164
+ context:
165
+ correlation_id: "webhook_emission--trigger_webhook_operation"
166
+ expected: |
167
+ Agent accepts the request and begins async execution. Response either
168
+ returns an immediate terminal status (no webhook needed) or an
169
+ interim status indicating async processing (webhook will follow).
170
+
171
+ - id: expect_webhook_presence
172
+ title: "Assert inbound webhook carries a valid idempotency_key"
173
+ narrative: |
174
+ Wait for a webhook at the per-step URL. When it arrives, validate
175
+ the payload against the webhook schema and assert the
176
+ idempotency_key is present and matches the required pattern.
177
+ task: expect_webhook
178
+ triggered_by: trigger_webhook_operation
179
+ filter:
180
+ operation_id: "{{prior_step.trigger_webhook_operation.operation_id}}"
181
+ timeout_seconds: 30
182
+ expect_idempotency_key: true
183
+ webhook_payload_schema_ref: "core/mcp-webhook-payload.json"
184
+ stateful: true
185
+ expected: |
186
+ Webhook arrives within 30 seconds. Payload validates against
187
+ mcp-webhook-payload.json. idempotency_key is present and matches
188
+ the pattern `^[A-Za-z0-9_.:-]{16,255}$`. Any other status fails the
189
+ phase with a specific error code: no_webhook_received,
190
+ schema_violation, missing_idempotency_key, or
191
+ invalid_idempotency_key_format.
192
+
193
+ - id: idempotency_key_stability
194
+ title: "idempotency_key is byte-identical across retries of the same event"
195
+ narrative: |
196
+ The runner's receiver deterministically returns HTTP 503 for the first
197
+ `count` deliveries, then 200. The runner records the idempotency_key on
198
+ every delivery and asserts all recorded keys are byte-identical. A
199
+ sender that regenerates the key on retry breaks at-least-once semantics
200
+ and fails the phase.
201
+
202
+ This is the conformance test that cannot be replaced by schema
203
+ validation — schema validation catches "no key at all" but not "wrong
204
+ key on retry." Only a live observation catches publisher-side retry
205
+ bugs.
206
+
207
+ steps:
208
+ - id: trigger_retry_scenario
209
+ title: "Trigger a webhook that will be retried via 5xx response"
210
+ narrative: |
211
+ Runner calls a webhook-emitting operation with
212
+ push_notification_config.url = {{runner.webhook_url:trigger_retry_scenario}}.
213
+ The runner's receiver at that URL returns 503 for the first 3
214
+ deliveries and 200 afterwards. Any conformant at-least-once sender
215
+ will retry on each 5xx and eventually succeed.
216
+ task: "$test_kit.operations.primary_webhook_emitter"
217
+ task_default: create_media_buy
218
+ schema_ref: "$test_kit.schemas.primary_request"
219
+ response_schema_ref: "$test_kit.schemas.primary_response"
220
+ doc_ref: "/building/implementation/webhooks"
221
+ comply_scenario: webhook_retry_trigger
222
+ stateful: false
223
+ sample_request:
224
+ push_notification_config:
225
+ url: "{{runner.webhook_url:trigger_retry_scenario}}"
226
+ idempotency_key: "$generate:uuid_v4#webhook_emission_retry_trigger"
227
+ context:
228
+ correlation_id: "webhook_emission--trigger_retry_scenario"
229
+ expected: |
230
+ Agent accepts the request and begins async execution. The webhook
231
+ it emits will be rejected with 503 by the runner and retried.
232
+
233
+ - id: expect_key_stable_across_retries
234
+ title: "Assert idempotency_key byte-identical across all deliveries"
235
+ narrative: |
236
+ Runner records every delivery and asserts all recorded keys are
237
+ byte-identical. Requires at least 2 deliveries observed within the
238
+ timeout window — a sender that doesn't retry at all cannot be
239
+ graded on retry stability.
240
+ task: expect_webhook_retry_keys_stable
241
+ triggered_by: trigger_retry_scenario
242
+ filter:
243
+ operation_id: "{{prior_step.trigger_retry_scenario.operation_id}}"
244
+ retry_trigger:
245
+ count: 3
246
+ http_status: 503
247
+ timeout_seconds: 90
248
+ expect_min_deliveries: 2
249
+ stateful: true
250
+ expected: |
251
+ At least 2 deliveries of the same logical event observed within
252
+ 90 seconds; all deliveries carry byte-identical idempotency_key.
253
+ Fails with insufficient_retries if fewer than 2 deliveries arrive,
254
+ idempotency_key_rotated if the key changes across deliveries, or
255
+ idempotency_key_format_changed if a later delivery carries a
256
+ different-shaped value.
257
+
258
+ - id: signing_keys_published
259
+ title: "Agent publishes a webhook-signing JWKS at brand.json"
260
+ narrative: |
261
+ Precheck: any agent advertising webhook-emitting operations MUST publish
262
+ a JWKS at the `jwks_uri` on its `brand.json` `agents[]` entry containing
263
+ at least one key with `adcp_use: "webhook-signing"`. This is the on-ramp
264
+ gate — an agent that has only ever signed HMAC and never published a
265
+ 9421 signing key fails here, before the signature phase even runs.
266
+
267
+ The runner resolves the agent's `brand.json` from its
268
+ `get_adcp_capabilities` advertisement (or, for agents not yet member-
269
+ registered, from operator configuration), fetches the JWKS at
270
+ `agents[].jwks_uri`, and asserts at least one key has
271
+ `adcp_use: "webhook-signing"` and a non-revoked status. Absent or
272
+ malformed JWKS produces `webhook_signing_keys_unpublished`; JWKS present
273
+ but with no webhook-signing key produces
274
+ `webhook_signing_keys_wrong_purpose`.
275
+
276
+ This phase is observable-only and stateless — no traffic flows. It runs
277
+ before the signature phase so an operator debugging "why did signing
278
+ fail" gets a specific keys-vs-signing diagnostic instead of a generic
279
+ `signature_key_unknown` deep in the verifier checklist.
280
+
281
+ steps:
282
+ - id: fetch_brand_json
283
+ title: "Fetch brand.json and resolve jwks_uri"
284
+ narrative: |
285
+ Runner fetches the agent's `brand.json` (resolved from
286
+ `get_adcp_capabilities` or operator configuration), iterates the
287
+ `agents[]` array, and asserts at least one entry exposes a
288
+ `jwks_uri` reachable at HTTP 200.
289
+ task: fetch_brand_jwks
290
+ stateful: false
291
+ expected: |
292
+ brand.json reachable and parseable; at least one `agents[]` entry
293
+ has a `jwks_uri` returning a valid JWKS document. Fails with
294
+ `brand_json_unreachable`, `brand_json_malformed`, or
295
+ `agents_jwks_uri_missing`.
296
+
297
+ - id: assert_webhook_signing_key_present
298
+ title: "Assert JWKS contains a webhook-signing key"
299
+ narrative: |
300
+ Runner inspects the JWKS and asserts at least one key has
301
+ `adcp_use: "webhook-signing"`. Keys advertising other purposes
302
+ (`request-signing`, `webhook-receipts`, etc.) do not satisfy this
303
+ check — purpose-separation is enforced per the `adcp_use` rule
304
+ (one cryptoKeyVersion per signing purpose; receivers enforce
305
+ purpose at JWK `adcp_use`, not RFC 9421 tag).
306
+ task: assert_jwks_purpose
307
+ stateful: false
308
+ expected: |
309
+ At least one JWK in the agent's published JWKS carries
310
+ `adcp_use: "webhook-signing"` and is not marked revoked. Fails
311
+ with `webhook_signing_keys_unpublished` (no JWKS or empty JWKS),
312
+ `webhook_signing_keys_wrong_purpose` (JWKS present but no key
313
+ with the webhook-signing purpose), or
314
+ `webhook_signing_keys_all_revoked` (all webhook-signing keys
315
+ revoked).
316
+
317
+ - id: signature_validity
318
+ title: "Webhook signatures validate under the 9421 profile"
319
+ narrative: |
320
+ Every outbound webhook MUST verify under the 14-step webhook verifier
321
+ checklist per
322
+ docs/building/implementation/security.mdx#verifier-checklist-for-webhooks.
323
+ The runner registers the trigger as a 9421-default buyer (no
324
+ `authentication` block on `push_notification_config`); the agent is
325
+ graded on the signatures it emits in that mode.
326
+
327
+ Verification is delegated to the `@adcp/client` 9421 webhook verifier
328
+ (see test-kits/webhook-receiver-runner.yaml client_primitives section).
329
+ Until the client verifier lands in a published release, this phase
330
+ grades as `not_applicable` rather than skipping silently — operators
331
+ get an explicit "verifier not yet available" signal instead of a
332
+ false-pass.
333
+
334
+ Negative conformance — signatures that MUST be rejected with a specific
335
+ webhook_signature_* error code — is tested via static conformance
336
+ vectors at `/compliance/{version}/test-vectors/webhook-signing/`
337
+ (follow-up), not by this phase. This phase only grades positive-path
338
+ agents emitting conformant signatures on live traffic.
339
+
340
+ steps:
341
+ - id: trigger_signed_webhook
342
+ title: "Trigger a webhook the agent will sign"
343
+ narrative: |
344
+ Runner calls a webhook-emitting operation with no `authentication`
345
+ block on push_notification_config, forcing 9421 signing per the
346
+ baseline rule.
347
+ task: "$test_kit.operations.primary_webhook_emitter"
348
+ task_default: create_media_buy
349
+ schema_ref: "$test_kit.schemas.primary_request"
350
+ response_schema_ref: "$test_kit.schemas.primary_response"
351
+ doc_ref: "/building/implementation/webhooks"
352
+ comply_scenario: webhook_signed_trigger
353
+ stateful: false
354
+ sample_request:
355
+ push_notification_config:
356
+ url: "{{runner.webhook_url:trigger_signed_webhook}}"
357
+ idempotency_key: "$generate:uuid_v4#webhook_emission_signed_trigger"
358
+ context:
359
+ correlation_id: "webhook_emission--trigger_signed_webhook"
360
+ expected: |
361
+ Agent accepts the request; the webhook it emits will carry
362
+ Signature-Input, Signature, and Content-Digest headers per the
363
+ 9421 webhook profile.
364
+
365
+ - id: expect_signature_valid
366
+ title: "Assert webhook signature verifies under the 9421 profile"
367
+ narrative: |
368
+ Runner delegates to the @adcp/client 9421 webhook verifier (14-step
369
+ checklist). A passing signature means: covered components include
370
+ `@method`, `@target-uri`, `@authority`, `content-type`,
371
+ `content-digest`; `tag` is `adcp/webhook-signing/v1`; `alg` is
372
+ allowlisted; `keyid` resolves via the agent's brand.json
373
+ `agents[]` jwks_uri; content-digest recomputes cleanly; nonce is
374
+ not replayed.
375
+ task: expect_webhook_signature_valid
376
+ triggered_by: trigger_signed_webhook
377
+ filter:
378
+ operation_id: "{{prior_step.trigger_signed_webhook.operation_id}}"
379
+ timeout_seconds: 30
380
+ require_tag: "adcp/webhook-signing/v1"
381
+ stateful: true
382
+ expected: |
383
+ Signature verifies under the 9421 webhook profile. Fails with the
384
+ specific webhook_signature_* error code on any checklist failure
385
+ (e.g., signature_invalid, signature_expired, signature_key_unknown,
386
+ signature_digest_mismatch, signature_tag_invalid). Not_applicable
387
+ if the client library doesn't yet implement 9421 webhook
388
+ verification.
389
+
390
+ grading:
391
+ pass_criteria: |
392
+ Phases idempotency_key_presence, idempotency_key_stability,
393
+ signing_keys_published, and signature_validity MUST pass when the agent
394
+ advertises any webhook-emitting operation and the runner hosts a webhook
395
+ receiver. Agents without a published webhook-signing JWKS fail
396
+ signing_keys_published — there is no exemption for "HMAC legacy mode."
397
+ Agents that advertise no webhook-emitting operations grade the entire
398
+ universal as not_applicable. Runners without a webhook receiver grade the
399
+ entire universal as not_applicable. signature_validity may grade
400
+ not_applicable if the runner's `@adcp/client` 9421 webhook verifier is
401
+ not yet available; this is an explicit operator signal, not a silent
402
+ skip.
403
+ report_format: |
404
+ Per-phase pass/fail/not_applicable, with per-step error codes on failure.
405
+ Retry-stability failures include a diff of the observed keys across
406
+ deliveries so operators can debug sender-side retry bugs without re-running
407
+ the full suite. signing_keys_published failures cite the specific gap —
408
+ `webhook_signing_keys_unpublished`, `webhook_signing_keys_wrong_purpose`,
409
+ or `webhook_signing_keys_all_revoked` — so operators distinguish "never
410
+ set up keys" from "set up keys with the wrong purpose label" without
411
+ reading the JWKS by hand.