feat(creative): normative VAST validation contract with capability-gated levels and error codes#5820
Conversation
…ted levels and error codes The format-layer contract for a vast asset is a single vast_version string; nothing requires parsing the document, checking Ad/MediaFile presence, verifying the version attribute, or bounding wrapper chains, and the error enum has no VAST codes. Define three seller-declared validation levels (structural, document, wrapper) via creative_specs.vast_validation on get_adcp_capabilities, following the media_buy.governance_aware capability-gating pattern, with normative checks in the video channel docs and three new correctable error codes (VAST_PARSE_FAILED, VAST_VERSION_MISMATCH, VAST_WRAPPER_DEPTH_EXCEEDED). Validation runs at sync_creatives including dry_run; validate_input stays manifest-structure-only. Macro correctness is explicitly out of scope.
There was a problem hiding this comment.
Argus is not auto-reviewing this PR because it modifies protected paths that require human review (.changeset/feat-vast-validation-contract.md, static/schemas/source/enums/error-code.json, static/schemas/source/protocol/get-adcp-capabilities-response.json). A human reviewer should review and merge this PR; Argus will resume on subsequent PRs once these changes land on main.
IPR Policy Agreement Required@aleksUIX — thanks for the contribution. Before this PR can be merged, the AgenticAdvertising.Org IPR Policy requires your agreement. To agree, post a new comment on this PR with the exact phrase: Your signature is recorded once and covers all contributions to AAO repositories. See |
|
I have read the IPR Policy |
Summary
The entire format-layer contract for a
vastasset today is thevast_versionstring incore/requirements/vast-asset-requirements.json. Nothing in the spec requires parsing the document, checking that an<Ad>or<MediaFile>exists, verifying the<VAST version>attribute against what the buyer declared, or bounding wrapper chains beyond themax_wrapper_depthinteger onvideo_vast, anderror-code.jsoncarries no VAST codes. A structurally valid manifest can therefore traffic an unplayable tag that fails silently at serve time, and sellers that do inspect tags have no canonical codes to reject with.Change
Capability-gated validation levels. New
creative_specs.vast_validationonget_adcp_capabilities(structural|document|wrapper, defaultstructural), following the patternmedia_buy.governance_awareset in 3.1.1: sellers that do not inspect VAST documents keep the default and are completely unaffected; sellers that do can now declare it and buyers can rely on it.Normative checks per level (new "VAST Validation" section in
docs/creative/channels/video.mdx):document: parse as XML,<VAST>root present, version attribute agrees with the asset's declaredvast_version/ the format requirement / the seller'svast_versions,<Ad>and inline<MediaFile>presence, HTTPS URLs. Unresolved ad-server macros are explicitly opaque tokens, never failures.wrapper: resolve<VASTAdTagURI>redirects bounded by the format's existingmax_wrapper_depth, loop detection, per-hop timeout, HTTPS-only hops, document checks on the terminal<InLine>.sync_creatives(includingdry_run);validate_inputstays manifest-structure-only, consistent with its normative statement invalidate-input-result.json.Three error codes with
enumDescriptionsandenumMetadata(all correctable,error.details.reasondiscriminators):VAST_PARSE_FAILED,VAST_VERSION_MISMATCH(distinct fromVERSION_UNSUPPORTED, which is protocol version negotiation),VAST_WRAPPER_DEPTH_EXCEEDED(depth, loop, or timeout).Non-goals
omid_verificationasset type: tracked separately in the spec's own deferred list.vast-asset-requirements.jsonor thevideo_vastcanonical format.Files
static/schemas/source/protocol/get-adcp-capabilities-response.json(new optionalcreative_specs.vast_validation)static/schemas/source/enums/error-code.json(+3 codes with descriptions and metadata)scripts/error-code-drift-dispositions.json(held-for-next-minor, target 3.2)docs/creative/channels/video.mdx(normative section),docs/creative/task-reference/sync_creatives.mdx(error-table pointer).changeset/feat-vast-validation-contract.md(minor)Verification
scripts/lint-error-codes.cjsclean (95 canonical codes);scripts/lint-error-code-drift.cjsclean with the three disposition entriesscripts/check-changeset-protocol-scope.cjs origin/mainpasses; changeset status shows minor bump onlymain)Happy to route this through the RFC process instead if the WG prefers that for a new capability field; the surface is additive and default-off either way.