@adcp/sdk 7.10.2 → 7.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compliance/cache/3.1.0-rc.2/domains/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/domains/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/domains/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/domains/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/index.json +356 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/protocols/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/protocols/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/protocols/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/audience-sync/index.yaml +313 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/index.yaml +350 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/scenarios/governance_denied.yaml +226 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/collection-lists/index.yaml +359 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/content-standards/index.yaml +572 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-ad-server/index.yaml +409 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/generative-seller.yaml +807 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/index.yaml +758 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-template/index.yaml +510 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/index.yaml +143 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-delivery-monitor/index.yaml +441 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/denied.yaml +221 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/index.yaml +330 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/property-lists/index.yaml +482 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-broadcast-tv/index.yaml +738 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-catalog-driven/index.yaml +840 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-guaranteed/index.yaml +601 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-non-guaranteed/index.yaml +546 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-proposal-mode/index.yaml +586 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-social/index.yaml +919 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/index.yaml +424 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/scenarios/governance_denied.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-owned/index.yaml +317 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sponsored-intelligence/index.yaml +59 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor-live.yaml +78 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor.yaml +223 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/billing-gate-runner.yaml +115 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/bistro-oranje.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/distributed-brand-runner.yaml +281 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/nova-motors.yaml +262 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/osei-natural.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/parallel-dispatch-runner.yaml +196 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/rate-limit-trip-runner.yaml +172 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/signed-requests-runner.yaml +155 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/single-side-trust-runner.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/substitution-observer-runner.yaml +688 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/summit-foods.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/webhook-receiver-runner.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/001-minimal-plan.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/002-full-plan.json +217 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/README.md +220 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/canonicalization.json +241 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/keys.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/001-basic-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/003-es256-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/README.md +211 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/keys.json +61 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
- package/compliance/cache/3.1.0-rc.2/universal/billing-gate-dispatch.yaml +450 -0
- package/compliance/cache/3.1.0-rc.2/universal/canonical-format-validate-input.yaml +640 -0
- package/compliance/cache/3.1.0-rc.2/universal/capability-discovery.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/universal/collection-lists-pagination-integrity.yaml +306 -0
- package/compliance/cache/3.1.0-rc.2/universal/comply-controller-mode-gate.yaml +141 -0
- package/compliance/cache/3.1.0-rc.2/universal/content-standards-pagination-integrity.yaml +326 -0
- package/compliance/cache/3.1.0-rc.2/universal/deterministic-testing.yaml +1430 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance-signals.yaml +377 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance.yaml +528 -0
- package/compliance/cache/3.1.0-rc.2/universal/fictional-entities.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-media-buys-pagination-integrity.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-signals-pagination-integrity.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/universal/idempotency.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-event-scope.yaml +119 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-lifecycle.yaml +337 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-rejections.yaml +107 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-creative-formats.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-list-accounts.yaml +245 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity.yaml +263 -0
- package/compliance/cache/3.1.0-rc.2/universal/property-lists-pagination-integrity.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/read-tool-idempotency.yaml +405 -0
- package/compliance/cache/3.1.0-rc.2/universal/runner-output-contract.yaml +1285 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation-signals.yaml +181 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation.yaml +548 -0
- package/compliance/cache/3.1.0-rc.2/universal/security.yaml +539 -0
- package/compliance/cache/3.1.0-rc.2/universal/signed-requests.yaml +217 -0
- package/compliance/cache/3.1.0-rc.2/universal/stale-response-advisory.yaml +295 -0
- package/compliance/cache/3.1.0-rc.2/universal/storyboard-schema.yaml +2194 -0
- package/compliance/cache/3.1.0-rc.2/universal/v3-envelope-integrity.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/universal/version-negotiation.yaml +130 -0
- package/compliance/cache/3.1.0-rc.2/universal/webhook-emission.yaml +411 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-bulk-webhooks.yaml +82 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-product-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-products.yaml +151 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signal-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signals.yaml +149 -0
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +9 -5
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +30 -1
- package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +84 -21
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +21 -0
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/types.d.ts +9 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.d.ts +6707 -12040
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +1 -1
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/utils/signal-id-builders.d.ts +19 -0
- package/dist/lib/utils/signal-id-builders.d.ts.map +1 -1
- package/dist/lib/utils/signal-id-builders.js +30 -0
- package/dist/lib/utils/signal-id-builders.js.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.ts.map +1 -1
- package/dist/lib/utils/tool-request-schemas.js +3 -0
- package/dist/lib/utils/tool-request-schemas.js.map +1 -1
- package/dist/lib/v2/projection/constants.d.ts +28 -0
- package/dist/lib/v2/projection/constants.d.ts.map +1 -0
- package/dist/lib/v2/projection/constants.js +31 -0
- package/dist/lib/v2/projection/constants.js.map +1 -0
- package/dist/lib/v2/projection/registry.d.ts.map +1 -1
- package/dist/lib/v2/projection/registry.js +9 -4
- package/dist/lib/v2/projection/registry.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
- package/skills/SHAPE-GOTCHAS.md +5 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
id: notification_config_event_scope
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Notification config event-scope rejection"
|
|
4
|
+
category: schema_validation
|
|
5
|
+
summary: "Validates that sync_accounts.accounts[].notification_configs[] rejects media-buy-anchored notification types even though they are valid notification-type enum values."
|
|
6
|
+
track: core
|
|
7
|
+
required_tools:
|
|
8
|
+
- sync_accounts
|
|
9
|
+
|
|
10
|
+
narrative: |
|
|
11
|
+
`notification-type.json` intentionally contains both media-buy-anchored
|
|
12
|
+
event types (`scheduled`, `final`, `delayed`, `adjusted`, `impairment`) and
|
|
13
|
+
account-anchored event types (`creative.*`, `product.*`, `signal.*`,
|
|
14
|
+
`wholesale_feed.bulk_change`). JSON Schema can validate that a value is in
|
|
15
|
+
the enum, but it cannot know which registration surface the value belongs
|
|
16
|
+
on.
|
|
17
|
+
|
|
18
|
+
This storyboard closes that semantic gap for the account-level surface:
|
|
19
|
+
`sync_accounts.accounts[].notification_configs[]` MUST reject media-buy-
|
|
20
|
+
anchored event types. Those events belong on a media buy or task's
|
|
21
|
+
`push_notification_config`; accepting them on account-level configs would
|
|
22
|
+
imply a subscription lifecycle and payload contract the spec does not define.
|
|
23
|
+
|
|
24
|
+
The request is schema-valid on purpose. A seller that only performs JSON
|
|
25
|
+
Schema validation and persists the entry will fail the storyboard; a
|
|
26
|
+
conformant seller returns a per-account failure with a correctable validation
|
|
27
|
+
error.
|
|
28
|
+
|
|
29
|
+
agent:
|
|
30
|
+
interaction_model: media_buy_seller
|
|
31
|
+
capabilities: []
|
|
32
|
+
examples:
|
|
33
|
+
- "Any AdCP agent that accepts sync_accounts"
|
|
34
|
+
|
|
35
|
+
caller:
|
|
36
|
+
role: buyer_agent
|
|
37
|
+
example: "Compliance test harness"
|
|
38
|
+
|
|
39
|
+
prerequisites:
|
|
40
|
+
description: |
|
|
41
|
+
The agent under test exposes `sync_accounts`. The sample request uses
|
|
42
|
+
provisioning mode against the Acme Outdoor sandbox brand. Explicit-account
|
|
43
|
+
sellers that only support settings-update mode SHOULD run the same vector
|
|
44
|
+
against a pre-provisioned account reference; the invariant is identical:
|
|
45
|
+
account-level `notification_configs[]` must reject media-buy-anchored
|
|
46
|
+
event types.
|
|
47
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
48
|
+
controller_seeding: false
|
|
49
|
+
|
|
50
|
+
phases:
|
|
51
|
+
- id: reject_media_buy_anchored_event_type
|
|
52
|
+
title: "Reject media-buy-anchored event type on account config"
|
|
53
|
+
narrative: |
|
|
54
|
+
The buyer submits a schema-valid notification config that asks an
|
|
55
|
+
account-level subscriber to receive `scheduled` delivery reports.
|
|
56
|
+
`scheduled` is a valid `notification-type.json` value, but it is
|
|
57
|
+
media-buy anchored and belongs on `push_notification_config`, not on
|
|
58
|
+
`sync_accounts.accounts[].notification_configs[]`. The seller must reject the
|
|
59
|
+
per-account entry rather than silently persisting or dropping the
|
|
60
|
+
subscriber.
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- id: sync_accounts_rejects_scheduled_account_notification
|
|
64
|
+
title: "Submit scheduled in notification_configs[].event_types"
|
|
65
|
+
task: sync_accounts
|
|
66
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
67
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
68
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
69
|
+
# sync_accounts reports per-entry validation failures in
|
|
70
|
+
# accounts[].errors[] under a transport-level success. This is not a
|
|
71
|
+
# transport-layer error.
|
|
72
|
+
stateful: false
|
|
73
|
+
expected: |
|
|
74
|
+
Reject the per-account entry with:
|
|
75
|
+
- accounts[0].action: "failed"
|
|
76
|
+
- accounts[0].status: "rejected"
|
|
77
|
+
- accounts[0].errors[0].code: INVALID_REQUEST or VALIDATION_ERROR
|
|
78
|
+
- accounts[0].errors[0].field pointing at the invalid event_types entry
|
|
79
|
+
|
|
80
|
+
sample_request:
|
|
81
|
+
accounts:
|
|
82
|
+
- brand:
|
|
83
|
+
domain: "acmeoutdoor.example"
|
|
84
|
+
operator: "pinnacle-agency.example"
|
|
85
|
+
billing: "operator"
|
|
86
|
+
sandbox: true
|
|
87
|
+
notification_configs:
|
|
88
|
+
- subscriber_id: "delivery-reports"
|
|
89
|
+
url: "https://example.com/webhooks/adcp/account"
|
|
90
|
+
event_types:
|
|
91
|
+
- "scheduled"
|
|
92
|
+
active: false
|
|
93
|
+
idempotency_key: "$generate:uuid_v4#notification_config_event_scope_reject_scheduled"
|
|
94
|
+
context:
|
|
95
|
+
correlation_id: "notification_config_event_scope--reject_scheduled"
|
|
96
|
+
|
|
97
|
+
validations:
|
|
98
|
+
- check: response_schema
|
|
99
|
+
description: "Response matches sync-accounts-response.json schema even on per-account failure"
|
|
100
|
+
- check: field_value
|
|
101
|
+
path: "accounts[0].action"
|
|
102
|
+
value: "failed"
|
|
103
|
+
description: "Per-account action is failed"
|
|
104
|
+
- check: field_value
|
|
105
|
+
path: "accounts[0].status"
|
|
106
|
+
value: "rejected"
|
|
107
|
+
description: "Per-account status is rejected"
|
|
108
|
+
- check: field_value
|
|
109
|
+
path: "accounts[0].errors[0].code"
|
|
110
|
+
allowed_values: ["INVALID_REQUEST", "VALIDATION_ERROR"]
|
|
111
|
+
description: "Media-buy-anchored event type is rejected as a correctable request validation error"
|
|
112
|
+
- check: field_value
|
|
113
|
+
path: "accounts[0].errors[0].field"
|
|
114
|
+
value: "notification_configs[0].event_types[0]"
|
|
115
|
+
description: "Error identifies the invalid event_types field so SDKs can correct the registration"
|
|
116
|
+
- check: field_value
|
|
117
|
+
path: "context.correlation_id"
|
|
118
|
+
value: "notification_config_event_scope--reject_scheduled"
|
|
119
|
+
description: "Context correlation_id returned unchanged on error response"
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
id: notification_config_lifecycle
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Notification config lifecycle"
|
|
4
|
+
category: account_lifecycle
|
|
5
|
+
summary: "Validates account-level notification_configs[] lifecycle behavior on sync_accounts: paused registration, durable echo, subscriber-keyed replacement, and clear."
|
|
6
|
+
track: core
|
|
7
|
+
required_tools:
|
|
8
|
+
- sync_accounts
|
|
9
|
+
- list_accounts
|
|
10
|
+
|
|
11
|
+
narrative: |
|
|
12
|
+
AdCP 3.1 makes `sync_accounts.accounts[].notification_configs[]` the
|
|
13
|
+
durable account-level subscription surface for creative lifecycle and
|
|
14
|
+
wholesale-feed webhook events. This storyboard verifies the positive
|
|
15
|
+
lifecycle: a paused subscriber can be registered without endpoint proof,
|
|
16
|
+
the seller echoes the applied state on `sync_accounts` and `list_accounts`, re-sending the same
|
|
17
|
+
`subscriber_id` replaces the subscriber rather than appending a duplicate,
|
|
18
|
+
inactive entries are preserved as paused subscriptions, and `[]` clears the
|
|
19
|
+
subscriber set. Active registration is intentionally out of scope here:
|
|
20
|
+
sellers MUST complete the account-level proof-of-control challenge before
|
|
21
|
+
persisting or echoing a new subscriber as `active: true`.
|
|
22
|
+
|
|
23
|
+
agent:
|
|
24
|
+
interaction_model: media_buy_seller
|
|
25
|
+
capabilities: []
|
|
26
|
+
examples:
|
|
27
|
+
- "Any AdCP agent that accepts sync_accounts and list_accounts"
|
|
28
|
+
|
|
29
|
+
caller:
|
|
30
|
+
role: buyer_agent
|
|
31
|
+
example: "Compliance test harness"
|
|
32
|
+
|
|
33
|
+
prerequisites:
|
|
34
|
+
description: |
|
|
35
|
+
The agent under test exposes `sync_accounts` and `list_accounts`. The
|
|
36
|
+
sample requests use sandbox provisioning mode first, then settings-update
|
|
37
|
+
mode by returned `account_id` so both sync_accounts key shapes are
|
|
38
|
+
exercised without requiring out-of-band explicit account setup.
|
|
39
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
40
|
+
controller_seeding: false
|
|
41
|
+
|
|
42
|
+
phases:
|
|
43
|
+
- id: register_and_echo_paused_subscriber
|
|
44
|
+
title: "Register and read a paused account-level subscriber"
|
|
45
|
+
narrative: |
|
|
46
|
+
The buyer provisions a sandbox account with one paused creative lifecycle
|
|
47
|
+
subscriber. Paused entries do not receive fires and may skip the outbound
|
|
48
|
+
endpoint-control proof while inactive, but the seller must still persist
|
|
49
|
+
and echo the applied state without relying on any media-buy-scoped webhook
|
|
50
|
+
surface.
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- id: sync_accounts_create_paused_notification_config
|
|
54
|
+
title: "Create account with paused notification config"
|
|
55
|
+
task: sync_accounts
|
|
56
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
57
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
58
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
59
|
+
stateful: true
|
|
60
|
+
context_outputs:
|
|
61
|
+
- name: notification_config_account_id
|
|
62
|
+
path: "accounts[0].account_id"
|
|
63
|
+
expected: |
|
|
64
|
+
Create or update the sandbox account and echo one paused
|
|
65
|
+
notification_configs[] entry keyed by subscriber_id.
|
|
66
|
+
|
|
67
|
+
sample_request:
|
|
68
|
+
accounts:
|
|
69
|
+
- brand:
|
|
70
|
+
domain: "acmeoutdoor.example"
|
|
71
|
+
operator: "pinnacle-agency.example"
|
|
72
|
+
billing: "operator"
|
|
73
|
+
payment_terms: "net_60"
|
|
74
|
+
sandbox: true
|
|
75
|
+
notification_configs:
|
|
76
|
+
- subscriber_id: "buyer-primary"
|
|
77
|
+
url: "https://example.com/webhooks/adcp/account-primary"
|
|
78
|
+
event_types:
|
|
79
|
+
- "creative.status_changed"
|
|
80
|
+
- "creative.purged"
|
|
81
|
+
active: false
|
|
82
|
+
idempotency_key: "$generate:uuid_v4#notification_config_lifecycle_create_paused"
|
|
83
|
+
context:
|
|
84
|
+
correlation_id: "notification_config_lifecycle--create_paused"
|
|
85
|
+
|
|
86
|
+
validations:
|
|
87
|
+
- check: response_schema
|
|
88
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
89
|
+
- check: field_present
|
|
90
|
+
path: "accounts[0].account_id"
|
|
91
|
+
description: "Account ID is returned for settings-update follow-up"
|
|
92
|
+
- check: field_value
|
|
93
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
94
|
+
value: "buyer-primary"
|
|
95
|
+
description: "Subscriber key is echoed"
|
|
96
|
+
- check: field_value
|
|
97
|
+
path: "accounts[0].notification_configs[0].url"
|
|
98
|
+
value: "https://example.com/webhooks/adcp/account-primary"
|
|
99
|
+
description: "Subscriber endpoint is echoed"
|
|
100
|
+
- check: field_value
|
|
101
|
+
path: "accounts[0].notification_configs[0].event_types[0]"
|
|
102
|
+
value: "creative.status_changed"
|
|
103
|
+
description: "Creative status event is registered"
|
|
104
|
+
- check: field_value
|
|
105
|
+
path: "accounts[0].notification_configs[0].event_types[1]"
|
|
106
|
+
value: "creative.purged"
|
|
107
|
+
description: "Creative purge event is registered"
|
|
108
|
+
- check: field_value
|
|
109
|
+
path: "accounts[0].notification_configs[0].active"
|
|
110
|
+
value: false
|
|
111
|
+
description: "Paused subscriber is persisted without requiring activation proof"
|
|
112
|
+
- check: field_absent
|
|
113
|
+
path: "accounts[0].notification_configs[1].subscriber_id"
|
|
114
|
+
description: "Exactly one subscriber is present"
|
|
115
|
+
- check: field_value
|
|
116
|
+
path: "context.correlation_id"
|
|
117
|
+
value: "notification_config_lifecycle--create_paused"
|
|
118
|
+
description: "Context correlation_id returned unchanged"
|
|
119
|
+
|
|
120
|
+
- id: list_accounts_echoes_notification_config
|
|
121
|
+
title: "Read persisted notification config"
|
|
122
|
+
task: list_accounts
|
|
123
|
+
schema_ref: "account/list-accounts-request.json"
|
|
124
|
+
response_schema_ref: "account/list-accounts-response.json"
|
|
125
|
+
doc_ref: "/accounts/tasks/list_accounts"
|
|
126
|
+
stateful: true
|
|
127
|
+
expected: |
|
|
128
|
+
Return the sandbox account with the persisted notification config.
|
|
129
|
+
|
|
130
|
+
sample_request:
|
|
131
|
+
account:
|
|
132
|
+
account_id: "$context.notification_config_account_id"
|
|
133
|
+
status: "active"
|
|
134
|
+
sandbox: true
|
|
135
|
+
pagination:
|
|
136
|
+
max_results: 100
|
|
137
|
+
context:
|
|
138
|
+
correlation_id: "notification_config_lifecycle--list_after_create"
|
|
139
|
+
|
|
140
|
+
validations:
|
|
141
|
+
- check: response_schema
|
|
142
|
+
description: "Response matches list-accounts-response.json schema"
|
|
143
|
+
- check: field_value
|
|
144
|
+
path: "accounts[0].account_id"
|
|
145
|
+
value: "$context.notification_config_account_id"
|
|
146
|
+
description: "The configured account is visible on list_accounts"
|
|
147
|
+
- check: field_value
|
|
148
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
149
|
+
value: "buyer-primary"
|
|
150
|
+
description: "Persisted subscriber is visible on list_accounts"
|
|
151
|
+
- check: field_value
|
|
152
|
+
path: "accounts[0].notification_configs[0].active"
|
|
153
|
+
value: false
|
|
154
|
+
description: "Persisted subscriber remains paused"
|
|
155
|
+
- check: field_value
|
|
156
|
+
path: "context.correlation_id"
|
|
157
|
+
value: "notification_config_lifecycle--list_after_create"
|
|
158
|
+
description: "Context correlation_id returned unchanged"
|
|
159
|
+
|
|
160
|
+
- id: replace_pause_and_clear
|
|
161
|
+
title: "Replace, pause, and clear subscribers"
|
|
162
|
+
narrative: |
|
|
163
|
+
The buyer targets the account by `account_id` and sends a full desired
|
|
164
|
+
subscriber set. The existing `subscriber_id` must be replaced in place,
|
|
165
|
+
not duplicated. An inactive subscriber must remain persisted as paused,
|
|
166
|
+
and a later empty array must clear the account's subscriber set.
|
|
167
|
+
|
|
168
|
+
steps:
|
|
169
|
+
- id: sync_accounts_replace_and_pause_subscriber
|
|
170
|
+
title: "Replace subscriber fields and pause delivery"
|
|
171
|
+
task: sync_accounts
|
|
172
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
173
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
174
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
175
|
+
stateful: true
|
|
176
|
+
expected: |
|
|
177
|
+
Replace the buyer-primary subscriber with the new endpoint and
|
|
178
|
+
event filter, preserving exactly one paused subscriber.
|
|
179
|
+
|
|
180
|
+
sample_request:
|
|
181
|
+
accounts:
|
|
182
|
+
- account:
|
|
183
|
+
account_id: "$context.notification_config_account_id"
|
|
184
|
+
payment_terms: "net_45"
|
|
185
|
+
notification_configs:
|
|
186
|
+
- subscriber_id: "buyer-primary"
|
|
187
|
+
url: "https://example.com/webhooks/adcp/account-paused"
|
|
188
|
+
event_types:
|
|
189
|
+
- "creative.purged"
|
|
190
|
+
active: false
|
|
191
|
+
idempotency_key: "$generate:uuid_v4#notification_config_lifecycle_replace_pause"
|
|
192
|
+
context:
|
|
193
|
+
correlation_id: "notification_config_lifecycle--replace_pause"
|
|
194
|
+
|
|
195
|
+
validations:
|
|
196
|
+
- check: response_schema
|
|
197
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
198
|
+
- check: field_value
|
|
199
|
+
path: "accounts[0].action"
|
|
200
|
+
value: "updated"
|
|
201
|
+
description: "Settings-update mode updates the existing account"
|
|
202
|
+
- check: field_value
|
|
203
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
204
|
+
value: "buyer-primary"
|
|
205
|
+
description: "Subscriber key is preserved"
|
|
206
|
+
- check: field_value
|
|
207
|
+
path: "accounts[0].notification_configs[0].url"
|
|
208
|
+
value: "https://example.com/webhooks/adcp/account-paused"
|
|
209
|
+
description: "Subscriber endpoint is replaced"
|
|
210
|
+
- check: field_value
|
|
211
|
+
path: "accounts[0].notification_configs[0].event_types[0]"
|
|
212
|
+
value: "creative.purged"
|
|
213
|
+
description: "Event filter is replaced"
|
|
214
|
+
- check: field_value
|
|
215
|
+
path: "accounts[0].notification_configs[0].active"
|
|
216
|
+
value: false
|
|
217
|
+
description: "Inactive subscriber is persisted as paused"
|
|
218
|
+
- check: field_absent
|
|
219
|
+
path: "accounts[0].notification_configs[1].subscriber_id"
|
|
220
|
+
description: "Replacement by subscriber_id did not create a duplicate"
|
|
221
|
+
- check: field_value
|
|
222
|
+
path: "context.correlation_id"
|
|
223
|
+
value: "notification_config_lifecycle--replace_pause"
|
|
224
|
+
description: "Context correlation_id returned unchanged"
|
|
225
|
+
|
|
226
|
+
- id: list_accounts_echoes_paused_replacement
|
|
227
|
+
title: "Read paused replacement"
|
|
228
|
+
task: list_accounts
|
|
229
|
+
schema_ref: "account/list-accounts-request.json"
|
|
230
|
+
response_schema_ref: "account/list-accounts-response.json"
|
|
231
|
+
doc_ref: "/accounts/tasks/list_accounts"
|
|
232
|
+
stateful: true
|
|
233
|
+
expected: |
|
|
234
|
+
Return the account with exactly one paused buyer-primary subscriber.
|
|
235
|
+
|
|
236
|
+
sample_request:
|
|
237
|
+
account:
|
|
238
|
+
account_id: "$context.notification_config_account_id"
|
|
239
|
+
status: "active"
|
|
240
|
+
sandbox: true
|
|
241
|
+
pagination:
|
|
242
|
+
max_results: 100
|
|
243
|
+
context:
|
|
244
|
+
correlation_id: "notification_config_lifecycle--list_after_pause"
|
|
245
|
+
|
|
246
|
+
validations:
|
|
247
|
+
- check: response_schema
|
|
248
|
+
description: "Response matches list-accounts-response.json schema"
|
|
249
|
+
- check: field_value
|
|
250
|
+
path: "accounts[0].account_id"
|
|
251
|
+
value: "$context.notification_config_account_id"
|
|
252
|
+
description: "The configured account is visible on list_accounts"
|
|
253
|
+
- check: field_value
|
|
254
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
255
|
+
value: "buyer-primary"
|
|
256
|
+
description: "Paused subscriber remains persisted"
|
|
257
|
+
- check: field_value
|
|
258
|
+
path: "accounts[0].notification_configs[0].active"
|
|
259
|
+
value: false
|
|
260
|
+
description: "Paused state is visible on list_accounts"
|
|
261
|
+
- check: field_value
|
|
262
|
+
path: "context.correlation_id"
|
|
263
|
+
value: "notification_config_lifecycle--list_after_pause"
|
|
264
|
+
description: "Context correlation_id returned unchanged"
|
|
265
|
+
|
|
266
|
+
- id: sync_accounts_clear_subscribers
|
|
267
|
+
title: "Clear all account-level subscribers"
|
|
268
|
+
task: sync_accounts
|
|
269
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
270
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
271
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
272
|
+
stateful: true
|
|
273
|
+
expected: |
|
|
274
|
+
Sending notification_configs: [] clears the account-level subscriber
|
|
275
|
+
set and echoes an empty array.
|
|
276
|
+
|
|
277
|
+
sample_request:
|
|
278
|
+
accounts:
|
|
279
|
+
- account:
|
|
280
|
+
account_id: "$context.notification_config_account_id"
|
|
281
|
+
notification_configs: []
|
|
282
|
+
idempotency_key: "$generate:uuid_v4#notification_config_lifecycle_clear"
|
|
283
|
+
context:
|
|
284
|
+
correlation_id: "notification_config_lifecycle--clear"
|
|
285
|
+
|
|
286
|
+
validations:
|
|
287
|
+
- check: response_schema
|
|
288
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
289
|
+
- check: field_present
|
|
290
|
+
path: "accounts[0].notification_configs"
|
|
291
|
+
description: "The clear operation echoes the now-empty subscriber array"
|
|
292
|
+
- check: field_absent
|
|
293
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
294
|
+
description: "No subscribers remain after clear"
|
|
295
|
+
- check: field_value
|
|
296
|
+
path: "context.correlation_id"
|
|
297
|
+
value: "notification_config_lifecycle--clear"
|
|
298
|
+
description: "Context correlation_id returned unchanged"
|
|
299
|
+
|
|
300
|
+
- id: list_accounts_echoes_cleared_subscribers
|
|
301
|
+
title: "Read cleared subscriber set"
|
|
302
|
+
task: list_accounts
|
|
303
|
+
schema_ref: "account/list-accounts-request.json"
|
|
304
|
+
response_schema_ref: "account/list-accounts-response.json"
|
|
305
|
+
doc_ref: "/accounts/tasks/list_accounts"
|
|
306
|
+
stateful: true
|
|
307
|
+
expected: |
|
|
308
|
+
Return the target account with no persisted notification_configs[]
|
|
309
|
+
entries after the clear operation.
|
|
310
|
+
|
|
311
|
+
sample_request:
|
|
312
|
+
account:
|
|
313
|
+
account_id: "$context.notification_config_account_id"
|
|
314
|
+
status: "active"
|
|
315
|
+
sandbox: true
|
|
316
|
+
pagination:
|
|
317
|
+
max_results: 100
|
|
318
|
+
context:
|
|
319
|
+
correlation_id: "notification_config_lifecycle--list_after_clear"
|
|
320
|
+
|
|
321
|
+
validations:
|
|
322
|
+
- check: response_schema
|
|
323
|
+
description: "Response matches list-accounts-response.json schema"
|
|
324
|
+
- check: field_value
|
|
325
|
+
path: "accounts[0].account_id"
|
|
326
|
+
value: "$context.notification_config_account_id"
|
|
327
|
+
description: "The configured account is visible on list_accounts after clear"
|
|
328
|
+
- check: field_present
|
|
329
|
+
path: "accounts[0].notification_configs"
|
|
330
|
+
description: "The account echoes an empty subscriber array after clear"
|
|
331
|
+
- check: field_absent
|
|
332
|
+
path: "accounts[0].notification_configs[0].subscriber_id"
|
|
333
|
+
description: "No persisted subscribers remain after clear"
|
|
334
|
+
- check: field_value
|
|
335
|
+
path: "context.correlation_id"
|
|
336
|
+
value: "notification_config_lifecycle--list_after_clear"
|
|
337
|
+
description: "Context correlation_id returned unchanged"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
id: notification_config_rejections
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Notification config semantic rejections"
|
|
4
|
+
category: schema_validation
|
|
5
|
+
summary: "Validates account-level notification_configs[] semantic rejection for duplicate subscriber keys."
|
|
6
|
+
track: core
|
|
7
|
+
required_tools:
|
|
8
|
+
- sync_accounts
|
|
9
|
+
requires_scenarios:
|
|
10
|
+
- notification_config_event_scope
|
|
11
|
+
|
|
12
|
+
narrative: |
|
|
13
|
+
JSON Schema validates the basic `notification_configs[]` item shape, but
|
|
14
|
+
some account-level rules are semantic: `subscriber_id` must be unique
|
|
15
|
+
within one submitted array, and account-level configs must reject
|
|
16
|
+
media-buy-anchored event types. This storyboard covers duplicate keys and
|
|
17
|
+
links the existing
|
|
18
|
+
`notification_config_event_scope` storyboard for the event-anchor rejection
|
|
19
|
+
vector. The 16-subscriber fan-out cap is enforced by the request schema's
|
|
20
|
+
`maxItems` contract rather than a schema-invalid runtime sample.
|
|
21
|
+
|
|
22
|
+
agent:
|
|
23
|
+
interaction_model: media_buy_seller
|
|
24
|
+
capabilities: []
|
|
25
|
+
examples:
|
|
26
|
+
- "Any AdCP agent that accepts sync_accounts"
|
|
27
|
+
|
|
28
|
+
caller:
|
|
29
|
+
role: buyer_agent
|
|
30
|
+
example: "Compliance test harness"
|
|
31
|
+
|
|
32
|
+
prerequisites:
|
|
33
|
+
description: |
|
|
34
|
+
The agent under test exposes `sync_accounts`. Rejections are expected as
|
|
35
|
+
per-account failures inside a transport-level success response so callers
|
|
36
|
+
can correlate the failed account entry by index.
|
|
37
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
38
|
+
controller_seeding: false
|
|
39
|
+
|
|
40
|
+
phases:
|
|
41
|
+
- id: reject_duplicate_subscriber_id
|
|
42
|
+
title: "Reject duplicate subscriber IDs in one request"
|
|
43
|
+
narrative: |
|
|
44
|
+
A buyer submits two notification configs with the same account-scoped
|
|
45
|
+
`subscriber_id`. The seller must reject the per-account entry instead of
|
|
46
|
+
silently last-write-wins merging or creating duplicate subscriptions.
|
|
47
|
+
|
|
48
|
+
steps:
|
|
49
|
+
- id: sync_accounts_rejects_duplicate_subscriber_id
|
|
50
|
+
title: "Submit duplicate subscriber_id values"
|
|
51
|
+
task: sync_accounts
|
|
52
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
53
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
54
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
55
|
+
stateful: false
|
|
56
|
+
expected: |
|
|
57
|
+
Reject the per-account entry with:
|
|
58
|
+
- accounts[0].action: "failed"
|
|
59
|
+
- accounts[0].status: "rejected"
|
|
60
|
+
- accounts[0].errors[0].code: INVALID_REQUEST or VALIDATION_ERROR
|
|
61
|
+
- accounts[0].errors[0].field pointing at the duplicate subscriber_id
|
|
62
|
+
|
|
63
|
+
sample_request:
|
|
64
|
+
accounts:
|
|
65
|
+
- brand:
|
|
66
|
+
domain: "acmeoutdoor.example"
|
|
67
|
+
operator: "pinnacle-agency.example"
|
|
68
|
+
billing: "operator"
|
|
69
|
+
sandbox: true
|
|
70
|
+
notification_configs:
|
|
71
|
+
- subscriber_id: "buyer-primary"
|
|
72
|
+
url: "https://example.com/webhooks/adcp/account-a"
|
|
73
|
+
event_types:
|
|
74
|
+
- "creative.status_changed"
|
|
75
|
+
active: false
|
|
76
|
+
- subscriber_id: "buyer-primary"
|
|
77
|
+
url: "https://example.com/webhooks/adcp/account-b"
|
|
78
|
+
event_types:
|
|
79
|
+
- "creative.purged"
|
|
80
|
+
active: false
|
|
81
|
+
idempotency_key: "$generate:uuid_v4#notification_config_rejections_duplicate_subscriber"
|
|
82
|
+
context:
|
|
83
|
+
correlation_id: "notification_config_rejections--duplicate_subscriber"
|
|
84
|
+
|
|
85
|
+
validations:
|
|
86
|
+
- check: response_schema
|
|
87
|
+
description: "Response matches sync-accounts-response.json schema even on per-account failure"
|
|
88
|
+
- check: field_value
|
|
89
|
+
path: "accounts[0].action"
|
|
90
|
+
value: "failed"
|
|
91
|
+
description: "Per-account action is failed"
|
|
92
|
+
- check: field_value
|
|
93
|
+
path: "accounts[0].status"
|
|
94
|
+
value: "rejected"
|
|
95
|
+
description: "Per-account status is rejected"
|
|
96
|
+
- check: field_value
|
|
97
|
+
path: "accounts[0].errors[0].code"
|
|
98
|
+
allowed_values: ["INVALID_REQUEST", "VALIDATION_ERROR"]
|
|
99
|
+
description: "Duplicate subscriber_id is rejected as a correctable request validation error"
|
|
100
|
+
- check: field_value
|
|
101
|
+
path: "accounts[0].errors[0].field"
|
|
102
|
+
value: "notification_configs[1].subscriber_id"
|
|
103
|
+
description: "Error identifies the duplicate subscriber_id field"
|
|
104
|
+
- check: field_value
|
|
105
|
+
path: "context.correlation_id"
|
|
106
|
+
value: "notification_config_rejections--duplicate_subscriber"
|
|
107
|
+
description: "Context correlation_id returned unchanged"
|