@adcp/sdk 7.11.0 → 7.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compliance/cache/3.1.0-rc.2/domains/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/domains/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/domains/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/domains/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/index.json +356 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/protocols/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/protocols/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/protocols/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/audience-sync/index.yaml +313 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/index.yaml +350 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/scenarios/governance_denied.yaml +226 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/collection-lists/index.yaml +359 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/content-standards/index.yaml +572 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-ad-server/index.yaml +409 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/generative-seller.yaml +807 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/index.yaml +758 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-template/index.yaml +510 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/index.yaml +143 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-delivery-monitor/index.yaml +441 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/denied.yaml +221 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/index.yaml +330 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/property-lists/index.yaml +482 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-broadcast-tv/index.yaml +738 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-catalog-driven/index.yaml +840 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-guaranteed/index.yaml +601 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-non-guaranteed/index.yaml +546 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-proposal-mode/index.yaml +586 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-social/index.yaml +919 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/index.yaml +424 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/scenarios/governance_denied.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-owned/index.yaml +317 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sponsored-intelligence/index.yaml +59 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor-live.yaml +78 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor.yaml +223 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/billing-gate-runner.yaml +115 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/bistro-oranje.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/distributed-brand-runner.yaml +281 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/nova-motors.yaml +262 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/osei-natural.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/parallel-dispatch-runner.yaml +196 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/rate-limit-trip-runner.yaml +172 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/signed-requests-runner.yaml +155 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/single-side-trust-runner.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/substitution-observer-runner.yaml +688 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/summit-foods.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/webhook-receiver-runner.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/001-minimal-plan.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/002-full-plan.json +217 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/README.md +220 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/canonicalization.json +241 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/keys.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/001-basic-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/003-es256-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/README.md +211 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/keys.json +61 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
- package/compliance/cache/3.1.0-rc.2/universal/billing-gate-dispatch.yaml +450 -0
- package/compliance/cache/3.1.0-rc.2/universal/canonical-format-validate-input.yaml +640 -0
- package/compliance/cache/3.1.0-rc.2/universal/capability-discovery.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/universal/collection-lists-pagination-integrity.yaml +306 -0
- package/compliance/cache/3.1.0-rc.2/universal/comply-controller-mode-gate.yaml +141 -0
- package/compliance/cache/3.1.0-rc.2/universal/content-standards-pagination-integrity.yaml +326 -0
- package/compliance/cache/3.1.0-rc.2/universal/deterministic-testing.yaml +1430 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance-signals.yaml +377 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance.yaml +528 -0
- package/compliance/cache/3.1.0-rc.2/universal/fictional-entities.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-media-buys-pagination-integrity.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-signals-pagination-integrity.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/universal/idempotency.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-event-scope.yaml +119 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-lifecycle.yaml +337 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-rejections.yaml +107 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-creative-formats.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-list-accounts.yaml +245 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity.yaml +263 -0
- package/compliance/cache/3.1.0-rc.2/universal/property-lists-pagination-integrity.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/read-tool-idempotency.yaml +405 -0
- package/compliance/cache/3.1.0-rc.2/universal/runner-output-contract.yaml +1285 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation-signals.yaml +181 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation.yaml +548 -0
- package/compliance/cache/3.1.0-rc.2/universal/security.yaml +539 -0
- package/compliance/cache/3.1.0-rc.2/universal/signed-requests.yaml +217 -0
- package/compliance/cache/3.1.0-rc.2/universal/stale-response-advisory.yaml +295 -0
- package/compliance/cache/3.1.0-rc.2/universal/storyboard-schema.yaml +2194 -0
- package/compliance/cache/3.1.0-rc.2/universal/v3-envelope-integrity.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/universal/version-negotiation.yaml +130 -0
- package/compliance/cache/3.1.0-rc.2/universal/webhook-emission.yaml +411 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-bulk-webhooks.yaml +82 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-product-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-products.yaml +151 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signal-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signals.yaml +149 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +23 -0
- package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +84 -21
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +21 -0
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/types.d.ts +9 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
id: media_buy_seller/event_dedup_flow
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller deduplicates the same event across multiple registered event sources"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a seller advertising conversion_tracking.multi_source_event_dedup can register multiple event sources for the same buy and deduplicate inbound events by event_id so the same conversion from a pixel and a CAPI source counts once, not twice. Sibling to media_buy_seller/performance_buy_flow gated on the dedup sub-capability bit: sellers that don't advertise multi-source dedup grade not_applicable."
|
|
6
|
+
track: media_buy
|
|
7
|
+
|
|
8
|
+
# Gate: scenario runs only when the seller declares
|
|
9
|
+
# conversion_tracking.multi_source_event_dedup equals true. Sellers that
|
|
10
|
+
# don't (most social platforms with independently-managed pixel + CAPI
|
|
11
|
+
# pipelines, retail-media networks attributing per-source) grade
|
|
12
|
+
# `not_applicable`, not failing. multi_source_event_dedup is a sub-capability
|
|
13
|
+
# of conversion_tracking — gating on this bit rather than on
|
|
14
|
+
# conversion_tracking presence avoids over-claiming against the broad
|
|
15
|
+
# performance-tracking community.
|
|
16
|
+
requires_capability:
|
|
17
|
+
path: media_buy.conversion_tracking.multi_source_event_dedup
|
|
18
|
+
equals: true
|
|
19
|
+
|
|
20
|
+
required_tools:
|
|
21
|
+
- sync_event_sources
|
|
22
|
+
- create_media_buy
|
|
23
|
+
- log_event
|
|
24
|
+
- get_media_buy_delivery
|
|
25
|
+
- comply_test_controller
|
|
26
|
+
|
|
27
|
+
invariants:
|
|
28
|
+
- status.monotonic
|
|
29
|
+
|
|
30
|
+
narrative: |
|
|
31
|
+
"Multi-source event dedup" is the discriminating capability of sellers
|
|
32
|
+
whose attribution pipelines can deduplicate the same conversion observed
|
|
33
|
+
via two independent ingestion paths — typically a website pixel and a
|
|
34
|
+
server-side Conversions API (CAPI) feed, sharing event_id. When the
|
|
35
|
+
seller advertises multi_source_event_dedup: true, buyers can register
|
|
36
|
+
both sources on the same optimization_goal and rely on the seller
|
|
37
|
+
attributing each unique event_id once.
|
|
38
|
+
|
|
39
|
+
Most adopters cannot do this. Independently-managed pixel and CAPI
|
|
40
|
+
pipelines in social platforms attribute per source; retail-media networks
|
|
41
|
+
attribute at the line / placement level without cross-source dedup;
|
|
42
|
+
broadcast / CTV performance products dedup only within a single MMP feed.
|
|
43
|
+
Gating this scenario on the explicit sub-capability bit is what keeps
|
|
44
|
+
honest implementations from failing.
|
|
45
|
+
|
|
46
|
+
Discriminating behaviors this scenario verifies:
|
|
47
|
+
1. sync_event_sources can register multiple event sources for the same
|
|
48
|
+
buyer account, each with its own event_source_id but overlapping
|
|
49
|
+
event_types and allowed_domains.
|
|
50
|
+
2. create_media_buy accepts an event-kind optimization_goal whose
|
|
51
|
+
event_sources array contains both source ids — the seller commits to
|
|
52
|
+
deduplicating across them.
|
|
53
|
+
3. log_event accepts the SAME event_id from BOTH sources without
|
|
54
|
+
rejecting either as a duplicate (both API-level acks succeed —
|
|
55
|
+
the dedup happens in attribution, not ingestion).
|
|
56
|
+
4. get_media_buy_delivery reports the cumulative conversion count as 1,
|
|
57
|
+
not 2. The point of multi_source_event_dedup: true is that the same
|
|
58
|
+
event_id from two registered sources counts once.
|
|
59
|
+
|
|
60
|
+
Sellers without this capability would either reject the second log_event
|
|
61
|
+
call (overly conservative) or count both (the silent-double-count failure
|
|
62
|
+
mode this scenario guards against). The bit gates the scenario; the
|
|
63
|
+
assertion is the cumulative count.
|
|
64
|
+
|
|
65
|
+
Per-event-source conversion breakdown (conversions split per
|
|
66
|
+
event_source_id within media_buy_deliveries[].totals) is deliberately NOT
|
|
67
|
+
asserted: that field isn't first-class in delivery-metrics.json today.
|
|
68
|
+
A follow-up scenario gated on a sub-capability bit will land per-source
|
|
69
|
+
attribution once the breakdown shape is in spec.
|
|
70
|
+
|
|
71
|
+
agent:
|
|
72
|
+
interaction_model: media_buy_seller
|
|
73
|
+
capabilities:
|
|
74
|
+
- sells_media
|
|
75
|
+
- conversion_tracking
|
|
76
|
+
examples:
|
|
77
|
+
- "Social platforms with unified pixel+CAPI dedup (rare — most don't)"
|
|
78
|
+
- "DSPs operating their own attribution graph"
|
|
79
|
+
- "Walled-garden platforms with deterministic cross-source dedup"
|
|
80
|
+
|
|
81
|
+
caller:
|
|
82
|
+
role: buyer_agent
|
|
83
|
+
example: "Pinnacle Agency (buyer)"
|
|
84
|
+
|
|
85
|
+
prerequisites:
|
|
86
|
+
description: |
|
|
87
|
+
The seller must implement comply_test_controller with simulate_delivery
|
|
88
|
+
accepting a `conversions` param so the dedup outcome is observable via
|
|
89
|
+
get_media_buy_delivery without a real attribution run.
|
|
90
|
+
|
|
91
|
+
The buyer fixture supplies a brand, an operator, and two event-source
|
|
92
|
+
definitions (a website pixel and a CAPI feed) sufficient to exercise
|
|
93
|
+
multi-source registration and dedup.
|
|
94
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
95
|
+
controller_seeding: true
|
|
96
|
+
|
|
97
|
+
fixtures:
|
|
98
|
+
products:
|
|
99
|
+
- product_id: "dedup_performance_q2"
|
|
100
|
+
delivery_type: "non_guaranteed"
|
|
101
|
+
channels: ["display"]
|
|
102
|
+
format_ids:
|
|
103
|
+
- id: "display_300x250"
|
|
104
|
+
pricing_options:
|
|
105
|
+
- product_id: "dedup_performance_q2"
|
|
106
|
+
pricing_option_id: "auction_cpm"
|
|
107
|
+
pricing_model: "cpm"
|
|
108
|
+
currency: "USD"
|
|
109
|
+
floor_price: 1.50
|
|
110
|
+
|
|
111
|
+
phases:
|
|
112
|
+
|
|
113
|
+
- id: setup
|
|
114
|
+
title: "Establish account and discover products"
|
|
115
|
+
steps:
|
|
116
|
+
- id: sync_accounts
|
|
117
|
+
title: "Establish account"
|
|
118
|
+
task: sync_accounts
|
|
119
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
120
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
121
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
122
|
+
stateful: true
|
|
123
|
+
expected: |
|
|
124
|
+
Return the account with account_id and status active.
|
|
125
|
+
sample_request:
|
|
126
|
+
accounts:
|
|
127
|
+
- brand:
|
|
128
|
+
domain: "acmeoutdoor.example"
|
|
129
|
+
operator: "pinnacle-agency.example"
|
|
130
|
+
billing: "operator"
|
|
131
|
+
idempotency_key: "$generate:uuid_v4#event_dedup_flow_setup_sync_accounts"
|
|
132
|
+
validations:
|
|
133
|
+
- check: response_schema
|
|
134
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
135
|
+
- check: field_present
|
|
136
|
+
path: "accounts[0].account_id"
|
|
137
|
+
description: "Account has a platform-assigned ID"
|
|
138
|
+
|
|
139
|
+
- id: get_products_for_dedup
|
|
140
|
+
title: "Discover products supporting multi-source event dedup"
|
|
141
|
+
task: get_products
|
|
142
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
143
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
144
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
145
|
+
stateful: false
|
|
146
|
+
expected: |
|
|
147
|
+
Return at least one product whose conversion_tracking capabilities
|
|
148
|
+
include multi_source_event_dedup.
|
|
149
|
+
sample_request:
|
|
150
|
+
buying_mode: "brief"
|
|
151
|
+
brief: "Performance display, US, adults 25-54. Target CPA $40 with pixel + CAPI conversion sources; same event_id from both must dedup."
|
|
152
|
+
required_capabilities:
|
|
153
|
+
- "conversion_tracking"
|
|
154
|
+
account:
|
|
155
|
+
brand:
|
|
156
|
+
domain: "acmeoutdoor.example"
|
|
157
|
+
operator: "pinnacle-agency.example"
|
|
158
|
+
validations:
|
|
159
|
+
- check: response_schema
|
|
160
|
+
description: "Response matches get-products-response.json schema"
|
|
161
|
+
- check: field_present
|
|
162
|
+
path: "products"
|
|
163
|
+
description: "Response contains products"
|
|
164
|
+
|
|
165
|
+
- id: register_two_event_sources
|
|
166
|
+
title: "Register a pixel and a CAPI source sharing event types"
|
|
167
|
+
narrative: |
|
|
168
|
+
Two event_sources in a single sync_event_sources call — a website
|
|
169
|
+
pixel and a server-side CAPI feed. Both observe the same purchase
|
|
170
|
+
events; the buyer expects the seller to dedup by event_id when both
|
|
171
|
+
sources are attached to the same optimization_goal.
|
|
172
|
+
|
|
173
|
+
steps:
|
|
174
|
+
- id: sync_event_sources
|
|
175
|
+
title: "Register pixel + CAPI as two sources on one account"
|
|
176
|
+
task: sync_event_sources
|
|
177
|
+
schema_ref: "media-buy/sync-event-sources-request.json"
|
|
178
|
+
response_schema_ref: "media-buy/sync-event-sources-response.json"
|
|
179
|
+
doc_ref: "/media-buy/task-reference/sync_event_sources"
|
|
180
|
+
stateful: true
|
|
181
|
+
expected: |
|
|
182
|
+
Return both event_sources with event_source_id, setup.snippet,
|
|
183
|
+
and action: created. Both ids are referenced in the next phase's
|
|
184
|
+
create_media_buy call.
|
|
185
|
+
sample_request:
|
|
186
|
+
account:
|
|
187
|
+
brand:
|
|
188
|
+
domain: "acmeoutdoor.example"
|
|
189
|
+
operator: "pinnacle-agency.example"
|
|
190
|
+
event_sources:
|
|
191
|
+
- event_source_id: "acmeoutdoor_website_pixel"
|
|
192
|
+
name: "Acme Outdoor website pixel"
|
|
193
|
+
event_types: ["purchase", "add_to_cart"]
|
|
194
|
+
allowed_domains: ["acmeoutdoor.example"]
|
|
195
|
+
- event_source_id: "acmeoutdoor_website_capi"
|
|
196
|
+
name: "Acme Outdoor server-side CAPI"
|
|
197
|
+
event_types: ["purchase", "add_to_cart"]
|
|
198
|
+
allowed_domains: ["acmeoutdoor.example"]
|
|
199
|
+
idempotency_key: "$generate:uuid_v4#event_dedup_flow_register_two_event_sources_sync_event_sources"
|
|
200
|
+
validations:
|
|
201
|
+
- check: response_schema
|
|
202
|
+
description: "Response matches sync-event-sources-response.json schema"
|
|
203
|
+
- check: field_present
|
|
204
|
+
path: "event_sources[0].event_source_id"
|
|
205
|
+
description: "First event source has a platform-assigned ID"
|
|
206
|
+
- check: field_present
|
|
207
|
+
path: "event_sources[1].event_source_id"
|
|
208
|
+
description: "Second event source has a platform-assigned ID"
|
|
209
|
+
|
|
210
|
+
- id: create_buy_with_dedup_goal
|
|
211
|
+
title: "Create a performance buy whose goal attaches BOTH event sources"
|
|
212
|
+
narrative: |
|
|
213
|
+
The buyer creates a media buy whose package carries an event-kind
|
|
214
|
+
optimization_goal binding to BOTH the pixel and the CAPI source.
|
|
215
|
+
Target is target_cpa $40 on purchase events; the seller commits to
|
|
216
|
+
deduplicating event_ids across the two sources.
|
|
217
|
+
|
|
218
|
+
steps:
|
|
219
|
+
- id: create_media_buy_dedup
|
|
220
|
+
title: "Create media buy with two event_sources on one goal"
|
|
221
|
+
task: create_media_buy
|
|
222
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
223
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
224
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
225
|
+
stateful: true
|
|
226
|
+
expected: |
|
|
227
|
+
Create the media buy. Response carries a media_buy_id used for
|
|
228
|
+
subsequent log_event and get_media_buy_delivery calls.
|
|
229
|
+
sample_request:
|
|
230
|
+
brand:
|
|
231
|
+
domain: "acmeoutdoor.example"
|
|
232
|
+
account:
|
|
233
|
+
brand:
|
|
234
|
+
domain: "acmeoutdoor.example"
|
|
235
|
+
operator: "pinnacle-agency.example"
|
|
236
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
237
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
238
|
+
packages:
|
|
239
|
+
- product_id: "dedup_performance_q2"
|
|
240
|
+
budget: 20000
|
|
241
|
+
pricing_option_id: "auction_cpm"
|
|
242
|
+
optimization_goals:
|
|
243
|
+
- kind: "event"
|
|
244
|
+
event_sources:
|
|
245
|
+
- event_source_id: "acmeoutdoor_website_pixel"
|
|
246
|
+
event_type: "purchase"
|
|
247
|
+
- event_source_id: "acmeoutdoor_website_capi"
|
|
248
|
+
event_type: "purchase"
|
|
249
|
+
target:
|
|
250
|
+
kind: "cost_per"
|
|
251
|
+
value: 40.00
|
|
252
|
+
priority: 1
|
|
253
|
+
idempotency_key: "$generate:uuid_v4#event_dedup_flow_create_buy_with_dedup_goal_create_media_buy"
|
|
254
|
+
context_outputs:
|
|
255
|
+
- name: media_buy_id
|
|
256
|
+
path: "media_buy_id"
|
|
257
|
+
validations:
|
|
258
|
+
- check: response_schema
|
|
259
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
260
|
+
- check: field_present
|
|
261
|
+
path: "media_buy_id"
|
|
262
|
+
description: "Media buy has a platform-assigned ID"
|
|
263
|
+
|
|
264
|
+
- id: log_same_event_id_from_both_sources
|
|
265
|
+
title: "Log the same event_id from BOTH registered sources"
|
|
266
|
+
narrative: |
|
|
267
|
+
The buyer logs the SAME purchase event_id from the pixel AND from
|
|
268
|
+
the CAPI source. Both calls succeed at the API level — the dedup
|
|
269
|
+
happens in attribution, not ingestion. A seller that rejects the
|
|
270
|
+
second call as a duplicate at the API level is over-claiming
|
|
271
|
+
ingestion-level dedup, which is not what multi_source_event_dedup
|
|
272
|
+
asserts.
|
|
273
|
+
|
|
274
|
+
steps:
|
|
275
|
+
- id: log_event_from_pixel
|
|
276
|
+
title: "Log purchase event from the pixel"
|
|
277
|
+
task: log_event
|
|
278
|
+
schema_ref: "media-buy/log-event-request.json"
|
|
279
|
+
response_schema_ref: "media-buy/log-event-response.json"
|
|
280
|
+
doc_ref: "/media-buy/task-reference/log_event"
|
|
281
|
+
stateful: true
|
|
282
|
+
expected: |
|
|
283
|
+
Acknowledge the event with accepted status.
|
|
284
|
+
sample_request:
|
|
285
|
+
account:
|
|
286
|
+
brand:
|
|
287
|
+
domain: "acmeoutdoor.example"
|
|
288
|
+
operator: "pinnacle-agency.example"
|
|
289
|
+
event_source_id: "acmeoutdoor_website_pixel"
|
|
290
|
+
events:
|
|
291
|
+
- event_type: "purchase"
|
|
292
|
+
event_id: "evt_dedup_001"
|
|
293
|
+
event_time: "2026-06-05T14:30:00Z"
|
|
294
|
+
user_match:
|
|
295
|
+
hashed_email: "a000000000000000000000000000000000000000000000000000000000000010"
|
|
296
|
+
custom_data:
|
|
297
|
+
order_total: 199.99
|
|
298
|
+
currency: "USD"
|
|
299
|
+
idempotency_key: "$generate:uuid_v4#event_dedup_flow_log_same_event_id_from_both_sources_log_event_pixel"
|
|
300
|
+
validations:
|
|
301
|
+
- check: response_schema
|
|
302
|
+
description: "Response matches log-event-response.json schema"
|
|
303
|
+
|
|
304
|
+
- id: log_event_from_capi
|
|
305
|
+
title: "Log the SAME event_id from the CAPI source"
|
|
306
|
+
task: log_event
|
|
307
|
+
schema_ref: "media-buy/log-event-request.json"
|
|
308
|
+
response_schema_ref: "media-buy/log-event-response.json"
|
|
309
|
+
doc_ref: "/media-buy/task-reference/log_event"
|
|
310
|
+
stateful: true
|
|
311
|
+
expected: |
|
|
312
|
+
Acknowledge the event with accepted status. The seller MUST NOT
|
|
313
|
+
reject this as a duplicate at the API level — dedup is an
|
|
314
|
+
attribution-time concern, asserted via the totals.conversions
|
|
315
|
+
check in the next phase.
|
|
316
|
+
sample_request:
|
|
317
|
+
account:
|
|
318
|
+
brand:
|
|
319
|
+
domain: "acmeoutdoor.example"
|
|
320
|
+
operator: "pinnacle-agency.example"
|
|
321
|
+
event_source_id: "acmeoutdoor_website_capi"
|
|
322
|
+
events:
|
|
323
|
+
- event_type: "purchase"
|
|
324
|
+
event_id: "evt_dedup_001"
|
|
325
|
+
event_time: "2026-06-05T14:30:00Z"
|
|
326
|
+
user_match:
|
|
327
|
+
hashed_email: "a000000000000000000000000000000000000000000000000000000000000010"
|
|
328
|
+
custom_data:
|
|
329
|
+
order_total: 199.99
|
|
330
|
+
currency: "USD"
|
|
331
|
+
idempotency_key: "$generate:uuid_v4#event_dedup_flow_log_same_event_id_from_both_sources_log_event_capi"
|
|
332
|
+
validations:
|
|
333
|
+
- check: response_schema
|
|
334
|
+
description: "Response matches log-event-response.json schema"
|
|
335
|
+
|
|
336
|
+
- id: assert_single_attribution
|
|
337
|
+
title: "Delivery reports the deduplicated event ONCE, not twice"
|
|
338
|
+
narrative: |
|
|
339
|
+
The discriminating assertion: get_media_buy_delivery surfaces
|
|
340
|
+
totals.conversions equal to the count of unique event_ids attributed
|
|
341
|
+
to the buy. simulate_delivery injects conversions: 1 reflecting the
|
|
342
|
+
single unique event_id; the seller's response totals.conversions must
|
|
343
|
+
equal 1, not 2. If the seller failed to dedup, the cumulative count
|
|
344
|
+
would double-count and the assertion fails.
|
|
345
|
+
|
|
346
|
+
steps:
|
|
347
|
+
- id: simulate_deduplicated_delivery
|
|
348
|
+
title: "Inject impressions + ONE attributed conversion"
|
|
349
|
+
task: comply_test_controller
|
|
350
|
+
requires_tool: comply_test_controller
|
|
351
|
+
stateful: true
|
|
352
|
+
expected: |
|
|
353
|
+
The test controller acknowledges the simulated delivery with the
|
|
354
|
+
deduplicated conversion count (1, not 2 — the same event_id from
|
|
355
|
+
two sources is one conversion).
|
|
356
|
+
sample_request:
|
|
357
|
+
account:
|
|
358
|
+
sandbox: true
|
|
359
|
+
scenario: "simulate_delivery"
|
|
360
|
+
params:
|
|
361
|
+
media_buy_id: "$context.media_buy_id"
|
|
362
|
+
impressions: 150000
|
|
363
|
+
clicks: 3200
|
|
364
|
+
conversions: 1
|
|
365
|
+
reported_spend:
|
|
366
|
+
amount: 2400.00
|
|
367
|
+
currency: "USD"
|
|
368
|
+
validations:
|
|
369
|
+
- check: field_value
|
|
370
|
+
path: "success"
|
|
371
|
+
allowed_values: [true]
|
|
372
|
+
description: "Delivery simulation succeeds"
|
|
373
|
+
|
|
374
|
+
- id: get_dedup_delivery
|
|
375
|
+
title: "Get delivery and verify single conversion attribution"
|
|
376
|
+
task: get_media_buy_delivery
|
|
377
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
378
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
379
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
380
|
+
stateful: true
|
|
381
|
+
expected: |
|
|
382
|
+
Delivery response includes totals.conversions equal to 1 — the
|
|
383
|
+
same event_id from two registered sources counts once. A seller
|
|
384
|
+
double-counting would report 2 and fail this assertion.
|
|
385
|
+
sample_request:
|
|
386
|
+
account:
|
|
387
|
+
brand:
|
|
388
|
+
domain: "acmeoutdoor.example"
|
|
389
|
+
operator: "pinnacle-agency.example"
|
|
390
|
+
media_buy_ids:
|
|
391
|
+
- "$context.media_buy_id"
|
|
392
|
+
include_package_daily_breakdown: true
|
|
393
|
+
validations:
|
|
394
|
+
- check: response_schema
|
|
395
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
396
|
+
- check: field_value
|
|
397
|
+
path: "media_buy_deliveries[0].totals.conversions"
|
|
398
|
+
value: 1
|
|
399
|
+
description: "Cumulative conversions equals 1 — the same event_id from two sources dedups to one (the discriminating assertion of multi_source_event_dedup)"
|