@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/domains/media-buy/scenarios/performance_buy_flow_roas.yaml
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
id: media_buy_seller/performance_buy_flow_roas
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller fulfills a performance (event-kind goal) media buy with a ROAS target"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a seller advertising conversion_tracking with per_ad_spend in supported_targets can accept a media buy whose event-kind optimization_goal carries a ROAS (per_ad_spend) target bound to an event source with value_field, reject ROAS goals that omit value_field on every event-source entry, ingest valued purchase events, and report conversion_value + roas alongside conversions and cost_per_acquisition. Sibling to media_buy_seller/performance_buy_flow gated on the supported_targets sub-capability: sellers that don't advertise per_ad_spend (most broadcast TV, upper-funnel video, signal-only) grade not_applicable."
|
|
6
|
+
track: media_buy
|
|
7
|
+
|
|
8
|
+
# Gate: scenario runs only when the seller declares per_ad_spend in
|
|
9
|
+
# conversion_tracking.supported_targets. Sellers that compute conversions
|
|
10
|
+
# but not return-on-ad-spend (broadcast TV, upper-funnel video, signal-only,
|
|
11
|
+
# many MMP-mediated mobile pipelines) grade `not_applicable`, not failing.
|
|
12
|
+
# supported_targets is a per-target-kind enumeration of the target kinds the
|
|
13
|
+
# seller can actually optimize toward (proposed in #4639). Gating on the
|
|
14
|
+
# explicit kind rather than on conversion_tracking presence is what keeps
|
|
15
|
+
# honest CPA-only implementations from failing. Requires runner support for
|
|
16
|
+
# the `contains:` matcher (adcp-client >= 7.70).
|
|
17
|
+
requires_capability:
|
|
18
|
+
path: media_buy.conversion_tracking.supported_targets
|
|
19
|
+
contains: "per_ad_spend"
|
|
20
|
+
|
|
21
|
+
required_tools:
|
|
22
|
+
- get_products
|
|
23
|
+
- sync_event_sources
|
|
24
|
+
- create_media_buy
|
|
25
|
+
- log_event
|
|
26
|
+
- get_media_buy_delivery
|
|
27
|
+
- comply_test_controller
|
|
28
|
+
|
|
29
|
+
invariants:
|
|
30
|
+
- status.monotonic
|
|
31
|
+
|
|
32
|
+
narrative: |
|
|
33
|
+
A "ROAS buy" is a performance media buy whose optimization_goal targets
|
|
34
|
+
return-on-ad-spend rather than cost-per-acquisition. The buyer commits to
|
|
35
|
+
a target_roas (per_ad_spend) and binds the buy to one or more conversion
|
|
36
|
+
event sources whose events carry monetary value. value_field on the
|
|
37
|
+
event-source entry tells the seller which custom_data field carries the
|
|
38
|
+
per-event value to aggregate; without value_field there is nothing to
|
|
39
|
+
divide by spend, so the seller MUST reject the goal.
|
|
40
|
+
|
|
41
|
+
This scenario is a sibling to media_buy_seller/performance_buy_flow, gated
|
|
42
|
+
on a separate sub-capability bit (conversion_tracking.supported_targets
|
|
43
|
+
contains per_ad_spend). The CPA scenario is gated on conversion_tracking
|
|
44
|
+
presence — every seller that tracks conversions can compute CPA. ROAS is
|
|
45
|
+
narrower: many performance sellers honestly track conversions but don't
|
|
46
|
+
compute return-on-ad-spend because their attribution doesn't carry value.
|
|
47
|
+
Gating ROAS on the explicit per_ad_spend kind in supported_targets is what
|
|
48
|
+
prevents that population from being marked failing instead of
|
|
49
|
+
not_applicable.
|
|
50
|
+
|
|
51
|
+
Discriminating behaviors this scenario verifies:
|
|
52
|
+
1. sync_event_sources returns an event_source_id that is valid as the
|
|
53
|
+
binding target on a per_ad_spend optimization_goal.
|
|
54
|
+
2. create_media_buy with an event-kind goal whose target.kind is
|
|
55
|
+
per_ad_spend AND whose event_sources[k].value_field is populated is
|
|
56
|
+
accepted.
|
|
57
|
+
3. create_media_buy with target.kind = per_ad_spend AND NO value_field on
|
|
58
|
+
any event_sources[] entry is rejected with INVALID_REQUEST. The seller
|
|
59
|
+
cannot compute ROAS without a value field; silent acceptance would mean
|
|
60
|
+
reporting roas: 0 for the life of the buy. error.field points at the
|
|
61
|
+
offending value_field absence at packages[0].optimization_goals[0].event_sources[0].value_field.
|
|
62
|
+
4. log_event flows valued conversions back, scoped to the registered
|
|
63
|
+
event_source_id with order_total in custom_data.
|
|
64
|
+
5. get_media_buy_delivery returns first-class ROAS metrics — conversion_value
|
|
65
|
+
and roas — alongside conversions and cost_per_acquisition. CPA is still
|
|
66
|
+
computed (spend / conversions is well-defined for any conversion source);
|
|
67
|
+
roas is the field this scenario exists to assert.
|
|
68
|
+
|
|
69
|
+
Per-creative ROAS breakdown is deliberately NOT asserted here for the
|
|
70
|
+
same reason per-creative attribution is deferred in performance_buy_flow:
|
|
71
|
+
honest adopters report at differing granularities (social per-ad, retail-
|
|
72
|
+
media per-line, MMP-mediated per-campaign, broadcast/CTV per-placement).
|
|
73
|
+
A follow-up scenario gated on a sub-capability bit will land per-creative
|
|
74
|
+
value attribution once the breakdown shape is settled.
|
|
75
|
+
|
|
76
|
+
agent:
|
|
77
|
+
interaction_model: media_buy_seller
|
|
78
|
+
capabilities:
|
|
79
|
+
- sells_media
|
|
80
|
+
- supports_non_guaranteed
|
|
81
|
+
- conversion_tracking
|
|
82
|
+
examples:
|
|
83
|
+
- "Performance-mode DSPs with value-aware bidding"
|
|
84
|
+
- "Retail-media networks (Amazon Ads, Criteo, Walmart Connect)"
|
|
85
|
+
- "Social platforms with value optimization (Meta VBO, TikTok VBO)"
|
|
86
|
+
- "Agentic optimizers that pass value into upstream attribution"
|
|
87
|
+
|
|
88
|
+
caller:
|
|
89
|
+
role: buyer_agent
|
|
90
|
+
example: "Pinnacle Agency (buyer)"
|
|
91
|
+
|
|
92
|
+
prerequisites:
|
|
93
|
+
description: |
|
|
94
|
+
The seller must implement comply_test_controller with simulate_delivery
|
|
95
|
+
(already required for delivery_reporting). simulate_delivery's
|
|
96
|
+
`conversions` param injects attributed conversion counts and the seller
|
|
97
|
+
is expected to compute conversion_value from logged events with
|
|
98
|
+
order_total. Sellers whose attribution pipeline cannot ingest a value
|
|
99
|
+
field do not advertise per_ad_spend in supported_targets and grade
|
|
100
|
+
not_applicable.
|
|
101
|
+
|
|
102
|
+
The buyer fixture supplies a brand, an operator, a conversion event
|
|
103
|
+
source definition, and a valued purchase event sufficient to exercise
|
|
104
|
+
the ROAS reporting contract.
|
|
105
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
106
|
+
controller_seeding: true
|
|
107
|
+
|
|
108
|
+
fixtures:
|
|
109
|
+
products:
|
|
110
|
+
- product_id: "performance_roas_native_q2"
|
|
111
|
+
delivery_type: "non_guaranteed"
|
|
112
|
+
channels: ["display", "native"]
|
|
113
|
+
format_ids:
|
|
114
|
+
- id: "native_feed_1x1"
|
|
115
|
+
- id: "display_300x250"
|
|
116
|
+
pricing_options:
|
|
117
|
+
- product_id: "performance_roas_native_q2"
|
|
118
|
+
pricing_option_id: "auction_cpm"
|
|
119
|
+
pricing_model: "cpm"
|
|
120
|
+
currency: "USD"
|
|
121
|
+
floor_price: 1.50
|
|
122
|
+
|
|
123
|
+
phases:
|
|
124
|
+
|
|
125
|
+
- id: setup
|
|
126
|
+
title: "Establish account and discover products"
|
|
127
|
+
steps:
|
|
128
|
+
- id: sync_accounts
|
|
129
|
+
title: "Establish account"
|
|
130
|
+
task: sync_accounts
|
|
131
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
132
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
133
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
134
|
+
stateful: true
|
|
135
|
+
expected: |
|
|
136
|
+
Return the account with account_id and status active.
|
|
137
|
+
sample_request:
|
|
138
|
+
accounts:
|
|
139
|
+
- brand:
|
|
140
|
+
domain: "acmeoutdoor.example"
|
|
141
|
+
operator: "pinnacle-agency.example"
|
|
142
|
+
billing: "operator"
|
|
143
|
+
idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_setup_sync_accounts"
|
|
144
|
+
validations:
|
|
145
|
+
- check: response_schema
|
|
146
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
147
|
+
- check: field_present
|
|
148
|
+
path: "accounts[0].account_id"
|
|
149
|
+
description: "Account has a platform-assigned ID"
|
|
150
|
+
|
|
151
|
+
- id: get_products_for_roas
|
|
152
|
+
title: "Discover products that support ROAS optimization"
|
|
153
|
+
task: get_products
|
|
154
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
155
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
156
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
157
|
+
stateful: false
|
|
158
|
+
expected: |
|
|
159
|
+
Return at least one product whose conversion_tracking capabilities
|
|
160
|
+
accept per_ad_spend event-kind targets.
|
|
161
|
+
sample_request:
|
|
162
|
+
buying_mode: "brief"
|
|
163
|
+
brief: "Performance native + display, US, adults 25-54. Target ROAS 4.0 on purchase events with order_total from acmeoutdoor.example."
|
|
164
|
+
required_capabilities:
|
|
165
|
+
- "conversion_tracking"
|
|
166
|
+
account:
|
|
167
|
+
brand:
|
|
168
|
+
domain: "acmeoutdoor.example"
|
|
169
|
+
operator: "pinnacle-agency.example"
|
|
170
|
+
validations:
|
|
171
|
+
- check: response_schema
|
|
172
|
+
description: "Response matches get-products-response.json schema"
|
|
173
|
+
- check: field_present
|
|
174
|
+
path: "products"
|
|
175
|
+
description: "Response contains products"
|
|
176
|
+
|
|
177
|
+
- id: event_source_binding
|
|
178
|
+
title: "Register the conversion event source"
|
|
179
|
+
narrative: |
|
|
180
|
+
The ROAS buy cannot be created without a registered event source whose
|
|
181
|
+
entry carries value_field. This phase exercises the binding —
|
|
182
|
+
sync_event_sources returns an event_source_id that the next phase
|
|
183
|
+
references on a per_ad_spend optimization_goal.
|
|
184
|
+
|
|
185
|
+
steps:
|
|
186
|
+
- id: sync_event_sources
|
|
187
|
+
title: "Register a website conversion source"
|
|
188
|
+
task: sync_event_sources
|
|
189
|
+
schema_ref: "media-buy/sync-event-sources-request.json"
|
|
190
|
+
response_schema_ref: "media-buy/sync-event-sources-response.json"
|
|
191
|
+
doc_ref: "/media-buy/task-reference/sync_event_sources"
|
|
192
|
+
stateful: true
|
|
193
|
+
expected: |
|
|
194
|
+
Return event_sources with event_source_id, setup.snippet, and
|
|
195
|
+
action: created. The id is captured for the ROAS create_media_buy
|
|
196
|
+
phase.
|
|
197
|
+
sample_request:
|
|
198
|
+
account:
|
|
199
|
+
brand:
|
|
200
|
+
domain: "acmeoutdoor.example"
|
|
201
|
+
operator: "pinnacle-agency.example"
|
|
202
|
+
event_sources:
|
|
203
|
+
- event_source_id: "acmeoutdoor_website"
|
|
204
|
+
name: "Acme Outdoor Website"
|
|
205
|
+
event_types: ["purchase"]
|
|
206
|
+
allowed_domains: ["acmeoutdoor.example"]
|
|
207
|
+
idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_event_source_binding_sync_event_sources"
|
|
208
|
+
validations:
|
|
209
|
+
- check: response_schema
|
|
210
|
+
description: "Response matches sync-event-sources-response.json schema"
|
|
211
|
+
- check: field_present
|
|
212
|
+
path: "event_sources[0].event_source_id"
|
|
213
|
+
description: "Event source has a platform-assigned ID"
|
|
214
|
+
- check: field_present
|
|
215
|
+
path: "event_sources[0].setup.snippet"
|
|
216
|
+
description: "Event source returns integration code"
|
|
217
|
+
# Anti-façade: an adapter that returns a shape-valid
|
|
218
|
+
# sync_event_sources response without forwarding the source
|
|
219
|
+
# definition upstream fails this check. Adopters who don't
|
|
220
|
+
# advertise query_upstream_traffic grade not_applicable.
|
|
221
|
+
- check: upstream_traffic
|
|
222
|
+
description: "sync_event_sources caused upstream traffic registering the event source"
|
|
223
|
+
min_count: 1
|
|
224
|
+
endpoint_pattern: "POST *"
|
|
225
|
+
|
|
226
|
+
- id: create_performance_buy_roas
|
|
227
|
+
title: "Create a performance buy with a ROAS goal"
|
|
228
|
+
narrative: |
|
|
229
|
+
The buyer creates a media buy whose package carries an event-kind
|
|
230
|
+
optimization_goal binding to the registered event source. The target
|
|
231
|
+
is per_ad_spend (ROAS) 4.0 on purchase events, with value_field
|
|
232
|
+
"order_total" telling the seller which custom_data field to aggregate.
|
|
233
|
+
|
|
234
|
+
steps:
|
|
235
|
+
- id: create_media_buy_roas
|
|
236
|
+
title: "Create media buy with event-kind goal (per_ad_spend target)"
|
|
237
|
+
task: create_media_buy
|
|
238
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
239
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
240
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
241
|
+
stateful: true
|
|
242
|
+
expected: |
|
|
243
|
+
Create the media buy. Response carries a media_buy_id used for
|
|
244
|
+
subsequent log_event and get_media_buy_delivery calls.
|
|
245
|
+
sample_request:
|
|
246
|
+
brand:
|
|
247
|
+
domain: "acmeoutdoor.example"
|
|
248
|
+
account:
|
|
249
|
+
brand:
|
|
250
|
+
domain: "acmeoutdoor.example"
|
|
251
|
+
operator: "pinnacle-agency.example"
|
|
252
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
253
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
254
|
+
packages:
|
|
255
|
+
- product_id: "performance_roas_native_q2"
|
|
256
|
+
budget: 25000
|
|
257
|
+
pricing_option_id: "auction_cpm"
|
|
258
|
+
optimization_goals:
|
|
259
|
+
- kind: "event"
|
|
260
|
+
event_sources:
|
|
261
|
+
- event_source_id: "acmeoutdoor_website"
|
|
262
|
+
event_type: "purchase"
|
|
263
|
+
value_field: "order_total"
|
|
264
|
+
target:
|
|
265
|
+
kind: "per_ad_spend"
|
|
266
|
+
value: 4.0
|
|
267
|
+
priority: 1
|
|
268
|
+
idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_create_performance_buy_roas_create_media_buy"
|
|
269
|
+
context_outputs:
|
|
270
|
+
- name: media_buy_id
|
|
271
|
+
path: "media_buy_id"
|
|
272
|
+
validations:
|
|
273
|
+
- check: response_schema
|
|
274
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
275
|
+
- check: field_present
|
|
276
|
+
path: "media_buy_id"
|
|
277
|
+
description: "Media buy has a platform-assigned ID"
|
|
278
|
+
|
|
279
|
+
- id: rejection_per_ad_spend_no_value_field
|
|
280
|
+
title: "Reject a per_ad_spend goal that omits value_field"
|
|
281
|
+
narrative: |
|
|
282
|
+
Silent acceptance of a per_ad_spend target with no value_field on any
|
|
283
|
+
event_sources[] entry is a façade — the seller cannot compute ROAS
|
|
284
|
+
without a value to divide by spend, so the buy would silently report
|
|
285
|
+
roas: 0 (or absent) for the life of the flight. The seller MUST reject
|
|
286
|
+
with INVALID_REQUEST and set error.field to the offending value_field
|
|
287
|
+
absence on the first event_sources entry. This mirrors the unbound
|
|
288
|
+
event_source_id rejection in performance_buy_flow on the value side.
|
|
289
|
+
|
|
290
|
+
optimization-goal.json:148-156 makes the requirement explicit: target
|
|
291
|
+
kinds per_ad_spend and maximize_value require value_field on at least
|
|
292
|
+
one entry. Sellers MUST reject when the requirement is unmet.
|
|
293
|
+
|
|
294
|
+
steps:
|
|
295
|
+
- id: create_media_buy_per_ad_spend_no_value_field
|
|
296
|
+
title: "Submit a per_ad_spend goal with no value_field on any source"
|
|
297
|
+
task: create_media_buy
|
|
298
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
299
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
300
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
301
|
+
expect_error: true
|
|
302
|
+
negative_path: payload_well_formed
|
|
303
|
+
stateful: false
|
|
304
|
+
expected: |
|
|
305
|
+
Reject with INVALID_REQUEST. error.field points at the missing
|
|
306
|
+
value_field on the event_sources entry. media_buy_id is not
|
|
307
|
+
allocated.
|
|
308
|
+
sample_request:
|
|
309
|
+
brand:
|
|
310
|
+
domain: "acmeoutdoor.example"
|
|
311
|
+
account:
|
|
312
|
+
brand:
|
|
313
|
+
domain: "acmeoutdoor.example"
|
|
314
|
+
operator: "pinnacle-agency.example"
|
|
315
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
316
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
317
|
+
packages:
|
|
318
|
+
- product_id: "performance_roas_native_q2"
|
|
319
|
+
budget: 5000
|
|
320
|
+
pricing_option_id: "auction_cpm"
|
|
321
|
+
optimization_goals:
|
|
322
|
+
- kind: "event"
|
|
323
|
+
event_sources:
|
|
324
|
+
- event_source_id: "acmeoutdoor_website"
|
|
325
|
+
event_type: "purchase"
|
|
326
|
+
target:
|
|
327
|
+
kind: "per_ad_spend"
|
|
328
|
+
value: 4.0
|
|
329
|
+
idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_rejection_per_ad_spend_no_value_field"
|
|
330
|
+
validations:
|
|
331
|
+
- check: error_code
|
|
332
|
+
allowed_values: ["INVALID_REQUEST"]
|
|
333
|
+
description: "Seller rejects the per_ad_spend goal with no value_field with INVALID_REQUEST"
|
|
334
|
+
- check: field_value
|
|
335
|
+
path: "errors[0].field"
|
|
336
|
+
value: "packages[0].optimization_goals[0].event_sources[0].value_field"
|
|
337
|
+
description: "Error.field points at the missing value_field on the first event_sources entry (core/error.json defines field as deterministic JSONPath-lite — literal equality; the value_field path is more buyer-actionable than pointing at target.kind because it tells the buyer what to add, not what to remove)"
|
|
338
|
+
|
|
339
|
+
- id: log_purchase_event
|
|
340
|
+
title: "Log a valued purchase event against the bound source"
|
|
341
|
+
narrative: |
|
|
342
|
+
The buyer logs a purchase event with order_total in custom_data tied
|
|
343
|
+
to the registered event_source_id. The seller's attribution pipeline
|
|
344
|
+
ingests order_total via the value_field declared on the goal and
|
|
345
|
+
aggregates it into conversion_value, surfaced in delivery in the next
|
|
346
|
+
phase.
|
|
347
|
+
|
|
348
|
+
steps:
|
|
349
|
+
- id: log_purchase_event
|
|
350
|
+
title: "Log a purchase event with order_total"
|
|
351
|
+
task: log_event
|
|
352
|
+
schema_ref: "media-buy/log-event-request.json"
|
|
353
|
+
response_schema_ref: "media-buy/log-event-response.json"
|
|
354
|
+
doc_ref: "/media-buy/task-reference/log_event"
|
|
355
|
+
stateful: true
|
|
356
|
+
expected: |
|
|
357
|
+
Acknowledge the event with accepted status.
|
|
358
|
+
sample_request:
|
|
359
|
+
account:
|
|
360
|
+
brand:
|
|
361
|
+
domain: "acmeoutdoor.example"
|
|
362
|
+
operator: "pinnacle-agency.example"
|
|
363
|
+
event_source_id: "acmeoutdoor_website"
|
|
364
|
+
events:
|
|
365
|
+
- event_type: "purchase"
|
|
366
|
+
event_id: "evt_perf_buy_flow_roas_001"
|
|
367
|
+
event_time: "2026-06-05T14:30:00Z"
|
|
368
|
+
user_match:
|
|
369
|
+
hashed_email: "a000000000000000000000000000000000000000000000000000000000000020"
|
|
370
|
+
custom_data:
|
|
371
|
+
order_total: 149.99
|
|
372
|
+
currency: "USD"
|
|
373
|
+
idempotency_key: "$generate:uuid_v4#performance_buy_flow_roas_log_purchase_event_log_event"
|
|
374
|
+
validations:
|
|
375
|
+
- check: response_schema
|
|
376
|
+
description: "Response matches log-event-response.json schema"
|
|
377
|
+
- check: upstream_traffic
|
|
378
|
+
description: "log_event forwards the event to the seller's upstream conversion endpoint with the order_total value"
|
|
379
|
+
min_count: 1
|
|
380
|
+
endpoint_pattern: "POST *"
|
|
381
|
+
identifier_paths:
|
|
382
|
+
- "events[*].user_match.hashed_email"
|
|
383
|
+
|
|
384
|
+
- id: attributed_roas_delivery
|
|
385
|
+
title: "Delivery reporting carries ROAS, conversion_value, conversions, and CPA"
|
|
386
|
+
narrative: |
|
|
387
|
+
The discriminating assertion of the ROAS buy mode: delivery reporting
|
|
388
|
+
MUST surface conversion_value and roas — not just conversions and CPA.
|
|
389
|
+
The runner injects simulated impressions, conversions, and spend via
|
|
390
|
+
the test controller, then verifies get_media_buy_delivery returns all
|
|
391
|
+
four first-class metrics at the buy level.
|
|
392
|
+
|
|
393
|
+
CPA is still computed (spend / conversions is well-defined whenever
|
|
394
|
+
the seller tracks conversions); ROAS is the addition this scenario
|
|
395
|
+
exists to certify. Sellers that advertise per_ad_spend in
|
|
396
|
+
supported_targets are committing to populate conversion_value and roas
|
|
397
|
+
on delivery responses.
|
|
398
|
+
|
|
399
|
+
Per-creative ROAS breakdown is deliberately NOT asserted here for the
|
|
400
|
+
same reason performance_buy_flow defers per-creative attribution:
|
|
401
|
+
honest adopters report at differing granularities and gating
|
|
402
|
+
per-creative value attribution on a sub-capability bit lands as a
|
|
403
|
+
follow-up scenario.
|
|
404
|
+
|
|
405
|
+
steps:
|
|
406
|
+
- id: simulate_roas_delivery
|
|
407
|
+
title: "Inject impressions + conversions + spend"
|
|
408
|
+
task: comply_test_controller
|
|
409
|
+
requires_tool: comply_test_controller
|
|
410
|
+
stateful: true
|
|
411
|
+
expected: |
|
|
412
|
+
The test controller acknowledges the simulated delivery.
|
|
413
|
+
sample_request:
|
|
414
|
+
account:
|
|
415
|
+
sandbox: true
|
|
416
|
+
scenario: "simulate_delivery"
|
|
417
|
+
params:
|
|
418
|
+
media_buy_id: "$context.media_buy_id"
|
|
419
|
+
impressions: 200000
|
|
420
|
+
clicks: 4500
|
|
421
|
+
conversions: 90
|
|
422
|
+
reported_spend:
|
|
423
|
+
amount: 3000.00
|
|
424
|
+
currency: "USD"
|
|
425
|
+
validations:
|
|
426
|
+
- check: field_value
|
|
427
|
+
path: "success"
|
|
428
|
+
allowed_values: [true]
|
|
429
|
+
description: "Delivery simulation succeeds"
|
|
430
|
+
|
|
431
|
+
- id: get_attributed_roas_delivery
|
|
432
|
+
title: "Get delivery and verify ROAS-attributed metrics"
|
|
433
|
+
task: get_media_buy_delivery
|
|
434
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
435
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
436
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
437
|
+
stateful: true
|
|
438
|
+
expected: |
|
|
439
|
+
Delivery response includes:
|
|
440
|
+
- conversions (the count of attributed conversions)
|
|
441
|
+
- conversion_value (the sum of order_total across attributed conversions)
|
|
442
|
+
- roas (conversion_value / spend — the discriminating assertion for this scenario)
|
|
443
|
+
- cost_per_acquisition (still computed; ROAS is in addition, not instead)
|
|
444
|
+
|
|
445
|
+
Per-creative value attribution is intentionally NOT asserted here
|
|
446
|
+
(see phase narrative). A follow-up scenario gated on a sub-capability
|
|
447
|
+
bit will land per-creative ROAS once the breakdown shape is settled.
|
|
448
|
+
sample_request:
|
|
449
|
+
account:
|
|
450
|
+
brand:
|
|
451
|
+
domain: "acmeoutdoor.example"
|
|
452
|
+
operator: "pinnacle-agency.example"
|
|
453
|
+
media_buy_ids:
|
|
454
|
+
- "$context.media_buy_id"
|
|
455
|
+
include_package_daily_breakdown: true
|
|
456
|
+
validations:
|
|
457
|
+
- check: response_schema
|
|
458
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
459
|
+
- check: field_present
|
|
460
|
+
path: "media_buy_deliveries[0].totals.conversions"
|
|
461
|
+
description: "Conversion count surfaced at the buy level"
|
|
462
|
+
- check: field_present
|
|
463
|
+
path: "media_buy_deliveries[0].totals.conversion_value"
|
|
464
|
+
description: "Aggregated conversion_value surfaced at the buy level (sum of order_total across attributed conversions)"
|
|
465
|
+
- check: field_present
|
|
466
|
+
path: "media_buy_deliveries[0].totals.roas"
|
|
467
|
+
description: "ROAS surfaced at the buy level — the discriminating assertion of per_ad_spend optimization (conversion_value / spend)"
|
|
468
|
+
- check: field_present
|
|
469
|
+
path: "media_buy_deliveries[0].totals.cost_per_acquisition"
|
|
470
|
+
description: "CPA still computed alongside ROAS (spend / conversions)"
|