@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,172 @@
1
+ # Rate Limit Trip Runner — Harness Contract Test Kit
2
+ #
3
+ # Applies to:
4
+ # - universal/idempotency.yaml (rate_limit_replay_invariant phase — verifies
5
+ # that a RATE_LIMITED response on idempotency-cache insert MUST NOT be
6
+ # cached as the canonical replay for that key, per
7
+ # L1/security.mdx#idempotency bullet 8 + rule 3 ("Only successful
8
+ # responses are cached")).
9
+ # - Any future storyboard that needs to drive a fresh-key burst until a
10
+ # RATE_LIMITED response appears, then verify a downstream invariant.
11
+ #
12
+ # Storyboards are sequential by default and the storyboard YAML has no
13
+ # loop primitive. This test-kit defines the coordination contract between
14
+ # a runner that can drive a sequential burst of fresh-idempotency-key
15
+ # requests and a storyboard step that needs that capability.
16
+ #
17
+ # The runner's burst happens at the @adcp/client layer (or its Python/Go
18
+ # equivalents) using the SDK's request primitive in a tight sequential
19
+ # loop with a configurable max-attempts ceiling. The storyboard author
20
+ # MUST NOT try to express the burst via separate YAML steps.
21
+
22
+ id: rate_limit_trip_runner
23
+ applies_to:
24
+ universals:
25
+ - idempotency
26
+
27
+ description: |
28
+ Coordination contract between a runner that can drive a fresh-key burst
29
+ until a `RATE_LIMITED` response is observed and a storyboard step that
30
+ needs to verify the replay invariant on the rate-limited key. The runner
31
+ fires up to `max_attempts` sequential requests with fresh
32
+ `idempotency_key` values and otherwise-identical canonical payloads. On
33
+ the first `RATE_LIMITED` response it captures the request's idempotency
34
+ key, sleeps `error.details.retry_after` seconds, and then re-submits the
35
+ same key with the same payload. The cross-step assertion compares the
36
+ replay response against the rate-limit response and fails if the replay
37
+ returned the cached `RATE_LIMITED`.
38
+
39
+ endpoint_scope: sandbox
40
+ # Driving a burst against production would consume rate-limit budget that
41
+ # legitimate traffic relies on and may produce real downstream commitments
42
+ # if any of the sequential requests succeed before the limiter trips.
43
+ # Graders MUST target a sandbox/staging endpoint. Agents claiming the
44
+ # universal SHOULD expose a dedicated grading endpoint whose limiter is
45
+ # configured at the same ceiling as production but whose downstream side
46
+ # effects are sandboxed.
47
+
48
+ harness_mode: black_box
49
+
50
+ # --- Trip mechanism ---
51
+ #
52
+ # The runner fires requests sequentially against a single mutating-op
53
+ # target named by the storyboard step. Each request carries a fresh
54
+ # UUID v4 idempotency_key and an otherwise-identical canonical payload.
55
+ # The runner observes each response and stops when one of:
56
+ #
57
+ # 1. A response with envelope error_code = RATE_LIMITED is observed.
58
+ # The runner captures the request's idempotency_key into the
59
+ # step's context as `rate_limited_key`, captures the response's
60
+ # `error.details.retry_after` as `retry_after_seconds`, captures
61
+ # the rate-limit response body for the replay assertion, and
62
+ # proceeds to the wait + replay phase.
63
+ #
64
+ # 2. `max_attempts` requests complete without producing RATE_LIMITED.
65
+ # The runner grades the step as `not_applicable` with reason
66
+ # `rate_limit_not_triggered` — sellers may legitimately configure
67
+ # a sandbox limiter at a higher ceiling than this contract's
68
+ # max_attempts. The remainder of the storyboard is unaffected.
69
+ #
70
+ # Pacing. The runner fires requests as fast as the transport will accept
71
+ # without artificial throttling — the goal is to exceed the seller's
72
+ # configured insert-rate ceiling within max_attempts. Runners MAY use the
73
+ # SDK's connection pooling but MUST NOT batch via parallel_dispatch (that
74
+ # changes the cross-key timing and risks IDEMPOTENCY_IN_FLIGHT noise on
75
+ # parallel paths). Sequential is the simpler shape and matches what
76
+ # attacker-burst traffic would look like.
77
+
78
+ burst_step_contract:
79
+ required_step_fields:
80
+ - rate_limit_trip.trip_target_task
81
+ - rate_limit_trip.trip_target_sample_request
82
+ - rate_limit_trip.max_attempts
83
+ optional_step_fields:
84
+ - rate_limit_trip.replay_max_wait_seconds
85
+ max_attempts_min: 50
86
+ max_attempts_max: 500
87
+ # 50 ≤ max_attempts ≤ 500. Below 50 won't reliably trip a 60/sec-sustained
88
+ # limiter even with HTTP/2 multiplexing; above 500 inflates runtime
89
+ # materially without improving signal. Storyboards SHOULD start at 200
90
+ # and adjust per observed trip rates in CI.
91
+
92
+ # --- Wait + replay mechanism ---
93
+ #
94
+ # When a RATE_LIMITED is observed the runner reads
95
+ # `error.details.retry_after` (seconds), waits that long (capped by
96
+ # `rate_limit_trip.replay_max_wait_seconds`, default 30), then re-submits
97
+ # the rate-limited request:
98
+ #
99
+ # - Same idempotency_key (the one captured at trip time).
100
+ # - Same canonical payload (the trip_target_sample_request, with the
101
+ # same `$generate:uuid_v4#alias` resolutions as the trip request).
102
+ # - A distinct correlation_id so the replay's response is traceable in
103
+ # runner output.
104
+ #
105
+ # Sellers returning `retry_after` greater than `replay_max_wait_seconds`
106
+ # fail the step on `replay_wait_exceeded` rather than the replay invariant
107
+ # itself — `retry_after` values larger than the runner's wait budget are
108
+ # either a seller-side bug or a production-tuning mismatch with the
109
+ # conformance budget, and either way prevent the invariant from being
110
+ # verified.
111
+ #
112
+ # Sellers returning a `RATE_LIMITED` response without
113
+ # `error.details.retry_after` (or with retry_after = 0) fail with
114
+ # `missing_retry_after` — the retry hint is required to make rate-limit
115
+ # responses actionable, per L1/security.mdx error semantics.
116
+
117
+ # --- Cross-step assertion ---
118
+ #
119
+ # The runner emits a single structured result with three response objects
120
+ # the storyboard validations[] can target:
121
+ #
122
+ # trip_response.<path> The first RATE_LIMITED response observed
123
+ # during the burst.
124
+ # replay_response.<path> The response to the replay request issued
125
+ # after the retry_after wait.
126
+ # rate_limited_request.idempotency_key
127
+ # The key captured at trip time, for traceability.
128
+ #
129
+ # The step's validations declare the invariant against `replay_response`.
130
+ # The minimum required assertion is the not-cached check below; storyboards
131
+ # MAY add further assertions on `replay_response.media_buy_id` (success
132
+ # path) or other handler outputs.
133
+
134
+ replay_invariant_check_kinds:
135
+ - replay_not_cached_rate_limit
136
+
137
+ # `replay_not_cached_rate_limit` semantics: the runner compares
138
+ # `trip_response.error.code` against `replay_response.error.code` (when
139
+ # the replay carries an error envelope) or against the absence of error
140
+ # (when the replay carries a success envelope). If both responses carry
141
+ # error_code = RATE_LIMITED, the replay was served from the idempotency
142
+ # cache and the invariant fails. Any other replay response shape passes
143
+ # the invariant — either the handler succeeded (RATE_LIMITED was not
144
+ # cached, the seller correctly re-executed), or the handler returned a
145
+ # different error (the seller correctly re-executed and a state-dependent
146
+ # error fired).
147
+
148
+ # --- What the contract does NOT cover ---
149
+ #
150
+ # Burst-volume attestation of the 60/300 req/sec ceiling itself. The
151
+ # contract observes whether the limiter exists and behaves correctly under
152
+ # the replay invariant; it does NOT measure the threshold at which the
153
+ # limiter activates. Threshold attestation is structurally non-deterministic
154
+ # in CI environments (runner CPU, network jitter, agent cold-start) and is
155
+ # better evaluated via operator-side load testing or self-attestation.
156
+ #
157
+ # Cross-scope rate-limit leakage. The contract dispatches all requests
158
+ # within a single (authenticated_agent, account) scope. Storyboards needing
159
+ # to verify that one agent's rate-limit budget does not affect another
160
+ # agent's traffic require a separate contract.
161
+ #
162
+ # RATE_LIMITED on read paths. The contract drives mutating-op traffic
163
+ # (where idempotency caching applies). Sellers MAY also rate-limit read
164
+ # operations, but the replay invariant doesn't apply there — reads are
165
+ # inherently safe to retry.
166
+
167
+ # --- Reviewer checks ---
168
+
169
+ reviewer_checks:
170
+ - "Confirm the seller's idempotency-cache implementation explicitly excludes RATE_LIMITED (and other transient-error) responses from the cached-replay path. Review the storage layer or runbook describing which response classes are persisted under idempotency_key."
171
+ - "Confirm the seller's rate-limit response carries a usable retry_after value (seconds, integer, > 0, ≤ a documented ceiling). A seller that returns retry_after values larger than buyers' realistic retry windows produces unusable rate-limit signaling."
172
+ - "Confirm the seller's rate-limit budget is scoped per (authenticated_agent, account) tuple — not shared across all agents or accounts globally — so one agent's burst cannot exhaust another's budget."
@@ -0,0 +1,155 @@
1
+ # Signed-Requests Runner — Harness Contract Test Kit
2
+ #
3
+ # Applies to: universal/signed-requests.yaml (gated on
4
+ # `request_signing.supported: true` in get_adcp_capabilities).
5
+ #
6
+ # The signed-requests storyboard grades an agent's RFC 9421 verifier against 28
7
+ # conformance vectors at /compliance/{version}/test-vectors/request-signing/.
8
+ # Most vectors are pure black-box: the runner constructs a signed HTTP request,
9
+ # sends it, and checks the response. Three negative vectors assert behavior that
10
+ # depends on verifier state the runner cannot set from the outside:
11
+ #
12
+ # 016-replayed-nonce — replay cache must already contain (keyid, nonce)
13
+ # 017-key-revoked — keyid must already be in the revocation list
14
+ # 020-rate-abuse — per-keyid replay cache must be at its configured cap
15
+ #
16
+ # This test-kit defines the coordination contract between a black-box runner and
17
+ # a request-signing agent under test. Agents advertising
18
+ # `request_signing.supported: true` MUST pre-configure their verifier per this
19
+ # contract before the negative phase runs. The runner reads this file to know
20
+ # (a) the keyids it will sign with, (b) how to provoke each stateful negative
21
+ # vector, and (c) the grading-time cap values it will target (which are NOT
22
+ # production recommendations — see each field). See `scope` below for what the
23
+ # contract does NOT specify.
24
+
25
+ id: signed_requests_runner
26
+ applies_to:
27
+ universal_storyboard: signed-requests
28
+
29
+ description: |
30
+ Coordination contract between a black-box runner and a request-signing agent
31
+ under test. The runner signs vectors dynamically using the keypairs published
32
+ in keys.json. The agent pre-configures its verifier — accepted JWKS, pre-revoked
33
+ keyid, replay TTL, per-keyid cap — so that the three stateful negative vectors
34
+ produce their expected error codes without the runner injecting verifier state.
35
+
36
+ Vectors requiring coordination declare `requires_contract` in their fixture;
37
+ the runner gates those vectors on this contract being in scope.
38
+
39
+ endpoint_scope: sandbox
40
+ # The replay-window contract sends a live, validly-signed mutating request as
41
+ # its first step (the second copy is what the grader expects to be rejected).
42
+ # Running this against a production endpoint would create a real media buy.
43
+ # Graders MUST target a sandbox/staging endpoint or an idempotency-keyed
44
+ # sacrificial path the agent discards post-grading. Agents advertising
45
+ # `request_signing.supported: true` SHOULD expose a dedicated grading endpoint
46
+ # rather than grading in prod.
47
+
48
+ harness_mode: black_box
49
+ # Agents participating in a white-box test harness (e.g., SDK internal tests
50
+ # against the reference verifier) MAY satisfy the stateful vectors via direct
51
+ # state injection using the vector's `test_harness_state` block, and declare
52
+ # `harness_mode: white_box` in their own runner configuration. AdCP Verified
53
+ # grading runs in black_box mode only.
54
+
55
+ runner_signing_keys:
56
+ # Runner signs every non-negative-key vector with one of these keypairs. The
57
+ # agent's verifier MUST treat these keyids as a registered test counterparty
58
+ # whose JWKS contains the corresponding public keys with
59
+ # adcp_use: "request-signing". Private keys for signing live in keys.json
60
+ # under `_private_d_for_test_only`.
61
+ - keyid: test-ed25519-2026
62
+ alg: ed25519
63
+ jwks_source: /compliance/{version}/test-vectors/request-signing/keys.json
64
+ - keyid: test-es256-2026
65
+ alg: ecdsa-p256-sha256
66
+ jwks_source: /compliance/{version}/test-vectors/request-signing/keys.json
67
+
68
+ stateful_vector_contract:
69
+ replay_window:
70
+ # Vector 016-replayed-nonce.
71
+ #
72
+ # The runner provokes the replay rejection by sending the same signed
73
+ # request twice in sequence. The agent MUST accept the first submission
74
+ # (standard positive path) and reject the second with
75
+ # request_signature_replayed at checklist step 12.
76
+ #
77
+ # The agent's replay-cache TTL for this test counterparty MUST be at least
78
+ # `min_replay_ttl_seconds`, which is strictly greater than
79
+ # `max_interval_seconds` to absorb clock skew between runner and agent and
80
+ # scheduler jitter on either side. Otherwise the cache entry for the first
81
+ # request may evict before the second arrives and the vector will pass
82
+ # spuriously (i.e., both requests accepted = no replay rejection). The
83
+ # runner's own interval between the two submissions MUST NOT exceed
84
+ # `max_interval_seconds`.
85
+ #
86
+ # This supersedes vector 016's `test_harness_state.replay_cache_entries`
87
+ # for black-box mode. In white-box mode, the harness MAY inject the cache
88
+ # entry directly and skip the first request.
89
+ vector_id: 016-replayed-nonce
90
+ black_box_behavior: repeat_request
91
+ max_interval_seconds: 5
92
+ min_replay_ttl_seconds: 10
93
+
94
+ revocation:
95
+ # Vector 017-key-revoked.
96
+ #
97
+ # The runner cannot revoke a key on the agent's side. The agent MUST
98
+ # pre-configure its revocation list with `test-revoked-2026` before the
99
+ # negative phase runs. The runner signs vector 017 with this keyid and
100
+ # expects request_signature_key_revoked at checklist step 9.
101
+ #
102
+ # A dedicated revoked keypair (rather than reusing a runner signing key)
103
+ # keeps positive vectors and vector 017 independent: the positive phase
104
+ # remains runnable after vector 017 is graded.
105
+ vector_id: 017-key-revoked
106
+ pre_revoked_keyid: test-revoked-2026
107
+
108
+ rate_abuse:
109
+ # Vector 020-rate-abuse (checklist step 9a).
110
+ #
111
+ # The runner sends N+1 distinct-nonce requests signed by the same keyid
112
+ # within the window. The agent MUST reject the (N+1)th with
113
+ # request_signature_rate_abuse once the per-keyid cap is hit.
114
+ #
115
+ # `grading_target_per_keyid_cap_requests` is the cap the runner will
116
+ # target during grading — NOT a production recommendation. Agents MAY
117
+ # configure a lower cap for the test-kit counterparty only so grading
118
+ # finishes in a reasonable time. Production caps MUST follow the spec
119
+ # recommendation at docs/building/implementation/security.mdx
120
+ # §per-keyid cap (at least 1,000,000 entries per keyid). Implementers
121
+ # copying a value from this file into production code SHOULD use
122
+ # `production_min_per_keyid_cap_requests` below as the floor, not
123
+ # `grading_target_per_keyid_cap_requests`.
124
+ vector_id: 020-rate-abuse
125
+ grading_target_per_keyid_cap_requests: 100
126
+ production_min_per_keyid_cap_requests: 1000000
127
+ window_seconds: 60
128
+
129
+ scope:
130
+ in_scope: |
131
+ - Keyids the runner will sign with and their JWKS source.
132
+ - Agent-side preconditions for each stateful negative vector.
133
+ - Grading-time cap the runner will target for rate-abuse grading (NOT a
134
+ production recommendation; see rate_abuse block).
135
+ - Minimum replay-cache TTL so the replay-window contract is reliable.
136
+ - Black-box vs. white-box harness mode selection.
137
+ - Endpoint scope (sandbox only — see endpoint_scope).
138
+ out_of_scope: |
139
+ - Specific error-code strings — those live in each vector's
140
+ expected_outcome.error_code and are graded byte-for-byte.
141
+ - Checklist step numbers — informational only; grading is on the error
142
+ code, not the step.
143
+ - Pre-signed Signature bytes in the vectors — unchanged by this contract.
144
+ Black-box runners re-sign dynamically; pre-signed bytes remain valid
145
+ for white-box cross-SDK byte-equivalence checks.
146
+ - The agent's internal replay TTL or cap storage mechanism — the contract
147
+ specifies observable behavior, not implementation.
148
+ - Production verifier configuration — this contract configures a test
149
+ counterparty only.
150
+
151
+ references:
152
+ universal_storyboard: static/compliance/source/universal/signed-requests.yaml
153
+ test_vectors: /compliance/{version}/test-vectors/request-signing/
154
+ verifier_checklist: /docs/building/by-layer/L1/security.mdx#verifier-checklist-requests
155
+ runner_implementation: https://github.com/adcontextprotocol/adcp-client/issues/585
@@ -0,0 +1,294 @@
1
+ # Single-Side Trust Runner — Harness Contract Test Kit
2
+ #
3
+ # Applies to:
4
+ # - protocols/brand/scenarios/single_side_trust_extension.yaml
5
+ #
6
+ # The single-side-trust scenario is a partner-conformance red test. Unlike
7
+ # every other storyboard in the corpus today — which grades an agent serving
8
+ # verify_brand_claim — this scenario grades a CONSUMER of verify_brand_claim.
9
+ # The subject under test is a partner that may extend governance trust (auto-
10
+ # provision a member account, propagate billable seat inclusion, inherit
11
+ # governance posture) based on what verify_brand_claim returns. The red test
12
+ # asserts the asymmetric trust rule from
13
+ # /docs/brand-protocol/tasks/verify_brand_claim §"The trust rule — two calls,
14
+ # not one": a single signed `owned` response is NOT trust-extending.
15
+ #
16
+ # This is a framework extension. The conformance corpus today drives an agent
17
+ # under test and grades its response. Grading a consumer-side trust decision
18
+ # requires:
19
+ #
20
+ # 1. The runner hosts fixture brand-agents (a malicious house signing
21
+ # `owned` for relationships it does not legitimately have) plus the
22
+ # static brand.json files that should — under the spec — fail to
23
+ # reciprocate.
24
+ #
25
+ # 2. The runner exercises the partner under test through whatever surface
26
+ # that partner exposes for "evaluate a verify_brand_claim response and
27
+ # decide whether to extend trust" — the partner advertises this surface
28
+ # via comply_test_controller (scenario name
29
+ # `evaluate_verify_brand_claim_trust_extension`, defined below). Partners
30
+ # that do not advertise it grade the scenario `not_applicable`.
31
+ #
32
+ # 3. The runner queries the partner's comply_test_controller
33
+ # `query_upstream_traffic` to confirm:
34
+ # - The partner DID call leaf-side reciprocation (positive assertion:
35
+ # `min_count: 1` against a `GET *.well-known/brand.json` pattern on
36
+ # the leaf, OR a verify_brand_claim call with `claim_type: "parent"`
37
+ # on a leaf-side brand-agent — when one exists).
38
+ # - The partner did NOT extend trust (negative assertion: `min_count: 0`
39
+ # against governance-trust-extension endpoint patterns the partner
40
+ # declares via this contract).
41
+ #
42
+ # Runner-side implementation is pending. Until adcp-client lands the consumer-
43
+ # under-test dispatch primitive, scenario steps grade `not_applicable` via
44
+ # their `requires_contract: single_side_trust_runner` declaration. This file
45
+ # documents the contract so the dispatch can be implemented against a stable
46
+ # fixture surface.
47
+
48
+ id: single_side_trust_runner
49
+ applies_to:
50
+ protocol_scenarios:
51
+ - single_side_trust_extension
52
+
53
+ description: |
54
+ Coordination contract between a black-box runner and a partner under test
55
+ whose responsibility is to evaluate verify_brand_claim responses and decide
56
+ whether to extend governance trust. The runner hosts the malicious-house
57
+ fixture brand-agent and the non-reciprocating leaf brand.json. The partner
58
+ receives a `verify_brand_claim` invocation through its comply_test_controller
59
+ `evaluate_verify_brand_claim_trust_extension` scenario, performs whatever
60
+ verification the spec mandates, and exposes its outbound HTTP traffic via
61
+ `query_upstream_traffic` for the runner to assert against.
62
+
63
+ endpoint_scope: sandbox
64
+ # The partner under test executes a real verify-and-decide pipeline against
65
+ # the runner-hosted fixtures. Partners MUST NOT run this against any
66
+ # production trust-extension surface; the runner's `owned` responses describe
67
+ # fabricated relationships and any partner that auto-provisions on them in
68
+ # production is the bug this test exists to surface.
69
+
70
+ harness_mode: black_box
71
+
72
+ # --- Fixture brand-agents and static documents the runner hosts ---
73
+ #
74
+ # The runner stands up three fixture surfaces. All use the IANA-reserved
75
+ # `.example` TLD. The runner is the authoritative origin for every URL below
76
+ # during a test run; partners under test resolve these names against the
77
+ # runner's DNS or hosts override per the operator's harness configuration.
78
+
79
+ fixtures:
80
+ malicious_house:
81
+ # A brand-agent at a runner-controlled domain that signs `owned` for
82
+ # arbitrary subsidiary / property / trademark claims. The agent's JWKS is
83
+ # published at the same domain so signature verification succeeds — the
84
+ # point of the red test is that signature validity does NOT confer
85
+ # relationship trust without reciprocation.
86
+ domain: "malicious-house.example"
87
+ brand_agent_url: "https://malicious-house.example/agents/brand"
88
+ jwks_uri: "https://malicious-house.example/.well-known/jwks.json"
89
+ response_signing_keyid: "test-malicious-house-2026"
90
+ # When the runner asks the malicious house's brand-agent any of the
91
+ # supported claim types, it returns `owned` with a freshly signed
92
+ # response. Behavior matrix:
93
+ response_matrix:
94
+ - claim_type: subsidiary
95
+ # Any `claim.subsidiary_domain` returns owned, regardless of whether
96
+ # the leaf actually claims this house as its parent.
97
+ status: owned
98
+ details:
99
+ brand_id: "fabricated_subsidiary"
100
+ - claim_type: property
101
+ # Any `claim.property.identifier` returns owned, regardless of the
102
+ # real registrant of that property.
103
+ status: owned
104
+ details:
105
+ relationship: "owned"
106
+ - claim_type: trademark
107
+ # Returns `licensed_in` claiming a licensor the runner ALSO hosts as
108
+ # a non-reciprocating fixture (see `non_reciprocating_licensor`
109
+ # below).
110
+ status: licensed_in
111
+ details:
112
+ matched_registration: "fabricated-mark-001"
113
+ licensor_domain: "non-reciprocating-licensor.example"
114
+
115
+ non_reciprocating_leaf:
116
+ # A static brand.json hosted at a runner-controlled domain. The brand
117
+ # declares NO `house_domain` (or declares a different parent). No
118
+ # brand-agent is advertised at this domain — reciprocation requires a
119
+ # static crawl. This is the "leaf does not agree" half of the asymmetric
120
+ # trust model.
121
+ domain: "independent-leaf.example"
122
+ brand_json_url: "https://independent-leaf.example/.well-known/brand.json"
123
+ brand_json_shape:
124
+ # The leaf is standalone — no `house_domain` field at all. A spec-
125
+ # conformant consumer that crawls this MUST conclude no relationship
126
+ # exists with malicious-house.example.
127
+ brand_id: "independent_leaf"
128
+ names:
129
+ - { locale: "en", value: "Independent Leaf" }
130
+ house_domain: null
131
+
132
+ non_reciprocating_licensor:
133
+ # A static brand.json for the trademark licensed_in variant. The
134
+ # malicious house claims `licensed_in` from this licensor; the licensor
135
+ # does NOT publish a matching `licensed_out` for the mark. Per the
136
+ # trademark trust rule, partners SHOULD treat `licensed_in` as
137
+ # unverified until the licensor reciprocates.
138
+ domain: "non-reciprocating-licensor.example"
139
+ brand_json_url: "https://non-reciprocating-licensor.example/.well-known/brand.json"
140
+ brand_json_shape:
141
+ brand_id: "non_reciprocating_licensor"
142
+ names:
143
+ - { locale: "en", value: "Non-Reciprocating Licensor" }
144
+ # No trademarks[] entry naming malicious-house.example as a licensee.
145
+ trademarks: []
146
+
147
+ non_reciprocating_property_owner:
148
+ # A static brand.json for the property variant. The runner exposes a
149
+ # property identifier (a website) the malicious house claims `owned`,
150
+ # but the property's actual owning brand publishes a brand.json that
151
+ # does NOT include the property in its `properties[]`.
152
+ domain: "real-property-owner.example"
153
+ brand_json_url: "https://real-property-owner.example/.well-known/brand.json"
154
+ property_under_test:
155
+ type: "website"
156
+ identifier: "real-property-owner.example"
157
+ brand_json_shape:
158
+ brand_id: "real_property_owner"
159
+ names:
160
+ - { locale: "en", value: "Real Property Owner" }
161
+ # The property is listed here under the real owner, NOT under the
162
+ # malicious house's `owned` claim.
163
+ properties:
164
+ - { type: "website", identifier: "real-property-owner.example" }
165
+
166
+ # --- Consumer-under-test dispatch contract ---
167
+ #
168
+ # The runner drives the partner under test via its comply_test_controller.
169
+ # The partner MUST advertise this scenario in its `list_scenarios` response
170
+ # to participate; partners that do not advertise it grade the scenario
171
+ # `not_applicable` (not failed) — the scenario is opt-in by partner
172
+ # capability, matching the upstream_traffic convention documented in
173
+ # storyboard-schema.yaml > authored_check_kinds.
174
+ #
175
+ # The contract is forward-looking: today no partner implements this
176
+ # controller scenario, and runner support is pending. Partners that want to
177
+ # claim conformance against this red test register support here.
178
+
179
+ consumer_test_controller_scenario:
180
+ name: evaluate_verify_brand_claim_trust_extension
181
+ request_shape:
182
+ # Variant the runner is exercising.
183
+ variant: subsidiary | property | trademark_licensed_in
184
+ # The malicious-house brand-agent URL the partner should call
185
+ # verify_brand_claim against.
186
+ brand_agent_url: "<runner-supplied URL from fixtures.malicious_house>"
187
+ # The claim payload the partner should pass.
188
+ claim:
189
+ # Shape varies by variant — matches verify-brand-claim-request.json
190
+ # discriminator arms.
191
+ claim_type: subsidiary | property | trademark
192
+ claim: { ... }
193
+ # Optional account context. Partners that only auto-provision under
194
+ # an authenticated account context use this to scope the test to that
195
+ # path.
196
+ requesting_account:
197
+ brand:
198
+ domain: "<runner-supplied partner-controlled account domain>"
199
+ operator: "<runner-supplied operator>"
200
+
201
+ expected_partner_behavior:
202
+ # The partner MUST call verify_brand_claim on brand_agent_url.
203
+ # The partner MUST then EITHER:
204
+ # (a) crawl the leaf's static brand.json for reciprocation, OR
205
+ # (b) call a leaf-side brand-agent's verify_brand_claim with
206
+ # claim_type: "parent" — if the leaf advertises one (in this
207
+ # contract's fixtures, none does, forcing path (a)).
208
+ # The partner MUST NOT extend governance trust on the strength of the
209
+ # malicious-house's signed `owned` alone.
210
+
211
+ # --- Upstream-traffic assertions the runner applies ---
212
+ #
213
+ # After dispatching the scenario, the runner queries the partner's
214
+ # comply_test_controller `query_upstream_traffic` and applies these
215
+ # assertions. See storyboard-schema.yaml > `upstream_traffic` for the
216
+ # check primitives.
217
+
218
+ upstream_traffic_contract:
219
+ reciprocation_call_observed:
220
+ # POSITIVE assertion. The partner MUST have called either the leaf's
221
+ # static brand.json or a leaf-side brand-agent's verify_brand_claim
222
+ # (claim_type: "parent" / property crawl / licensor reciprocation,
223
+ # depending on variant).
224
+ min_count: 1
225
+ endpoint_pattern_by_variant:
226
+ subsidiary: "GET *://independent-leaf.example/.well-known/brand.json"
227
+ property: "GET *://real-property-owner.example/.well-known/brand.json"
228
+ trademark_licensed_in: "GET *://non-reciprocating-licensor.example/.well-known/brand.json"
229
+
230
+ trust_extension_not_taken:
231
+ # NEGATIVE assertion. The partner MUST NOT have extended governance
232
+ # trust on the malicious house's response alone. Partners declare the
233
+ # endpoint patterns that represent trust-extension side effects in
234
+ # their own conformance config; the runner exercises a closed set:
235
+ min_count: 0
236
+ candidate_endpoint_patterns:
237
+ # The partner is configured (out of band, when registering for this
238
+ # red test) to surface trust-extension side effects through one of
239
+ # these well-known patterns OR through a partner-declared list
240
+ # carried alongside its list_scenarios response. The runner asserts
241
+ # NONE of these fire during the test window.
242
+ - "POST */governance/auto-provision"
243
+ - "POST */accounts/auto-create-member"
244
+ - "POST */governance/contexts"
245
+ - "POST */billing/seats/auto-add"
246
+
247
+ # --- Identifier echo for anti-façade ---
248
+ #
249
+ # To raise the bar against partners that satisfy the controller scenario
250
+ # without actually performing the upstream calls, the runner injects a
251
+ # load-bearing identifier (a per-run nonce) into the malicious-house's
252
+ # response_signing keyid path or the claim payload's `subsidiary_brand_id`
253
+ # field. The reciprocation call MUST carry that identifier verbatim — a
254
+ # façade that fabricates an empty traffic record cannot satisfy the
255
+ # `identifier_paths` echo check.
256
+
257
+ identifier_echo:
258
+ nonce_injection_field:
259
+ subsidiary: "claim.subsidiary_brand_id"
260
+ property: "claim.property.identifier"
261
+ trademark_licensed_in: "claim.mark"
262
+ identifier_paths_in_reciprocation_request:
263
+ # The runner asserts the leaf-side fetch (whether brand.json crawl or
264
+ # verify_brand_claim with claim_type: "parent") carries the same
265
+ # identifier value at the appropriate path.
266
+ subsidiary: "<HTTP path component containing the leaf domain>"
267
+ property: "<HTTP path component containing the property identifier>"
268
+ trademark_licensed_in: "<HTTP path component containing the licensor domain>"
269
+
270
+ scope:
271
+ in_scope: |
272
+ - Fixture brand-agent endpoints (URLs, JWKS, signing keyids).
273
+ - Fixture static brand.json shapes that fail reciprocation.
274
+ - The consumer-test-controller scenario name and request shape the
275
+ runner uses to dispatch the partner under test.
276
+ - The endpoint patterns the runner asserts on via query_upstream_traffic.
277
+ - Identifier echo paths for anti-façade verification.
278
+ out_of_scope: |
279
+ - The partner's specific trust-extension implementation (account-
280
+ auto-provisioning, governance-context creation, billable seat
281
+ inclusion, etc.). The contract names the side-effect patterns it
282
+ asserts on; how the partner internally wires trust extension is
283
+ partner-specific.
284
+ - Runner-side dispatch implementation. Tracked separately when
285
+ partner adoption reaches a quorum — until then, scenario steps
286
+ grade not_applicable via `requires_contract`.
287
+ - Real-world brand domains. Every fixture domain is on the
288
+ IANA-reserved `.example` TLD.
289
+
290
+ references:
291
+ scenario: static/compliance/source/protocols/brand/scenarios/single_side_trust_extension.yaml
292
+ task_spec: /brand-protocol/tasks/verify_brand_claim
293
+ trust_model: /brand-protocol/brand-json#agent-augmented-verification
294
+ source_issue: https://github.com/adcontextprotocol/adcp/issues/4597