Repository navigation
[Change] § 2, § 4.1, § 5.1 — Add #33's ext container: keyed by domain, ignored when unknown, kept in the agreed record #131
Description
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:
- No override. Ignoring an entry is safe only if it can't change the agreed terms. A term the buyer must understand belongs in a field, or in a vocabulary term with a skip rule. Under [Change] § 5.6 — Give cost_method an extensible vocabulary, and say what several pricing[] entries mean #94 an unknown
cost_methodmakes its entry unavailable. Under our channel definitions PR (#119) a receiver skips a line item with an unknownchannel. - Keep it ([Comment] § 2 — The draft does not say what a parser does with a key it does not define #33). Our binding-record change request (#63) digests the Full Representation minus a fixed list, and
extisn't on it. A party that strips an entry breaksrecord_digest, so assent catches [Comment] § 2 — The draft does not say what a parser does with a key it does not define #33's mismatch. - Frozen at
agreed([Comment] § 2 — The draft does not say what a parser does with a key it does not define #33). Ids assigned after agreement, such as an ad server line id, go inexternal_references[](§ 5.10), outside the digest.
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
- Appendix A and Appendix B: two
seller-setrows. - The print object in @matthew-iabtechlab's print channel request (#102) and the
oohobject in @premesh's static OOH comment (#125) are specification fields, notext. - A receiver rejects a document with an undefined key with
validation, under our error-model change request. - A schema derived from the text, as in our schema implementation feedback (#121), sets
additionalProperties: falseon the objects whose keys the text lists.
Open questions for the working group
- Should an
extkey 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,extkeys, and extension error codes. - 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_versionin @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 unknowncost_method(#94) andchannel(PR #119) meet the same question. - Should
extalso go on other objects, such as apricing[]entry,commitment, or anegotiation_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. - 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 bindingextterm need explicit acceptance beforeagreed, or the line item is rejected. One mechanism is a list of keys the receiver must understand, likecrit. Informational entries, such asext.gam, are ignored, as proposed. Still open: whether the working group wants that list or the no-override rule, which keeps binding terms out ofext. - May a summary in § 2.1 and the manifest in PR #76 carry
ext, so that screening agents see an entry? - Should the AAMP hub state one extension rule for OpenProposal and the primitives? The primitives use
extas the single extension slot, reservex_, and drop what they don't know on re-serialization. This change request keysextby domain and keeps it.
Would this break an implementation already built to this draft?
No — additive or editorial
Alternatives you considered and rejected
- The strict answer in [Comment] § 2 — The draft does not say what a parser does with a key it does not define #33. Vendor data moves into
specificationsorcontent_detailprose, where no agent can parse it reliably. - Flat keys with a reserved prefix, as the primitives reserve
x_. Extension keys mix with defined ones, and a prefix names no owner. extoutside the binding record. An intermediary could change it without breakingrecord_digest.
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