@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
package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
id: media_buy_seller/refine_finalize_exclusivity
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller enforces refine[] finalize-exclusivity and MULTI_FINALIZE_UNSUPPORTED"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Validates that sellers reject mixed-finalize requests (INVALID_REQUEST), structurally-invalid finalize entries, and handle multi-proposal finalize atomically or reject with MULTI_FINALIZE_UNSUPPORTED."
|
|
6
|
+
track: media_buy
|
|
7
|
+
required_tools:
|
|
8
|
+
- get_products
|
|
9
|
+
|
|
10
|
+
requires_capability:
|
|
11
|
+
path: media_buy.supports_proposals
|
|
12
|
+
equals: true
|
|
13
|
+
|
|
14
|
+
narrative: |
|
|
15
|
+
Issue #4107 clarified finalize-exclusivity semantics for refine[]: if any entry carries
|
|
16
|
+
action: "finalize", the entire array must consist exclusively of proposal-scoped finalize
|
|
17
|
+
entries. Mixing finalize with request- or product-scoped entries, or with include/omit
|
|
18
|
+
actions, is a business-rule violation. Current proposal storyboards exercise only the
|
|
19
|
+
happy-path finalize flow; this scenario covers the three normative negative cases.
|
|
20
|
+
|
|
21
|
+
1. Mixed finalize + non-finalize — one proposal-scoped finalize entry combined with a
|
|
22
|
+
request-scoped entry in the same refine[] call. Each entry is individually schema-valid;
|
|
23
|
+
the combination violates the exclusivity rule. The seller must reject with INVALID_REQUEST
|
|
24
|
+
before any state changes and should populate error.field identifying the offending entry.
|
|
25
|
+
|
|
26
|
+
2. Non-proposal-scoped finalize — a product-scoped entry carrying action: "finalize".
|
|
27
|
+
The schema's additionalProperties: false on the product variant makes this structurally
|
|
28
|
+
invalid (action: "finalize" is not in the product scope's action enum). The seller must
|
|
29
|
+
reject with INVALID_REQUEST.
|
|
30
|
+
|
|
31
|
+
3. Multi-proposal finalize — two proposal-scoped finalize entries in one call. Sellers that
|
|
32
|
+
can guarantee atomic pre-commit validation handle this and commit all named proposals;
|
|
33
|
+
sellers that cannot MUST reject with MULTI_FINALIZE_UNSUPPORTED (preferred, distinguishes
|
|
34
|
+
capability gap from malformed request) or INVALID_REQUEST (acceptable fallback for
|
|
35
|
+
pre-3.1 error catalogs). This case uses a branch set: the storyboard accepts either
|
|
36
|
+
outcome from a conformant seller. Because both branches are optional and the runner
|
|
37
|
+
executes both, the branch that does not match the seller's behavior will fail its
|
|
38
|
+
validation step (tolerated as optional) while the matching branch contributes; the
|
|
39
|
+
gate asserts at least one contributed.
|
|
40
|
+
|
|
41
|
+
A second brief is attempted in the setup_second_proposal phase to capture a second
|
|
42
|
+
proposal_id. If the seller returns fewer than two proposals, all multi-finalize phases
|
|
43
|
+
skip gracefully via skip_if guards and the storyboard still passes on the two mandatory
|
|
44
|
+
cases.
|
|
45
|
+
|
|
46
|
+
agent:
|
|
47
|
+
interaction_model: media_buy_seller
|
|
48
|
+
capabilities:
|
|
49
|
+
- sells_media
|
|
50
|
+
- accepts_briefs
|
|
51
|
+
- generates_proposals
|
|
52
|
+
examples:
|
|
53
|
+
- "Full-service publisher with proposal engine"
|
|
54
|
+
- "Retail media network with curated packages"
|
|
55
|
+
|
|
56
|
+
caller:
|
|
57
|
+
role: buyer_agent
|
|
58
|
+
example: "Pinnacle Agency (buyer)"
|
|
59
|
+
|
|
60
|
+
prerequisites:
|
|
61
|
+
description: |
|
|
62
|
+
The seller must support proposal generation (media_buy.supports_proposals: true).
|
|
63
|
+
The Acme Outdoor test kit provides brand and operator credentials.
|
|
64
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
65
|
+
|
|
66
|
+
phases:
|
|
67
|
+
- id: setup
|
|
68
|
+
title: "Account setup and first proposal discovery"
|
|
69
|
+
steps:
|
|
70
|
+
- id: sync_accounts
|
|
71
|
+
title: "Establish account"
|
|
72
|
+
task: sync_accounts
|
|
73
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
74
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
75
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
76
|
+
stateful: true
|
|
77
|
+
expected: |
|
|
78
|
+
Return the account with account_id and status active.
|
|
79
|
+
sample_request:
|
|
80
|
+
accounts:
|
|
81
|
+
- brand:
|
|
82
|
+
domain: "acmeoutdoor.example"
|
|
83
|
+
operator: "pinnacle-agency.example"
|
|
84
|
+
billing: "operator"
|
|
85
|
+
payment_terms: "net_30"
|
|
86
|
+
idempotency_key: "$generate:uuid_v4#media_buy_seller_refine_finalize_exclusivity_setup_sync_accounts"
|
|
87
|
+
validations:
|
|
88
|
+
- check: response_schema
|
|
89
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
90
|
+
- check: field_present
|
|
91
|
+
path: "accounts[0].account_id"
|
|
92
|
+
description: "Account has a platform-assigned ID"
|
|
93
|
+
|
|
94
|
+
- id: get_products_brief
|
|
95
|
+
title: "Request proposals — captures proposal_id_1 for mandatory error probes"
|
|
96
|
+
task: get_products
|
|
97
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
98
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
99
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
100
|
+
comply_scenario: full_sales_flow
|
|
101
|
+
stateful: false
|
|
102
|
+
expected: |
|
|
103
|
+
Return at least one proposal with a proposal_id. proposal_id_1 is captured
|
|
104
|
+
here for the mandatory mixed-finalize and non-proposal-finalize error probes.
|
|
105
|
+
sample_request:
|
|
106
|
+
buying_mode: "brief"
|
|
107
|
+
brief: "Premium video and display across outdoor lifestyle and sports. Q2 flight, $50K budget. Adults 25-54, US and Canada."
|
|
108
|
+
account:
|
|
109
|
+
brand:
|
|
110
|
+
domain: "acmeoutdoor.example"
|
|
111
|
+
operator: "pinnacle-agency.example"
|
|
112
|
+
context_outputs:
|
|
113
|
+
- path: "proposals[0].proposal_id"
|
|
114
|
+
key: "proposal_id_1"
|
|
115
|
+
validations:
|
|
116
|
+
- check: response_schema
|
|
117
|
+
description: "Response matches get-products-response.json schema"
|
|
118
|
+
- check: field_present
|
|
119
|
+
path: "proposals[0].proposal_id"
|
|
120
|
+
description: "At least one proposal returned with an ID"
|
|
121
|
+
|
|
122
|
+
- id: setup_second_proposal
|
|
123
|
+
title: "Attempt second proposal capture for multi-finalize coverage"
|
|
124
|
+
optional: true
|
|
125
|
+
narrative: |
|
|
126
|
+
Sends a second brief to capture a second proposal_id for the multi-finalize branch
|
|
127
|
+
set. This phase is optional: if the seller returns fewer than two proposals, this
|
|
128
|
+
phase fails gracefully and all multi-finalize phases skip via skip_if guards. The
|
|
129
|
+
two mandatory error-probe phases (mixed_finalize_rejected, non_proposal_finalize_rejected)
|
|
130
|
+
are unaffected.
|
|
131
|
+
steps:
|
|
132
|
+
- id: get_products_brief_second
|
|
133
|
+
title: "Second brief to capture proposal_id_2"
|
|
134
|
+
task: get_products
|
|
135
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
136
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
137
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
138
|
+
comply_scenario: full_sales_flow
|
|
139
|
+
stateful: false
|
|
140
|
+
expected: |
|
|
141
|
+
Return at least two proposals. proposals[1].proposal_id is captured as
|
|
142
|
+
proposal_id_2. If the seller returns only one proposal, this step fails
|
|
143
|
+
(tolerated — phase is optional), proposal_id_2 stays unset, and the
|
|
144
|
+
multi-finalize phases skip gracefully.
|
|
145
|
+
sample_request:
|
|
146
|
+
buying_mode: "brief"
|
|
147
|
+
brief: "Premium video and display across outdoor lifestyle and sports. Q2 flight, $50K budget. Adults 25-54, US and Canada."
|
|
148
|
+
account:
|
|
149
|
+
brand:
|
|
150
|
+
domain: "acmeoutdoor.example"
|
|
151
|
+
operator: "pinnacle-agency.example"
|
|
152
|
+
context_outputs:
|
|
153
|
+
- path: "proposals[1].proposal_id"
|
|
154
|
+
key: "proposal_id_2"
|
|
155
|
+
validations:
|
|
156
|
+
- check: field_present
|
|
157
|
+
path: "proposals[1].proposal_id"
|
|
158
|
+
description: "Second proposal present for multi-finalize test"
|
|
159
|
+
|
|
160
|
+
- id: mixed_finalize_rejected
|
|
161
|
+
title: "Mixed finalize rejected"
|
|
162
|
+
narrative: |
|
|
163
|
+
A refine[] array where one entry is a proposal-scoped finalize and another is a
|
|
164
|
+
request-scoped refinement. Each entry is individually schema-valid; their combination
|
|
165
|
+
violates the finalize-exclusivity rule. The seller must reject with INVALID_REQUEST
|
|
166
|
+
before any proposal state changes. Per issue #4107, the error response should include
|
|
167
|
+
error.field identifying which refine entry triggered the violation.
|
|
168
|
+
|
|
169
|
+
steps:
|
|
170
|
+
- id: get_products_mixed_finalize
|
|
171
|
+
title: "Finalize entry mixed with request-scoped entry"
|
|
172
|
+
task: get_products
|
|
173
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
174
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
175
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
176
|
+
comply_scenario: full_sales_flow
|
|
177
|
+
expect_error: true
|
|
178
|
+
negative_path: payload_well_formed
|
|
179
|
+
stateful: true
|
|
180
|
+
expected: |
|
|
181
|
+
Reject with:
|
|
182
|
+
- code: INVALID_REQUEST
|
|
183
|
+
- error.field: pointing at the offending refine entry (e.g. "refine[0]",
|
|
184
|
+
"refine[1]", or "refine" — seller-chosen, any index that identifies
|
|
185
|
+
the violation is conformant)
|
|
186
|
+
No proposal state is changed; the finalize entry does not commit.
|
|
187
|
+
sample_request:
|
|
188
|
+
buying_mode: "refine"
|
|
189
|
+
refine:
|
|
190
|
+
- scope: "proposal"
|
|
191
|
+
proposal_id: "$context.proposal_id_1"
|
|
192
|
+
action: "finalize"
|
|
193
|
+
- scope: "request"
|
|
194
|
+
ask: "Also increase CTV budget allocation"
|
|
195
|
+
account:
|
|
196
|
+
brand:
|
|
197
|
+
domain: "acmeoutdoor.example"
|
|
198
|
+
operator: "pinnacle-agency.example"
|
|
199
|
+
validations:
|
|
200
|
+
- check: error_code
|
|
201
|
+
value: "INVALID_REQUEST"
|
|
202
|
+
description: "Mixed finalize + non-finalize refine[] rejected with INVALID_REQUEST"
|
|
203
|
+
- check: field_present
|
|
204
|
+
path: "errors[0].field"
|
|
205
|
+
description: "Seller populates error.field pointing at the offending refine entry"
|
|
206
|
+
|
|
207
|
+
- id: non_proposal_finalize_rejected
|
|
208
|
+
title: "Non-proposal finalize rejected"
|
|
209
|
+
narrative: |
|
|
210
|
+
A product-scoped refine entry carrying action: "finalize". The get-products-request
|
|
211
|
+
schema allows action: "finalize" only on the proposal-scoped variant; the product
|
|
212
|
+
variant defines action as "include" | "omit" | "more_like_this" with
|
|
213
|
+
additionalProperties: false. This is a structurally invalid payload — the runner
|
|
214
|
+
skips sample_request schema validation (negative_path: schema_invalid) and verifies
|
|
215
|
+
the seller returns INVALID_REQUEST rather than a 500 or silent acceptance.
|
|
216
|
+
|
|
217
|
+
The product_id value is a synthetic test sentinel; since the request fails at schema
|
|
218
|
+
validation before any product lookup, no fixture seeding is required.
|
|
219
|
+
|
|
220
|
+
steps:
|
|
221
|
+
- id: get_products_product_finalize
|
|
222
|
+
title: "Product-scoped entry with action: finalize"
|
|
223
|
+
task: get_products
|
|
224
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
225
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
226
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
227
|
+
comply_scenario: full_sales_flow
|
|
228
|
+
expect_error: true
|
|
229
|
+
negative_path: schema_invalid
|
|
230
|
+
stateful: false
|
|
231
|
+
expected: |
|
|
232
|
+
Reject with INVALID_REQUEST. The schema prohibits action: "finalize" on
|
|
233
|
+
product-scoped entries; the seller must not silently ignore the field or
|
|
234
|
+
treat it as action: "include".
|
|
235
|
+
sample_request:
|
|
236
|
+
buying_mode: "refine"
|
|
237
|
+
refine:
|
|
238
|
+
- scope: "product"
|
|
239
|
+
product_id: "test-product-finalize-exclusivity-v1"
|
|
240
|
+
action: "finalize"
|
|
241
|
+
account:
|
|
242
|
+
brand:
|
|
243
|
+
domain: "acmeoutdoor.example"
|
|
244
|
+
operator: "pinnacle-agency.example"
|
|
245
|
+
validations:
|
|
246
|
+
- check: error_code
|
|
247
|
+
value: "INVALID_REQUEST"
|
|
248
|
+
description: "Product-scoped finalize entry rejected with INVALID_REQUEST"
|
|
249
|
+
|
|
250
|
+
- id: multi_finalize_atomic_path
|
|
251
|
+
title: "Multi-finalize handled atomically"
|
|
252
|
+
optional: true
|
|
253
|
+
branch_set:
|
|
254
|
+
id: multi_finalize_handled
|
|
255
|
+
semantics: any_of
|
|
256
|
+
skip_if: "!context.proposal_id_2"
|
|
257
|
+
narrative: |
|
|
258
|
+
The seller supports atomic multi-finalize: both proposals commit in a single call or
|
|
259
|
+
neither does. This branch passes when the seller returns a success response with both
|
|
260
|
+
proposals present. The spec requires atomicity at the observation point — the seller
|
|
261
|
+
must not return success unless every named proposal has been persisted as committed.
|
|
262
|
+
|
|
263
|
+
steps:
|
|
264
|
+
- id: get_products_multi_finalize_atomic
|
|
265
|
+
title: "Finalize two proposals in a single call — atomic success path"
|
|
266
|
+
task: get_products
|
|
267
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
268
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
269
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
270
|
+
comply_scenario: full_sales_flow
|
|
271
|
+
stateful: true
|
|
272
|
+
contributes: true
|
|
273
|
+
expected: |
|
|
274
|
+
Return both proposals with committed status and expires_at hold windows.
|
|
275
|
+
Neither proposal is partially committed — the seller has run pre-commit
|
|
276
|
+
validation across all named proposals before returning success.
|
|
277
|
+
sample_request:
|
|
278
|
+
buying_mode: "refine"
|
|
279
|
+
refine:
|
|
280
|
+
- scope: "proposal"
|
|
281
|
+
proposal_id: "$context.proposal_id_1"
|
|
282
|
+
action: "finalize"
|
|
283
|
+
- scope: "proposal"
|
|
284
|
+
proposal_id: "$context.proposal_id_2"
|
|
285
|
+
action: "finalize"
|
|
286
|
+
account:
|
|
287
|
+
brand:
|
|
288
|
+
domain: "acmeoutdoor.example"
|
|
289
|
+
operator: "pinnacle-agency.example"
|
|
290
|
+
validations:
|
|
291
|
+
- check: response_schema
|
|
292
|
+
description: "Response matches get-products-response.json schema"
|
|
293
|
+
- check: field_present
|
|
294
|
+
path: "proposals"
|
|
295
|
+
description: "Response contains the finalized proposals"
|
|
296
|
+
|
|
297
|
+
- id: multi_finalize_unsupported_path
|
|
298
|
+
title: "Multi-finalize rejected with MULTI_FINALIZE_UNSUPPORTED"
|
|
299
|
+
optional: true
|
|
300
|
+
branch_set:
|
|
301
|
+
id: multi_finalize_handled
|
|
302
|
+
semantics: any_of
|
|
303
|
+
skip_if: "!context.proposal_id_2"
|
|
304
|
+
narrative: |
|
|
305
|
+
The seller cannot guarantee atomic pre-commit validation across multiple proposals.
|
|
306
|
+
Per the spec, such sellers MUST reject with MULTI_FINALIZE_UNSUPPORTED (preferred —
|
|
307
|
+
distinguishes seller-side capability gap from a malformed request) or INVALID_REQUEST
|
|
308
|
+
(acceptable fallback for sellers on a pre-3.1 error catalog). No proposal is committed.
|
|
309
|
+
|
|
310
|
+
Note: the runner executes both branch-set peers regardless of which succeeds. For
|
|
311
|
+
a seller that handled atomically in the sibling branch, this step will attempt to
|
|
312
|
+
finalize already-committed proposals and may receive a different error (e.g.
|
|
313
|
+
INVALID_STATE). That step failure is tolerated (optional branch); the atomic branch's
|
|
314
|
+
contribution is sufficient for the gate assertion.
|
|
315
|
+
|
|
316
|
+
steps:
|
|
317
|
+
- id: get_products_multi_finalize_unsupported
|
|
318
|
+
title: "Multi-finalize rejected by seller without atomic commit support"
|
|
319
|
+
task: get_products
|
|
320
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
321
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
322
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
323
|
+
comply_scenario: full_sales_flow
|
|
324
|
+
expect_error: true
|
|
325
|
+
negative_path: payload_well_formed
|
|
326
|
+
stateful: true
|
|
327
|
+
contributes: true
|
|
328
|
+
expected: |
|
|
329
|
+
Reject with MULTI_FINALIZE_UNSUPPORTED (preferred) or INVALID_REQUEST
|
|
330
|
+
(acceptable fallback). No proposal is committed. Buyers receiving
|
|
331
|
+
MULTI_FINALIZE_UNSUPPORTED should sequence individual finalize calls.
|
|
332
|
+
sample_request:
|
|
333
|
+
buying_mode: "refine"
|
|
334
|
+
refine:
|
|
335
|
+
- scope: "proposal"
|
|
336
|
+
proposal_id: "$context.proposal_id_1"
|
|
337
|
+
action: "finalize"
|
|
338
|
+
- scope: "proposal"
|
|
339
|
+
proposal_id: "$context.proposal_id_2"
|
|
340
|
+
action: "finalize"
|
|
341
|
+
account:
|
|
342
|
+
brand:
|
|
343
|
+
domain: "acmeoutdoor.example"
|
|
344
|
+
operator: "pinnacle-agency.example"
|
|
345
|
+
validations:
|
|
346
|
+
- check: error_code
|
|
347
|
+
allowed_values: ["MULTI_FINALIZE_UNSUPPORTED", "INVALID_REQUEST"]
|
|
348
|
+
description: "Multi-finalize rejected with MULTI_FINALIZE_UNSUPPORTED or INVALID_REQUEST"
|
|
349
|
+
|
|
350
|
+
- id: multi_finalize_gate
|
|
351
|
+
title: "At least one multi-finalize path contributed"
|
|
352
|
+
skip_if: "!context.proposal_id_2"
|
|
353
|
+
steps:
|
|
354
|
+
- id: assert_multi_finalize
|
|
355
|
+
title: "Assert multi-finalize path contributed"
|
|
356
|
+
task: assert_contribution
|
|
357
|
+
validations:
|
|
358
|
+
- check: any_of
|
|
359
|
+
allowed_values: ["multi_finalize_handled"]
|
|
360
|
+
description: "Seller either handled multi-finalize atomically or rejected with MULTI_FINALIZE_UNSUPPORTED"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
id: media_buy_seller/refine_products
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller handles product refinement"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a media buy seller supports buying_mode: refine with product-level and request-level changes."
|
|
6
|
+
track: media_buy
|
|
7
|
+
required_tools:
|
|
8
|
+
- get_products
|
|
9
|
+
|
|
10
|
+
narrative: |
|
|
11
|
+
After a buyer receives products from a brief, they refine the results without starting
|
|
12
|
+
over. The buyer calls get_products with buying_mode: refine and a refine array describing
|
|
13
|
+
changes at the request level ("only guaranteed") or product level ("increase this product's
|
|
14
|
+
budget").
|
|
15
|
+
|
|
16
|
+
The seller must apply each refinement, return updated products, and include
|
|
17
|
+
refinement_applied showing how each request was handled. This is the standard negotiation
|
|
18
|
+
loop — brief, review, refine, repeat until satisfied.
|
|
19
|
+
|
|
20
|
+
Every media buy seller that supports negotiation (not just wholesale) must handle
|
|
21
|
+
product-level refinement.
|
|
22
|
+
|
|
23
|
+
agent:
|
|
24
|
+
interaction_model: media_buy_seller
|
|
25
|
+
capabilities:
|
|
26
|
+
- sells_media
|
|
27
|
+
- accepts_briefs
|
|
28
|
+
examples:
|
|
29
|
+
- "Any media buy seller that accepts briefs"
|
|
30
|
+
|
|
31
|
+
caller:
|
|
32
|
+
role: buyer_agent
|
|
33
|
+
example: "Pinnacle Agency (buyer)"
|
|
34
|
+
|
|
35
|
+
prerequisites:
|
|
36
|
+
description: |
|
|
37
|
+
The caller needs a brand identity and operator credentials.
|
|
38
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
39
|
+
|
|
40
|
+
phases:
|
|
41
|
+
- id: setup
|
|
42
|
+
title: "Account setup"
|
|
43
|
+
steps:
|
|
44
|
+
- id: sync_accounts
|
|
45
|
+
title: "Establish account"
|
|
46
|
+
task: sync_accounts
|
|
47
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
48
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
49
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
50
|
+
stateful: true
|
|
51
|
+
expected: |
|
|
52
|
+
Return the account with account_id and status active.
|
|
53
|
+
|
|
54
|
+
sample_request:
|
|
55
|
+
accounts:
|
|
56
|
+
- brand:
|
|
57
|
+
domain: "acmeoutdoor.example"
|
|
58
|
+
operator: "pinnacle-agency.example"
|
|
59
|
+
billing: "operator"
|
|
60
|
+
payment_terms: "net_30"
|
|
61
|
+
|
|
62
|
+
idempotency_key: "$generate:uuid_v4#media_buy_seller_refine_products_setup_sync_accounts"
|
|
63
|
+
validations:
|
|
64
|
+
- check: response_schema
|
|
65
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
66
|
+
- check: field_present
|
|
67
|
+
path: "accounts[0].account_id"
|
|
68
|
+
description: "Account has a platform-assigned ID"
|
|
69
|
+
|
|
70
|
+
- id: brief
|
|
71
|
+
title: "Initial brief"
|
|
72
|
+
narrative: |
|
|
73
|
+
Send a brief to get the initial product set that the buyer will refine.
|
|
74
|
+
|
|
75
|
+
steps:
|
|
76
|
+
- id: get_products_brief
|
|
77
|
+
title: "Send a brief"
|
|
78
|
+
task: get_products
|
|
79
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
80
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
81
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
82
|
+
comply_scenario: full_sales_flow
|
|
83
|
+
stateful: false
|
|
84
|
+
expected: |
|
|
85
|
+
Return products matching the brief. Each product should include product_id,
|
|
86
|
+
delivery_type, pricing_models, and forecast.
|
|
87
|
+
|
|
88
|
+
sample_request:
|
|
89
|
+
buying_mode: "brief"
|
|
90
|
+
brief: "Premium video and display on sports and outdoor lifestyle. Q2 flight, $50K budget. Adults 25-54, US and Canada."
|
|
91
|
+
account:
|
|
92
|
+
brand:
|
|
93
|
+
domain: "acmeoutdoor.example"
|
|
94
|
+
operator: "pinnacle-agency.example"
|
|
95
|
+
|
|
96
|
+
validations:
|
|
97
|
+
- check: response_schema
|
|
98
|
+
description: "Response matches get-products-response.json schema"
|
|
99
|
+
- check: field_present
|
|
100
|
+
path: "products"
|
|
101
|
+
description: "Response contains products"
|
|
102
|
+
- check: field_present
|
|
103
|
+
path: "products[0].product_id"
|
|
104
|
+
description: "Products have IDs"
|
|
105
|
+
|
|
106
|
+
- id: refine
|
|
107
|
+
title: "Refine products"
|
|
108
|
+
narrative: |
|
|
109
|
+
The buyer has reviewed the initial products and wants to narrow down. They call
|
|
110
|
+
get_products with buying_mode: refine and a refine array with request-level and
|
|
111
|
+
product-level changes. The seller applies each refinement and returns the updated
|
|
112
|
+
product set.
|
|
113
|
+
|
|
114
|
+
steps:
|
|
115
|
+
- id: get_products_refine
|
|
116
|
+
title: "Refine with request-level and product-level changes"
|
|
117
|
+
task: get_products
|
|
118
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
119
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
120
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
121
|
+
comply_scenario: full_sales_flow
|
|
122
|
+
stateful: true
|
|
123
|
+
expected: |
|
|
124
|
+
Return updated products reflecting the refinements:
|
|
125
|
+
- Apply each refinement to the relevant scope (request or product)
|
|
126
|
+
- Include refinement_applied showing how each request was handled
|
|
127
|
+
- Preserve products that weren't targeted by refinements
|
|
128
|
+
- Update pricing and forecasts to reflect the changes
|
|
129
|
+
|
|
130
|
+
sample_request:
|
|
131
|
+
buying_mode: "refine"
|
|
132
|
+
refine:
|
|
133
|
+
- scope: "request"
|
|
134
|
+
ask: "Only guaranteed packages. Must include completion rate SLA above 80%."
|
|
135
|
+
- scope: "product"
|
|
136
|
+
product_id: "sports_preroll_q2"
|
|
137
|
+
ask: "Increase budget allocation to $30K"
|
|
138
|
+
account:
|
|
139
|
+
brand:
|
|
140
|
+
domain: "acmeoutdoor.example"
|
|
141
|
+
operator: "pinnacle-agency.example"
|
|
142
|
+
|
|
143
|
+
validations:
|
|
144
|
+
- check: response_schema
|
|
145
|
+
description: "Response matches get-products-response.json schema"
|
|
146
|
+
- check: field_present
|
|
147
|
+
path: "products"
|
|
148
|
+
description: "Response contains updated products"
|