@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.
- 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/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +23 -0
- 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/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
id: media_buy_seller/dependency_impairment
|
|
2
|
+
version: "2.0.0"
|
|
3
|
+
title: "Dependency impairment end-to-end — resource transition propagates to media buy health"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Forces a creative from approved → rejected on a non-terminal media buy, verifies the buy reflects health: impaired with a matching impairments[] entry, and recovers via assignment swap to a different creative (canonical recovery vector — re-approval of the same creative_id is uncommon in production)."
|
|
6
|
+
track: media_buy
|
|
7
|
+
required_tools:
|
|
8
|
+
- get_products
|
|
9
|
+
- create_media_buy
|
|
10
|
+
- get_media_buys
|
|
11
|
+
- sync_creatives
|
|
12
|
+
- update_media_buy
|
|
13
|
+
- comply_test_controller
|
|
14
|
+
|
|
15
|
+
narrative: |
|
|
16
|
+
Per the dependency-impairment surface ([adcp#2855](https://github.com/adcontextprotocol/adcp/issues/2855)
|
|
17
|
+
and `core/impairment.json`), sellers MUST propagate resource-state transitions
|
|
18
|
+
into the affected media buys. The compliance contract is `impairment.coherence`
|
|
19
|
+
(adcp#2859) — a cross-resource invariant tying `media_buy.impairments[]` to the
|
|
20
|
+
underlying resource state. The runner registers and grades this invariant via
|
|
21
|
+
adcp-client#1801; this storyboard is what makes it run end-to-end instead of
|
|
22
|
+
grading not_applicable.
|
|
23
|
+
|
|
24
|
+
Five phases, exercised entirely against the comply test controller's sandbox:
|
|
25
|
+
|
|
26
|
+
1. **setup** — discover a product, create an active media buy, sync a creative
|
|
27
|
+
and assign it to the buy's package. Capture media_buy_id, package_id, and
|
|
28
|
+
creative_id for the rest of the run.
|
|
29
|
+
2. **baseline_healthy** — read the buy via get_media_buys. `health` MUST be
|
|
30
|
+
`ok`, and `impairments[]` MUST be empty or absent. This establishes the
|
|
31
|
+
pre-transition snapshot the impairment.coherence runner ledgers against.
|
|
32
|
+
3. **transition_offline** — call comply_test_controller force_creative_status
|
|
33
|
+
to flip the creative to `rejected` with a rejection_reason. This is the
|
|
34
|
+
resource-state transition the runner observes.
|
|
35
|
+
4. **verify_impaired** — read the buy again. `health` MUST be `impaired`, and
|
|
36
|
+
`impairments[]` MUST contain an entry whose resource_type is `creative`,
|
|
37
|
+
resource_id matches the rejected creative, package_ids contains the
|
|
38
|
+
creative's package, transition.to is `rejected`, and the required
|
|
39
|
+
fields (impairment_id, reason_code, observed_at) are populated. This
|
|
40
|
+
closes the forward rule (every entry references a currently-offline
|
|
41
|
+
resource) and the inverse rule (the offline resource referenced by a
|
|
42
|
+
non-terminal buy appears in impairments[]) for this transition, and
|
|
43
|
+
captures the health-iff rule in the `impaired` direction.
|
|
44
|
+
5. **swap_recovery** — sync a second creative (B, approved) and use
|
|
45
|
+
`update_media_buy` with `packages[].creative_assignments` (replacement
|
|
46
|
+
semantics — the new list fully replaces the old) to swap the package's
|
|
47
|
+
binding from creative A (still rejected in the library) to creative B
|
|
48
|
+
(approved). Read the buy and assert `health: ok` with `impairments[]`
|
|
49
|
+
empty/absent. This is the canonical recovery vector in production —
|
|
50
|
+
buyers rarely re-approve a rejected creative on the same ID; they swap
|
|
51
|
+
to a replacement asset. Creative A's library status stays `rejected`,
|
|
52
|
+
but it is no longer a dependency of any package on this buy, so the
|
|
53
|
+
impairment clears.
|
|
54
|
+
|
|
55
|
+
A seller that transitions a creative without propagating to the buy fails
|
|
56
|
+
phase 4. A seller that holds stale `impairments[]` after the swap (where
|
|
57
|
+
creative A is no longer referenced) fails phase 5. A seller that
|
|
58
|
+
maintains a stale `health: impaired` with empty `impairments[]` (or vice
|
|
59
|
+
versa) on a non-terminal buy fails the impairment.coherence runner
|
|
60
|
+
invariant alongside the per-step assertions.
|
|
61
|
+
|
|
62
|
+
**Same-ID re-approval as recovery vector.** Some sellers' review flows do
|
|
63
|
+
support `rejected → approved` on the same creative_id (post-policy review
|
|
64
|
+
reinstatement, takedown reversed). That's covered by the opt-in sibling
|
|
65
|
+
scenario `media_buy_seller/dependency_impairment_reapprove_recovery`
|
|
66
|
+
(filed at adcp#4682 as a secondary variant). Sellers without same-ID
|
|
67
|
+
re-approval grade that sibling not_applicable; this scenario (swap) is
|
|
68
|
+
the universal recovery path.
|
|
69
|
+
|
|
70
|
+
**Capability gating.** Sellers whose
|
|
71
|
+
`capabilities.media_buy.propagation_surfaces` does NOT include
|
|
72
|
+
`"snapshot"` (e.g., `["webhook"]` or `["out_of_band"]`) grade this
|
|
73
|
+
whole scenario not_applicable — their compliance contract is the
|
|
74
|
+
webhook channel or the offline agreement, not the snapshot. Sellers
|
|
75
|
+
declaring `["snapshot", "webhook"]` are graded on the snapshot surface
|
|
76
|
+
here and on the webhook contract separately. See lifecycle.mdx §
|
|
77
|
+
Compliance for the surface declaration.
|
|
78
|
+
|
|
79
|
+
Audience-track and catalog-track variants are out of scope here — the
|
|
80
|
+
comply test controller only ships force_creative_status today; the
|
|
81
|
+
force_audience_status / force_catalog_item_status surface lands in a
|
|
82
|
+
follow-up.
|
|
83
|
+
|
|
84
|
+
agent:
|
|
85
|
+
interaction_model: media_buy_seller
|
|
86
|
+
capabilities:
|
|
87
|
+
- sells_media
|
|
88
|
+
- has_creative_library
|
|
89
|
+
examples:
|
|
90
|
+
- "Any media buy seller that exposes comply_test_controller and propagates creative state to buy.impairments[]"
|
|
91
|
+
|
|
92
|
+
caller:
|
|
93
|
+
role: buyer_agent
|
|
94
|
+
example: "Pinnacle Agency (buyer)"
|
|
95
|
+
|
|
96
|
+
prerequisites:
|
|
97
|
+
description: |
|
|
98
|
+
Seller MUST expose comply_test_controller with force_creative_status support.
|
|
99
|
+
Sellers without the controller (or without force_creative_status) grade this
|
|
100
|
+
scenario not_applicable — the cross-resource exercise requires deterministic
|
|
101
|
+
resource transitions the buyer can drive directly.
|
|
102
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
103
|
+
|
|
104
|
+
phases:
|
|
105
|
+
- id: setup
|
|
106
|
+
title: "Create an active buy with a creative assignment"
|
|
107
|
+
narrative: |
|
|
108
|
+
Discover a product, create a media buy, sync one creative into the library
|
|
109
|
+
with an inline assignment to the buy's first package. The buy's `health`
|
|
110
|
+
starts as `ok` (default) and `impairments[]` is empty.
|
|
111
|
+
|
|
112
|
+
steps:
|
|
113
|
+
- id: get_products_brief
|
|
114
|
+
title: "Discover a product"
|
|
115
|
+
task: get_products
|
|
116
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
117
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
118
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
119
|
+
comply_scenario: full_sales_flow
|
|
120
|
+
stateful: false
|
|
121
|
+
expected: |
|
|
122
|
+
Return at least one product with a pricing option and at least one format_id.
|
|
123
|
+
sample_request:
|
|
124
|
+
buying_mode: "brief"
|
|
125
|
+
brief: "Display inventory on outdoor lifestyle content for dependency-impairment testing."
|
|
126
|
+
filters:
|
|
127
|
+
is_fixed_price: true
|
|
128
|
+
account:
|
|
129
|
+
brand:
|
|
130
|
+
domain: "acmeoutdoor.example"
|
|
131
|
+
operator: "pinnacle-agency.example"
|
|
132
|
+
context:
|
|
133
|
+
correlation_id: "dependency_impairment--get_products"
|
|
134
|
+
context_outputs:
|
|
135
|
+
- path: "products[0].product_id"
|
|
136
|
+
key: "product_id"
|
|
137
|
+
- path: "products[0].pricing_options[0].pricing_option_id"
|
|
138
|
+
key: "pricing_option_id"
|
|
139
|
+
- path: "products[0].format_ids[0].agent_url"
|
|
140
|
+
key: "format_agent_url"
|
|
141
|
+
- path: "products[0].format_ids[0].id"
|
|
142
|
+
key: "format_id"
|
|
143
|
+
validations:
|
|
144
|
+
- check: response_schema
|
|
145
|
+
description: "Response matches get-products-response.json schema"
|
|
146
|
+
- check: field_present
|
|
147
|
+
path: "products[0].format_ids[0].id"
|
|
148
|
+
description: "Product exposes at least one format_id for creative sync"
|
|
149
|
+
- check: field_present
|
|
150
|
+
path: "products[0].pricing_options[0].fixed_price"
|
|
151
|
+
description: "The captured pricing option is fixed-price; fixed-price storyboards do not send bid_price"
|
|
152
|
+
|
|
153
|
+
- id: create_buy
|
|
154
|
+
title: "Create an active media buy"
|
|
155
|
+
task: create_media_buy
|
|
156
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
157
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
158
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
159
|
+
comply_scenario: create_media_buy
|
|
160
|
+
stateful: true
|
|
161
|
+
expected: |
|
|
162
|
+
Media buy created with media_buy_id and at least one package. Flight is
|
|
163
|
+
forward-dated; status is pending_creatives or pending_start.
|
|
164
|
+
|
|
165
|
+
sample_request:
|
|
166
|
+
brand:
|
|
167
|
+
domain: "acmeoutdoor.example"
|
|
168
|
+
account:
|
|
169
|
+
brand:
|
|
170
|
+
domain: "acmeoutdoor.example"
|
|
171
|
+
operator: "pinnacle-agency.example"
|
|
172
|
+
idempotency_key: "$generate:uuid_v4#dependency_impairment_create_buy"
|
|
173
|
+
start_time: "2026-11-01T00:00:00Z"
|
|
174
|
+
end_time: "2026-11-30T23:59:59Z"
|
|
175
|
+
packages:
|
|
176
|
+
- product_id: "$context.product_id"
|
|
177
|
+
budget: 5000
|
|
178
|
+
pricing_option_id: "$context.pricing_option_id"
|
|
179
|
+
context:
|
|
180
|
+
correlation_id: "dependency_impairment--create_buy"
|
|
181
|
+
context_outputs:
|
|
182
|
+
- path: "media_buy_id"
|
|
183
|
+
key: "media_buy_id"
|
|
184
|
+
- path: "packages[0].package_id"
|
|
185
|
+
key: "package_id"
|
|
186
|
+
validations:
|
|
187
|
+
- check: response_schema
|
|
188
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
189
|
+
- check: field_present
|
|
190
|
+
path: "media_buy_id"
|
|
191
|
+
description: "Seller returns media_buy_id"
|
|
192
|
+
- check: field_present
|
|
193
|
+
path: "packages[0].package_id"
|
|
194
|
+
description: "Seller returns package_id"
|
|
195
|
+
|
|
196
|
+
- id: sync_creative
|
|
197
|
+
title: "Sync a creative into the library"
|
|
198
|
+
narrative: |
|
|
199
|
+
Sync one creative into the seller's library. The creative enters
|
|
200
|
+
through the seller's review flow but is not yet bound to a package —
|
|
201
|
+
the next step does the assignment via update_media_buy.
|
|
202
|
+
task: sync_creatives
|
|
203
|
+
schema_ref: "creative/sync-creatives-request.json"
|
|
204
|
+
response_schema_ref: "creative/sync-creatives-response.json"
|
|
205
|
+
doc_ref: "/creative/task-reference/sync_creatives"
|
|
206
|
+
comply_scenario: creative_sync
|
|
207
|
+
stateful: true
|
|
208
|
+
expected: |
|
|
209
|
+
Creative accepted (action: created). Status is processing,
|
|
210
|
+
pending_review, or approved.
|
|
211
|
+
|
|
212
|
+
sample_request:
|
|
213
|
+
account:
|
|
214
|
+
brand:
|
|
215
|
+
domain: "acmeoutdoor.example"
|
|
216
|
+
operator: "pinnacle-agency.example"
|
|
217
|
+
creatives:
|
|
218
|
+
- creative_id: "acme_dep_banner_001"
|
|
219
|
+
name: "Acme Outdoor dependency-test banner"
|
|
220
|
+
format_id:
|
|
221
|
+
agent_url: "$context.format_agent_url"
|
|
222
|
+
id: "$context.format_id"
|
|
223
|
+
assets:
|
|
224
|
+
image:
|
|
225
|
+
asset_type: "image"
|
|
226
|
+
url: "https://cdn.pinnacle-agency.example/acme-dep-banner.png"
|
|
227
|
+
width: 300
|
|
228
|
+
height: 250
|
|
229
|
+
mime_type: "image/png"
|
|
230
|
+
idempotency_key: "$generate:uuid_v4#dependency_impairment_sync_creative"
|
|
231
|
+
context:
|
|
232
|
+
correlation_id: "dependency_impairment--sync_creative"
|
|
233
|
+
context_outputs:
|
|
234
|
+
- path: "creatives[0].creative_id"
|
|
235
|
+
key: "creative_id"
|
|
236
|
+
validations:
|
|
237
|
+
- check: response_schema
|
|
238
|
+
description: "Response matches sync-creatives-response.json schema"
|
|
239
|
+
- check: field_present
|
|
240
|
+
path: "creatives[0].creative_id"
|
|
241
|
+
description: "Response echoes back the buyer-supplied creative_id"
|
|
242
|
+
|
|
243
|
+
- id: assign_creative_to_package
|
|
244
|
+
title: "Bind the creative to the package via update_media_buy"
|
|
245
|
+
narrative: |
|
|
246
|
+
The assignment is what makes the creative a dependency of the media
|
|
247
|
+
buy — impairment.coherence ties the propagation rule to the creative
|
|
248
|
+
↔ package binding. The spec defines two equal canonical surfaces for
|
|
249
|
+
the binding: inline `sync_creatives.assignments[]` and
|
|
250
|
+
`update_media_buy.packages[].creative_assignments` (replacement
|
|
251
|
+
semantics). This scenario uses the update_media_buy surface; the
|
|
252
|
+
impairment contract is identical regardless of which path the buyer
|
|
253
|
+
chose to establish the binding.
|
|
254
|
+
task: update_media_buy
|
|
255
|
+
schema_ref: "media-buy/update-media-buy-request.json"
|
|
256
|
+
response_schema_ref: "media-buy/update-media-buy-response.json"
|
|
257
|
+
doc_ref: "/media-buy/task-reference/update_media_buy"
|
|
258
|
+
stateful: true
|
|
259
|
+
expected: |
|
|
260
|
+
Update accepted. The package's creative_assignments now contains
|
|
261
|
+
the synced creative.
|
|
262
|
+
|
|
263
|
+
sample_request:
|
|
264
|
+
account:
|
|
265
|
+
brand:
|
|
266
|
+
domain: "acmeoutdoor.example"
|
|
267
|
+
operator: "pinnacle-agency.example"
|
|
268
|
+
media_buy_id: "$context.media_buy_id"
|
|
269
|
+
packages:
|
|
270
|
+
- package_id: "$context.package_id"
|
|
271
|
+
creative_assignments:
|
|
272
|
+
- creative_id: "acme_dep_banner_001"
|
|
273
|
+
idempotency_key: "$generate:uuid_v4#dependency_impairment_assign_creative"
|
|
274
|
+
context:
|
|
275
|
+
correlation_id: "dependency_impairment--assign_creative"
|
|
276
|
+
validations:
|
|
277
|
+
- check: response_schema
|
|
278
|
+
description: "Response matches update-media-buy-response.json schema"
|
|
279
|
+
|
|
280
|
+
- id: force_creative_approved
|
|
281
|
+
title: "Force the creative to approved baseline"
|
|
282
|
+
narrative: |
|
|
283
|
+
Use comply_test_controller force_creative_status to seed the creative
|
|
284
|
+
at `approved` so the next phase observes a clean approved → rejected
|
|
285
|
+
transition. Sellers with their own deterministic review flow may
|
|
286
|
+
already land at approved; this call is the safe baseline that lets
|
|
287
|
+
the rest of the storyboard depend on a known starting state.
|
|
288
|
+
task: comply_test_controller
|
|
289
|
+
schema_ref: "compliance/comply-test-controller-request.json"
|
|
290
|
+
response_schema_ref: "compliance/comply-test-controller-response.json"
|
|
291
|
+
doc_ref: "/building/implementation/comply-test-controller"
|
|
292
|
+
comply_scenario: full_sales_flow
|
|
293
|
+
stateful: true
|
|
294
|
+
expected: |
|
|
295
|
+
success: true. Creative is now at status: approved on the seller side.
|
|
296
|
+
|
|
297
|
+
sample_request:
|
|
298
|
+
account:
|
|
299
|
+
sandbox: true
|
|
300
|
+
scenario: "force_creative_status"
|
|
301
|
+
params:
|
|
302
|
+
creative_id: "acme_dep_banner_001"
|
|
303
|
+
status: "approved"
|
|
304
|
+
context:
|
|
305
|
+
correlation_id: "dependency_impairment--force_creative_approved"
|
|
306
|
+
validations:
|
|
307
|
+
- check: response_schema
|
|
308
|
+
description: "Response matches comply-test-controller-response.json schema"
|
|
309
|
+
- check: field_value
|
|
310
|
+
path: "success"
|
|
311
|
+
allowed_values: [true]
|
|
312
|
+
description: "Controller acknowledged the directive"
|
|
313
|
+
|
|
314
|
+
- id: baseline_healthy
|
|
315
|
+
title: "Baseline: buy reads as healthy, no impairments"
|
|
316
|
+
narrative: |
|
|
317
|
+
With the creative at approved and assigned, the buy MUST report
|
|
318
|
+
`health: ok` and an empty (or absent) `impairments[]`. This is the
|
|
319
|
+
pre-transition snapshot impairment.coherence ledgers against.
|
|
320
|
+
|
|
321
|
+
steps:
|
|
322
|
+
- id: get_buy_baseline
|
|
323
|
+
title: "Read the buy — health: ok, impairments[] empty"
|
|
324
|
+
task: get_media_buys
|
|
325
|
+
schema_ref: "media-buy/get-media-buys-request.json"
|
|
326
|
+
response_schema_ref: "media-buy/get-media-buys-response.json"
|
|
327
|
+
doc_ref: "/media-buy/task-reference/get_media_buys"
|
|
328
|
+
comply_scenario: media_buy_lifecycle
|
|
329
|
+
stateful: true
|
|
330
|
+
expected: |
|
|
331
|
+
The buy is returned with health: ok and impairments[] empty or absent.
|
|
332
|
+
|
|
333
|
+
sample_request:
|
|
334
|
+
account:
|
|
335
|
+
brand:
|
|
336
|
+
domain: "acmeoutdoor.example"
|
|
337
|
+
operator: "pinnacle-agency.example"
|
|
338
|
+
media_buy_ids:
|
|
339
|
+
- "$context.media_buy_id"
|
|
340
|
+
context:
|
|
341
|
+
correlation_id: "dependency_impairment--get_buy_baseline"
|
|
342
|
+
validations:
|
|
343
|
+
- check: response_schema
|
|
344
|
+
description: "Response matches get-media-buys-response.json schema"
|
|
345
|
+
- check: field_value
|
|
346
|
+
path: "media_buys[0].media_buy_id"
|
|
347
|
+
value: "$context.media_buy_id"
|
|
348
|
+
description: "Seller returns the buy by media_buy_id"
|
|
349
|
+
- check: field_value
|
|
350
|
+
path: "media_buys[0].health"
|
|
351
|
+
allowed_values: ["ok"]
|
|
352
|
+
description: "Buy health is ok in the baseline snapshot (health-iff rule, ok direction)"
|
|
353
|
+
- check: field_value_or_absent
|
|
354
|
+
path: "media_buys[0].impairments"
|
|
355
|
+
value: []
|
|
356
|
+
description: "impairments[] is empty (or absent) in the baseline — no resources are offline yet"
|
|
357
|
+
|
|
358
|
+
- id: transition_offline
|
|
359
|
+
title: "Force the creative to rejected"
|
|
360
|
+
narrative: |
|
|
361
|
+
The seller transitions the creative from approved → rejected via
|
|
362
|
+
comply_test_controller. This is the resource-state transition that the
|
|
363
|
+
seller MUST propagate to every non-terminal buy referencing the creative.
|
|
364
|
+
|
|
365
|
+
steps:
|
|
366
|
+
- id: force_creative_rejected
|
|
367
|
+
title: "comply_test_controller force_creative_status → rejected"
|
|
368
|
+
task: comply_test_controller
|
|
369
|
+
schema_ref: "compliance/comply-test-controller-request.json"
|
|
370
|
+
response_schema_ref: "compliance/comply-test-controller-response.json"
|
|
371
|
+
doc_ref: "/building/implementation/comply-test-controller"
|
|
372
|
+
comply_scenario: creative_lifecycle
|
|
373
|
+
stateful: true
|
|
374
|
+
expected: |
|
|
375
|
+
success: true. Creative is now at status: rejected. The seller has
|
|
376
|
+
observed the transition; the next get_media_buys read MUST reflect
|
|
377
|
+
the impairment on the affected buy.
|
|
378
|
+
|
|
379
|
+
sample_request:
|
|
380
|
+
account:
|
|
381
|
+
sandbox: true
|
|
382
|
+
scenario: "force_creative_status"
|
|
383
|
+
params:
|
|
384
|
+
creative_id: "acme_dep_banner_001"
|
|
385
|
+
status: "rejected"
|
|
386
|
+
rejection_reason: "Dependency-impairment scenario: forcing approved → rejected to exercise impairment.coherence."
|
|
387
|
+
context:
|
|
388
|
+
correlation_id: "dependency_impairment--force_creative_rejected"
|
|
389
|
+
validations:
|
|
390
|
+
- check: response_schema
|
|
391
|
+
description: "Response matches comply-test-controller-response.json schema"
|
|
392
|
+
- check: field_value
|
|
393
|
+
path: "success"
|
|
394
|
+
allowed_values: [true]
|
|
395
|
+
description: "Controller acknowledged the rejection directive"
|
|
396
|
+
|
|
397
|
+
- id: verify_impaired
|
|
398
|
+
title: "Buy reads as impaired with a matching impairments[] entry"
|
|
399
|
+
narrative: |
|
|
400
|
+
After the rejection, the buy MUST report `health: impaired` and
|
|
401
|
+
`impairments[]` MUST contain an entry whose resource_type is `creative`,
|
|
402
|
+
resource_id matches the rejected creative, package_ids contains the
|
|
403
|
+
creative's package, and transition.to is `rejected`. This closes the
|
|
404
|
+
forward + inverse rules for this transition; the impairment.coherence
|
|
405
|
+
invariant grades the cross-resource match.
|
|
406
|
+
|
|
407
|
+
steps:
|
|
408
|
+
- id: get_buy_impaired
|
|
409
|
+
title: "Read the buy — health: impaired, impairment entry present"
|
|
410
|
+
task: get_media_buys
|
|
411
|
+
schema_ref: "media-buy/get-media-buys-request.json"
|
|
412
|
+
response_schema_ref: "media-buy/get-media-buys-response.json"
|
|
413
|
+
doc_ref: "/media-buy/task-reference/get_media_buys"
|
|
414
|
+
comply_scenario: media_buy_lifecycle
|
|
415
|
+
stateful: true
|
|
416
|
+
expected: |
|
|
417
|
+
The buy is returned with:
|
|
418
|
+
- health: impaired
|
|
419
|
+
- impairments[] containing at least one entry where
|
|
420
|
+
resource_type: creative, resource_id: acme_dep_banner_001,
|
|
421
|
+
package_ids includes the buy's package, transition.to: rejected.
|
|
422
|
+
|
|
423
|
+
sample_request:
|
|
424
|
+
account:
|
|
425
|
+
brand:
|
|
426
|
+
domain: "acmeoutdoor.example"
|
|
427
|
+
operator: "pinnacle-agency.example"
|
|
428
|
+
media_buy_ids:
|
|
429
|
+
- "$context.media_buy_id"
|
|
430
|
+
context:
|
|
431
|
+
correlation_id: "dependency_impairment--get_buy_impaired"
|
|
432
|
+
validations:
|
|
433
|
+
- check: response_schema
|
|
434
|
+
description: "Response matches get-media-buys-response.json schema"
|
|
435
|
+
- check: field_value
|
|
436
|
+
path: "media_buys[0].health"
|
|
437
|
+
allowed_values: ["impaired"]
|
|
438
|
+
description: "Buy health flipped to impaired after the creative was rejected (health-iff rule, impaired direction)"
|
|
439
|
+
- check: field_present
|
|
440
|
+
path: "media_buys[0].impairments[0]"
|
|
441
|
+
description: "Buy reports at least one impairment entry (inverse rule)"
|
|
442
|
+
- check: field_value
|
|
443
|
+
path: "media_buys[0].impairments[0].resource_type"
|
|
444
|
+
allowed_values: ["creative"]
|
|
445
|
+
description: "Impairment entry's resource_type is creative"
|
|
446
|
+
- check: field_value
|
|
447
|
+
path: "media_buys[0].impairments[0].resource_id"
|
|
448
|
+
value: "acme_dep_banner_001"
|
|
449
|
+
description: "Impairment entry's resource_id matches the rejected creative (forward rule)"
|
|
450
|
+
- check: field_value
|
|
451
|
+
path: "media_buys[0].impairments[0].package_ids[0]"
|
|
452
|
+
value: "$context.package_id"
|
|
453
|
+
description: "Impairment entry's package_ids[] contains the buy's package — without this, a seller could list a different package and still pass the impairment-present check"
|
|
454
|
+
- check: field_value
|
|
455
|
+
path: "media_buys[0].impairments[0].transition.to"
|
|
456
|
+
allowed_values: ["rejected"]
|
|
457
|
+
description: "Impairment entry's transition.to is rejected"
|
|
458
|
+
- check: field_present
|
|
459
|
+
path: "media_buys[0].impairments[0].impairment_id"
|
|
460
|
+
description: "Impairment carries the required impairment_id (notification_id for state-event webhooks; see snapshot-and-log Rule 1)"
|
|
461
|
+
- check: field_present
|
|
462
|
+
path: "media_buys[0].impairments[0].reason_code"
|
|
463
|
+
description: "Impairment carries a reason_code (required per impairment.json) — buyer needs this to route remediation"
|
|
464
|
+
- check: field_present
|
|
465
|
+
path: "media_buys[0].impairments[0].observed_at"
|
|
466
|
+
description: "Impairment carries observed_at (required per impairment.json) — buyer needs this to reconcile webhook ordering against the snapshot"
|
|
467
|
+
|
|
468
|
+
- id: swap_recovery
|
|
469
|
+
title: "Recover via assignment swap — different creative replaces the rejected one"
|
|
470
|
+
narrative: |
|
|
471
|
+
Sync a second creative (B) into the library as approved, then use
|
|
472
|
+
update_media_buy to swap the package's creative_assignments from
|
|
473
|
+
creative A (still rejected) to creative B. Re-read the buy and verify
|
|
474
|
+
health returns to ok with impairments[] cleared. Creative A's library
|
|
475
|
+
status stays rejected — the seller is NOT required to re-approve it
|
|
476
|
+
— but A is no longer a dependency of any package on this buy, so the
|
|
477
|
+
impairment clears.
|
|
478
|
+
|
|
479
|
+
This is the production-canonical recovery path. Buyers rarely re-approve
|
|
480
|
+
a rejected creative on the same ID; they ship a corrected asset under
|
|
481
|
+
a new ID and update assignments. The same-ID re-approval path is
|
|
482
|
+
covered separately by an opt-in sibling scenario (#4682 secondary
|
|
483
|
+
variant) for sellers whose review flow supports it.
|
|
484
|
+
|
|
485
|
+
steps:
|
|
486
|
+
- id: sync_replacement_creative
|
|
487
|
+
title: "Sync replacement creative B (approved baseline)"
|
|
488
|
+
narrative: |
|
|
489
|
+
Add a second creative to the library WITHOUT assigning it to the
|
|
490
|
+
package yet. The package's current binding is still to creative A
|
|
491
|
+
(rejected). The next step uses update_media_buy to do the swap.
|
|
492
|
+
task: sync_creatives
|
|
493
|
+
schema_ref: "creative/sync-creatives-request.json"
|
|
494
|
+
response_schema_ref: "creative/sync-creatives-response.json"
|
|
495
|
+
doc_ref: "/creative/task-reference/sync_creatives"
|
|
496
|
+
comply_scenario: creative_sync
|
|
497
|
+
stateful: true
|
|
498
|
+
expected: |
|
|
499
|
+
Replacement creative accepted (action: created). No assignment yet
|
|
500
|
+
— the package's binding remains on creative A until the next step.
|
|
501
|
+
|
|
502
|
+
sample_request:
|
|
503
|
+
account:
|
|
504
|
+
brand:
|
|
505
|
+
domain: "acmeoutdoor.example"
|
|
506
|
+
operator: "pinnacle-agency.example"
|
|
507
|
+
creatives:
|
|
508
|
+
- creative_id: "acme_dep_banner_002"
|
|
509
|
+
name: "Acme Outdoor dependency-test replacement banner"
|
|
510
|
+
format_id:
|
|
511
|
+
agent_url: "$context.format_agent_url"
|
|
512
|
+
id: "$context.format_id"
|
|
513
|
+
assets:
|
|
514
|
+
image:
|
|
515
|
+
asset_type: "image"
|
|
516
|
+
url: "https://cdn.pinnacle-agency.example/acme-dep-banner-replacement.png"
|
|
517
|
+
width: 300
|
|
518
|
+
height: 250
|
|
519
|
+
mime_type: "image/png"
|
|
520
|
+
idempotency_key: "$generate:uuid_v4#dependency_impairment_sync_replacement"
|
|
521
|
+
context:
|
|
522
|
+
correlation_id: "dependency_impairment--sync_replacement_creative"
|
|
523
|
+
validations:
|
|
524
|
+
- check: response_schema
|
|
525
|
+
description: "Response matches sync-creatives-response.json schema"
|
|
526
|
+
- check: field_present
|
|
527
|
+
path: "creatives[0].creative_id"
|
|
528
|
+
description: "Replacement creative_id returned"
|
|
529
|
+
|
|
530
|
+
- id: force_replacement_approved
|
|
531
|
+
title: "Force replacement creative B to approved"
|
|
532
|
+
narrative: |
|
|
533
|
+
Baseline creative B at approved via comply_test_controller so the
|
|
534
|
+
swap binds the package to an in-policy creative. Sellers whose
|
|
535
|
+
deterministic flow already lands B at approved on sync grade this
|
|
536
|
+
step a no-op; the call is the safe seed.
|
|
537
|
+
task: comply_test_controller
|
|
538
|
+
schema_ref: "compliance/comply-test-controller-request.json"
|
|
539
|
+
response_schema_ref: "compliance/comply-test-controller-response.json"
|
|
540
|
+
doc_ref: "/building/implementation/comply-test-controller"
|
|
541
|
+
comply_scenario: creative_lifecycle
|
|
542
|
+
stateful: true
|
|
543
|
+
expected: |
|
|
544
|
+
success: true. Replacement creative is now at status: approved.
|
|
545
|
+
|
|
546
|
+
sample_request:
|
|
547
|
+
account:
|
|
548
|
+
sandbox: true
|
|
549
|
+
scenario: "force_creative_status"
|
|
550
|
+
params:
|
|
551
|
+
creative_id: "acme_dep_banner_002"
|
|
552
|
+
status: "approved"
|
|
553
|
+
context:
|
|
554
|
+
correlation_id: "dependency_impairment--force_replacement_approved"
|
|
555
|
+
validations:
|
|
556
|
+
- check: response_schema
|
|
557
|
+
description: "Response matches comply-test-controller-response.json schema"
|
|
558
|
+
- check: field_value
|
|
559
|
+
path: "success"
|
|
560
|
+
allowed_values: [true]
|
|
561
|
+
description: "Controller acknowledged the directive"
|
|
562
|
+
|
|
563
|
+
- id: swap_assignment
|
|
564
|
+
title: "Swap the package's creative_assignments — replacement semantics"
|
|
565
|
+
narrative: |
|
|
566
|
+
update_media_buy with packages[].creative_assignments uses
|
|
567
|
+
replacement semantics (per package-update.json) — the new list
|
|
568
|
+
fully replaces the old. Provide ONLY creative B; creative A is
|
|
569
|
+
unbound from the package and is no longer a dependency of this
|
|
570
|
+
buy. The library's reject status on A is preserved.
|
|
571
|
+
task: update_media_buy
|
|
572
|
+
schema_ref: "media-buy/update-media-buy-request.json"
|
|
573
|
+
response_schema_ref: "media-buy/update-media-buy-response.json"
|
|
574
|
+
doc_ref: "/media-buy/task-reference/update_media_buy"
|
|
575
|
+
comply_scenario: media_buy_lifecycle
|
|
576
|
+
stateful: true
|
|
577
|
+
expected: |
|
|
578
|
+
The seller accepts the package update and the next get_media_buys
|
|
579
|
+
reflects the new assignment with the impairment cleared.
|
|
580
|
+
|
|
581
|
+
sample_request:
|
|
582
|
+
account:
|
|
583
|
+
brand:
|
|
584
|
+
domain: "acmeoutdoor.example"
|
|
585
|
+
operator: "pinnacle-agency.example"
|
|
586
|
+
media_buy_id: "$context.media_buy_id"
|
|
587
|
+
packages:
|
|
588
|
+
- package_id: "$context.package_id"
|
|
589
|
+
creative_assignments:
|
|
590
|
+
- creative_id: "acme_dep_banner_002"
|
|
591
|
+
idempotency_key: "$generate:uuid_v4#dependency_impairment_swap_assignment"
|
|
592
|
+
context:
|
|
593
|
+
correlation_id: "dependency_impairment--swap_assignment"
|
|
594
|
+
validations:
|
|
595
|
+
- check: response_schema
|
|
596
|
+
description: "Response matches update-media-buy-response.json schema"
|
|
597
|
+
|
|
598
|
+
- id: get_buy_recovered
|
|
599
|
+
title: "Read the buy — health: ok, impairments[] cleared via swap"
|
|
600
|
+
task: get_media_buys
|
|
601
|
+
schema_ref: "media-buy/get-media-buys-request.json"
|
|
602
|
+
response_schema_ref: "media-buy/get-media-buys-response.json"
|
|
603
|
+
doc_ref: "/media-buy/task-reference/get_media_buys"
|
|
604
|
+
comply_scenario: media_buy_lifecycle
|
|
605
|
+
stateful: true
|
|
606
|
+
expected: |
|
|
607
|
+
health: ok, impairments[] empty/absent. Creative A is still
|
|
608
|
+
rejected in the library (verifiable separately via list_creatives)
|
|
609
|
+
but is no longer assigned to the package, so the impairment
|
|
610
|
+
clears. A non-empty impairments[] here indicates the seller is
|
|
611
|
+
holding stale state — the assignment swap should have removed
|
|
612
|
+
creative A as a buy dependency.
|
|
613
|
+
|
|
614
|
+
sample_request:
|
|
615
|
+
account:
|
|
616
|
+
brand:
|
|
617
|
+
domain: "acmeoutdoor.example"
|
|
618
|
+
operator: "pinnacle-agency.example"
|
|
619
|
+
media_buy_ids:
|
|
620
|
+
- "$context.media_buy_id"
|
|
621
|
+
context:
|
|
622
|
+
correlation_id: "dependency_impairment--get_buy_recovered"
|
|
623
|
+
validations:
|
|
624
|
+
- check: response_schema
|
|
625
|
+
description: "Response matches get-media-buys-response.json schema"
|
|
626
|
+
- check: field_value
|
|
627
|
+
path: "media_buys[0].health"
|
|
628
|
+
allowed_values: ["ok"]
|
|
629
|
+
description: "Buy health returned to ok after assignment swap (health-iff rule, ok direction)"
|
|
630
|
+
- check: field_value_or_absent
|
|
631
|
+
path: "media_buys[0].impairments"
|
|
632
|
+
value: []
|
|
633
|
+
description: "impairments[] is empty (or absent) — seller cleared the stale A-entry when A stopped being a dependency. health-iff biconditional would fail with health: ok and a non-empty impairments[]."
|