Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
# Changelog

## 3.3.0-beta.1

### Minor Changes

- 0555b8a: Add installments to the canonical Product used by the compact proposal lifecycle, and let a proposal buy named slots.

**Stable.** `core/canonical-product.json` gains `installments[]` of the new `core/canonical-installment.json`, closing the compact-lifecycle gap recorded in known limitations. The canonical installment is identified by the `(collection_ref, installment_id)` tuple alone: `collection_ref` is required, the deprecated publisher-domain-free `collection_id` shorthand is not inherited, a derivative names its source with `derivative_of.installment_ref`, and the shape is closed. `installments` requires `collections`, and joins the `list_products` `fields` projection — absence is run-of-collection only inside a projection that requested the field. Legacy `get_products` keeps `core/installment.json` unchanged, including its deprecated shorthand, because removing a declared property there would be a major change.

**Experimental** (`media_buy.installment_selection`). `media-buy/product-purchase.json` gains `installments[]`, so a proposal purchase names the exact slots it buys inside `commercial_terms` and therefore under `terms_digest`. Entries use the new closed `core/canonical-installment-ref.json` and are ordered by the JCS bytes of each reference, so equal bought sets always serialize to equal digests. `media-buy/proposal-refinement.json` gains `installment_changes` (`core/installment-change-set.json`) to drop or swap a slot on `revise`, forbidden on `finalize` and `extend_hold`; `refine-proposals-response.json` reports shortfalls through `unsatisfied_installment_changes`, which is also a witness for `constraint_unsatisfiable`. `installment_changes` joins `media_buy.proposal_refinement.supported_dimensions`, and declaring it requires `media_buy.installment_selection` in `experimental_features`.

`terms_digest` binds which slot identifiers were bought, not what the seller later publishes under them: installment references are deliberately not definition-pinned, and that bound is recorded in known limitations.
- 277e0a5: Compliance: define the collection fixture preparation contract for storyboards that must buy a real collection-bearing product. Adds the closed `collection_selection_satisfies` fixture-resolution operator, same-graph `context_outputs` captures (`path`, `snapshot: selected_entity`, seven named witnesses), the reserved `__adcp_fixture_` context namespace and reusable-preparation authorization rules, the authored `collection_set_equals_context` check, and the runner-synthesized `fixture_capture_unbuildable`, `protected_context_violation` and `prepared_fixtures_authorization` outputs. An authorization refusal is an access-control outcome: the refused caller receives a typed denial, not a grading result, and the complete result is retained unredacted in the host's authorized audit scope under every existing output MUST (#8254).
- 5e52313: Add experimental core gender audience targeting for AdCP 3.3 (`media_buy.gender_targeting`): female, male, and non_binary value sets; explicit independent unknown handling; product-scoped native/signals capabilities; exact gender-only and mixed age/gender targeting readback; sex_gender governance classification; and a conformance storyboard. Implementing sellers MUST declare the feature id in experimental_features. Preserve stable age targeting and whole-demographics mutation semantics.

Gender's `include_unknown` controls one unstated/unknown group covering both unavailable gender information and an explicit choice not to state gender (for example, "prefer not to say"). The wire field and named gender values are unchanged.

AdCP 3.2 core remains age-only. Buyers MUST NOT send core gender fields on a 3.2 contract; the bilateral 3.2 extension bridge is docs-only guidance and is not included in 3.3 source schemas.

AdCP 3.3 limitation: demographic-reporting-capability.json and canonical by_demographic delivery rows remain age-only. A gender-targeted package has exact targeting readback, but no canonical gendered delivery readback.
- c630be9: Add product creative-review timing, business-clock SLA windows with seller calendars, and an elapsed critical-report acknowledgement commitment. Add minimal report_media_buy_issue and get_media_buy_issue contracts for human acknowledgement and resolution status. Reporting remains independent of commercial change rights; review commitments pass from product policy to resolved buy actions.
- 563f199: Add experimental `media_buy.purchase_rights` (#8090): an optional `rights[]` array on `product-purchase.json` carries usage and amplification rights inside `commercial_terms`, so `terms_digest` and `accept_proposal` bind them. Rights are priced in the purchase, the media seller grants or warrants them, and exclusivity is per purchase. The array references a new `brand/rights-scope.json` (`uses`, `start_date`, `end_date`, `exclusivity`) hoisted from `brand/rights-terms.json`, which now composes it with `allOf` alongside its pricing fields. `rights-terms` properties and required fields are unchanged, with one tightening: an empty `uses` array is now rejected (`minItems: 1`). Generated types for this experimental surface may change shape. The `right-use` enum gains `paid_amplification` and `content_reuse`, covered by `brand.rights_lifecycle`; the enum is shared, so `rights-constraint` and `generation-credential` also accept them before attested grants exist. No rights grant is minted at acceptance; attested grants that a `rights-constraint` can cite are planned for 3.4.
- 3f6d145: Require package retention on canceled and completed media buys beginning with AdCP 3.3. Preserve records held at adoption and packages subsequently created or observed, including stable identities, correlation data, platform mappings, and the latest recorded committed configuration regardless of origin. Disclose irrecoverable earlier or never-observed external history through nonfatal errors rather than silently returning an incomplete list. Preserve prior terminal package outcomes and original cancellation metadata; the buy's terminal state stops all package serving. Released creative assignments remain released, and missing statistics must not be reported as zero delivery. Explicitly document that responses served as AdCP 3.2 permit empty terminal package lists and offer no retention guarantee.

Add a 3.3 stateful conformance scenario that verifies complete package readback after individual and whole-buy cancellation, including stable product and buyer mappings, a committed configuration update, and preserved earlier cancellation metadata.
- 163ba7e: Add optional structured package inputs to product-scoped get_products refinement for exact pre-booking availability checks. Share create-package field types and validation, require explicit per-entry forecast outcomes with configured product mapping and resolved flight timestamps, and define independent, read-only forecasting without booking or reserving inventory. The reference training seller explicitly reports unsupported package forecasts rather than acknowledging ignored inputs.

Compact media-buy MCP schema references using their embedded canonical resource IDs, preserving validation while keeping the shared package graph within the existing projection size budget.
- 0e341e6: Webhook-signing mode is now selected only by the seller's `legacy_hmac_fallback` capability and its per-counterparty onboarding record, not by a field in the registering request's body. Condition (b) of `request_signature_required` ("payload carries a field that triggers signing regardless of `required_for`") and the per-request `authentication` block as a mode trigger are deprecated in 3.x and removed in 4.0. The mode no longer comes from the body; rejection with the new code still reads the body, but it never changes mode or escalates authentication. This resolves the conflict with the "policy before body parsing" rule (adcp#7563). During the transition, a seller with `legacy_hmac_fallback: false` rejects a registration carrying `authentication.credentials` with the new `webhook_hmac_not_supported` (correctable by changing the registration, not retryable as-is) (HTTP 400) instead of `request_signature_required`; the code is added to `request-signing-error-code.json` on both `enumDescriptions` and `enumMetadata`. Sellers with `legacy_hmac_fallback: true` and no onboarding record keep the 3.x behavior. The documented-exception alternative is recorded as rejected: it makes the verifier parse unauthenticated bytes to decide whether they required authentication.

A verifier now rejects a JSON-RPC batch (a JSON array body) with `request_body_malformed` (SHOULD in 3.2.x, MUST from 3.3, per the existing hardening schedule), replacing the 3.2 interim rule that let a verifier resolve every element (adcp#7565). A signed AdCP request carries exactly one JSON-RPC message.

Conformance: vector `request-signing/negative/027` (and its 3.2 mirror) now declares `applies_when: "webhook_signing.legacy_hmac_fallback == true"` and is graded only for such agents. The functional create fixtures in `media_buy_seller` (two steps), `create_media_buy_async`, `creative_generative/seller` and `sales_broadcast_tv` no longer send `push_notification_config.authentication`, so a signing seller with `legacy_hmac_fallback: false` is not forced to fail either 027 or an unrelated create step. Webhook-emission grading of the 9421 baseline is unchanged.

Composition with the 3.3 rule that `reporting_webhook` and `artifact_webhook` may omit `authentication` (adcp#8177): the same capability-only selection applies to every webhook registration. On those two registrations the new code and condition (b) apply only to a request served at 3.3 or later, because `authentication` stays required on a request served below 3.3 and so carries no preference signal there.

### Patch Changes

- 212360e: Collection selection and owner-sold carriage checks now discover native wholesale sandbox products instead of seeding invented collection support. Six independent scopes cover selectable subsets, one-pair default materialization, fixed bundles (omitted or false targeting flag), and structural cross-publisher selection. A completed valid catalog with no qualifying product reports `not_applicable` (`fixture_unsatisfied`): the feature was not tested, not passed or proven unsupported. Discovery and selected-path errors still fail.

Selectors, negative witnesses and commercial terms come from the same selected product/price graph. Exact echoes compare domain-qualified sets without assuming illustrative collection names, domains or prices. Two separately tool-gated companions retain persisted subset/default checks without making optional `get_media_buys` support a prerequisite for creation. Only non-guaranteed, fixed-price CPM catalog products are covered; seeded-only and brief-only support remains outside this evidence.

Completes #8254 with the reporting correction in #8336. No seller capability field, controller seed-refusal rule or released artifact is changed.
- 3e94f5e: `advanced_delivery_reporting` no longer seeds a video product. It grades
format-breakdown reporting only when your wholesale sandbox catalog contains a
non-guaranteed, fixed-price CPM product with
`reporting_capabilities.supports_format_breakdown: true`. When completed valid
catalog discovery finds no qualifying product, it reports `not_applicable`
(`fixture_unsatisfied`). Time-based-view checks move to a new
`time_based_delivery_reporting` storyboard, selected independently from native
wholesale sandbox products listing `time_based_views`, with the same
non-guaranteed, fixed-price CPM restriction. Neither requires a specific threshold, basis, format
kind or non-empty rows. Partially addresses #8254; collection storyboards are
unchanged.
- e2f2d3a: Schema: `display_tag` declares `macro_declarations`, `provenance`, `width`, `height`, and `sizes` once on the base object. Each `delivery_type` branch now only narrows `macro_declarations[].location.field` to its own fields, the same way `vast` and `daast` already do. The set of valid assets is unchanged. When every `$ref` is written out in full, the asset drops from ~280 KB to ~74 KB (#8374).
- 7bb86ad: Release tooling: forward merges from the 3.0, 3.1 and 3.2 maintenance lines into main no longer drop main's own release records. `CHANGELOG.md` keeps main's file and inserts each maintenance release block it lacks, in semver order. `static/compliance/published-versions.json` takes the union of both lines' registered versions. `dist/schemas/index.json` and `latest.json` are regenerated from the merged release directories after every merge. Before this, the workflows took the maintenance copies wholesale, which would have deleted main's `3.3.0-beta.0` changelog section and schema-discovery entry at 3.2.6. `scripts/build-schemas.cjs` now exports `writeRootSchemaDiscovery` for the resolver.
- a401fda: docs(compliance): say what `preview` specialism status actually means, and when a preview specialism is promoted

The compliance catalog and conformance page described `preview` as a placeholder storyboard that the runner grades as `passed: null`, with badges showing a distinct indicator. That is no longer true: ten of the eleven preview storyboards are fully authored and graded pass or fail, and what preview actually changes is that the claim does not count toward AAO Verified badge issuance or eligibility. The definition now says that, adds the criteria for promoting a preview specialism to `stable`, and the `sponsored-intelligence` placeholder narrative no longer cites the `passed: null` contract.

## 3.3.0-beta.0

### Minor Changes
Expand Down
Loading
Loading