@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,172 @@
|
|
|
1
|
+
# Rate Limit Trip Runner — Harness Contract Test Kit
|
|
2
|
+
#
|
|
3
|
+
# Applies to:
|
|
4
|
+
# - universal/idempotency.yaml (rate_limit_replay_invariant phase — verifies
|
|
5
|
+
# that a RATE_LIMITED response on idempotency-cache insert MUST NOT be
|
|
6
|
+
# cached as the canonical replay for that key, per
|
|
7
|
+
# L1/security.mdx#idempotency bullet 8 + rule 3 ("Only successful
|
|
8
|
+
# responses are cached")).
|
|
9
|
+
# - Any future storyboard that needs to drive a fresh-key burst until a
|
|
10
|
+
# RATE_LIMITED response appears, then verify a downstream invariant.
|
|
11
|
+
#
|
|
12
|
+
# Storyboards are sequential by default and the storyboard YAML has no
|
|
13
|
+
# loop primitive. This test-kit defines the coordination contract between
|
|
14
|
+
# a runner that can drive a sequential burst of fresh-idempotency-key
|
|
15
|
+
# requests and a storyboard step that needs that capability.
|
|
16
|
+
#
|
|
17
|
+
# The runner's burst happens at the @adcp/client layer (or its Python/Go
|
|
18
|
+
# equivalents) using the SDK's request primitive in a tight sequential
|
|
19
|
+
# loop with a configurable max-attempts ceiling. The storyboard author
|
|
20
|
+
# MUST NOT try to express the burst via separate YAML steps.
|
|
21
|
+
|
|
22
|
+
id: rate_limit_trip_runner
|
|
23
|
+
applies_to:
|
|
24
|
+
universals:
|
|
25
|
+
- idempotency
|
|
26
|
+
|
|
27
|
+
description: |
|
|
28
|
+
Coordination contract between a runner that can drive a fresh-key burst
|
|
29
|
+
until a `RATE_LIMITED` response is observed and a storyboard step that
|
|
30
|
+
needs to verify the replay invariant on the rate-limited key. The runner
|
|
31
|
+
fires up to `max_attempts` sequential requests with fresh
|
|
32
|
+
`idempotency_key` values and otherwise-identical canonical payloads. On
|
|
33
|
+
the first `RATE_LIMITED` response it captures the request's idempotency
|
|
34
|
+
key, sleeps `error.details.retry_after` seconds, and then re-submits the
|
|
35
|
+
same key with the same payload. The cross-step assertion compares the
|
|
36
|
+
replay response against the rate-limit response and fails if the replay
|
|
37
|
+
returned the cached `RATE_LIMITED`.
|
|
38
|
+
|
|
39
|
+
endpoint_scope: sandbox
|
|
40
|
+
# Driving a burst against production would consume rate-limit budget that
|
|
41
|
+
# legitimate traffic relies on and may produce real downstream commitments
|
|
42
|
+
# if any of the sequential requests succeed before the limiter trips.
|
|
43
|
+
# Graders MUST target a sandbox/staging endpoint. Agents claiming the
|
|
44
|
+
# universal SHOULD expose a dedicated grading endpoint whose limiter is
|
|
45
|
+
# configured at the same ceiling as production but whose downstream side
|
|
46
|
+
# effects are sandboxed.
|
|
47
|
+
|
|
48
|
+
harness_mode: black_box
|
|
49
|
+
|
|
50
|
+
# --- Trip mechanism ---
|
|
51
|
+
#
|
|
52
|
+
# The runner fires requests sequentially against a single mutating-op
|
|
53
|
+
# target named by the storyboard step. Each request carries a fresh
|
|
54
|
+
# UUID v4 idempotency_key and an otherwise-identical canonical payload.
|
|
55
|
+
# The runner observes each response and stops when one of:
|
|
56
|
+
#
|
|
57
|
+
# 1. A response with envelope error_code = RATE_LIMITED is observed.
|
|
58
|
+
# The runner captures the request's idempotency_key into the
|
|
59
|
+
# step's context as `rate_limited_key`, captures the response's
|
|
60
|
+
# `error.details.retry_after` as `retry_after_seconds`, captures
|
|
61
|
+
# the rate-limit response body for the replay assertion, and
|
|
62
|
+
# proceeds to the wait + replay phase.
|
|
63
|
+
#
|
|
64
|
+
# 2. `max_attempts` requests complete without producing RATE_LIMITED.
|
|
65
|
+
# The runner grades the step as `not_applicable` with reason
|
|
66
|
+
# `rate_limit_not_triggered` — sellers may legitimately configure
|
|
67
|
+
# a sandbox limiter at a higher ceiling than this contract's
|
|
68
|
+
# max_attempts. The remainder of the storyboard is unaffected.
|
|
69
|
+
#
|
|
70
|
+
# Pacing. The runner fires requests as fast as the transport will accept
|
|
71
|
+
# without artificial throttling — the goal is to exceed the seller's
|
|
72
|
+
# configured insert-rate ceiling within max_attempts. Runners MAY use the
|
|
73
|
+
# SDK's connection pooling but MUST NOT batch via parallel_dispatch (that
|
|
74
|
+
# changes the cross-key timing and risks IDEMPOTENCY_IN_FLIGHT noise on
|
|
75
|
+
# parallel paths). Sequential is the simpler shape and matches what
|
|
76
|
+
# attacker-burst traffic would look like.
|
|
77
|
+
|
|
78
|
+
burst_step_contract:
|
|
79
|
+
required_step_fields:
|
|
80
|
+
- rate_limit_trip.trip_target_task
|
|
81
|
+
- rate_limit_trip.trip_target_sample_request
|
|
82
|
+
- rate_limit_trip.max_attempts
|
|
83
|
+
optional_step_fields:
|
|
84
|
+
- rate_limit_trip.replay_max_wait_seconds
|
|
85
|
+
max_attempts_min: 50
|
|
86
|
+
max_attempts_max: 500
|
|
87
|
+
# 50 ≤ max_attempts ≤ 500. Below 50 won't reliably trip a 60/sec-sustained
|
|
88
|
+
# limiter even with HTTP/2 multiplexing; above 500 inflates runtime
|
|
89
|
+
# materially without improving signal. Storyboards SHOULD start at 200
|
|
90
|
+
# and adjust per observed trip rates in CI.
|
|
91
|
+
|
|
92
|
+
# --- Wait + replay mechanism ---
|
|
93
|
+
#
|
|
94
|
+
# When a RATE_LIMITED is observed the runner reads
|
|
95
|
+
# `error.details.retry_after` (seconds), waits that long (capped by
|
|
96
|
+
# `rate_limit_trip.replay_max_wait_seconds`, default 30), then re-submits
|
|
97
|
+
# the rate-limited request:
|
|
98
|
+
#
|
|
99
|
+
# - Same idempotency_key (the one captured at trip time).
|
|
100
|
+
# - Same canonical payload (the trip_target_sample_request, with the
|
|
101
|
+
# same `$generate:uuid_v4#alias` resolutions as the trip request).
|
|
102
|
+
# - A distinct correlation_id so the replay's response is traceable in
|
|
103
|
+
# runner output.
|
|
104
|
+
#
|
|
105
|
+
# Sellers returning `retry_after` greater than `replay_max_wait_seconds`
|
|
106
|
+
# fail the step on `replay_wait_exceeded` rather than the replay invariant
|
|
107
|
+
# itself — `retry_after` values larger than the runner's wait budget are
|
|
108
|
+
# either a seller-side bug or a production-tuning mismatch with the
|
|
109
|
+
# conformance budget, and either way prevent the invariant from being
|
|
110
|
+
# verified.
|
|
111
|
+
#
|
|
112
|
+
# Sellers returning a `RATE_LIMITED` response without
|
|
113
|
+
# `error.details.retry_after` (or with retry_after = 0) fail with
|
|
114
|
+
# `missing_retry_after` — the retry hint is required to make rate-limit
|
|
115
|
+
# responses actionable, per L1/security.mdx error semantics.
|
|
116
|
+
|
|
117
|
+
# --- Cross-step assertion ---
|
|
118
|
+
#
|
|
119
|
+
# The runner emits a single structured result with three response objects
|
|
120
|
+
# the storyboard validations[] can target:
|
|
121
|
+
#
|
|
122
|
+
# trip_response.<path> The first RATE_LIMITED response observed
|
|
123
|
+
# during the burst.
|
|
124
|
+
# replay_response.<path> The response to the replay request issued
|
|
125
|
+
# after the retry_after wait.
|
|
126
|
+
# rate_limited_request.idempotency_key
|
|
127
|
+
# The key captured at trip time, for traceability.
|
|
128
|
+
#
|
|
129
|
+
# The step's validations declare the invariant against `replay_response`.
|
|
130
|
+
# The minimum required assertion is the not-cached check below; storyboards
|
|
131
|
+
# MAY add further assertions on `replay_response.media_buy_id` (success
|
|
132
|
+
# path) or other handler outputs.
|
|
133
|
+
|
|
134
|
+
replay_invariant_check_kinds:
|
|
135
|
+
- replay_not_cached_rate_limit
|
|
136
|
+
|
|
137
|
+
# `replay_not_cached_rate_limit` semantics: the runner compares
|
|
138
|
+
# `trip_response.error.code` against `replay_response.error.code` (when
|
|
139
|
+
# the replay carries an error envelope) or against the absence of error
|
|
140
|
+
# (when the replay carries a success envelope). If both responses carry
|
|
141
|
+
# error_code = RATE_LIMITED, the replay was served from the idempotency
|
|
142
|
+
# cache and the invariant fails. Any other replay response shape passes
|
|
143
|
+
# the invariant — either the handler succeeded (RATE_LIMITED was not
|
|
144
|
+
# cached, the seller correctly re-executed), or the handler returned a
|
|
145
|
+
# different error (the seller correctly re-executed and a state-dependent
|
|
146
|
+
# error fired).
|
|
147
|
+
|
|
148
|
+
# --- What the contract does NOT cover ---
|
|
149
|
+
#
|
|
150
|
+
# Burst-volume attestation of the 60/300 req/sec ceiling itself. The
|
|
151
|
+
# contract observes whether the limiter exists and behaves correctly under
|
|
152
|
+
# the replay invariant; it does NOT measure the threshold at which the
|
|
153
|
+
# limiter activates. Threshold attestation is structurally non-deterministic
|
|
154
|
+
# in CI environments (runner CPU, network jitter, agent cold-start) and is
|
|
155
|
+
# better evaluated via operator-side load testing or self-attestation.
|
|
156
|
+
#
|
|
157
|
+
# Cross-scope rate-limit leakage. The contract dispatches all requests
|
|
158
|
+
# within a single (authenticated_agent, account) scope. Storyboards needing
|
|
159
|
+
# to verify that one agent's rate-limit budget does not affect another
|
|
160
|
+
# agent's traffic require a separate contract.
|
|
161
|
+
#
|
|
162
|
+
# RATE_LIMITED on read paths. The contract drives mutating-op traffic
|
|
163
|
+
# (where idempotency caching applies). Sellers MAY also rate-limit read
|
|
164
|
+
# operations, but the replay invariant doesn't apply there — reads are
|
|
165
|
+
# inherently safe to retry.
|
|
166
|
+
|
|
167
|
+
# --- Reviewer checks ---
|
|
168
|
+
|
|
169
|
+
reviewer_checks:
|
|
170
|
+
- "Confirm the seller's idempotency-cache implementation explicitly excludes RATE_LIMITED (and other transient-error) responses from the cached-replay path. Review the storage layer or runbook describing which response classes are persisted under idempotency_key."
|
|
171
|
+
- "Confirm the seller's rate-limit response carries a usable retry_after value (seconds, integer, > 0, ≤ a documented ceiling). A seller that returns retry_after values larger than buyers' realistic retry windows produces unusable rate-limit signaling."
|
|
172
|
+
- "Confirm the seller's rate-limit budget is scoped per (authenticated_agent, account) tuple — not shared across all agents or accounts globally — so one agent's burst cannot exhaust another's budget."
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Signed-Requests Runner — Harness Contract Test Kit
|
|
2
|
+
#
|
|
3
|
+
# Applies to: universal/signed-requests.yaml (gated on
|
|
4
|
+
# `request_signing.supported: true` in get_adcp_capabilities).
|
|
5
|
+
#
|
|
6
|
+
# The signed-requests storyboard grades an agent's RFC 9421 verifier against 28
|
|
7
|
+
# conformance vectors at /compliance/{version}/test-vectors/request-signing/.
|
|
8
|
+
# Most vectors are pure black-box: the runner constructs a signed HTTP request,
|
|
9
|
+
# sends it, and checks the response. Three negative vectors assert behavior that
|
|
10
|
+
# depends on verifier state the runner cannot set from the outside:
|
|
11
|
+
#
|
|
12
|
+
# 016-replayed-nonce — replay cache must already contain (keyid, nonce)
|
|
13
|
+
# 017-key-revoked — keyid must already be in the revocation list
|
|
14
|
+
# 020-rate-abuse — per-keyid replay cache must be at its configured cap
|
|
15
|
+
#
|
|
16
|
+
# This test-kit defines the coordination contract between a black-box runner and
|
|
17
|
+
# a request-signing agent under test. Agents advertising
|
|
18
|
+
# `request_signing.supported: true` MUST pre-configure their verifier per this
|
|
19
|
+
# contract before the negative phase runs. The runner reads this file to know
|
|
20
|
+
# (a) the keyids it will sign with, (b) how to provoke each stateful negative
|
|
21
|
+
# vector, and (c) the grading-time cap values it will target (which are NOT
|
|
22
|
+
# production recommendations — see each field). See `scope` below for what the
|
|
23
|
+
# contract does NOT specify.
|
|
24
|
+
|
|
25
|
+
id: signed_requests_runner
|
|
26
|
+
applies_to:
|
|
27
|
+
universal_storyboard: signed-requests
|
|
28
|
+
|
|
29
|
+
description: |
|
|
30
|
+
Coordination contract between a black-box runner and a request-signing agent
|
|
31
|
+
under test. The runner signs vectors dynamically using the keypairs published
|
|
32
|
+
in keys.json. The agent pre-configures its verifier — accepted JWKS, pre-revoked
|
|
33
|
+
keyid, replay TTL, per-keyid cap — so that the three stateful negative vectors
|
|
34
|
+
produce their expected error codes without the runner injecting verifier state.
|
|
35
|
+
|
|
36
|
+
Vectors requiring coordination declare `requires_contract` in their fixture;
|
|
37
|
+
the runner gates those vectors on this contract being in scope.
|
|
38
|
+
|
|
39
|
+
endpoint_scope: sandbox
|
|
40
|
+
# The replay-window contract sends a live, validly-signed mutating request as
|
|
41
|
+
# its first step (the second copy is what the grader expects to be rejected).
|
|
42
|
+
# Running this against a production endpoint would create a real media buy.
|
|
43
|
+
# Graders MUST target a sandbox/staging endpoint or an idempotency-keyed
|
|
44
|
+
# sacrificial path the agent discards post-grading. Agents advertising
|
|
45
|
+
# `request_signing.supported: true` SHOULD expose a dedicated grading endpoint
|
|
46
|
+
# rather than grading in prod.
|
|
47
|
+
|
|
48
|
+
harness_mode: black_box
|
|
49
|
+
# Agents participating in a white-box test harness (e.g., SDK internal tests
|
|
50
|
+
# against the reference verifier) MAY satisfy the stateful vectors via direct
|
|
51
|
+
# state injection using the vector's `test_harness_state` block, and declare
|
|
52
|
+
# `harness_mode: white_box` in their own runner configuration. AdCP Verified
|
|
53
|
+
# grading runs in black_box mode only.
|
|
54
|
+
|
|
55
|
+
runner_signing_keys:
|
|
56
|
+
# Runner signs every non-negative-key vector with one of these keypairs. The
|
|
57
|
+
# agent's verifier MUST treat these keyids as a registered test counterparty
|
|
58
|
+
# whose JWKS contains the corresponding public keys with
|
|
59
|
+
# adcp_use: "request-signing". Private keys for signing live in keys.json
|
|
60
|
+
# under `_private_d_for_test_only`.
|
|
61
|
+
- keyid: test-ed25519-2026
|
|
62
|
+
alg: ed25519
|
|
63
|
+
jwks_source: /compliance/{version}/test-vectors/request-signing/keys.json
|
|
64
|
+
- keyid: test-es256-2026
|
|
65
|
+
alg: ecdsa-p256-sha256
|
|
66
|
+
jwks_source: /compliance/{version}/test-vectors/request-signing/keys.json
|
|
67
|
+
|
|
68
|
+
stateful_vector_contract:
|
|
69
|
+
replay_window:
|
|
70
|
+
# Vector 016-replayed-nonce.
|
|
71
|
+
#
|
|
72
|
+
# The runner provokes the replay rejection by sending the same signed
|
|
73
|
+
# request twice in sequence. The agent MUST accept the first submission
|
|
74
|
+
# (standard positive path) and reject the second with
|
|
75
|
+
# request_signature_replayed at checklist step 12.
|
|
76
|
+
#
|
|
77
|
+
# The agent's replay-cache TTL for this test counterparty MUST be at least
|
|
78
|
+
# `min_replay_ttl_seconds`, which is strictly greater than
|
|
79
|
+
# `max_interval_seconds` to absorb clock skew between runner and agent and
|
|
80
|
+
# scheduler jitter on either side. Otherwise the cache entry for the first
|
|
81
|
+
# request may evict before the second arrives and the vector will pass
|
|
82
|
+
# spuriously (i.e., both requests accepted = no replay rejection). The
|
|
83
|
+
# runner's own interval between the two submissions MUST NOT exceed
|
|
84
|
+
# `max_interval_seconds`.
|
|
85
|
+
#
|
|
86
|
+
# This supersedes vector 016's `test_harness_state.replay_cache_entries`
|
|
87
|
+
# for black-box mode. In white-box mode, the harness MAY inject the cache
|
|
88
|
+
# entry directly and skip the first request.
|
|
89
|
+
vector_id: 016-replayed-nonce
|
|
90
|
+
black_box_behavior: repeat_request
|
|
91
|
+
max_interval_seconds: 5
|
|
92
|
+
min_replay_ttl_seconds: 10
|
|
93
|
+
|
|
94
|
+
revocation:
|
|
95
|
+
# Vector 017-key-revoked.
|
|
96
|
+
#
|
|
97
|
+
# The runner cannot revoke a key on the agent's side. The agent MUST
|
|
98
|
+
# pre-configure its revocation list with `test-revoked-2026` before the
|
|
99
|
+
# negative phase runs. The runner signs vector 017 with this keyid and
|
|
100
|
+
# expects request_signature_key_revoked at checklist step 9.
|
|
101
|
+
#
|
|
102
|
+
# A dedicated revoked keypair (rather than reusing a runner signing key)
|
|
103
|
+
# keeps positive vectors and vector 017 independent: the positive phase
|
|
104
|
+
# remains runnable after vector 017 is graded.
|
|
105
|
+
vector_id: 017-key-revoked
|
|
106
|
+
pre_revoked_keyid: test-revoked-2026
|
|
107
|
+
|
|
108
|
+
rate_abuse:
|
|
109
|
+
# Vector 020-rate-abuse (checklist step 9a).
|
|
110
|
+
#
|
|
111
|
+
# The runner sends N+1 distinct-nonce requests signed by the same keyid
|
|
112
|
+
# within the window. The agent MUST reject the (N+1)th with
|
|
113
|
+
# request_signature_rate_abuse once the per-keyid cap is hit.
|
|
114
|
+
#
|
|
115
|
+
# `grading_target_per_keyid_cap_requests` is the cap the runner will
|
|
116
|
+
# target during grading — NOT a production recommendation. Agents MAY
|
|
117
|
+
# configure a lower cap for the test-kit counterparty only so grading
|
|
118
|
+
# finishes in a reasonable time. Production caps MUST follow the spec
|
|
119
|
+
# recommendation at docs/building/implementation/security.mdx
|
|
120
|
+
# §per-keyid cap (at least 1,000,000 entries per keyid). Implementers
|
|
121
|
+
# copying a value from this file into production code SHOULD use
|
|
122
|
+
# `production_min_per_keyid_cap_requests` below as the floor, not
|
|
123
|
+
# `grading_target_per_keyid_cap_requests`.
|
|
124
|
+
vector_id: 020-rate-abuse
|
|
125
|
+
grading_target_per_keyid_cap_requests: 100
|
|
126
|
+
production_min_per_keyid_cap_requests: 1000000
|
|
127
|
+
window_seconds: 60
|
|
128
|
+
|
|
129
|
+
scope:
|
|
130
|
+
in_scope: |
|
|
131
|
+
- Keyids the runner will sign with and their JWKS source.
|
|
132
|
+
- Agent-side preconditions for each stateful negative vector.
|
|
133
|
+
- Grading-time cap the runner will target for rate-abuse grading (NOT a
|
|
134
|
+
production recommendation; see rate_abuse block).
|
|
135
|
+
- Minimum replay-cache TTL so the replay-window contract is reliable.
|
|
136
|
+
- Black-box vs. white-box harness mode selection.
|
|
137
|
+
- Endpoint scope (sandbox only — see endpoint_scope).
|
|
138
|
+
out_of_scope: |
|
|
139
|
+
- Specific error-code strings — those live in each vector's
|
|
140
|
+
expected_outcome.error_code and are graded byte-for-byte.
|
|
141
|
+
- Checklist step numbers — informational only; grading is on the error
|
|
142
|
+
code, not the step.
|
|
143
|
+
- Pre-signed Signature bytes in the vectors — unchanged by this contract.
|
|
144
|
+
Black-box runners re-sign dynamically; pre-signed bytes remain valid
|
|
145
|
+
for white-box cross-SDK byte-equivalence checks.
|
|
146
|
+
- The agent's internal replay TTL or cap storage mechanism — the contract
|
|
147
|
+
specifies observable behavior, not implementation.
|
|
148
|
+
- Production verifier configuration — this contract configures a test
|
|
149
|
+
counterparty only.
|
|
150
|
+
|
|
151
|
+
references:
|
|
152
|
+
universal_storyboard: static/compliance/source/universal/signed-requests.yaml
|
|
153
|
+
test_vectors: /compliance/{version}/test-vectors/request-signing/
|
|
154
|
+
verifier_checklist: /docs/building/by-layer/L1/security.mdx#verifier-checklist-requests
|
|
155
|
+
runner_implementation: https://github.com/adcontextprotocol/adcp-client/issues/585
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Single-Side Trust Runner — Harness Contract Test Kit
|
|
2
|
+
#
|
|
3
|
+
# Applies to:
|
|
4
|
+
# - protocols/brand/scenarios/single_side_trust_extension.yaml
|
|
5
|
+
#
|
|
6
|
+
# The single-side-trust scenario is a partner-conformance red test. Unlike
|
|
7
|
+
# every other storyboard in the corpus today — which grades an agent serving
|
|
8
|
+
# verify_brand_claim — this scenario grades a CONSUMER of verify_brand_claim.
|
|
9
|
+
# The subject under test is a partner that may extend governance trust (auto-
|
|
10
|
+
# provision a member account, propagate billable seat inclusion, inherit
|
|
11
|
+
# governance posture) based on what verify_brand_claim returns. The red test
|
|
12
|
+
# asserts the asymmetric trust rule from
|
|
13
|
+
# /docs/brand-protocol/tasks/verify_brand_claim §"The trust rule — two calls,
|
|
14
|
+
# not one": a single signed `owned` response is NOT trust-extending.
|
|
15
|
+
#
|
|
16
|
+
# This is a framework extension. The conformance corpus today drives an agent
|
|
17
|
+
# under test and grades its response. Grading a consumer-side trust decision
|
|
18
|
+
# requires:
|
|
19
|
+
#
|
|
20
|
+
# 1. The runner hosts fixture brand-agents (a malicious house signing
|
|
21
|
+
# `owned` for relationships it does not legitimately have) plus the
|
|
22
|
+
# static brand.json files that should — under the spec — fail to
|
|
23
|
+
# reciprocate.
|
|
24
|
+
#
|
|
25
|
+
# 2. The runner exercises the partner under test through whatever surface
|
|
26
|
+
# that partner exposes for "evaluate a verify_brand_claim response and
|
|
27
|
+
# decide whether to extend trust" — the partner advertises this surface
|
|
28
|
+
# via comply_test_controller (scenario name
|
|
29
|
+
# `evaluate_verify_brand_claim_trust_extension`, defined below). Partners
|
|
30
|
+
# that do not advertise it grade the scenario `not_applicable`.
|
|
31
|
+
#
|
|
32
|
+
# 3. The runner queries the partner's comply_test_controller
|
|
33
|
+
# `query_upstream_traffic` to confirm:
|
|
34
|
+
# - The partner DID call leaf-side reciprocation (positive assertion:
|
|
35
|
+
# `min_count: 1` against a `GET *.well-known/brand.json` pattern on
|
|
36
|
+
# the leaf, OR a verify_brand_claim call with `claim_type: "parent"`
|
|
37
|
+
# on a leaf-side brand-agent — when one exists).
|
|
38
|
+
# - The partner did NOT extend trust (negative assertion: `min_count: 0`
|
|
39
|
+
# against governance-trust-extension endpoint patterns the partner
|
|
40
|
+
# declares via this contract).
|
|
41
|
+
#
|
|
42
|
+
# Runner-side implementation is pending. Until adcp-client lands the consumer-
|
|
43
|
+
# under-test dispatch primitive, scenario steps grade `not_applicable` via
|
|
44
|
+
# their `requires_contract: single_side_trust_runner` declaration. This file
|
|
45
|
+
# documents the contract so the dispatch can be implemented against a stable
|
|
46
|
+
# fixture surface.
|
|
47
|
+
|
|
48
|
+
id: single_side_trust_runner
|
|
49
|
+
applies_to:
|
|
50
|
+
protocol_scenarios:
|
|
51
|
+
- single_side_trust_extension
|
|
52
|
+
|
|
53
|
+
description: |
|
|
54
|
+
Coordination contract between a black-box runner and a partner under test
|
|
55
|
+
whose responsibility is to evaluate verify_brand_claim responses and decide
|
|
56
|
+
whether to extend governance trust. The runner hosts the malicious-house
|
|
57
|
+
fixture brand-agent and the non-reciprocating leaf brand.json. The partner
|
|
58
|
+
receives a `verify_brand_claim` invocation through its comply_test_controller
|
|
59
|
+
`evaluate_verify_brand_claim_trust_extension` scenario, performs whatever
|
|
60
|
+
verification the spec mandates, and exposes its outbound HTTP traffic via
|
|
61
|
+
`query_upstream_traffic` for the runner to assert against.
|
|
62
|
+
|
|
63
|
+
endpoint_scope: sandbox
|
|
64
|
+
# The partner under test executes a real verify-and-decide pipeline against
|
|
65
|
+
# the runner-hosted fixtures. Partners MUST NOT run this against any
|
|
66
|
+
# production trust-extension surface; the runner's `owned` responses describe
|
|
67
|
+
# fabricated relationships and any partner that auto-provisions on them in
|
|
68
|
+
# production is the bug this test exists to surface.
|
|
69
|
+
|
|
70
|
+
harness_mode: black_box
|
|
71
|
+
|
|
72
|
+
# --- Fixture brand-agents and static documents the runner hosts ---
|
|
73
|
+
#
|
|
74
|
+
# The runner stands up three fixture surfaces. All use the IANA-reserved
|
|
75
|
+
# `.example` TLD. The runner is the authoritative origin for every URL below
|
|
76
|
+
# during a test run; partners under test resolve these names against the
|
|
77
|
+
# runner's DNS or hosts override per the operator's harness configuration.
|
|
78
|
+
|
|
79
|
+
fixtures:
|
|
80
|
+
malicious_house:
|
|
81
|
+
# A brand-agent at a runner-controlled domain that signs `owned` for
|
|
82
|
+
# arbitrary subsidiary / property / trademark claims. The agent's JWKS is
|
|
83
|
+
# published at the same domain so signature verification succeeds — the
|
|
84
|
+
# point of the red test is that signature validity does NOT confer
|
|
85
|
+
# relationship trust without reciprocation.
|
|
86
|
+
domain: "malicious-house.example"
|
|
87
|
+
brand_agent_url: "https://malicious-house.example/agents/brand"
|
|
88
|
+
jwks_uri: "https://malicious-house.example/.well-known/jwks.json"
|
|
89
|
+
response_signing_keyid: "test-malicious-house-2026"
|
|
90
|
+
# When the runner asks the malicious house's brand-agent any of the
|
|
91
|
+
# supported claim types, it returns `owned` with a freshly signed
|
|
92
|
+
# response. Behavior matrix:
|
|
93
|
+
response_matrix:
|
|
94
|
+
- claim_type: subsidiary
|
|
95
|
+
# Any `claim.subsidiary_domain` returns owned, regardless of whether
|
|
96
|
+
# the leaf actually claims this house as its parent.
|
|
97
|
+
status: owned
|
|
98
|
+
details:
|
|
99
|
+
brand_id: "fabricated_subsidiary"
|
|
100
|
+
- claim_type: property
|
|
101
|
+
# Any `claim.property.identifier` returns owned, regardless of the
|
|
102
|
+
# real registrant of that property.
|
|
103
|
+
status: owned
|
|
104
|
+
details:
|
|
105
|
+
relationship: "owned"
|
|
106
|
+
- claim_type: trademark
|
|
107
|
+
# Returns `licensed_in` claiming a licensor the runner ALSO hosts as
|
|
108
|
+
# a non-reciprocating fixture (see `non_reciprocating_licensor`
|
|
109
|
+
# below).
|
|
110
|
+
status: licensed_in
|
|
111
|
+
details:
|
|
112
|
+
matched_registration: "fabricated-mark-001"
|
|
113
|
+
licensor_domain: "non-reciprocating-licensor.example"
|
|
114
|
+
|
|
115
|
+
non_reciprocating_leaf:
|
|
116
|
+
# A static brand.json hosted at a runner-controlled domain. The brand
|
|
117
|
+
# declares NO `house_domain` (or declares a different parent). No
|
|
118
|
+
# brand-agent is advertised at this domain — reciprocation requires a
|
|
119
|
+
# static crawl. This is the "leaf does not agree" half of the asymmetric
|
|
120
|
+
# trust model.
|
|
121
|
+
domain: "independent-leaf.example"
|
|
122
|
+
brand_json_url: "https://independent-leaf.example/.well-known/brand.json"
|
|
123
|
+
brand_json_shape:
|
|
124
|
+
# The leaf is standalone — no `house_domain` field at all. A spec-
|
|
125
|
+
# conformant consumer that crawls this MUST conclude no relationship
|
|
126
|
+
# exists with malicious-house.example.
|
|
127
|
+
brand_id: "independent_leaf"
|
|
128
|
+
names:
|
|
129
|
+
- { locale: "en", value: "Independent Leaf" }
|
|
130
|
+
house_domain: null
|
|
131
|
+
|
|
132
|
+
non_reciprocating_licensor:
|
|
133
|
+
# A static brand.json for the trademark licensed_in variant. The
|
|
134
|
+
# malicious house claims `licensed_in` from this licensor; the licensor
|
|
135
|
+
# does NOT publish a matching `licensed_out` for the mark. Per the
|
|
136
|
+
# trademark trust rule, partners SHOULD treat `licensed_in` as
|
|
137
|
+
# unverified until the licensor reciprocates.
|
|
138
|
+
domain: "non-reciprocating-licensor.example"
|
|
139
|
+
brand_json_url: "https://non-reciprocating-licensor.example/.well-known/brand.json"
|
|
140
|
+
brand_json_shape:
|
|
141
|
+
brand_id: "non_reciprocating_licensor"
|
|
142
|
+
names:
|
|
143
|
+
- { locale: "en", value: "Non-Reciprocating Licensor" }
|
|
144
|
+
# No trademarks[] entry naming malicious-house.example as a licensee.
|
|
145
|
+
trademarks: []
|
|
146
|
+
|
|
147
|
+
non_reciprocating_property_owner:
|
|
148
|
+
# A static brand.json for the property variant. The runner exposes a
|
|
149
|
+
# property identifier (a website) the malicious house claims `owned`,
|
|
150
|
+
# but the property's actual owning brand publishes a brand.json that
|
|
151
|
+
# does NOT include the property in its `properties[]`.
|
|
152
|
+
domain: "real-property-owner.example"
|
|
153
|
+
brand_json_url: "https://real-property-owner.example/.well-known/brand.json"
|
|
154
|
+
property_under_test:
|
|
155
|
+
type: "website"
|
|
156
|
+
identifier: "real-property-owner.example"
|
|
157
|
+
brand_json_shape:
|
|
158
|
+
brand_id: "real_property_owner"
|
|
159
|
+
names:
|
|
160
|
+
- { locale: "en", value: "Real Property Owner" }
|
|
161
|
+
# The property is listed here under the real owner, NOT under the
|
|
162
|
+
# malicious house's `owned` claim.
|
|
163
|
+
properties:
|
|
164
|
+
- { type: "website", identifier: "real-property-owner.example" }
|
|
165
|
+
|
|
166
|
+
# --- Consumer-under-test dispatch contract ---
|
|
167
|
+
#
|
|
168
|
+
# The runner drives the partner under test via its comply_test_controller.
|
|
169
|
+
# The partner MUST advertise this scenario in its `list_scenarios` response
|
|
170
|
+
# to participate; partners that do not advertise it grade the scenario
|
|
171
|
+
# `not_applicable` (not failed) — the scenario is opt-in by partner
|
|
172
|
+
# capability, matching the upstream_traffic convention documented in
|
|
173
|
+
# storyboard-schema.yaml > authored_check_kinds.
|
|
174
|
+
#
|
|
175
|
+
# The contract is forward-looking: today no partner implements this
|
|
176
|
+
# controller scenario, and runner support is pending. Partners that want to
|
|
177
|
+
# claim conformance against this red test register support here.
|
|
178
|
+
|
|
179
|
+
consumer_test_controller_scenario:
|
|
180
|
+
name: evaluate_verify_brand_claim_trust_extension
|
|
181
|
+
request_shape:
|
|
182
|
+
# Variant the runner is exercising.
|
|
183
|
+
variant: subsidiary | property | trademark_licensed_in
|
|
184
|
+
# The malicious-house brand-agent URL the partner should call
|
|
185
|
+
# verify_brand_claim against.
|
|
186
|
+
brand_agent_url: "<runner-supplied URL from fixtures.malicious_house>"
|
|
187
|
+
# The claim payload the partner should pass.
|
|
188
|
+
claim:
|
|
189
|
+
# Shape varies by variant — matches verify-brand-claim-request.json
|
|
190
|
+
# discriminator arms.
|
|
191
|
+
claim_type: subsidiary | property | trademark
|
|
192
|
+
claim: { ... }
|
|
193
|
+
# Optional account context. Partners that only auto-provision under
|
|
194
|
+
# an authenticated account context use this to scope the test to that
|
|
195
|
+
# path.
|
|
196
|
+
requesting_account:
|
|
197
|
+
brand:
|
|
198
|
+
domain: "<runner-supplied partner-controlled account domain>"
|
|
199
|
+
operator: "<runner-supplied operator>"
|
|
200
|
+
|
|
201
|
+
expected_partner_behavior:
|
|
202
|
+
# The partner MUST call verify_brand_claim on brand_agent_url.
|
|
203
|
+
# The partner MUST then EITHER:
|
|
204
|
+
# (a) crawl the leaf's static brand.json for reciprocation, OR
|
|
205
|
+
# (b) call a leaf-side brand-agent's verify_brand_claim with
|
|
206
|
+
# claim_type: "parent" — if the leaf advertises one (in this
|
|
207
|
+
# contract's fixtures, none does, forcing path (a)).
|
|
208
|
+
# The partner MUST NOT extend governance trust on the strength of the
|
|
209
|
+
# malicious-house's signed `owned` alone.
|
|
210
|
+
|
|
211
|
+
# --- Upstream-traffic assertions the runner applies ---
|
|
212
|
+
#
|
|
213
|
+
# After dispatching the scenario, the runner queries the partner's
|
|
214
|
+
# comply_test_controller `query_upstream_traffic` and applies these
|
|
215
|
+
# assertions. See storyboard-schema.yaml > `upstream_traffic` for the
|
|
216
|
+
# check primitives.
|
|
217
|
+
|
|
218
|
+
upstream_traffic_contract:
|
|
219
|
+
reciprocation_call_observed:
|
|
220
|
+
# POSITIVE assertion. The partner MUST have called either the leaf's
|
|
221
|
+
# static brand.json or a leaf-side brand-agent's verify_brand_claim
|
|
222
|
+
# (claim_type: "parent" / property crawl / licensor reciprocation,
|
|
223
|
+
# depending on variant).
|
|
224
|
+
min_count: 1
|
|
225
|
+
endpoint_pattern_by_variant:
|
|
226
|
+
subsidiary: "GET *://independent-leaf.example/.well-known/brand.json"
|
|
227
|
+
property: "GET *://real-property-owner.example/.well-known/brand.json"
|
|
228
|
+
trademark_licensed_in: "GET *://non-reciprocating-licensor.example/.well-known/brand.json"
|
|
229
|
+
|
|
230
|
+
trust_extension_not_taken:
|
|
231
|
+
# NEGATIVE assertion. The partner MUST NOT have extended governance
|
|
232
|
+
# trust on the malicious house's response alone. Partners declare the
|
|
233
|
+
# endpoint patterns that represent trust-extension side effects in
|
|
234
|
+
# their own conformance config; the runner exercises a closed set:
|
|
235
|
+
min_count: 0
|
|
236
|
+
candidate_endpoint_patterns:
|
|
237
|
+
# The partner is configured (out of band, when registering for this
|
|
238
|
+
# red test) to surface trust-extension side effects through one of
|
|
239
|
+
# these well-known patterns OR through a partner-declared list
|
|
240
|
+
# carried alongside its list_scenarios response. The runner asserts
|
|
241
|
+
# NONE of these fire during the test window.
|
|
242
|
+
- "POST */governance/auto-provision"
|
|
243
|
+
- "POST */accounts/auto-create-member"
|
|
244
|
+
- "POST */governance/contexts"
|
|
245
|
+
- "POST */billing/seats/auto-add"
|
|
246
|
+
|
|
247
|
+
# --- Identifier echo for anti-façade ---
|
|
248
|
+
#
|
|
249
|
+
# To raise the bar against partners that satisfy the controller scenario
|
|
250
|
+
# without actually performing the upstream calls, the runner injects a
|
|
251
|
+
# load-bearing identifier (a per-run nonce) into the malicious-house's
|
|
252
|
+
# response_signing keyid path or the claim payload's `subsidiary_brand_id`
|
|
253
|
+
# field. The reciprocation call MUST carry that identifier verbatim — a
|
|
254
|
+
# façade that fabricates an empty traffic record cannot satisfy the
|
|
255
|
+
# `identifier_paths` echo check.
|
|
256
|
+
|
|
257
|
+
identifier_echo:
|
|
258
|
+
nonce_injection_field:
|
|
259
|
+
subsidiary: "claim.subsidiary_brand_id"
|
|
260
|
+
property: "claim.property.identifier"
|
|
261
|
+
trademark_licensed_in: "claim.mark"
|
|
262
|
+
identifier_paths_in_reciprocation_request:
|
|
263
|
+
# The runner asserts the leaf-side fetch (whether brand.json crawl or
|
|
264
|
+
# verify_brand_claim with claim_type: "parent") carries the same
|
|
265
|
+
# identifier value at the appropriate path.
|
|
266
|
+
subsidiary: "<HTTP path component containing the leaf domain>"
|
|
267
|
+
property: "<HTTP path component containing the property identifier>"
|
|
268
|
+
trademark_licensed_in: "<HTTP path component containing the licensor domain>"
|
|
269
|
+
|
|
270
|
+
scope:
|
|
271
|
+
in_scope: |
|
|
272
|
+
- Fixture brand-agent endpoints (URLs, JWKS, signing keyids).
|
|
273
|
+
- Fixture static brand.json shapes that fail reciprocation.
|
|
274
|
+
- The consumer-test-controller scenario name and request shape the
|
|
275
|
+
runner uses to dispatch the partner under test.
|
|
276
|
+
- The endpoint patterns the runner asserts on via query_upstream_traffic.
|
|
277
|
+
- Identifier echo paths for anti-façade verification.
|
|
278
|
+
out_of_scope: |
|
|
279
|
+
- The partner's specific trust-extension implementation (account-
|
|
280
|
+
auto-provisioning, governance-context creation, billable seat
|
|
281
|
+
inclusion, etc.). The contract names the side-effect patterns it
|
|
282
|
+
asserts on; how the partner internally wires trust extension is
|
|
283
|
+
partner-specific.
|
|
284
|
+
- Runner-side dispatch implementation. Tracked separately when
|
|
285
|
+
partner adoption reaches a quorum — until then, scenario steps
|
|
286
|
+
grade not_applicable via `requires_contract`.
|
|
287
|
+
- Real-world brand domains. Every fixture domain is on the
|
|
288
|
+
IANA-reserved `.example` TLD.
|
|
289
|
+
|
|
290
|
+
references:
|
|
291
|
+
scenario: static/compliance/source/protocols/brand/scenarios/single_side_trust_extension.yaml
|
|
292
|
+
task_spec: /brand-protocol/tasks/verify_brand_claim
|
|
293
|
+
trust_model: /brand-protocol/brand-json#agent-augmented-verification
|
|
294
|
+
source_issue: https://github.com/adcontextprotocol/adcp/issues/4597
|