Skip to content

feat(creative): normative VAST validation contract with capability-gated levels and error codes#5820

Open
aleksUIX wants to merge 1 commit into
adcontextprotocol:mainfrom
aleksUIX:feat/vast-validation-contract
Open

feat(creative): normative VAST validation contract with capability-gated levels and error codes#5820
aleksUIX wants to merge 1 commit into
adcontextprotocol:mainfrom
aleksUIX:feat/vast-validation-contract

Conversation

@aleksUIX

@aleksUIX aleksUIX commented Jul 6, 2026

Copy link
Copy Markdown

Summary

The entire format-layer contract for a vast asset today is the vast_version string in core/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 the max_wrapper_depth integer on video_vast, and error-code.json carries 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_validation on get_adcp_capabilities (structural | document | wrapper, default structural), following the pattern media_buy.governance_aware set 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 declared vast_version / the format requirement / the seller's vast_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 existing max_wrapper_depth, loop detection, per-hop timeout, HTTPS-only hops, document checks on the terminal <InLine>.
  • Validation runs at sync_creatives (including dry_run); validate_input stays manifest-structure-only, consistent with its normative statement in validate-input-result.json.
  • A passing preflight is explicitly not approval of future responses from a decisioning endpoint, and URL fetches inherit the seller's usual server-side request protections.

Three error codes with enumDescriptions and enumMetadata (all correctable, error.details.reason discriminators): VAST_PARSE_FAILED, VAST_VERSION_MISMATCH (distinct from VERSION_UNSUPPORTED, which is protocol version negotiation), VAST_WRAPPER_DEPTH_EXCEEDED (depth, loop, or timeout).

Non-goals

Files

  • static/schemas/source/protocol/get-adcp-capabilities-response.json (new optional creative_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.cjs clean (95 canonical codes); scripts/lint-error-code-drift.cjs clean with the three disposition entries
  • scripts/check-changeset-protocol-scope.cjs origin/main passes; changeset status shows minor bump only
  • JSON schemas parse; docs example validation tests pass locally (the only local failures reproduce identically on clean main)

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.

…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.

@aao-release-bot aao-release-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@aao-ipr-bot

aao-ipr-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

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:

I have read the IPR Policy

Your signature is recorded once and covers all contributions to AAO repositories. See signatures/README.md for what gets recorded and why.

@aleksUIX

aleksUIX commented Jul 6, 2026

Copy link
Copy Markdown
Author

I have read the IPR Policy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant