Repository navigation
§ 2.4, § 2.5, § 2.7 — Errors, extensions, and forward compatibility (#130) - #138
Open
KonstantinMirin wants to merge 23 commits into
Open
KonstantinMirin wants to merge 23 commits into
KonstantinMirin wants to merge 23 commits into
Conversation
A proposal can say its line items must be bought together (linked_execution, § 4.1), and a line item can name the line items or spend that must be in the same commitment (requires, § 5.6.3). A bonus line is a line item with requires and its own price. The § 2 "binding terms" hook now points at a field, and the Summary Representation carries has_requires and linked_execution. Adds a CTV bonus line example (§ 6.5) and linked_execution: none to the proposal example. Refs IABTechLab#23
The seller declares which exclusion types it accepts and how it
enforces each (exclusions_accepted); the buyer supplies its lists
(exclusions). Blocked apps carry their store, { platform, bundle },
so one store id is never applied across stores. Exclusions are
recompute inputs (§ 3.3) and are never disclosed to other parties
(§ 5.8). The display example declares and supplies lists.
Refs IABTechLab#25
A commitment names the proposal and version it was priced against (§ 5.6.1). The seller rejects a new attempt on a stale version, or past valid_until or price_valid_until, and returns the current version. An authenticated replay with the same idempotency_key and terms returns the stored result without re-running those checks; the same key with different terms is a conflict. Keys are opaque and scoped to one buyer and seller pair. § 4.1 states that each revision while published increments version. The display, CTV and audio examples carry proposal_id and version. Refs IABTechLab#24
A new § 2.3 lets a seller publish its public standard line items at /.well-known/openproposal.json: seller_id, generated_at, spec_version and, per proposal, proposal_id, version, the Summary Representation of each line item and a full_url. ETag / Last-Modified are required, only line items with visibility public appear, and entries must match the current version. Buyers discover from the manifest, then fetch the Full Representation of shortlisted line items. Adds examples/manifest.json (§ 6.5) and visibility: public to the CTV and audio examples; the registry_gated display line item is not listed. Refs IABTechLab#29
The specification does not define authentication yet (WS1; see IABTechLab#62), so the replay rule now applies to a replay from the same buyer rather than an authenticated replay. Refs IABTechLab#24
The rule that a hold on a linked_execution: all proposal uses hold_scope: proposal came from a comment on IABTechLab#23, not the change request as filed. It moves to the PR description as a point for the working group, so this PR carries only the filed change. Refs IABTechLab#23
IABTechLab#25 names the content-category list iab_content_category[], a list of IAB Content Taxonomy ids. The earlier commit renamed it content_category with a version-pinned taxonomy_ref, which nobody proposed. This restores the filed name and shape; which taxonomy version to reference is left to the working group. Refs IABTechLab#25
Read the media condition from the ad served when an impression accepts several media, name the seller as the party that serves, place linear TV outside the table, and state environments as (distribution channel, device type) pairs. Insert environments.available[] into the summary list without rewrapping it, shorten the changelog entry and drop audio_streaming from OQ-7 in docs/open-questions.md. Refs IABTechLab#90
"At least one of" an empty list is never satisfied, so the bonus line would fail a literal check. An absent key sets no condition. Only the examples change; the any_of[] row and the rules stay as filed in IABTechLab#23. Refs IABTechLab#23
From the Postindustria review on IABTechLab#73: - a replay matches on the same body, every value the buyer sent except idempotency_key, and returns the stored result whether an acceptance or a rejection; a retry against a new version uses a new key; - version increments on each revision of the proposal, not only while published, so a counter under review also moves it; - "deterministic" now says what the checks depend on: the stored proposal and the time the seller receives the attempt; - the price check names the pricing[] entry the commitment is priced against. Refs IABTechLab#24
Give each repeated concept one type in section 2.2, and state the table, presence, type, key, and value rules in section 2.6. Add Type and Required columns to every field and key table. Add the lifecycle, recorded, asserted, and mixed markers, and a line_items[] field. Define the Summary as a strict path subset, with manifest key tables. Delete catalog_ref. Rename the time, reference, delta, cap, and path fields to use the shared types. Number every heading, and keep issue citations and edit history out of normative text. Update the examples, the manifest, the appendices, and the docs. Teach check_appendix.py the new columns and a closed layout list, and add check_examples.py, which checks the examples against the spec's tables.
Add section 2.4: a rejection returns errors[], one or more ErrorObjects with an open code list, retry values that read for any request, and informative HTTP fits. Name the code each rejection in sections 5.5, 5.6.1, and 5.6.3 returns, and drop the requires cycle ban. Add the Ext type and section 2.5: ext on the proposal and each line item, keyed by owner domain, ignored and kept when not understood, and frozen at agreed. Make spec_version a required proposal field, and ask in section 8 how a receiver reads a later release. Add informative security considerations in section 2.7. Word the open questions without a count. Update the examples and appendices, and teach check_examples.py the Ext type and the open ErrorObject.
This was referenced Nov 4, 2026
Open
Open
This was referenced Nov 4, 2026
Open
Open
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Draft 1 doesn't say what a rejection carries, or what a reader does with a key the draft doesn't define. This PR answers both.
errors[], one or moreErrorObjects, with ten core codes and aretryvalue. HTTP fits are informative. A decline isn't an error.requirescycle ban; our packages PR replacesrequires.Ext, and § 2.5 states its rules. The proposal (§ 4.1) and each line item (§ 5.1) MAY carryext.spec_versionis a REQUIRED proposal field (§ 4.1). § 8 question 8 asks how a receiver reads a later release.scripts/check_examples.pychecksExt, and treatsErrorObjectas open.Related issue
Closes #130, a change request from Postindustria (IAB Tech Lab member).
Refs #131, our extensions change request. This PR carries its text, and OQ-8 keeps tracking its question there.
Refs #33, #71, #73, #70.
Builds on
This PR builds on our shared types PR. It carries #71 by @Sirajmx and #73 by @Kishore-2572, at their heads. The merges give their new rows Type and Required cells. #71 drops its
catalog_refclause, and #73'svalid_untilreadsoffer_window.end. Review the last commit and the merges of #71 and #73.Type
Checklist
spec_version, andexton the proposal and the line item;scripts/check_appendix.pypassesseller-set33 → 36; 76 → 79 fieldsexamples/is updated and still parses —proposal.yamlgainsspec_versionandext,line-item-display.yamlgainsext;scripts/check_examples.pypassesspec_versionamong what the proposal supplies; each object carries its ownextselectabledeclaresavailable[]andincluded[]; anythingsettabledeclares bounds (§ 3.1, § 3.2) — no newselectableorsettablefieldsKnock-on effects
spec_versionis invalid. So is a key outsideextthat a key table doesn't list. A stale or expired commitment returns a code, not prose.exttakes the reserved-container answer of @VJAlkimi's #33. The skip bullet in § 2.5 follows @jaanijuk's implementation evidence.ErrorObjectbuilds on the shape in @VJAlkimi's #32. It answers the asks for a structured error from @aleksUIX and @fgranata on [Change] § 5.5 — Buyer-supplied block lists (exclusions_accepted, exclusions) #25, and from @EvgenyAndroid on #128.record_digestmismatch isrecord_mismatch, notvalidation.not_eligibleanswers [Change] § 2, § 5.5, § 5.6 — One error object for rejections: code, pointer, current version, retry #130's question 4.idempotency_conflicttests "a different body", as § 4.1, § 5.6.1 — Commitments carry proposal_id and version (#24) #73 defines it.record_digestand § 4.1.1, which therecord_mismatchrow cites. It pointsstale_versionat § 4.1.3, and extendsnot_committableandnot_offered.not_eligible, and the key a seller uses for its ownextentries.idempotency_conflicttest "a differentCommit".not_offered. The audience PR also typesexclusions_acceptedandexclusions, which stay pending.extonchange_requests[]entries (§ 4.4).extfollows OpenRTB 2.6, AdCOM 1.0, and OpenDirect 2.1, and adds keys by owner domain. The binding carrieserrors[], so nothing ties it to HTTP.By opening this pull request I agree my contribution may be published under this
repository's licence, as set out in CONTRIBUTING.md.
Analyzed and generated with the help of Claude, fully reviewed by me.