Skip to content

[Change] § 2, § 4.1, § 5.1 — Add #33's ext container: keyed by domain, ignored when unknown, kept in the agreed record #131

Open

Description

@KonstantinMirin

What kind of change?

Add a new field

Which section?

Whole document / more than one section

Current text

n/a — new field. Related text, unchanged:

§ 2: Each line item MUST be fully self-contained. A field on a line item MUST
NOT inherit its value from the proposal or from a sibling line item.

§ 2.2: When a proposal reaches status `agreed`, every `catalog_ref` MUST be
replaced by its resolved value in the stored record, so the committed artifact
is self-contained and immutable.

Proposed text

§ 4.1 and § 5.1, add a row to each table:

| `ext` | Object | seller-set | OPTIONAL. See Extensions (§ 2) |

§ 2, add a subsection:

### Extensions

The proposal and each line item MAY carry `ext`. Each key MUST be a domain
that its owner controls, and each value is an object that the owner defines.
A seller's own entries MUST use its `seller_domain` as the key.

    ext:
      examplepub.com: { placement_code: "BD-ROS-300x250-Q4" }

- An `ext` entry MUST NOT change the meaning of a field this specification
  defines. A term the counterparty must understand to transact MUST NOT be an
  `ext` entry; it is a field or a vocabulary term.
- A receiver MUST ignore an `ext` entry it does not understand, and MUST NOT
  reject a document because of it. It MUST keep `ext` unchanged when it
  stores or forwards the document.
- In an object whose keys this specification lists, a key outside `ext` that
  it does not list is invalid. An object whose content another definition
  sets, such as `specs` (the format registry entry), is unaffected.
- `ext` is part of the Full Representation and of the record frozen at
  `agreed` (§ 2.2). A seller change to `ext` is a revision.
- A receiver MAY skip a whole line item it cannot read, without assenting to
  it. It MUST NOT keep a line item after removing fields from it.

Why

@VJAlkimi's unknown-key comment (#33) found the gap: no rule says what a parser does with a key the draft doesn't define. It offers two answers. We ask for the second, as written: ext on the proposal and each line item, kept unchanged and frozen at agreed. Undefined keys elsewhere are invalid. We add domain keys and a no-override rule.

#33 shows the cost. A strict parser rejects a seller's placement code, a lenient one drops it, and the two agreed records differ.

Implementers already need one. On its unmerged feat/openproposal-mapping branch, IAB Tech Lab's reference seller agent adds ext to its OpenProposal line item. On every line item it maps from Google Ad Manager in the branch's examples, its mapper keeps fields with no OpenProposal home there. Yet its line-item model, in @jaanijuk's test, silently drops six undefined fields.

IAB standards share the placement. OpenRTB 2.6, § 2.9: "Any object may contain extensions … named ext." § 2.6: receivers "must tolerate receiving new or unexpected fields". AdCOM 1.0, OpenDirect 2.1, and the Deals API 1.0 put ext on their objects.

OpenRTB leaves ext unstructured, so two vendors can pick the same key. #33 writes reverse-DNS keys. We key by domain, the owner prefix that our cost-method change request (#94) and our cancellation and exclusivity change request (#98) give vocabulary terms. One owner domain then names terms, ext entries, and extension error codes.

A proposal binds, so it needs rules that OpenRTB doesn't. #33 gives two, keep and freeze; we add no override:

The other rules apply existing text. ext is seller-set (§ 3). A seller change is a new version, because our versioning change request (#64) counts every seller write. Each object carries its own ext, under the no-inheritance rule (§ 2).

Details: Extensions: full rationale and examples

Knock-on effects

Open questions for the working group

  1. Should an ext key be a domain (examplepub.com), as proposed, matching the <domain>:<name> prefix in our cost-method change request (#94)? Or a reverse-DNS key per entry (com.examplepub.placement_code), as #33 writes it? Either way, one form should serve vocabulary terms, ext keys, and extension error codes.
  2. How does a receiver built to one release read a document from a later release that adds keys? It could reject them as undefined, as proposed. That needs each document to name its release, like spec_version in @Kishore-2572's well-known manifest (PR #76). Or it could ignore unknown keys anywhere, as OpenRTB 2.6, § 2.6 does, which weakens the no-override rule. The skip rules for an unknown cost_method (#94) and channel (PR #119) meet the same question.
  3. Should ext also go on other objects, such as a pricing[] entry, commitment, or a negotiation_history[] entry? The reference seller agent puts one on its history entry. OpenRTB 2.6 and AdCOM 1.0 allow it on any object. Each would need a marker and a binding-record rule.
  4. Answered in part by @jaanijuk: Should an entry be able to require that a receiver understand it? VAST 4.3, § 3.18 requires that of every extension, and JWS crit (RFC 7515, § 4.1.11) allows it per header. Or is the no-override rule enough, as proposed? They propose that a binding ext term need explicit acceptance before agreed, or the line item is rejected. One mechanism is a list of keys the receiver must understand, like crit. Informational entries, such as ext.gam, are ignored, as proposed. Still open: whether the working group wants that list or the no-override rule, which keeps binding terms out of ext.
  5. May a summary in § 2.1 and the manifest in PR #76 carry ext, so that screening agents see an entry?
  6. Should the AAMP hub state one extension rule for OpenProposal and the primitives? The primitives use ext as the single extension slot, reserve x_, and drop what they don't know on re-serialization. This change request keys ext by domain and keeps it.

Would this break an implementation already built to this draft?

No — additive or editorial

Alternatives you considered and rejected

You are commenting as

Other — IAB Tech Lab member (Postindustria).

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.

Revised 2026-10-28: Adds @jaanijuk's skip rule and branch evidence from #33.

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

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions