Skip to content

[Change] § 5.4 — Validate assets[].format_ref against the resolved formats selection at submission, not at creative review #32

Open

Description

@VJAlkimi

What kind of change?

Change a normative requirement (MUST / SHOULD / MAY)

Which section?

5.4 — Creative requirements

Current text

§ 5.4:

formats · Object · selectable · available[] of registry format ids namespaced by channel (display/300x250, audio/host-read-30s), included[], pricing, max_select
specs · Object · seller-set · As defined by the referenced format registry entry. OpenProposal does not hardcode a shape per channel
assets[] · Array[Object] · supplied · Buyer-delivered. { asset_id, format_ref, url_or_tag, submitted_at, approval_status }
materials_due · Timestamp/Offset · requestable · Deadline for creative to land. A buyer MAY request a later date
approval · Object · seller-set · Review SLA and revision policy

§ 3:

An unset selectable or settable field takes its declared included[] or default, and that default MUST be explicit in the proposal.

§ 3, supplied marker:

The buyer provides data or an artifact. The seller does not pre-populate it.

Proposed text

§ 5.4, add after the assets[] row:

Every assets[].format_ref MUST be a member of the line item's resolved formats selection (selected[] when present, otherwise included[]). An asset whose format_ref is not in the resolved selection MUST be rejected at submission with a structured error naming the asset_id and the format_ref, and MUST NOT be treated as an implicit selection of that format. This check MUST be deterministic and MUST NOT wait for creative review.

Every assets[].format_ref MUST resolve to a specification: a registry entry, or an inline specs entry on the line item keyed by that format id. An asset whose format_ref resolves to neither MUST be rejected at submission.

§ 5.4, replace the approval row with:

approval · Object · seller-set · Review SLA and revision policy for content and policy conformance of a submitted asset. Format conformance is validated at submission under the rules above, not at review.

§ 5.4, replace the assets[] row with:

assets[] · Array[Object] · supplied · Buyer-delivered. { asset_id, format_ref, url_or_tag, submitted_at, approval_status }. approval_status is seller-populated: pending | approved | rejected, with rejection_reason when rejected.

Appendix A / B: no new fields. The approval_status enum is structure within assets[].

Why

Field(s) involved

assets[].format_ref, formats (available[], included[], selected[] per #22), specs, approval, assets[].approval_status, materials_due

The draft separates what is bought from what is delivered and never joins them. formats is the selectable field that says which creative shapes the buyer has bought. assets[] is the supplied field that carries the creative the buyer delivers. Nothing says the second must match the first.

The failure path, step by step, from the display example.

  1. The buyer commits without touching formats. Per § 3 the field resolves to included[], so the buyer has bought display/300x250 only.
  2. The buyer uploads a creative with format_ref: display/728x90. That id is in available[], so it looks valid, but it was never selected.
  3. No rule rejects the asset at submission. The draft's only check on an asset is the seller's review, which sets approval_status under the SLA in approval.
  4. The seller's reviewer sees a 728x90 creative on a 300x250 buy and rejects it, possibly days later, after materials_due has passed.
  5. The buyer is now in a seller-response loop on a supplied field that § 3 says resolves without one, and cannot fix it by selecting 728x90 because, until [Change] § 3 — Name the key the buyer writes its selection to: selected[] on selectable fields, value on settable fields #22 lands, there is no key to write that selection to.

Two rules are missing. A validation rule, so the mismatch is caught at the moment the asset is supplied rather than at human review. And a precedence rule, stating whether supplying an asset in an available-but-unselected format counts as selecting that format, or is simply invalid. Either answer works. Having neither means two implementations will behave differently: one will widen the selection silently, the other will reject at review, and the buyer cannot tell which from the document.

The proposed text chooses invalid, for one reason: an implicit selection would change agreed_rate without the buyer having asked for it. display/970x250 carries a 3.00 delta in the example. If uploading a 970x250 asset silently selected that format, the buyer would be charged 27.00 instead of 24.00 by an action the draft classifies as supplying data, not choosing an option. Rejection at submission keeps the price under the buyer's control.

This also makes approval mean one thing. Today approval covers "review SLA and revision policy" with no statement of what review checks. Format mismatch is mechanical and belongs to validation. Content and policy conformance needs a reviewer. The proposed text draws that line so a seller's SLA applies to the part that needs human time.

The rule depends on format ids resolving to something. OQ-4 (#5) records that the registry has no entries for audio, ctv or dooh, and the in-app comment there widens the gap. A format id that resolves to nothing cannot be validated against. The second proposed sentence requires every format_ref to resolve to a registry entry or an inline specs entry, which is the fallback we proposed on #5 and which lets this rule work before the registry is complete.

When assets[] is written is itself unstated, and the scenario below stays inside composition for that reason. The draft says commitment is "populated during composition" and "frozen when status becomes agreed", and § 2.2 says the agreed record is immutable. It does not say when assets[] is populated. If creative lands after agreed, as materials_due ("deadline for creative to land") and the example dates (materials due 24 September, flight from 6 October) suggest, then a supplied field is being written into a frozen record and approval_status is being updated on it, with no version or state defined for that. If creative lands before agreed, agreement waits on human review and materials_due has no separate job. Either answer needs a sentence the draft does not have. The validation proposed here does not depend on the answer: it applies at the moment an asset is supplied, whenever that is. The scenario therefore places the upload during composition, which is the one point the draft clearly allows supplied fields to be written.

Same shape as #25. #25 proposes that a seller "MUST reject deterministically rather than ignore" a buyer-supplied exclusion type the seller did not declare. This is the same rule applied to the same marker: a supplied value outside the seller's declared space is rejected at submission with a structured error. The two should use one error shape.

Concrete scenario

From examples/line-item-display.yaml:

formats:
  available:  ["display/300x250", "display/728x90", "display/970x250"]
  included:   ["display/300x250"]
  pricing:    { "display/970x250": { delta_cpm: 3.00 } }
  max_select: 2
materials_due: "2026-09-24"
approval: { sla: "2 business days", revisions: 2 }     # illustrative; the draft gives no shape

On 2026-09-20 the buyer's agent composes the line item. It leaves formats untouched, so the resolved selection is display/300x250. It fills commitment (80,000 USD spend, flight 6 October to 21 December) and, in the same composition, supplies its creative ahead of the 2026-09-24 materials_due:

assets:
  - { asset_id: "cr-001", format_ref: "display/970x250",
      url_or_tag: "https://cdn.example/cr-001.html", submitted_at: "2026-09-20T10:00:00Z" }

Under the current text the composition is valid. formats resolved to its default, commitment is inside commitment_bounds, and the asset is a supplied field the buyer is entitled to fill. The proposal moves to under_review. Nothing checks the asset against the formats until a reviewer looks. On 2026-09-24, at the approval SLA, the seller sets approval_status: rejected because a 970x250 creative was supplied on a 300x250 buy. materials_due has now passed, the buyer must request a later date (requestable, seller assent), and must either resubmit a 300x250 or try to add 970x250, which until #22 has no selection key and which carries a 3.00 delta the buyer never agreed to. If the seller's implementation instead treated the upload as selecting 970x250, agreed_rate moved from 24.00 to 27.00 through a file upload. Two round trips, and possibly a price change, on a composition the draft counts as resolving without either.

With the proposed text the buyer's agent validates before submitting: display/970x250 is not in the resolved selection, so the asset is rejected locally on 2026-09-20 with { field: "assets[0].format_ref", id: "display/970x250", reason: "not_in_resolved_formats" }. The agent either swaps in a 300x250 creative, or, if it wants 970x250, writes selected: ["display/300x250", "display/970x250"] per #22, sees agreed_rate become 27.00, and then attaches the asset. The composition that reaches the seller is consistent, the price only moved because the buyer selected, and the proposal can proceed to agreed with nothing left to discover at review.

Knock-on effects

Would this break an implementation already built to this draft?

Yes — breaking

Alternatives you considered and rejected

  • Treat an asset in an available-but-unselected format as an implicit selection. Changes agreed_rate through a supplied action. The buyer did not choose the option, and the delta applies anyway. Rejected for that reason; the seller may still offer it as a counter through the normal selectable path.
  • Leave it to approval. Pushes a mechanical check to a human SLA and discovers the mismatch at the deadline. The draft's own round-trip claim argues against this.
  • Validate only when selected[] is present. Leaves the example's failure path open: the buyer who never touched formats is exactly the one who uploads the wrong size.
  • Require format_ref to be in available[] only. Catches garbage ids but not the mismatch. 728x90 is in available[] and still wrong for a 300x250 buy.
  • Drop the resolution requirement and validate ids as strings. Lets an id with no spec pass validation, so the buyer can satisfy the rule with a creative the seller cannot render. The inline-specs fallback is the minimum that makes the rule meaningful.

You are commenting as

AdTech Provider

Before you submit

  • I have read CONTRIBUTING.md and agree my contribution may be published under this repository's licence.
  • This contains no confidential or commercially sensitive information.

Activity

  1. aleksUIX commented on Oct 13, 2026

    @aleksUIX

    Could we make “format conformance” more specific in the proposed approval description?

    An asset can use the selected ctv/instream-15s format and resolve to a specification while still containing malformed VAST XML. The membership and resolution checks both pass, but neither checks the document. For a VAST URL, the response may also depend on macros filled at ad-request time, so it may not be possible to inspect that response during composition.

    I'd replace the sentence about format conformance at submission with:

    The format-reference and specification-resolution checks above MUST run at submission. Passing these checks does not establish that the creative document or its referenced resources conform to the selected specification.

    If the seller also inspects the XML or follows wrappers, the result should identify the asset and say which checks were completed. A check that was skipped or could not finish should be distinguishable from both a pass and a failure. Inspecting one response from a VAST URL also shouldn't imply that future responses have been checked.

    I'd keep those results separate from approval_status, which this issue assigns to content and policy review.

    Commenting in a personal capacity.

  2. Sirajmx commented on Oct 21, 2026

    @Sirajmx
    Contributor

    Thank you for filing this. It has been triaged and labelled for the working group, and will be considered at adjudication after the comment period closes on 22 October 2026. The wording suggested by @aleksUIX above will be considered with it. Related: #5, #25, #42.

  3. KonstantinMirin commented on Oct 22, 2026

    @KonstantinMirin

    Postindustria (IAB Tech Lab member) supports separating validation from review. Review can need several approvers, including the buyer; the record must say who approves, what silence means, and whose loss a rejection is.

    1. Name the approvers. approval.approvers[] of { party, properties[], response_window, on_silence: approved | blocked }; party: seller, buyer, or landlord domain. An asset runs where every approver approves or stays silent under approved.
    2. Hold seller-made creative. assets[] ("Buyer-delivered", § 5.4) should also hold build_owner: seller reads, with approval_status per approver.
    3. Say whose loss it is. approval.rejection_effect: excluded (the denied share isn't owed), shortfall (§ 5.7), or buyer_replaces. Under buyer_replaces, the buyer has until a date the seller sets to supply an asset the approver accepts; after that date, the share is excluded. Buyer delays aren't shortfalls.

    As drafted (§ 5.4):

    stateDiagram-v2
        state "approval_status, no values defined" as status
        [*] --> status : buyer supplies asset
        status --> [*] : ? reviewed by whom, under the approval SLA
        note right of status
            one status per asset
            assets[]: "Buyer-delivered"
            approval: "Review SLA and revision policy"
            ? venue landlord approval
            ? buyer approval of seller-made creative
            ? what silence means
            ? lost plays, shortfall or not
        end note
    
    Loading

    Proposed:

    stateDiagram-v2
        state "pending with each approver" as pending
        state "blocked, does not run" as blocked
        state "runs on the property" as runs
        [*] --> pending : buyer asset validated, or seller delivers its creative
        pending --> runs : every approver approves, or is silent with on_silence approved
        pending --> blocked : an approver is silent with on_silence blocked
        blocked --> runs : approver approves late
        blocked --> rejected : approver rejects
        pending --> rejected : any approver rejects
        rejected --> pending : within rounds, creative revised, or buyer_replaces, replacement in time
        rejected --> excluded : after last round, rejection_effect excluded, or buyer_replaces date passed
        rejected --> shortfall : after last round, rejection_effect shortfall
        note right of pending
            approvers per property
            seller, venue landlord, or
            buyer for seller-made creative
            assets[]: one approval_status per approver
        end note
        note right of blocked
            buyer late: not a seller shortfall
            landlord late: follows rejection_effect
        end note
    
    Loading

    Open questions:

    1. Answered by @premesh on @aleksUIX's #122. Should rejection_effect have only excluded and shortfall, or also buyer_replaces, where the buyer has until a set date to supply an asset the approver accepts before the share is excluded? Yes: item 3 adds buyer_replaces. In OOH, when an authority rejects copy, "the buyer supplies replacement creative and the flight holds, rather than the line cancelling."
    2. Should excluded apply only where per-property plays are fixed at agreement, as with allocation: all in our DOOH properties filing, or should lost delivery follow one rule across channels, such as the line-level not-aired rule in our programs and live events filing?
    3. We assume review runs after agreed; should the spec say so, or can review start while the terms are still open (our binding record, record_digest (#63), our comment that the lifecycle ends at agreed (#68))?
    4. Should approval_status use the AdCOM Audit Status Codes, or keep pending | approved | rejected with a stated mapping to them?
    5. Should a host read's approval stages, rounds, and windows be terms in approval, as proposed, or part of the format registry entry discussed in open question 4 on format registry entries (#5)?

    Related: placement restrictions (#53), physical OOH lead times (#78). Creative approval: rationale and examples

    Revised 2026-10-27: rejection_effect gains buyer_replaces, following @premesh on @aleksUIX's #122, which answers open question 1.

    Analyzed and generated with the help of Claude, fully reviewed by me.

  4. aleksUIX commented on Oct 25, 2026

    @aleksUIX

    Following up on my earlier format-conformance comment, I suggest a narrow addition to § 5.4: define the scope of a technical inspection claim without adding a general readiness or approval state.

    The format-reference checks in this issue, the production-notification rule in #42/#118, and content/policy approval answer different questions. The recent feedback on #118 also makes the boundary useful: result semantics belong here, while the notification rule can stand on its own.

    Proposed wording after the submission-validation rules:

    An implementation reporting a technical inspection outcome MUST identify the submitted asset, the inspected input or inputs, the applicable format reference and resolved specification when available, the checks performed, and the observation time. An unresolved specification MUST be identified as unresolved. The check procedure and version MUST be identifiable so that the outcome can be interpreted.

    For each check in the reported inspection scope, the implementation MUST distinguish a completed pass, a completed failure, and a check that did not complete. A check that did not complete MUST include a reason, such as not attempted, unsupported, unavailable input, or retrieval blocked by policy. A check that was skipped or could not finish MUST NOT be reported as passed. Inability to complete a check does not by itself establish creative nonconformance.

    A claim that all required technical checks passed MUST identify the specification or inspection profile that defines that required set. Every applicable required check MUST have completed successfully for the inspected inputs. An empty or unspecified check set MUST NOT be presented as proof of technical conformance. Passing format-reference and specification-resolution checks alone MUST NOT imply document, referenced-resource or media conformance.

    Reuse of an inspection outcome MUST be limited to the inputs and conditions for which its applicability is established. An unchanged URL does not establish unchanged response content. An observation of a dynamic response MUST NOT be represented as inspection of all future responses. Changed inspection-relevant content, resolved constraints or inspection context requires reassessing which previous outcomes remain applicable.

    A technical inspection outcome MUST NOT, by itself, be presented as content/policy approval or proof that the creative is ready for live delivery.

    Constructed examples:

    • The selected format and its specification resolve, but the supplied VAST XML is malformed. The reference checks pass; document parsing fails. There is no overall technical-conformance pass.
    • The outer document parses, but a required wrapper cannot be retrieved under the inspection policy. The wrapper check is incomplete with that reason, rather than passed or evidence that the creative itself is malformed.
    • A URL returns different creative bytes tomorrow. Yesterday's inspection still describes yesterday's response; it does not cover the replacement bytes merely because the URL matches.
    • The registry publishes specification v2 while the agreed selection remains pinned to v1. This alone does not invalidate an inspection against the agreed v1 specification. This follows the version-pinning work in [Change] § 5.4 — Pin each format's spec to a version and keep it in the agreed record #87.

    These are information requirements on a claim, not proposed JSON keys or enum values in assets[]. A channel profile can define the actual checks and representation. Inspection may retain content digests or immutable response references to distinguish what was observed; this does not require exposing raw URLs, credentials or macro values. Required checks should be distinguished from additional optional checks.

    The deterministic submission checks still resolve as proposed here. Document retrieval, media inspection and human approval do not become a new seller round trip required to compose a supplied field. The no-production-notification requirement remains with #42/#118; this addition does not authorize executing trackers or click redirects.

    These examples are proposed acceptance cases, not results from a deployed readiness service.

    Member of the IAB Tech Lab Agentic Taskforce, commenting in a personal capacity.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingWould break an implementation already built to this draftchange-requestProposes specific normative wordingnormativeChanges what the spec requiressection:5.4-creative

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions