@adcp/sdk 6.9.0 → 6.11.0
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/bin/adcp.js +285 -5
- package/compliance/cache/3.0.6.previous/domains/brand/index.yaml +163 -0
- package/compliance/cache/3.0.6.previous/domains/creative/index.yaml +412 -0
- package/compliance/cache/3.0.6.previous/domains/governance/index.yaml +683 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/creative-reception.yaml +247 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/index.yaml +769 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/create_media_buy_async.yaml +232 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +414 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/delivery_reporting.yaml +205 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_approved.yaml +211 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_conditions.yaml +196 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_denied.yaml +192 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/governance_denied_recovery.yaml +244 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/invalid_transitions.yaml +284 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/inventory_list_no_match.yaml +143 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/inventory_list_targeting.yaml +271 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/measurement_terms_rejected.yaml +195 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/pending_creatives_to_start.yaml +250 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/proposal_finalize.yaml +243 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.0.6.previous/domains/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.0.6.previous/domains/signals/index.yaml +266 -0
- package/compliance/cache/3.0.6.previous/domains/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.0.6.previous/index.json +324 -0
- package/compliance/cache/3.0.6.previous/protocols/brand/index.yaml +163 -0
- package/compliance/cache/3.0.6.previous/protocols/creative/index.yaml +412 -0
- package/compliance/cache/3.0.6.previous/protocols/governance/index.yaml +683 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/creative-reception.yaml +247 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/index.yaml +769 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/create_media_buy_async.yaml +232 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +414 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/delivery_reporting.yaml +205 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_approved.yaml +211 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_conditions.yaml +196 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_denied.yaml +192 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/governance_denied_recovery.yaml +244 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/invalid_transitions.yaml +284 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/inventory_list_no_match.yaml +143 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/inventory_list_targeting.yaml +271 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +195 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +250 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/proposal_finalize.yaml +243 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.0.6.previous/protocols/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.0.6.previous/protocols/signals/index.yaml +266 -0
- package/compliance/cache/3.0.6.previous/protocols/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.0.6.previous/specialisms/audience-sync/index.yaml +280 -0
- package/compliance/cache/3.0.6.previous/specialisms/brand-rights/index.yaml +350 -0
- package/compliance/cache/3.0.6.previous/specialisms/brand-rights/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.0.6.previous/specialisms/collection-lists/index.yaml +359 -0
- package/compliance/cache/3.0.6.previous/specialisms/content-standards/index.yaml +572 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-ad-server/index.yaml +383 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-generative/generative-seller.yaml +758 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-generative/index.yaml +746 -0
- package/compliance/cache/3.0.6.previous/specialisms/creative-template/index.yaml +413 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-aware-seller/index.yaml +136 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-delivery-monitor/index.yaml +441 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-spend-authority/denied.yaml +221 -0
- package/compliance/cache/3.0.6.previous/specialisms/governance-spend-authority/index.yaml +330 -0
- package/compliance/cache/3.0.6.previous/specialisms/property-lists/index.yaml +482 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-broadcast-tv/index.yaml +689 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-catalog-driven/index.yaml +779 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-guaranteed/index.yaml +504 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-non-guaranteed/index.yaml +428 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-proposal-mode/index.yaml +520 -0
- package/compliance/cache/3.0.6.previous/specialisms/sales-social/index.yaml +584 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-marketplace/index.yaml +415 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-marketplace/scenarios/governance_denied.yaml +207 -0
- package/compliance/cache/3.0.6.previous/specialisms/signal-owned/index.yaml +316 -0
- package/compliance/cache/3.0.6.previous/test-kits/acme-outdoor.yaml +210 -0
- package/compliance/cache/3.0.6.previous/test-kits/bistro-oranje.yaml +126 -0
- package/compliance/cache/3.0.6.previous/test-kits/nova-motors.yaml +262 -0
- package/compliance/cache/3.0.6.previous/test-kits/osei-natural.yaml +126 -0
- package/compliance/cache/3.0.6.previous/test-kits/signed-requests-runner.yaml +155 -0
- package/compliance/cache/3.0.6.previous/test-kits/substitution-observer-runner.yaml +690 -0
- package/compliance/cache/3.0.6.previous/test-kits/summit-foods.yaml +125 -0
- package/compliance/cache/3.0.6.previous/test-kits/webhook-receiver-runner.yaml +265 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/001-minimal-plan.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/002-full-plan.json +217 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/README.md +219 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/canonicalization.json +241 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/keys.json +60 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/001-basic-post.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/003-es256-post.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/README.md +211 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/keys.json +61 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
- package/compliance/cache/3.0.6.previous/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
- package/compliance/cache/3.0.6.previous/universal/capability-discovery.yaml +125 -0
- package/compliance/cache/3.0.6.previous/universal/collection-lists-pagination-integrity.yaml +306 -0
- package/compliance/cache/3.0.6.previous/universal/content-standards-pagination-integrity.yaml +326 -0
- package/compliance/cache/3.0.6.previous/universal/deterministic-testing.yaml +1343 -0
- package/compliance/cache/3.0.6.previous/universal/error-compliance.yaml +474 -0
- package/compliance/cache/3.0.6.previous/universal/fictional-entities.yaml +307 -0
- package/compliance/cache/3.0.6.previous/universal/get-media-buys-pagination-integrity.yaml +160 -0
- package/compliance/cache/3.0.6.previous/universal/get-signals-pagination-integrity.yaml +211 -0
- package/compliance/cache/3.0.6.previous/universal/idempotency.yaml +593 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity-creative-formats.yaml +258 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity-list-accounts.yaml +262 -0
- package/compliance/cache/3.0.6.previous/universal/pagination-integrity.yaml +263 -0
- package/compliance/cache/3.0.6.previous/universal/property-lists-pagination-integrity.yaml +307 -0
- package/compliance/cache/3.0.6.previous/universal/runner-output-contract.yaml +358 -0
- package/compliance/cache/3.0.6.previous/universal/schema-validation.yaml +526 -0
- package/compliance/cache/3.0.6.previous/universal/security.yaml +431 -0
- package/compliance/cache/3.0.6.previous/universal/signed-requests.yaml +205 -0
- package/compliance/cache/3.0.6.previous/universal/storyboard-schema.yaml +1176 -0
- package/compliance/cache/3.0.6.previous/universal/v3-envelope-integrity.yaml +106 -0
- package/compliance/cache/3.0.6.previous/universal/webhook-emission.yaml +337 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.ts +33 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +127 -1
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/credential-policy.d.ts +221 -0
- package/dist/lib/server/credential-policy.d.ts.map +1 -0
- package/dist/lib/server/credential-policy.js +260 -0
- package/dist/lib/server/credential-policy.js.map +1 -0
- package/dist/lib/server/decisioning/async-outcome.d.ts +17 -0
- package/dist/lib/server/decisioning/async-outcome.d.ts.map +1 -1
- package/dist/lib/server/decisioning/async-outcome.js +23 -18
- package/dist/lib/server/decisioning/async-outcome.js.map +1 -1
- package/dist/lib/server/decisioning/context.d.ts +8 -2
- package/dist/lib/server/decisioning/context.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.d.ts +1 -0
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +6 -4
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +5 -2
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts +5 -0
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.js +4 -1
- package/dist/lib/server/decisioning/runtime/task-registry.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.js +10 -2
- package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
- package/dist/lib/server/dynamic-registry.d.ts +219 -0
- package/dist/lib/server/dynamic-registry.d.ts.map +1 -0
- package/dist/lib/server/dynamic-registry.js +245 -0
- package/dist/lib/server/dynamic-registry.js.map +1 -0
- package/dist/lib/server/index.d.ts +8 -0
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +15 -4
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/operational-platform.d.ts +239 -0
- package/dist/lib/server/operational-platform.d.ts.map +1 -0
- package/dist/lib/server/operational-platform.js +94 -0
- package/dist/lib/server/operational-platform.js.map +1 -0
- package/dist/lib/server/test-controller.d.ts +2 -0
- package/dist/lib/server/test-controller.d.ts.map +1 -1
- package/dist/lib/server/test-controller.js +6 -11
- package/dist/lib/server/test-controller.js.map +1 -1
- package/dist/lib/server/wire-safe.d.ts +211 -0
- package/dist/lib/server/wire-safe.d.ts.map +1 -0
- package/dist/lib/server/wire-safe.js +231 -0
- package/dist/lib/server/wire-safe.js.map +1 -0
- package/dist/lib/server/wire-spec-fields.generated.d.ts +168 -0
- package/dist/lib/server/wire-spec-fields.generated.d.ts.map +1 -0
- package/dist/lib/server/wire-spec-fields.generated.js +172 -0
- package/dist/lib/server/wire-spec-fields.generated.js.map +1 -0
- package/dist/lib/testing/compliance/index.d.ts +2 -0
- package/dist/lib/testing/compliance/index.d.ts.map +1 -1
- package/dist/lib/testing/compliance/index.js +6 -1
- package/dist/lib/testing/compliance/index.js.map +1 -1
- package/dist/lib/testing/compliance/summary.d.ts +77 -0
- package/dist/lib/testing/compliance/summary.d.ts.map +1 -0
- package/dist/lib/testing/compliance/summary.js +176 -0
- package/dist/lib/testing/compliance/summary.js.map +1 -0
- package/dist/lib/testing/comply-controller.d.ts +2 -0
- package/dist/lib/testing/comply-controller.d.ts.map +1 -1
- package/dist/lib/testing/comply-controller.js.map +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts +26 -0
- package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/compliance.js +51 -0
- package/dist/lib/testing/storyboard/compliance.js.map +1 -1
- package/dist/lib/testing/storyboard/index.d.ts +2 -2
- package/dist/lib/testing/storyboard/index.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/index.js +4 -2
- package/dist/lib/testing/storyboard/index.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +58 -5
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
id: creative_generative
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Generative creative agent"
|
|
4
|
+
protocol: creative
|
|
5
|
+
category: creative_generative
|
|
6
|
+
summary: "Agent that takes a brief and generates finished creatives from scratch — no input assets required."
|
|
7
|
+
required_tools:
|
|
8
|
+
- build_creative
|
|
9
|
+
# Note: sync_catalogs is NOT in required_tools. The catalog_augmented_generation
|
|
10
|
+
# phase below is additive — brief-only generative agents (pure-prompt DSPs) pass
|
|
11
|
+
# the other phases without claiming catalog support. Agents that do not implement
|
|
12
|
+
# sync_catalogs grade that phase not_applicable rather than fail the specialism.
|
|
13
|
+
|
|
14
|
+
# Cross-step assertion (adcp#2664). status.monotonic rejects resource
|
|
15
|
+
# status transitions observed across steps that aren't on the spec
|
|
16
|
+
# lifecycle graph — e.g. approved → processing on a creative asset.
|
|
17
|
+
invariants:
|
|
18
|
+
- status.monotonic
|
|
19
|
+
|
|
20
|
+
narrative: |
|
|
21
|
+
You run a generative creative platform — an AI ad network, a generative DSP, or any system
|
|
22
|
+
that creates ad creatives from a natural-language brief and brand identity. The buyer doesn't
|
|
23
|
+
push assets to you. Instead, they describe what they want, point you at a brand.json, and
|
|
24
|
+
your agent produces finished creatives ready for trafficking.
|
|
25
|
+
|
|
26
|
+
This is fundamentally different from template-based transformation (Celtra) or library-based
|
|
27
|
+
retrieval (Innovid). Your agent creates something new. The buyer sends a brief, optionally
|
|
28
|
+
with seed assets or constraints, and your platform generates creatives — potentially in
|
|
29
|
+
multiple formats at once.
|
|
30
|
+
|
|
31
|
+
This storyboard walks through the generation flow: format discovery, brief-driven generation,
|
|
32
|
+
multi-format builds, iterative refinement, and quality progression from draft to production.
|
|
33
|
+
|
|
34
|
+
agent:
|
|
35
|
+
interaction_model: stateless_generate
|
|
36
|
+
capabilities:
|
|
37
|
+
- supports_generation
|
|
38
|
+
examples:
|
|
39
|
+
- "OpenAds"
|
|
40
|
+
- "AI ad networks"
|
|
41
|
+
- "Generative DSPs"
|
|
42
|
+
|
|
43
|
+
caller:
|
|
44
|
+
role: buyer_agent
|
|
45
|
+
example: "Scope3 (DSP)"
|
|
46
|
+
|
|
47
|
+
prerequisites:
|
|
48
|
+
description: |
|
|
49
|
+
The caller needs a brand identity (brand.json at the brand's domain) for the agent
|
|
50
|
+
to resolve visual identity — logos, colors, fonts, tone. The test kit provides a
|
|
51
|
+
sample brand with campaign parameters.
|
|
52
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
53
|
+
|
|
54
|
+
phases:
|
|
55
|
+
- id: capability_discovery
|
|
56
|
+
title: "Capability discovery"
|
|
57
|
+
narrative: |
|
|
58
|
+
The buyer calls get_adcp_capabilities to confirm the agent supports creative operations before browsing or building creatives.
|
|
59
|
+
|
|
60
|
+
steps:
|
|
61
|
+
- id: get_capabilities
|
|
62
|
+
title: "Check agent capabilities"
|
|
63
|
+
narrative: |
|
|
64
|
+
Verify that the agent declares the expected protocol support before
|
|
65
|
+
proceeding with domain-specific operations.
|
|
66
|
+
task: get_adcp_capabilities
|
|
67
|
+
schema_ref: "protocol/get-adcp-capabilities-request.json"
|
|
68
|
+
response_schema_ref: "protocol/get-adcp-capabilities-response.json"
|
|
69
|
+
doc_ref: "/protocol/get_adcp_capabilities"
|
|
70
|
+
comply_scenario: capability_discovery
|
|
71
|
+
stateful: false
|
|
72
|
+
expected: |
|
|
73
|
+
Return capabilities declaring creative in supported_protocols, confirming the agent handles creative operations.
|
|
74
|
+
sample_request:
|
|
75
|
+
context:
|
|
76
|
+
correlation_id: "creative_generative--get_capabilities"
|
|
77
|
+
validations:
|
|
78
|
+
- check: response_schema
|
|
79
|
+
description: "Response matches get-adcp-capabilities-response.json schema"
|
|
80
|
+
- check: field_present
|
|
81
|
+
path: "supported_protocols"
|
|
82
|
+
description: "Agent declares supported protocols"
|
|
83
|
+
|
|
84
|
+
- check: field_present
|
|
85
|
+
path: "context"
|
|
86
|
+
description: "Response echoes back the context object"
|
|
87
|
+
- check: field_value
|
|
88
|
+
path: "context.correlation_id"
|
|
89
|
+
value: "creative_generative--get_capabilities"
|
|
90
|
+
description: "Context correlation_id returned unchanged"
|
|
91
|
+
- id: format_discovery
|
|
92
|
+
title: "Discover generative formats"
|
|
93
|
+
narrative: |
|
|
94
|
+
The buyer needs to know what your agent can generate. Unlike a template platform
|
|
95
|
+
where formats are fixed dimensions, generative formats describe what the agent
|
|
96
|
+
produces — the output type, constraints, and what inputs it accepts. A generative
|
|
97
|
+
format might be "display_300x250_generative" that accepts a brief and produces
|
|
98
|
+
a finished banner, or "social_post_generative" that creates platform-native content.
|
|
99
|
+
|
|
100
|
+
steps:
|
|
101
|
+
- id: discover_formats
|
|
102
|
+
title: "Discover available generative formats"
|
|
103
|
+
narrative: |
|
|
104
|
+
The buyer asks: "What can you generate?" Your platform returns the formats
|
|
105
|
+
you support. Each format describes the output type, dimensions, and what
|
|
106
|
+
inputs it needs (brief text, brand reference, seed images, etc.).
|
|
107
|
+
task: list_creative_formats
|
|
108
|
+
schema_ref: "creative/list-creative-formats-request.json"
|
|
109
|
+
response_schema_ref: "creative/list-creative-formats-response.json"
|
|
110
|
+
doc_ref: "/creative/task-reference/list_creative_formats"
|
|
111
|
+
comply_scenario: creative_sync
|
|
112
|
+
stateful: false
|
|
113
|
+
expected: |
|
|
114
|
+
Return your generative formats. Each format should include:
|
|
115
|
+
- format_id with your agent_url and a unique id
|
|
116
|
+
- Human-readable name and description
|
|
117
|
+
- Asset slots describing what inputs are accepted (brief text, images, etc.)
|
|
118
|
+
- Render dimensions for the output
|
|
119
|
+
- Variables for any dynamic fields the buyer can control
|
|
120
|
+
|
|
121
|
+
sample_request:
|
|
122
|
+
context:
|
|
123
|
+
correlation_id: "creative_generative--discover_formats"
|
|
124
|
+
|
|
125
|
+
validations:
|
|
126
|
+
- check: response_schema
|
|
127
|
+
description: "Response matches list-creative-formats-response.json schema"
|
|
128
|
+
- check: field_present
|
|
129
|
+
path: "formats"
|
|
130
|
+
description: "Response contains a formats array"
|
|
131
|
+
- check: field_present
|
|
132
|
+
path: "formats[0].format_id.agent_url"
|
|
133
|
+
description: "Each format has a format_id with agent_url"
|
|
134
|
+
|
|
135
|
+
- check: field_present
|
|
136
|
+
path: "context"
|
|
137
|
+
description: "Response echoes back the context object"
|
|
138
|
+
- check: field_value
|
|
139
|
+
path: "context.correlation_id"
|
|
140
|
+
value: "creative_generative--discover_formats"
|
|
141
|
+
description: "Context correlation_id returned unchanged"
|
|
142
|
+
- id: generate_from_brief
|
|
143
|
+
title: "Generate from brief"
|
|
144
|
+
narrative: |
|
|
145
|
+
The buyer describes what they want in natural language and your agent generates
|
|
146
|
+
a creative from scratch. The brief includes the campaign message, target audience
|
|
147
|
+
context, and a brand reference so your agent can resolve visual identity.
|
|
148
|
+
|
|
149
|
+
This is the core generative flow. The buyer doesn't provide finished assets —
|
|
150
|
+
they provide intent, and your agent creates.
|
|
151
|
+
|
|
152
|
+
steps:
|
|
153
|
+
- id: build_draft
|
|
154
|
+
title: "Generate a draft creative from brief"
|
|
155
|
+
narrative: |
|
|
156
|
+
The buyer sends a brief describing the campaign and a target format. Your
|
|
157
|
+
agent generates a draft creative — fast, lower-fidelity output the buyer can
|
|
158
|
+
review before committing to a production build.
|
|
159
|
+
|
|
160
|
+
The brief is passed as a message alongside the target format. The brand
|
|
161
|
+
reference lets your agent resolve brand.json for visual identity.
|
|
162
|
+
task: build_creative
|
|
163
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
164
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
165
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
166
|
+
comply_scenario: creative_flow
|
|
167
|
+
stateful: false
|
|
168
|
+
expected: |
|
|
169
|
+
Return a generated creative manifest:
|
|
170
|
+
- creative_manifest with the generated assets (images, copy, serving code)
|
|
171
|
+
- format_id matching the target format
|
|
172
|
+
- If include_preview is true, include a preview render
|
|
173
|
+
|
|
174
|
+
The output should be a coherent creative that reflects the brief and brand
|
|
175
|
+
identity — not a template with placeholder text.
|
|
176
|
+
|
|
177
|
+
sample_request:
|
|
178
|
+
message: "Create a display banner for a summer outdoor gear sale. Bold, adventurous tone. Headline should emphasize 40% off. Target audience: active adults 25-54."
|
|
179
|
+
target_format_id:
|
|
180
|
+
agent_url: "https://your-agent.example.com"
|
|
181
|
+
id: "display_300x250_generative"
|
|
182
|
+
account:
|
|
183
|
+
brand:
|
|
184
|
+
domain: "acmeoutdoor.example"
|
|
185
|
+
operator: "pinnacle-agency.example"
|
|
186
|
+
quality: "draft"
|
|
187
|
+
include_preview: true
|
|
188
|
+
|
|
189
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_generate_from_brief_build_draft"
|
|
190
|
+
context:
|
|
191
|
+
correlation_id: "creative_generative--build_draft"
|
|
192
|
+
validations:
|
|
193
|
+
- check: response_schema
|
|
194
|
+
description: "Response matches build-creative-response.json schema"
|
|
195
|
+
- check: field_present
|
|
196
|
+
path: "creative_manifest.assets"
|
|
197
|
+
description: "Output manifest includes generated assets"
|
|
198
|
+
- check: field_present
|
|
199
|
+
path: "creative_manifest.format_id"
|
|
200
|
+
description: "Output manifest includes format_id"
|
|
201
|
+
|
|
202
|
+
- check: field_present
|
|
203
|
+
path: "context"
|
|
204
|
+
description: "Response echoes back the context object"
|
|
205
|
+
- check: field_value
|
|
206
|
+
path: "context.correlation_id"
|
|
207
|
+
value: "creative_generative--build_draft"
|
|
208
|
+
description: "Context correlation_id returned unchanged"
|
|
209
|
+
- id: refine
|
|
210
|
+
title: "Refine the creative"
|
|
211
|
+
narrative: |
|
|
212
|
+
The buyer reviews the draft and wants changes. They send the generated manifest
|
|
213
|
+
back with refinement instructions. Your agent modifies the creative based on the
|
|
214
|
+
feedback — adjusting copy, swapping imagery, or changing the layout.
|
|
215
|
+
|
|
216
|
+
This is iterative: the buyer can refine multiple times until they're satisfied,
|
|
217
|
+
then request a production-quality build.
|
|
218
|
+
|
|
219
|
+
steps:
|
|
220
|
+
- id: refine_creative
|
|
221
|
+
title: "Refine with feedback"
|
|
222
|
+
narrative: |
|
|
223
|
+
The buyer passes the generated manifest back with a message describing what
|
|
224
|
+
to change. Your agent applies the refinements and returns an updated creative.
|
|
225
|
+
task: build_creative
|
|
226
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
227
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
228
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
229
|
+
comply_scenario: creative_flow
|
|
230
|
+
stateful: false
|
|
231
|
+
expected: |
|
|
232
|
+
Return a refined creative manifest reflecting the requested changes.
|
|
233
|
+
The output should preserve what worked in the original while applying
|
|
234
|
+
the refinements.
|
|
235
|
+
|
|
236
|
+
sample_request:
|
|
237
|
+
message: "Make the headline larger. Replace the mountain imagery with a trail running scene. Add a CTA button that says 'Shop Now'."
|
|
238
|
+
creative_manifest:
|
|
239
|
+
format_id:
|
|
240
|
+
agent_url: "https://your-agent.example.com"
|
|
241
|
+
id: "display_300x250_generative"
|
|
242
|
+
assets:
|
|
243
|
+
generated_image:
|
|
244
|
+
asset_type: "image"
|
|
245
|
+
url: "https://your-agent.example.com/generated/abc123.jpg"
|
|
246
|
+
width: 300
|
|
247
|
+
height: 250
|
|
248
|
+
headline:
|
|
249
|
+
asset_type: "text"
|
|
250
|
+
content: "Summer Sale — 40% Off All Gear"
|
|
251
|
+
target_format_id:
|
|
252
|
+
agent_url: "https://your-agent.example.com"
|
|
253
|
+
id: "display_300x250_generative"
|
|
254
|
+
account:
|
|
255
|
+
brand:
|
|
256
|
+
domain: "acmeoutdoor.example"
|
|
257
|
+
operator: "pinnacle-agency.example"
|
|
258
|
+
quality: "draft"
|
|
259
|
+
include_preview: true
|
|
260
|
+
|
|
261
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_refine_refine_creative"
|
|
262
|
+
context:
|
|
263
|
+
correlation_id: "creative_generative--refine_creative"
|
|
264
|
+
validations:
|
|
265
|
+
- check: response_schema
|
|
266
|
+
description: "Response matches build-creative-response.json schema"
|
|
267
|
+
- check: field_present
|
|
268
|
+
path: "creative_manifest.assets"
|
|
269
|
+
description: "Refined manifest includes assets"
|
|
270
|
+
|
|
271
|
+
- check: field_present
|
|
272
|
+
path: "context"
|
|
273
|
+
description: "Response echoes back the context object"
|
|
274
|
+
- check: field_value
|
|
275
|
+
path: "context.correlation_id"
|
|
276
|
+
value: "creative_generative--refine_creative"
|
|
277
|
+
description: "Context correlation_id returned unchanged"
|
|
278
|
+
- id: multi_format
|
|
279
|
+
title: "Multi-format generation"
|
|
280
|
+
narrative: |
|
|
281
|
+
The buyer needs the creative in multiple sizes. Instead of generating each
|
|
282
|
+
format separately, they pass target_format_ids (plural) and your agent produces
|
|
283
|
+
all formats in a single call. This is where generative agents shine — adapting
|
|
284
|
+
a concept across formats while maintaining visual coherence.
|
|
285
|
+
|
|
286
|
+
steps:
|
|
287
|
+
- id: build_multi_format
|
|
288
|
+
title: "Generate for multiple formats"
|
|
289
|
+
narrative: |
|
|
290
|
+
The buyer passes the refined manifest with multiple target formats. Your
|
|
291
|
+
agent generates a creative for each format, adapting layout, copy, and
|
|
292
|
+
imagery to fit each size while maintaining brand consistency.
|
|
293
|
+
task: build_creative
|
|
294
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
295
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
296
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
297
|
+
comply_scenario: creative_flow
|
|
298
|
+
stateful: false
|
|
299
|
+
expected: |
|
|
300
|
+
Return creative manifests for each requested format in creative_manifests
|
|
301
|
+
(plural). Each manifest should:
|
|
302
|
+
- Have a format_id matching one of the target formats
|
|
303
|
+
- Contain complete, format-appropriate assets
|
|
304
|
+
- Maintain visual coherence across formats
|
|
305
|
+
|
|
306
|
+
If a format cannot be produced, include it with an error — don't fail
|
|
307
|
+
the entire request.
|
|
308
|
+
|
|
309
|
+
sample_request:
|
|
310
|
+
message: "Generate production-ready versions for all three sizes."
|
|
311
|
+
creative_manifest:
|
|
312
|
+
format_id:
|
|
313
|
+
agent_url: "https://your-agent.example.com"
|
|
314
|
+
id: "display_300x250_generative"
|
|
315
|
+
assets:
|
|
316
|
+
generated_image:
|
|
317
|
+
asset_type: "image"
|
|
318
|
+
url: "https://your-agent.example.com/generated/abc123-refined.jpg"
|
|
319
|
+
width: 300
|
|
320
|
+
height: 250
|
|
321
|
+
headline:
|
|
322
|
+
asset_type: "text"
|
|
323
|
+
content: "Summer Sale — 40% Off All Gear"
|
|
324
|
+
cta:
|
|
325
|
+
asset_type: "text"
|
|
326
|
+
content: "Shop Now"
|
|
327
|
+
target_format_ids:
|
|
328
|
+
- agent_url: "https://your-agent.example.com"
|
|
329
|
+
id: "display_300x250_generative"
|
|
330
|
+
- agent_url: "https://your-agent.example.com"
|
|
331
|
+
id: "display_728x90_generative"
|
|
332
|
+
- agent_url: "https://your-agent.example.com"
|
|
333
|
+
id: "display_320x50_generative"
|
|
334
|
+
account:
|
|
335
|
+
brand:
|
|
336
|
+
domain: "acmeoutdoor.example"
|
|
337
|
+
operator: "pinnacle-agency.example"
|
|
338
|
+
quality: "production"
|
|
339
|
+
|
|
340
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_multi_format_build_multi_format"
|
|
341
|
+
context:
|
|
342
|
+
correlation_id: "creative_generative--build_multi_format"
|
|
343
|
+
validations:
|
|
344
|
+
- check: response_schema
|
|
345
|
+
description: "Response matches build-creative-response.json schema"
|
|
346
|
+
- check: field_present
|
|
347
|
+
path: "creative_manifests"
|
|
348
|
+
description: "Response contains creative_manifests array (plural)"
|
|
349
|
+
|
|
350
|
+
- check: field_present
|
|
351
|
+
path: "context"
|
|
352
|
+
description: "Response echoes back the context object"
|
|
353
|
+
- check: field_value
|
|
354
|
+
path: "context.correlation_id"
|
|
355
|
+
value: "creative_generative--build_multi_format"
|
|
356
|
+
description: "Context correlation_id returned unchanged"
|
|
357
|
+
- id: production_build
|
|
358
|
+
title: "Production build"
|
|
359
|
+
narrative: |
|
|
360
|
+
The buyer is satisfied with the concept and needs a final, production-quality
|
|
361
|
+
creative ready for trafficking. They switch quality from draft to production.
|
|
362
|
+
Your agent generates the finished output with full-fidelity assets.
|
|
363
|
+
|
|
364
|
+
steps:
|
|
365
|
+
- id: build_production
|
|
366
|
+
title: "Build at production quality"
|
|
367
|
+
narrative: |
|
|
368
|
+
The buyer requests a production-quality build of the approved concept. Your
|
|
369
|
+
agent generates the final creative with full-fidelity rendering, polished
|
|
370
|
+
assets, and serving code ready for trafficking.
|
|
371
|
+
task: build_creative
|
|
372
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
373
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
374
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
375
|
+
comply_scenario: creative_flow
|
|
376
|
+
stateful: false
|
|
377
|
+
expected: |
|
|
378
|
+
Return a production-quality creative manifest:
|
|
379
|
+
- Full-fidelity generated assets
|
|
380
|
+
- Serving code (HTML, JavaScript, or VAST) ready for trafficking
|
|
381
|
+
- Provenance metadata if AI-generated (digital_source_type, ai_tool)
|
|
382
|
+
|
|
383
|
+
sample_request:
|
|
384
|
+
message: "Final production build. No changes needed."
|
|
385
|
+
creative_manifest:
|
|
386
|
+
format_id:
|
|
387
|
+
agent_url: "https://your-agent.example.com"
|
|
388
|
+
id: "display_300x250_generative"
|
|
389
|
+
assets:
|
|
390
|
+
generated_image:
|
|
391
|
+
asset_type: "image"
|
|
392
|
+
url: "https://your-agent.example.com/generated/abc123-refined.jpg"
|
|
393
|
+
width: 300
|
|
394
|
+
height: 250
|
|
395
|
+
headline:
|
|
396
|
+
asset_type: "text"
|
|
397
|
+
content: "Summer Sale — 40% Off All Gear"
|
|
398
|
+
cta:
|
|
399
|
+
asset_type: "text"
|
|
400
|
+
content: "Shop Now"
|
|
401
|
+
target_format_id:
|
|
402
|
+
agent_url: "https://your-agent.example.com"
|
|
403
|
+
id: "display_300x250_generative"
|
|
404
|
+
account:
|
|
405
|
+
brand:
|
|
406
|
+
domain: "acmeoutdoor.example"
|
|
407
|
+
operator: "pinnacle-agency.example"
|
|
408
|
+
quality: "production"
|
|
409
|
+
include_preview: true
|
|
410
|
+
|
|
411
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_production_build_build_production"
|
|
412
|
+
context:
|
|
413
|
+
correlation_id: "creative_generative--build_production"
|
|
414
|
+
validations:
|
|
415
|
+
- check: response_schema
|
|
416
|
+
description: "Response matches build-creative-response.json schema"
|
|
417
|
+
- check: field_present
|
|
418
|
+
path: "creative_manifest.assets"
|
|
419
|
+
description: "Production manifest includes assets"
|
|
420
|
+
- check: field_present
|
|
421
|
+
path: "creative_manifest.format_id"
|
|
422
|
+
description: "Production manifest includes format_id"
|
|
423
|
+
|
|
424
|
+
- check: field_present
|
|
425
|
+
path: "context"
|
|
426
|
+
description: "Response echoes back the context object"
|
|
427
|
+
- check: field_value
|
|
428
|
+
path: "context.correlation_id"
|
|
429
|
+
value: "creative_generative--build_production"
|
|
430
|
+
description: "Context correlation_id returned unchanged"
|
|
431
|
+
|
|
432
|
+
- id: catalog_augmented_generation
|
|
433
|
+
title: "Catalog-augmented generation"
|
|
434
|
+
narrative: |
|
|
435
|
+
Generative platforms routinely hydrate catalog items into the generation context:
|
|
436
|
+
the buyer pushes a product catalog, and each generated creative references a specific
|
|
437
|
+
catalog item (via `{SKU}`, `{GTIN}`, or the catalog-item family) in its impression
|
|
438
|
+
trackers and click trackers. This is how generative DSPs produce per-SKU dynamic
|
|
439
|
+
creative at scale.
|
|
440
|
+
|
|
441
|
+
This phase exercises the catalog-acceptance leg and emits a generative build that
|
|
442
|
+
includes catalog-item macros in its tracker URL assets. `preview_creative` is the
|
|
443
|
+
natural observation point for the runtime substitution-safety check tracked in
|
|
444
|
+
#2638 — when the substitution-observer contract lands, a runner can assert that
|
|
445
|
+
the previewed HTML contains percent-encoded catalog-item values per
|
|
446
|
+
`docs/creative/universal-macros#substitution-safety-catalog-item-macros`.
|
|
447
|
+
|
|
448
|
+
steps:
|
|
449
|
+
- id: sync_generation_catalog
|
|
450
|
+
title: "Push a product catalog for generation"
|
|
451
|
+
narrative: |
|
|
452
|
+
The buyer pushes a small inline catalog. Your agent will use these items as the
|
|
453
|
+
hydration targets for subsequent generated creatives.
|
|
454
|
+
task: sync_catalogs
|
|
455
|
+
schema_ref: "media-buy/sync-catalogs-request.json"
|
|
456
|
+
response_schema_ref: "media-buy/sync-catalogs-response.json"
|
|
457
|
+
doc_ref: "/media-buy/task-reference/sync_catalogs"
|
|
458
|
+
stateful: true
|
|
459
|
+
expected: |
|
|
460
|
+
Return per-catalog results with catalog_id, action, item_count, and
|
|
461
|
+
items_approved counts.
|
|
462
|
+
|
|
463
|
+
sample_request:
|
|
464
|
+
account:
|
|
465
|
+
brand:
|
|
466
|
+
domain: "acmeoutdoor.example"
|
|
467
|
+
operator: "pinnacle-agency.example"
|
|
468
|
+
catalogs:
|
|
469
|
+
- catalog_id: "acme_generative_source"
|
|
470
|
+
type: "product"
|
|
471
|
+
content_id_type: "sku"
|
|
472
|
+
name: "Acme Outdoor — Generative source feed"
|
|
473
|
+
items:
|
|
474
|
+
- item_id: "peak_jacket_x"
|
|
475
|
+
title: "Peak Jacket X"
|
|
476
|
+
description: "Goretex 3L shell, seam-taped, 280g."
|
|
477
|
+
url: "https://acmeoutdoor.example/gear/peak-jacket-x"
|
|
478
|
+
image_url: "https://cdn.acmeoutdoor.example/gear/peak-jacket-x.jpg"
|
|
479
|
+
price:
|
|
480
|
+
amount: 449.00
|
|
481
|
+
currency: "USD"
|
|
482
|
+
|
|
483
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_catalog_augmented_generation_sync_generation_catalog"
|
|
484
|
+
context:
|
|
485
|
+
correlation_id: "creative_generative--sync_generation_catalog"
|
|
486
|
+
validations:
|
|
487
|
+
- check: response_schema
|
|
488
|
+
description: "Response matches sync-catalogs-response.json schema"
|
|
489
|
+
- check: field_present
|
|
490
|
+
path: "catalogs[0].catalog_id"
|
|
491
|
+
description: "Catalog has an ID"
|
|
492
|
+
- check: field_present
|
|
493
|
+
path: "context"
|
|
494
|
+
description: "Response echoes back the context object"
|
|
495
|
+
- check: field_value
|
|
496
|
+
path: "context.correlation_id"
|
|
497
|
+
value: "creative_generative--sync_generation_catalog"
|
|
498
|
+
description: "Context correlation_id returned unchanged"
|
|
499
|
+
|
|
500
|
+
- id: build_catalog_aware_creative
|
|
501
|
+
title: "Generate a creative bound to a catalog item"
|
|
502
|
+
narrative: |
|
|
503
|
+
The buyer asks your agent to build a creative for a specific catalog item.
|
|
504
|
+
The generated manifest MUST include tracker URLs with catalog-item macros
|
|
505
|
+
(`{SKU}`, `{GTIN}`) so impression-time substitution renders per-SKU output.
|
|
506
|
+
|
|
507
|
+
Per #2620, the substitution step MUST percent-encode catalog-item values
|
|
508
|
+
against the RFC 3986 unreserved set — but the substitution itself happens at
|
|
509
|
+
serve time, not in the build_creative response. Runtime observability is
|
|
510
|
+
tracked in #2638.
|
|
511
|
+
task: build_creative
|
|
512
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
513
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
514
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
515
|
+
comply_scenario: creative_flow
|
|
516
|
+
stateful: true
|
|
517
|
+
expected: |
|
|
518
|
+
Return a creative manifest whose tracker assets include catalog-item
|
|
519
|
+
macros ({SKU} or {GTIN}) and whose format references a catalog-capable
|
|
520
|
+
format declared by the agent.
|
|
521
|
+
|
|
522
|
+
sample_request:
|
|
523
|
+
message: "Generate a 300x250 display ad for the Peak Jacket X, using our catalog feed for product fields and tracker URLs."
|
|
524
|
+
target_format_id:
|
|
525
|
+
agent_url: "https://your-agent.example.com"
|
|
526
|
+
id: "display_300x250_generative"
|
|
527
|
+
account:
|
|
528
|
+
brand:
|
|
529
|
+
domain: "acmeoutdoor.example"
|
|
530
|
+
operator: "pinnacle-agency.example"
|
|
531
|
+
quality: "draft"
|
|
532
|
+
include_preview: true
|
|
533
|
+
|
|
534
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_catalog_augmented_generation_build_catalog_aware_creative"
|
|
535
|
+
context:
|
|
536
|
+
correlation_id: "creative_generative--build_catalog_aware_creative"
|
|
537
|
+
validations:
|
|
538
|
+
- check: response_schema
|
|
539
|
+
description: "Response matches build-creative-response.json schema"
|
|
540
|
+
- check: field_present
|
|
541
|
+
path: "creative_manifest.format_id"
|
|
542
|
+
description: "Generated manifest includes format_id"
|
|
543
|
+
- check: field_present
|
|
544
|
+
path: "context"
|
|
545
|
+
description: "Response echoes back the context object"
|
|
546
|
+
- check: field_value
|
|
547
|
+
path: "context.correlation_id"
|
|
548
|
+
value: "creative_generative--build_catalog_aware_creative"
|
|
549
|
+
description: "Context correlation_id returned unchanged"
|
|
550
|
+
|
|
551
|
+
- id: catalog_substitution_safety
|
|
552
|
+
title: "Catalog-item macro substitution safety"
|
|
553
|
+
narrative: |
|
|
554
|
+
Per docs/creative/universal-macros#substitution-safety-catalog-item-macros,
|
|
555
|
+
sales and creative agents MUST percent-encode catalog-item macro values
|
|
556
|
+
such that only RFC 3986 `unreserved` characters remain unescaped before
|
|
557
|
+
substituting them into a URL context. Nested macro expansion is prohibited.
|
|
558
|
+
|
|
559
|
+
This phase exercises the rule with five canonical attacker-shaped
|
|
560
|
+
catalog values drawn from the fixture at
|
|
561
|
+
`static/test-vectors/catalog-macro-substitution.json`:
|
|
562
|
+
reserved-char breakout, nested-expansion preservation, non-ASCII UTF-8,
|
|
563
|
+
CRLF injection, and bidi-override neutralization. Generative pipelines
|
|
564
|
+
have a higher risk profile on bidi-override than template pipelines
|
|
565
|
+
(LLM-generated copy with embedded user text can round-trip bidi
|
|
566
|
+
controls into attribute contexts), so this phase exercises bidi
|
|
567
|
+
alongside the baseline vectors. The two remaining fixture vectors —
|
|
568
|
+
`mixed-path-and-query-contexts` (requires the same macro in two URL
|
|
569
|
+
positions) and `url-scheme-injection-neutralized` (requires an
|
|
570
|
+
href-whole-value macro binding) — are unit-test-layer conformance only;
|
|
571
|
+
runtime observation in a storyboard requires specialism-specific
|
|
572
|
+
template shapes tracked as follow-ups.
|
|
573
|
+
|
|
574
|
+
`build_creative`-with-`include_preview: true` is the natural observation
|
|
575
|
+
point on a generative specialism — the substitution-observer runner
|
|
576
|
+
(#2638) parses the returned `preview_html` and asserts each macro
|
|
577
|
+
position carries the fixture's `expected_encoded` form, not the raw
|
|
578
|
+
attacker bytes.
|
|
579
|
+
|
|
580
|
+
Scope note: this phase validates substitution on the PREVIEW surface
|
|
581
|
+
only. Sellers with divergent preview vs impression-time substitution
|
|
582
|
+
paths MAY pass here while failing at serve time; serve-time attestation
|
|
583
|
+
or log-introspection observability is deferred (#2651, out-of-scope v1
|
|
584
|
+
per the observer contract).
|
|
585
|
+
|
|
586
|
+
The `expect_substitution_safe` step is gated on the
|
|
587
|
+
`substitution_observer_runner` test-kit contract (see
|
|
588
|
+
`test-kits/substitution-observer-runner.yaml`). Runners that do not
|
|
589
|
+
advertise the contract grade the step as `not_applicable` — the earlier
|
|
590
|
+
`sync_substitution_probe_catalog` and `build_substitution_probe_creative`
|
|
591
|
+
steps still run (exercising the catalog-acceptance and build paths),
|
|
592
|
+
but the substituted-URL assertion is skipped.
|
|
593
|
+
|
|
594
|
+
steps:
|
|
595
|
+
- id: sync_substitution_probe_catalog
|
|
596
|
+
title: "Push a probe catalog with attacker-shaped values"
|
|
597
|
+
narrative: |
|
|
598
|
+
Push a small probe catalog whose `sku` fields contain three of the
|
|
599
|
+
canonical attacker-shaped values from the substitution-safety
|
|
600
|
+
fixture. The agent MUST accept the payload at sync_catalogs — the
|
|
601
|
+
encoding rule applies at substitution time, not at ingest — but
|
|
602
|
+
subsequent build_creative output must percent-encode each value.
|
|
603
|
+
task: sync_catalogs
|
|
604
|
+
schema_ref: "media-buy/sync-catalogs-request.json"
|
|
605
|
+
response_schema_ref: "media-buy/sync-catalogs-response.json"
|
|
606
|
+
doc_ref: "/media-buy/task-reference/sync_catalogs"
|
|
607
|
+
stateful: true
|
|
608
|
+
expected: |
|
|
609
|
+
Catalog accepted with per-item counts. Runner captures the
|
|
610
|
+
catalog_id + item_ids for the downstream assertion binding.
|
|
611
|
+
|
|
612
|
+
sample_request:
|
|
613
|
+
account:
|
|
614
|
+
brand:
|
|
615
|
+
domain: "acmeoutdoor.example"
|
|
616
|
+
operator: "pinnacle-agency.example"
|
|
617
|
+
catalogs:
|
|
618
|
+
- catalog_id: "creative_generative_substitution_probe_v1"
|
|
619
|
+
type: "product"
|
|
620
|
+
content_id_type: "sku"
|
|
621
|
+
name: "Substitution safety probe"
|
|
622
|
+
items:
|
|
623
|
+
# item_id names the vector; the `sku` field carries the
|
|
624
|
+
# attacker-shaped value that substitution must encode.
|
|
625
|
+
- item_id: "reserved_char_breakout"
|
|
626
|
+
sku: "00013&cmd=drop"
|
|
627
|
+
title: "Reserved-char breakout probe"
|
|
628
|
+
url: "https://acmeoutdoor.example/probe/reserved"
|
|
629
|
+
image_url: "https://cdn.acmeoutdoor.example/probe/reserved.jpg"
|
|
630
|
+
price: { amount: 1.00, currency: "USD" }
|
|
631
|
+
- item_id: "nested_expansion"
|
|
632
|
+
sku: "vacancy-{DEVICE_ID}-42"
|
|
633
|
+
title: "Nested-expansion probe"
|
|
634
|
+
url: "https://acmeoutdoor.example/probe/nested"
|
|
635
|
+
image_url: "https://cdn.acmeoutdoor.example/probe/nested.jpg"
|
|
636
|
+
price: { amount: 1.00, currency: "USD" }
|
|
637
|
+
- item_id: "non_ascii"
|
|
638
|
+
sku: "café-amsterdam"
|
|
639
|
+
title: "Non-ASCII UTF-8 probe"
|
|
640
|
+
url: "https://acmeoutdoor.example/probe/non-ascii"
|
|
641
|
+
image_url: "https://cdn.acmeoutdoor.example/probe/non-ascii.jpg"
|
|
642
|
+
price: { amount: 1.00, currency: "USD" }
|
|
643
|
+
- item_id: "crlf_injection"
|
|
644
|
+
sku: "abc\r\nHost: evil.example"
|
|
645
|
+
title: "CRLF injection probe"
|
|
646
|
+
url: "https://acmeoutdoor.example/probe/crlf"
|
|
647
|
+
image_url: "https://cdn.acmeoutdoor.example/probe/crlf.jpg"
|
|
648
|
+
price: { amount: 1.00, currency: "USD" }
|
|
649
|
+
- item_id: "bidi_override"
|
|
650
|
+
sku: "VIN-\u202E1234"
|
|
651
|
+
title: "Bidi-override probe"
|
|
652
|
+
url: "https://acmeoutdoor.example/probe/bidi"
|
|
653
|
+
image_url: "https://cdn.acmeoutdoor.example/probe/bidi.jpg"
|
|
654
|
+
price: { amount: 1.00, currency: "USD" }
|
|
655
|
+
|
|
656
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_catalog_substitution_safety_sync_substitution_probe_catalog"
|
|
657
|
+
context:
|
|
658
|
+
correlation_id: "creative_generative--sync_substitution_probe_catalog"
|
|
659
|
+
validations:
|
|
660
|
+
- check: response_schema
|
|
661
|
+
description: "Response matches sync-catalogs-response.json schema"
|
|
662
|
+
- check: field_present
|
|
663
|
+
path: "catalogs[0].catalog_id"
|
|
664
|
+
description: "Probe catalog accepted"
|
|
665
|
+
|
|
666
|
+
- id: build_substitution_probe_creative
|
|
667
|
+
title: "Generate a creative with catalog-item macros bound to the probe"
|
|
668
|
+
narrative: |
|
|
669
|
+
Generate a draft creative that uses `{SKU}` in its impression tracker
|
|
670
|
+
URL and request `include_preview: true` so the substitution-observer
|
|
671
|
+
runner has a preview surface to inspect.
|
|
672
|
+
|
|
673
|
+
The `message` is a natural-language brief; a generative agent that
|
|
674
|
+
ignores the `{SKU}` directive (generates its own macro, inlines an
|
|
675
|
+
encoded value, omits the tracker) fails the downstream
|
|
676
|
+
`expect_substitution_safe` step with `substitution_binding_missing`.
|
|
677
|
+
To keep that failure mode diagnostically clear, this step validates
|
|
678
|
+
the creative_manifest contains `{SKU}` unsubstituted in at least
|
|
679
|
+
one tracker asset before the observer runs.
|
|
680
|
+
task: build_creative
|
|
681
|
+
schema_ref: "media-buy/build-creative-request.json"
|
|
682
|
+
response_schema_ref: "media-buy/build-creative-response.json"
|
|
683
|
+
doc_ref: "/creative/task-reference/build_creative"
|
|
684
|
+
comply_scenario: creative_flow
|
|
685
|
+
stateful: true
|
|
686
|
+
expected: |
|
|
687
|
+
Creative manifest returned with preview_html populated. Impression
|
|
688
|
+
tracker asset includes {SKU} unsubstituted in its template (to be
|
|
689
|
+
resolved at impression time against catalog items).
|
|
690
|
+
|
|
691
|
+
sample_request:
|
|
692
|
+
message: "Generate a 300x250 display ad for the creative_generative_substitution_probe_v1 catalog. Include the `{SKU}` macro as a literal token in the impression tracker URL — the platform resolves it per-impression against catalog items."
|
|
693
|
+
target_format_id:
|
|
694
|
+
agent_url: "https://your-agent.example.com"
|
|
695
|
+
id: "display_300x250_generative"
|
|
696
|
+
account:
|
|
697
|
+
brand:
|
|
698
|
+
domain: "acmeoutdoor.example"
|
|
699
|
+
operator: "pinnacle-agency.example"
|
|
700
|
+
quality: "draft"
|
|
701
|
+
include_preview: true
|
|
702
|
+
|
|
703
|
+
idempotency_key: "$generate:uuid_v4#creative_generative_catalog_substitution_safety_build_substitution_probe_creative"
|
|
704
|
+
context:
|
|
705
|
+
correlation_id: "creative_generative--build_substitution_probe_creative"
|
|
706
|
+
validations:
|
|
707
|
+
- check: response_schema
|
|
708
|
+
description: "Response matches build-creative-response.json schema"
|
|
709
|
+
- check: field_present
|
|
710
|
+
path: "creative_manifest.format_id"
|
|
711
|
+
description: "Creative manifest returned"
|
|
712
|
+
|
|
713
|
+
- id: expect_substitution_safe
|
|
714
|
+
title: "Assert substituted tracker URLs percent-encode attacker shapes"
|
|
715
|
+
narrative: |
|
|
716
|
+
The runner inspects the preview_html from the previous step, extracts
|
|
717
|
+
tracker URLs that bind `{SKU}` to a probe catalog item, and asserts
|
|
718
|
+
each value is percent-encoded per RFC 3986 (unreserved-whitelist).
|
|
719
|
+
Raw-byte leakage fails. Every declared binding MUST be observed — a
|
|
720
|
+
generative agent that silently strips `{SKU}` rather than
|
|
721
|
+
substituting it fails with `substitution_binding_missing`.
|
|
722
|
+
task: expect_substitution_safe
|
|
723
|
+
requires_contract: substitution_observer_runner
|
|
724
|
+
source: html_inline
|
|
725
|
+
source_path: "/creative_manifest/preview_html"
|
|
726
|
+
macro_template: "https://track.example/imp?sku={SKU}"
|
|
727
|
+
require_every_binding_observed: true
|
|
728
|
+
catalog_bindings:
|
|
729
|
+
# Each binding: `catalog_item_id` is the item_id in the probe
|
|
730
|
+
# catalog; `vector_name` is the fixture entry whose raw_value and
|
|
731
|
+
# expected_encoded the runner loads from the unit-test fixture.
|
|
732
|
+
- macro: "{SKU}"
|
|
733
|
+
catalog_item_id: "reserved_char_breakout"
|
|
734
|
+
vector_name: "reserved-character-breakout"
|
|
735
|
+
- macro: "{SKU}"
|
|
736
|
+
catalog_item_id: "nested_expansion"
|
|
737
|
+
vector_name: "nested-expansion-preserved-as-literal"
|
|
738
|
+
- macro: "{SKU}"
|
|
739
|
+
catalog_item_id: "non_ascii"
|
|
740
|
+
vector_name: "non-ascii-utf8-percent-encoding"
|
|
741
|
+
- macro: "{SKU}"
|
|
742
|
+
catalog_item_id: "crlf_injection"
|
|
743
|
+
vector_name: "crlf-injection-neutralized"
|
|
744
|
+
- macro: "{SKU}"
|
|
745
|
+
catalog_item_id: "bidi_override"
|
|
746
|
+
vector_name: "bidi-override-neutralized"
|