Skip to content

fix(schemas): open the 3.3 schemas that were meant to be open - #8866

Merged
bokelley merged 31 commits into
mainfrom
fix/open-closed-schemas-3-3
Nov 12, 2026
Merged

bokelley merged 31 commits into
mainfrom
fix/open-closed-schemas-3-3

Conversation

@bokelley

@bokelley bokelley commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

On 2026-11-09 the working group decided that 3.x opens the schemas that were meant to be open. Closing a schema only breaks validators that hard-code it, so opening one is not a protocol break. This PR makes that change for 3.3 on main. The next 3.2.x patch (#8864) backports it from the same inventory; 3.2.10 shipped without it.

Refs #8501. The re-triage of its 26 entries and the withdrawal drafts is posted there separately.

What stays closed, and why

Brian approved the kept-closed list on 2026-11-09. After Konstantin's review, the get_principal current branch and the sync_principal applied and validated branches open, which brings it to 112 locations. The commercial terms and proposal-budget-constraint are held closed until 4.0, as a hold rather than a structural reason.

Reason Count Why
oneOf disjointness 9 The oneOf branches are told apart only by which keys are present. Opening some of them (a2ui bound-value 0 and 3, brand.json 1 and 2) lets a payload that is valid for a sibling branch today also match them, so the oneOf would reject it. The other closed branches of the same union stay closed too: an open branch beside a closed one accepts a payload carrying a sibling's keys, which a reader that dispatches on key presence misreads.
Closed key set (no free text to agents) 1 Its description makes closure the contract: a typed setup action with human-readable text deliberately excluded, so a seller cannot put free text in front of a buyer agent here.
Closed key set (credential-free configuration) 10 Reporting destinations are credential-free by contract: destination_ref is an opaque routing reference, and the seller never accepts or returns credential material. Closure rejects credentials under any name (credentials, token, secret); no list of forbidden names could be complete.
Held closed until 4.0 (commercial terms) 26 A hold, not a structural reason. terms_digest covers every member of commercial_terms at every depth, open members included, so closure does not stop a buyer accepting a term it ignored. These objects stay closed until 4.0 gives commercial_terms a declared extension point with must-understand; new terms wait for it.
Closed key set (canonical identity) 2 Canonical identity: only the identity members are permitted, so one installment has one reference value and a set of references always serializes to the same JCS bytes. Extra keys would change the identity.
Closed key set (join key) 21 The key set identifies the row: consumers join and reconcile on (vendor, metric_id, qualifier) or on forecast dimensions. A reader that ignored an unknown key would merge rows that measure different things. DR-0019 class A.
Closed key set (privacy boundary) 19 Closure is how the schema enforces a MUST NOT on what the message carries: the TMP identity request carries no page context and the context request carries no identity (data minimization), and the not-found error, the per-agent PERMISSION_DENIED and BILLING_NOT_PERMITTED_FOR_AGENT details, the error objects of the reporting-status lookup_unavailable failure, the get_principal recognized, unconfigured and failed results and the sync_principal failed result have one invariant shape, so they cannot become an existence, commercial-state or cross-principal oracle, and carry no durable identifier a dry run must not issue (their descriptions and error-handling.mdx state the clamp).
Map keyed by identifier 5 patternProperties plus additionalProperties:false validates the map keys (component or slot IDs). It is a key-format check on a map, not a closed field list, so opening it only stops validating keys.
Closed key set (no key material or markup) 18 Closure keeps an open-ended class of content out of a security-sensitive document. trust.json sits on the signature-verification fetch path, and signing keys are published only in the key directory, so its records, agents, grants and acknowledgements carry no key material (jwks_uri, key pins, signing profiles) and no undeclared authority. placement-presentation is a declarative, non-executable frame that consumers render, so it carries no markup or script. A list of forbidden names could never be complete for either.
Signature envelope 1 Fixed JWS envelope for the response-signing profile (protected, payload, signature). An extra member would be unsigned data that a reader could take as signed.
All 112 kept-closed locations
File Pointer Reason
a2ui/bound-value.json /oneOf/0 oneOf disjointness
a2ui/bound-value.json /oneOf/1 oneOf disjointness
a2ui/bound-value.json /oneOf/2 oneOf disjointness
a2ui/bound-value.json /oneOf/3 oneOf disjointness
a2ui/bound-value.json /oneOf/4 oneOf disjointness
brand.json /oneOf/0 oneOf disjointness
brand.json /oneOf/1 oneOf disjointness
brand.json /oneOf/2 oneOf disjointness
brand.json /oneOf/3 oneOf disjointness
core/agent-reporting-destination-state.json /properties/setup Closed key set (no free text to agents)
core/agent-reporting-destination.json /oneOf/0 Closed key set (credential-free configuration)
core/agent-reporting-destination.json /oneOf/1 Closed key set (credential-free configuration)
core/agent-reporting-destination.json /oneOf/2 Closed key set (credential-free configuration)
core/bidding-policy.json (root) Held closed until 4.0 (commercial terms)
core/bidding-policy.json /properties/cost_per Held closed until 4.0 (commercial terms)
core/bidding-policy.json /properties/roas Held closed until 4.0 (commercial terms)
core/canonical-budget-allocation.json /oneOf/0 Held closed until 4.0 (commercial terms)
core/canonical-budget-allocation.json /oneOf/1 Held closed until 4.0 (commercial terms)
core/canonical-installment-ref.json (root) Closed key set (canonical identity)
core/canonical-installment-ref.json /properties/collection_ref Closed key set (canonical identity)
core/canonical-measurement-terms.json (root) Held closed until 4.0 (commercial terms)
core/canonical-measurement-terms.json /properties/billing_measurement Held closed until 4.0 (commercial terms)
core/canonical-measurement-terms.json /properties/makegood_policy Held closed until 4.0 (commercial terms)
core/canonical-metric-qualifier.json (root) Closed key set (join key)
core/canonical-performance-standard.json (root) Held closed until 4.0 (commercial terms)
core/canonical-pricing-option.json (root) Held closed until 4.0 (commercial terms)
core/canonical-reporting-commitment.json /oneOf/0 Held closed until 4.0 (commercial terms)
core/canonical-reporting-commitment.json /oneOf/1 Held closed until 4.0 (commercial terms)
core/catalog-item-reference-not-found-error.json (root) Closed key set (privacy boundary)
core/committed-metric.json /oneOf/0/properties/qualifier Closed key set (join key)
core/committed-metric.json /oneOf/1/properties/qualifier Closed key set (join key)
core/creative-asset.json /properties/component_assets Map keyed by identifier
core/creative-localization-readback.json /definitions/resolvedAssets Map keyed by identifier
core/creative-localization.json /properties/target_variants/items/properties/assets Map keyed by identifier
core/creative-manifest.json /properties/component_assets Map keyed by identifier
core/delivery-metric-aggregate.json /oneOf/0/properties/qualifier Closed key set (join key)
core/delivery-metric-aggregate.json /oneOf/1/properties/qualifier Closed key set (join key)
core/forecast-dimension-audience.json (root) Closed key set (join key)
core/forecast-dimension-device-platform.json (root) Closed key set (join key)
core/forecast-dimension-device-type.json (root) Closed key set (join key)
core/forecast-dimension-geo.json (root) Closed key set (join key)
core/forecast-dimension-placement.json (root) Closed key set (join key)
core/forecast-dimension-signal.json (root) Closed key set (join key)
core/forecast-dimension-time.json (root) Closed key set (join key)
core/missing-metric.json /oneOf/0/properties/qualifier Closed key set (join key)
core/missing-metric.json /oneOf/1/properties/qualifier Closed key set (join key)
core/performance-feedback-metric.json /oneOf/0/properties/qualifier Closed key set (join key)
core/performance-feedback-metric.json /oneOf/1/properties/qualifier Closed key set (join key)
core/performance-feedback.json /properties/metric/oneOf/0/properties/qualifier Closed key set (join key)
core/performance-feedback.json /properties/metric/oneOf/1/properties/qualifier Closed key set (join key)
core/placement-presentation.json (root) Closed key set (no key material or markup)
core/placement-presentation.json /properties/canvas Closed key set (no key material or markup)
core/placement-presentation.json /properties/creative_slot Closed key set (no key material or markup)
core/placement-presentation.json /definitions/rectangle Closed key set (no key material or markup)
core/placement-presentation.json /definitions/box_decoration Closed key set (no key material or markup)
core/placement-presentation.json /definitions/text_decoration Closed key set (no key material or markup)
core/placement-presentation.json /definitions/image_decoration Closed key set (no key material or markup)
core/placement-presentation.json /definitions/image_decoration/properties/image_ref Closed key set (no key material or markup)
core/reporting-dataset-share-destination.json /oneOf/0 Closed key set (credential-free configuration)
core/reporting-dataset-share-destination.json /oneOf/1 Closed key set (credential-free configuration)
core/reporting-dataset-share-destination.json /oneOf/1/properties/provider Closed key set (credential-free configuration)
core/reporting-dataset-share-destination.json /oneOf/1/properties/recipient Closed key set (credential-free configuration)
core/reporting-write-destination.json /oneOf/0 Closed key set (credential-free configuration)
core/reporting-write-destination.json /oneOf/1 Closed key set (credential-free configuration)
core/reporting-write-destination.json /oneOf/1/properties/provider Closed key set (credential-free configuration)
core/response-payload-jws-envelope.json (root) Signature envelope
core/sla-window.json (root) Held closed until 4.0 (commercial terms)
core/vendor-metric-value.json /properties/qualifier Closed key set (join key)
creative/list-creatives-response.json /properties/creatives/items/properties/component_assets Map keyed by identifier
error-details/agent-permission-denied.json (root) Closed key set (privacy boundary)
error-details/billing-not-permitted-for-agent.json (root) Closed key set (privacy boundary)
media-buy/change-term-constraints.json /oneOf/0 Held closed until 4.0 (commercial terms)
media-buy/change-term-constraints.json /oneOf/1 Held closed until 4.0 (commercial terms)
media-buy/change-term-constraints.json /oneOf/2 Held closed until 4.0 (commercial terms)
media-buy/change-term-constraints.json /oneOf/3 Held closed until 4.0 (commercial terms)
media-buy/change-term-constraints.json /definitions/money Held closed until 4.0 (commercial terms)
media-buy/change-term.json (root) Held closed until 4.0 (commercial terms)
media-buy/commercial-terms.json (root) Held closed until 4.0 (commercial terms)
media-buy/commercial-terms.json /properties/total_budget Held closed until 4.0 (commercial terms)
media-buy/commercial-terms.json /properties/reporting_commitments/items Held closed until 4.0 (commercial terms)
media-buy/commercial-terms.json /properties/cancellation_terms Held closed until 4.0 (commercial terms)
media-buy/commercial-terms.json /properties/cancellation_terms/properties/fee Held closed until 4.0 (commercial terms)
media-buy/get-reporting-status-response.json /oneOf/1/oneOf/0/properties/adcp_error Closed key set (privacy boundary)
media-buy/get-reporting-status-response.json /oneOf/1/oneOf/0/properties/errors/items Closed key set (privacy boundary)
media-buy/package-request.json /properties/committed_metrics/items/oneOf/0/properties/qualifier Closed key set (join key)
media-buy/package-request.json /properties/committed_metrics/items/oneOf/1/properties/qualifier Closed key set (join key)
media-buy/product-purchase.json (root) Held closed until 4.0 (commercial terms)
media-buy/proposal-budget-constraint.json (root) Held closed until 4.0 (commercial terms)
protocol/get-principal-response.json /properties/result/oneOf/1 Closed key set (privacy boundary)
protocol/get-principal-response.json /properties/result/oneOf/2 Closed key set (privacy boundary)
protocol/get-principal-response.json /properties/result/oneOf/3 Closed key set (privacy boundary)
protocol/sync-principal-response.json /properties/result/oneOf/2 Closed key set (privacy boundary)
trust/v1/trust.json /definitions/agent Closed key set (no key material or markup)
trust/v1/trust.json /definitions/agent/properties/profiles/allOf/1/properties/adcp Closed key set (no key material or markup)
trust/v1/trust.json /definitions/granted_agent Closed key set (no key material or markup)
trust/v1/trust.json /definitions/grant Closed key set (no key material or markup)
trust/v1/trust.json /definitions/grant/properties/profiles/allOf/1/properties/adcp Closed key set (no key material or markup)
trust/v1/trust.json /definitions/acknowledgement Closed key set (no key material or markup)
trust/v1/trust.json /definitions/acknowledgement/properties/profiles/allOf/1/properties/adcp Closed key set (no key material or markup)
trust/v1/trust.json /definitions/record_profiles/allOf/1/properties/adcp Closed key set (no key material or markup)
trust/v1/trust.json /oneOf/0 Closed key set (no key material or markup)
trust/v1/trust.json /oneOf/1 Closed key set (no key material or markup)
trusted-match/context-match-request.json (root) Closed key set (privacy boundary)
trusted-match/context-match-request.json /properties/artifact_refs/items Closed key set (privacy boundary)
trusted-match/context-match-request.json /properties/geo Closed key set (privacy boundary)
trusted-match/context-match-request.json /properties/geo/properties/metro Closed key set (privacy boundary)
trusted-match/context-match-request.json /properties/context_signals Closed key set (privacy boundary)
trusted-match/identity-match-request.json (root) Closed key set (privacy boundary)
trusted-match/identity-match-request.json /properties/identities/items Closed key set (privacy boundary)
trusted-match/identity-match-request.json /properties/identities/items/properties/attestation Closed key set (privacy boundary)
trusted-match/identity-match-request.json /properties/consent Closed key set (privacy boundary)
trusted-match/identity-match-request.json /properties/sealed_credentials/items Closed key set (privacy boundary)

Named rejections in opened schemas

Each node opens and keeps rejecting the named fields in not: { anyOf: [{ required: [...] }] }, and its description (or its union's) says what it rejects and why, because generated types can't express not. A rejection names only a field the protocol defines elsewhere or forbids there; probes for names defined nowhere now expect acceptance. The key-presence guards (account-ref, canonical-account-ref, image bleed, geo-region requirement and support countries, postal-area, sync-reporting-receipts-response results) keep union forms apart. Paths are under static/schemas/source/.

File Pointer Rejected by name
compliance/comply-test-controller-response.json /definitions/SetAccountTimezoneResult/properties/timezone_cutovers/items changed_at
core/account-identity-change.json /oneOf/0 reason
core/account-ref.json /oneOf/0 brand, currency, operator, operator_unit, sandbox, timezone
core/account-ref.json /oneOf/1 account_id
core/account-status-changed-webhook.json /properties/setup url
core/agent-notification-config-state.json /properties/authentication credentials
core/assets/display-tag-asset.json /properties/sizes/items unit
core/assets/html-asset.json /properties/sizes/items unit
core/assets/zip-asset.json /properties/sizes/items unit
core/attestation-reference.json (root) confidence, decision
core/audience-source.json /oneOf/0 segment_ref
core/audience-source.json /oneOf/1 access_expires_at, locator
core/bidding-policy-capability.json /definitions/scope_capability cost_per_strengths, modes, roas_strengths, supported_combinations
core/canonical-account-ref.json /anyOf/0 brand, currency, operator, operator_unit, sandbox, timezone
core/canonical-account-ref.json /anyOf/1 account_id
core/canonical-format-option.json (root) v1_format_ref
core/canonical-installment.json (root) collection_id
core/canonical-placement.json (root) format_ids
core/canonical-product-action.json (root) review_sla
core/canonical-proposal.json /properties/holds/items expires_at
core/collection.json /properties/related_collections/items publisher_domain
core/geo-place-requirement.json (root) max_packages, max_values_per_package
core/geo-region-requirement.json (root) max_packages, max_values_per_package
core/geo-region-requirement.json /properties/countries/additionalProperties/anyOf/0 values
core/geo-region-requirement.json /properties/countries/additionalProperties/anyOf/1 all_values
core/geo-region-support.json /properties/countries/additionalProperties/anyOf/0 values
core/geo-region-support.json /properties/countries/additionalProperties/anyOf/1 all_values
core/inventory-list-application.json /oneOf/0 auth_token
core/inventory-list-application.json /oneOf/1 auth_token
core/media-buy-issue.json (root) revision, sla
core/outcome-target-cost-per.json (root) max_bid
core/placement-selection.json /oneOf/1 placement_refs
core/postal-area.json /anyOf/1 country
core/product-allowed-action.json (root) review_sla
core/product-offer-filters.json /properties/availability_horizon timezone
core/proposal-created-webhook.json (root) proposal
core/proposal-offered-webhook.json (root) commercial_terms, opportunity_id
core/reporting-delivery-ready-webhook.json (root) access_token
core/reporting-revision.json (root) destination_ref
core/reporting-subscription.json /properties/selector offering_id
core/requirements/image-asset-requirements.json /properties/bleed/oneOf/0 bottom, left, right, top
core/requirements/image-asset-requirements.json /properties/bleed/oneOf/1 uniform
core/signal-delivery-method.json /oneOf/2 consumer_identities
core/signal-delivery-method.json /oneOf/4 bind_expiry_days, destination_ref
core/targeting-overlay-requirements.json /definitions/metroRequirement/anyOf/1 max_packages, max_values_per_package
core/targeting-overlay-requirements.json /properties/geo_proximity/anyOf/1 max_values_per_package
creative/creative-status-changed-webhook.json (root) staged_update
creative/sync-creatives-request.json /properties/assignment_operations/items/oneOf/1 landing_page_url, trackers
creative/sync-creatives-request.json /properties/assignment_operations/items/oneOf/2 landing_page_url, trackers
creative/sync-creatives-request.json /properties/assignment_operations/items/oneOf/3 landing_page_url, trackers, weight
media-buy/get-media-buy-issue-request.json (root) context_id
media-buy/get-products-request.json /properties/refine/items/oneOf/0 package
media-buy/get-products-request.json /properties/refine/items/oneOf/2 package
media-buy/outcome-target.json /properties/goal/oneOf/2 metric, target
media-buy/report-media-buy-issue-request.json (root) acknowledged_at, context_id, status
media-buy/sync-reporting-receipts-response.json /properties/results/items/anyOf/0 adjustment_receipt
media-buy/sync-reporting-receipts-response.json /properties/results/items/anyOf/1 adjustment_receipt
media-buy/sync-reporting-receipts-response.json /properties/results/items/anyOf/2 receipt
media-buy/sync-reporting-receipts-response.json /properties/results/items/anyOf/3 receipt
media-buy/sync-reporting-receipts-response.json /properties/results/items/anyOf/4 adjustment_receipt, receipt
governance/sync-plans-request.json /properties/plans/items version, status, syncedAt, revisionHistory, committedBudget, committedByType
protocol/get-adcp-capabilities-response.json /properties/adcp/properties/implementation approved
protocol/get-adcp-capabilities-response.json /properties/adcp/properties/implementation/properties/sdks/items approved
protocol/sync-principal-response.json /properties/result/oneOf/1 configuration_version, destination_ref

The assign branch of sync_creatives opens with no named rejection. Its operation const keeps the branches apart, so #8772's named exception for trackers and landing_page_url isn't needed.

Additive-minor lint

Docs and changesets

  • Migration guide. In the 3.2 to 3.3 guide, "Closed schemas stay closed within a major" becomes "Schemas are open by default". It covers what opened, why the rest stay closed, and what that means for validators, generated types and 3.2 peers.
  • Other 3.3 pages. The 3.3 beta page, What's new, the release notes and the 4.0 compatibility guide are updated to match.
  • Pending changesets. Changesets under .changeset/pre/ that cited "a minor never changes a closed schema" or a lettered DR-0036 correction now cite the hold (commercial_terms is held closed until 4.0) or DR-0024.
  • New changeset. open-schemas-meant-to-be-open.md (minor) says what opened and that generated types change: json-schema-to-typescript adds index signatures to opened objects, and Pydantic models stop forbidding extra fields.
  • Not touched. docs/reference/versioning.mdx and the decision records are left to docs(governance): DR-0036 records open schemas within a major; withdraw DR-0032 and DR-0033 #8858.

Compatibility

  • Nothing that was valid becomes invalid.
  • A strict validator built from 3.2.9 or earlier still rejects 3.3 fields on these objects, so a 3.3 field goes only to a 3.3 peer (DR-0024).
  • SDK type generators that honour additionalProperties see the opened objects as open.

Test plan

Base: rebased onto 811443077e (with the 3.2.9 forward-merge) for the review round, then origin/main (7ce107aa47, with the 3.2.10 forward-merge) merged in at 155896fbcd on 2026-11-11. A merge, not a rebase, so the review history stays.

  • What the merge brought in. package.json conflicted textually: test:schemas keeps this branch's four tests (account-ref, canonical-account-ref, image-bleed, sync-plans-reserved-names) and main's url-pattern-loosening (fix(schema): loosen over-specified URL patterns to ^https:// (#8398) #8792). Main's schema changes auto-merged: fix(schema): loosen over-specified URL patterns to ^https:// (#8398) #8792 loosens URL patterns to ^https:// in the attestation-, reporting- and product-audience-evidence-requirements schemas, and feat(schema): add 3gp, mpeg and m4v to video containers (#8107) #8668 adds 3gp, mpeg and m4v to video containers. release-notes.mdx, security.mdx and reporting-status-contract.test.cjs auto-merged too.

  • Inventory on the merged tree: no delta. None of main's changes touches an additionalProperties keyword. The scan finds exactly the same 112 closed locations as fa7aefacfe, all classified keep-closed, with the same four oneOf pairs at risk. The key-presence scan, run on main against the merged tree, finds the same 11 unions: three closed, one with its closed branch, seven guarded by name, none unguarded.

  • Wording after Konstantin's approval (06dc420d0c, 55ac5a5d76, 7d4dd1b289): whats-new-in-3-3, the release notes, experimental-status, the withdrawn-to-4-0 test comment and the additive-minor baseline $comment say the commercial terms are held closed until 4.0, and refinement.mdx's troubleshooting heading matches the error it shows.

  • Inventory. A script walks every additionalProperties: false location in the source tree, and checks each oneOf and anyOf for branches that are told apart only by key presence. After the review round, a key-presence scan of every oneOf and anyOf finds 11 unions. Three stay closed (a2ui bound-value, brand.json, trust.json), one keeps its closed branch (sync-catalogs-response errors), and the other seven are guarded by name.

  • Additive-minor lint. npm run test:additive-minor passes, with 76 lint tests and the baseline-ref check against origin/main. npm run lint:additive-minor reports 4 recorded changes, 0 new, against base 3.2.9, and one notice line for the openings.

  • Every npm test suite, run one after another on a clean npm run build:schemas. All pass, test:schemas, test:composed, test:examples, test:mcp-schema-projection and test:contracts included. The exception is test:release-workflow, which failed once with spawnSync bash ETIMEDOUT in a git-in-tempdir test under load. That's unrelated to this change, and it passes on the post-rebase rerun.

  • Server unit suite (vitest, 13,805 tests): passes apart from addie/matched-pair-ni/exact-inference. That test is pure statistics code and a known load flake. The tenant-smoke timeout passes when rerun on its own. Typecheck is clean.

  • Post-rebase reruns: lint:additive-minor, test:additive-minor, test:schemas, test:composed, test:mcp-schema-projection, test:examples, test:targeting-aware-discovery, test:principal, test:contracts and test:release-workflow all pass, as do the training-agent, discovery-parity, principal and tenant-smoke vitest files.

  • Storyboard matrix (local): /signals, /creative, /creative-builder, /brand and /si meet their floors. /sales and /governance fall short locally, with the failures fix(schema): withdraw 3.3 additions from get_products and sync_creatives assignments (#8501) #8758 documents as pre-existing in local runs: adcp.governance_enforcement.tasks.3, compact responses missing /status, and the local SDK pin serving 3.2. CI's training-agent-storyboards job, which runs once this is ready, is authoritative.

  • CI: all required checks are green. "Generate TypeScript SDK" (not required) fails because the adcp-client generator hard-codes that four get_reporting_status objects are closed (reportingStatusClosedStructures in scripts/generate-zod-from-ts.ts). They open here. fix(codegen): follow source additionalProperties instead of asserting closure adcp-client#3678 (merged, 29c9af4f4) makes the TypeScript generator follow the source additionalProperties, and a replay of this job against it passes. The failure clears once the job builds against SDK main. Follow-up: Zod exports don't enforce the schemas AdCP 3.3 keeps closed (adcp#8866 class b) adcp-client#3679, Zod enforcement of the class-(b) set. "Generate Python SDK" passes.

  • Hooks: commits were made with the pre-commit hook skipped, and pushes with HUSKY=0. Each hook step was run by hand as listed above. CI is the gate.

🤖 Generated with Claude Code

bokelley added a commit that referenced this pull request Nov 9, 2026
…hemas

Ports #8866's named rejections to 3.2.x for every node that exists
there: where closure was the only thing rejecting a specific field the
protocol defines elsewhere or forbids, the opened schema rejects it by
name in `not`, next to additionalProperties: true. 31 of #8866's 51
named rejections apply on 3.2.x; the rest target schemas or nodes that
3.2.x does not have.

Also ports #8866's description cleanups: opened schemas no longer say
they are closed, and the metric-qualifier descriptions say new keys
ship in a major release. The 3.3-only boolean-demographics deprecation
and gender-targeting wording are not ported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 9, 2026
Ports #8866's test edits for the test files 3.2.x has: generic
unknown-key assertions now expect the key to validate, citing DR-0009
(DR-0036 is not on 3.2.x), and the training agent test shows an unknown
hard overlay requirement still matches no product.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 9, 2026
Ports #8866's 9bda16d and 32768d4 to 3.2.x. Opening exposed
anyOf unions whose branches were told apart only by which keys are
present; each branch now rejects its sibling's keys by name: geo-region
requirement and support countries (all_values vs values), the canonical
account ref (account_id vs brand + operator), the deprecated
fused-system postal area (no country), and sync_reporting_receipts
results (receipt vs adjustment_receipt). Also names `step` on frequency
cap impression constraints and `mode` on list-application receipts.

Tests: adds canonical-account-ref.test.cjs (loading source schemas, as
3.2.x tests do), strips the format-key prohibitions from the MCP
legacy-graph check, and flips the generic unknown-key vectors, citing
DR-0009. PARITY_COMPILE_LIMIT is unchanged on 3.2.x; it does not trip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 9, 2026
…finitions on 3.2.x

Ports the tools/list and parity-test parts of 9c1c52d (#8866):
bundled definitions in the product-discovery tools/list schemas omit
`additionalProperties: true`, which is JSON Schema's default and carries
no information. The root keeps the keyword. The parity test compares
openness rather than the literal keyword.

The sync_principal part of 9c1c52d does not apply: the 3.2 training
agent does not implement sync_principal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit to adcontextprotocol/adcp-client that referenced this pull request Nov 9, 2026
… closure (#3678)

* fix(codegen): follow source additionalProperties instead of asserting closure

AdCP 3.x opens the schemas that were closed by accident
(adcontextprotocol/adcp#8866). The Zod generator required
`additionalProperties: false` on four get_reporting_status structures and
hard-coded `.strict()` or unknown-key rejection in several other
post-processors, so it either failed or stayed stricter than the source.

Read closure from the synced source cache everywhere a post-processor
restores strictness. Still-closed sources keep their strict output, and
the generated output for the current 3.3.0-beta.5 bundle is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(codegen): close only the Trusted Match request exports, not their neighbours

The privacy-boundary pass rewrote everything from ContextMatchRequestSchema
to OfferPriceSchema, which also closed TargetingKvsSchema, a context-match
response shape. It matched the source only while targeting_kvs items were
closed; adcontextprotocol/adcp#8866 opens them. Close just the request
export, and give TargetingKvsSchema its own source-driven policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(codegen): cover source-driven closure in the Zod post-processors

Inject inline source fixtures through the readSource parameters so the
tests never depend on schemas/cache/latest. For each changed post-processor
cover the closed source (previous strict output), the open source (no
unknown-key check, no throw, runtime accept/reject of emitted Zod), and the
new failure modes: title mismatch, closed root with open inline object,
changed closed key sets, and targeting_kvs disagreement. Also assert the
privacy-boundary pass closes only the request export.

Update the three tests that hard-coded the old assertion or read the cache.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(codegen): run the source-closure tests in the slow lane

The file spawns a tsx harness per post-processor and runs about 25s alone,
close to the fast lane's 60s file limit on a cold shard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(changeset): note the TargetingKvs closure fix

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley force-pushed the fix/open-closed-schemas-3-3 branch from 9c1c52d to 96d51c9 Compare November 9, 2026 22:40
@bokelley
bokelley marked this pull request as ready for review November 9, 2026 22:40

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated schema paths require human/CODEOWNERS sign-off, and this PR decides a protocol-policy question.

The reviewer found no code defects. The change mechanically opens additionalProperties: false→true at 744 of 859 locations under static/schemas/source/**, keeps 115 closed for structural reasons, and adds not:{anyOf:[{required}]} named rejections where closure previously rejected a protocol-defined field. The reviewer judged the openings disjointness-safe (unchanged oneOf baseline, discriminated unions), the lint rewrite sound, the runtime adaptation in training-agent/principal.ts safe (DECLARATION_AXES matches the schema's three members), docs coherent, and the minor changeset correct for additive opening. No critical/high/medium findings were filed.

However, two hard gates apply:

  1. Gated paths (decision row 2). gated_paths: true — hundreds of static/schemas/source/** files are modified — and review_decision is REVIEW_REQUIRED, not APPROVED. Per the hard approval gate, this PR must not be approved without a real human/CODEOWNERS approval.

  2. Prose gate — protocol-policy decision / precedent reversal. The reviewer explicitly flags that this PR reverses the DR-0036 precedent (the schema-closure ratchet) and leaves that reversal plus the gated schema sign-off "to the arbiter." A PR that reverses a governance decision record is a protocol-policy act requiring human ratification, not an auto-approvable mechanical change. Combined with the un-approved review status, escalation is required.

No blocking code findings exist, so this is not request-changes; it is an escalation for required human/CODEOWNERS review and governance ratification.

Why human review

  • Gated paths: this PR modifies hundreds of files under static/schemas/source/** (a hard, path-based approval gate) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval is required before merge.
  • Governance precedent reversal: the change reverses the DR-0036 schema-closure ratchet, a protocol-policy decision that requires explicit human ratification on the thread rather than auto-approval.
  • Protocol surface change at scale: opening additionalProperties false→true across 744 locations is a normative wire-shape decision the reviewer deliberately left to the arbiter for human sign-off.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/aao/agent-publishers.json (modified) matches static/schemas/source/**; static/schemas/source/account/sync-governance-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/sync-governance-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/collection/base-collection-source.json (modified) matches static/schemas/source/**; static/schemas/source/collection/collection-list-changed-webhook.json (modified) matches static/schemas/source/**; static/schemas/source/collection/collection-list-filters.json (modified) matches static/schemas/source/**; static/schemas/source/collection/collection-list.json (modified) matches static/schemas/source/**; static/schemas/source/collection/get-collection-list-request.json (modified) matches static/schemas/source/**; static/schemas/source/collection/get-collection-list-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/content-standards/get-media-buy-artifacts-request.json (modified) matches static/schemas/source/**; static/schemas/source/core/account-change-recorded-webhook.json (modified) matches static/schemas/source/**; st

…(truncated)…

@aao-secretariat aao-secretariat Bot added the ladon/needs-human-review Ladon has escalated this PR for human review. label Nov 9, 2026
@bokelley

Copy link
Copy Markdown
Contributor Author

@KonstantinMirin, could you review and approve this as code owner? This is the 3.3 half of the Nov 9 decision to open the schemas that were closed by accident. It builds on your #8772, so you're the right second reader. The account it was opened under can't count as its own code-owner approval.

What to look at:

All checks are green, including every storyboard tenant and "Generate TypeScript SDK" against SDK main (adcp-client#3678). The 3.2.x backport is #8864. The DR-0036 rewrite is #8858, which merges after this. RC is planned for Mon Nov 16.

bokelley added a commit that referenced this pull request Nov 10, 2026
…ort promise in DR-0039

Add a table that maps the eleven reasons #8866 gives for 3.3's closed
locations onto the record's eight, and note that the WG can split them
back. State that "supported" (security fixes plus corrections) widens
the versioning page's security-only promise. Drop the 4.0 GA-date
reasoning, which RFC #8756 carries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@KonstantinMirin KonstantinMirin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Brian, thank you for this, and for folding #8772 in. I went through the four areas you listed at 96d51c9aa6. Opening 744 locations and keeping 115 is the right shape, and most of the kept-closed classes hold up. I found four things I'd like fixed before I approve, and a handful of smaller ones. Each was checked against the head, the payload cases with ajv at head and at the merge base 0f337b4ede.

Before merge

1. Two oneOf unions lost their key-presence guards. The PR adds guards to canonical-account-ref.json, but two unions of the same kind were opened without them:

  • core/account-ref.json:17 and :52. {account_id, brand} and {account_id, operator} now validate through the account_id branch. At the base both were rejected, and canonical-account-ref.json still rejects them, so the two account-reference schemas now disagree on the same payload. Suggested fix, the same as canonical-account-ref: on branch 0 "not": { "anyOf": [{ "required": ["brand"] }, { "required": ["operator"] }] }, on branch 1 "not": { "required": ["account_id"] }, plus a copy of tests/canonical-account-ref.test.cjs for it.
  • core/requirements/image-asset-requirements.json:77 and :87 (bleed). {uniform: 2, top: 1} now validates under the uniform branch, so a reader that checks top first computes a different bleed than one that checks uniform first. Suggested fix: "not": { "anyOf": [{ "required": ["top"] }, { "required": ["right"] }, { "required": ["bottom"] }, { "required": ["left"] }] } on the uniform branch and "not": { "required": ["uniform"] } on the per-side branch.

The test plan says the inventory checked every oneOf and anyOf for branches told apart only by key presence, so it may be worth re-running it with these two cases in mind.

2. Twelve named rejections forbid names the protocol never defines. The description's rule is to name a rejection where closure rejected "a specific field the protocol defines elsewhere, or one its text forbids there". These don't meet it: step (frequency-cap-impression-constraints.json:34), access_token (reporting-delivery-ready-webhook.json:109), covered (reporting-subscription-coverage.json:145, reporting-subscription-state.json:115), gpc_honored (signal-definition.json:455), political (acceptance-context.json:56), threshold_rate and per_ad_spend (outcome-target.json:81), verified (get-adcp-capabilities-response.json:926, :934), and mode on inventory-list-application.json:85, :151. No schema defines the first eight names. mode is defined elsewhere, but only in unrelated schemas, and its only justification is "matching the 3.2.10 backport". Most trace back to tests that used them as arbitrary unknown-key probes while the node was closed, for example targeting-aware-discovery.test.cjs:272-275 and reporting-status-contract.test.cjs:1762. threshold_rate and per_ad_spend are "Deferred past 3.3" (outcome-target.test.cjs:224), so 3.3 would forbid names reserved for a later minor. You already handled the same situation in d10497f081 by flipping the probes to expect acceptance (entries_total, bucket_completness, response_due_at). I'd do the same here and drop these clauses, mirrored in #8864 for the nodes 3.2.x shares. If access_token is meant as a security clamp, I'd say so in its description.

3. Most named rejections don't say why. None of the 63 new not clauses has a $comment, and for about 31 of the rejected names the name appears nowhere in the file's descriptions, for example unit (html-asset.json:68), format_ids (canonical-placement.json:143), review_sla (product-allowed-action.json:56), max_bid (outcome-target-cost-per.json:25) and context_id/status/acknowledged_at (report-media-buy-issue-request.json:93). #8531's canonical-product precedent names the absent fields in its description. Generated types can't express not, and the changeset says they now treat these objects as open, so the description is the only place a consumer learns that the field is rejected. One sentence per node, or per union, would do.

4. The "Signed commercial terms" reason isn't true as written. terms_digest is the JCS digest of the whole commercial_terms value (core/canonical-proposal.json:100). Within it, 21 object roots are open at both base and head (core/targeting.json, core/frequency-cap.json, core/ext.json, core/context.json, core/format-option-ref.json, the price guidance and breakdown schemas), and this PR opens 40 more nodes inside the same digest (brand-key, business-entity, canonical-optimization-goal, six targeting children, and others). product-purchase.json stays closed while carrying ext and context. So keeping the 25 closed doesn't prevent what the docs say it prevents: "terms_digest signs exactly those terms. If the object were open, a 3.2 buyer could accept a 3.3 term it silently ignored" (3-2-to-3-3.mdx:78, also :391, release-notes.mdx:187, whats-new-in-3-3.mdx:324, 3-3-beta.mdx:169, v4-compatibility.mdx:143, and the two changesets). The disjointness and JWS-envelope reasons don't apply either. In the envelope an extra member would sit outside the signature; here every member is inside it.

I've put the rule that does protect a buyer in #8884: the digest covers every member at every depth, including ext; accepting binds you to all of them; a party that can't interpret one refuses with UNRECOGNIZED_TERMS. It opens and closes nothing, so the two PRs agree on schema state, and I'm happy for the 25 to stay closed for the RC. I'd only ask to drop those two sentences, or call the 25 a hold until 4.0 rather than a structural reason. git merge-tree shows #8884 and this PR conflicting in exactly those three docs pages, and I'll rebase #8884 on whichever lands first.

Smaller points

  • Privacy boundary, over-applied. get-principal-response.json result/oneOf/0 (current) and sync-principal-response.json result/oneOf/0, /oneOf/1 return the caller's own configuration and are dispatched by a kind const. The oracle argument fits recognized, unconfigured and failed, not these. I'd open them or state a reason that fits.
  • Reporting-status clamp. The description says the lookup_unavailable nodes' descriptions and error-handling.mdx state the clamp, but get-reporting-status-response.json:159-167 has empty descriptions and no docs page mentions it. The invariance comes from the const values. One description sentence would fix it.
  • Labels. "Hard constraint (must-understand)" (proposal-budget-constraint.json) makes the same argument as the signed-terms class. I'd label both the same way.
  • Baseline. metric_id (canonical-performance-standard.json) and clock/business_calendar_id (sla-window.json) are still additions to schemas that stay closed, against the guide's own line 401. If #8762 and #8501 entry 6 don't land before the RC, 3.3 ships them. Worth carrying on the RC checklist.
  • canonical-account-ref partial guard. The account_id branch names brand and operator but not operator_unit, currency, timezone or sandbox. {account_id, sandbox: true} now validates where the base rejected it. Either extend the guard or say in the description that those keys are ignored beside account_id.
  • Failed receipt branch. sync-reporting-receipts-response.json:82-90: the four other result branches exclude the sibling receipt key, and the failed branch doesn't, so {result: failed, ..., receipt: {...}} now validates, while the description still says failed results expose no resource metadata. A not for symmetry, or drop that claim.
  • Lint hint. scripts/lint-additive-minor.cjs:1355-1359 still tells a developer to "record it as a correction in DR-0036 and scripts/lint-additive-minor-corrections.json", a correction kind the loader now rejects (line ~906). #8777 had reworded this line, and the port didn't carry it.
  • Projection test. tests/mcp-schema-projection.test.cjs:60 strips the new prohibitions by exact serialized string. Skipping not subtrees structurally would survive reformatting and the next named rejection.
  • Backport sentence. "3.2.10 opens the same locations that 3.2 has" (.changeset/open-schemas-meant-to-be-open.md:24, 3-2-to-3-3.mdx:87) is off by one node: #8864 keeps get-reporting-status-response.json#/oneOf/1/oneOf/0 closed.
  • Baseline base. scripts/lint-additive-minor-baseline.json:3 says 3.2.8, while main now carries 3.2.9. A --prune-baseline after the next rebase fixes it; the lint result doesn't change (4 recorded, 0 new).
  • Lost from #8772's docs. The fold-in carried every schema change, test and the registry entry, but two doc hunks didn't come across. In 3-2-to-3-3.mdx, the summary bullet at line 22 and the Deprecations list at line 805 don't mention the boolean form of demographics, although this PR deprecates it with a sender MUST. In v4-compatibility.mdx:233, the count of x-removed-in: "4.0.0" fields didn't move by two, and "boolean demographics in product support" is missing from the seller-emitted list. Both hunks are in #8772 and can be copied as they are.
  • Closed-schema leftovers. get_products.mdx:493 and experimental-status.mdx:155 still say target_audiences sits beside audience_evidence_requirements because "the requirements object is a closed schema and a minor release never changes a closed schema". This PR opens core/audience-evidence-requirements.json. The sibling placement can stand on its own reason: one constrains which audience, the other the quality of the evidence.
  • Three copies of range. signal-listing.json#/properties/range, get-signals-response.json#/properties/signals/items/properties/range and wholesale-feed-event.json#/$defs/signal/properties/range are the same object (min, max, both required), differing only in description, inside allOf children that already reference signal-listing. Since this PR edits all three, it may be the moment to define it once as core/signal-range.json, reference it from signal-listing, and drop the two copies. It validates identically, so it's safe in a minor.
  • Description. The details heading says "All 116 kept-closed locations" over 115 rows. The named-rejection table also misses the fdabc7f987 guards (canonical-account-ref, geo-region-requirement and geo-region-support countries, postal-area, sync-reporting-receipts-response, step) and mode on inventory-list-application, which #8864's description does list.

Happy to help with any of these, or to push the guard fixes to the branch if that's easier for you.

bokelley added a commit that referenced this pull request Nov 10, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Bring the release notes, What's new, the 3.2 to 3.3 migration guide, the
prerelease program page, Versions, and the 3.3 rows of Choose your SDK to
the first release candidate. The prerelease page keeps its 3-3-beta URL
and is retitled, as the 3.2 page was at its RC. rc.0 joins the checkpoint
and wire-pin tables with the 3.3-rc documentation selector.

Cover the 2026-11-09 decision to open the schemas that were closed by
accident, and the #8501 triage that followed it: which beta fields stay in
3.3, which leave because they sit on deprecated tasks or would change a
signed term, and which move. The migration guide lists every field; the
other pages summarize it. Record boolean overlay demographics as
deprecated.

Leave the lines that #8866 rewrites alone, and fix the "closed schemas
stay closed" wording it does not touch: the Send-only-to-3.3-peers intro
and proposal-flow correction in the 3.2 to 3.3 guide, the 3.1 to 3.2
guide, optimization reporting, and the daily-budget spec.

Describe deprecated 3.3 features as expected to be removed in 4.0, with
3.3 supported for a window after 4.0 GA, instead of the six-month notice
promise. Record @adcp/sdk 17.0.0-beta.22 and Python adcp 10.0.0b15 on
beta.5, Python adcp 9.6.2 with the A2A input fix on the 3.2 line, no SDK
on rc.0 yet, and no Go or Java support for 3.3.

Content that depends on unmerged PRs or on the rc.0 cut carries a
{/* depends on ... */} marker (HTML comment in the spec markdown) so it
can be re-checked before the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…lease docs

After rebasing onto main with #8866 merged:

- Take #8866's wording for the boolean form of demographics in the
  migration guide's Deprecations section, and align the release notes and
  What's new with it (#8778 tracks the 4.0 removal).
- 3.2.10 shipped without the schema opening, so say "the next 3.2.x patch
  (#8864)" and "3.2.10 and earlier", including in #8866's
  Schemas-are-open-by-default bullet.
- Drop the dependency markers #8866 satisfied, and retarget the rest.
- Cover the other changes merged for rc.0: origin-only authorized_agents
  URLs (#8939), declared-option creative conformance (#8941), TMP cache
  isolation (#7446), creative.supports_registry_policy_enforcement
  (#8857), 3gp/mpeg/m4v containers (#8668), carousel card_image_sizes
  (#8937), and the loosened URL patterns (#8792).
- Refresh the in-review table against the 3.3.0 milestone on 2026-11-12,
  and remove the stray duplicate table header it carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…ves assignments (#8501)

3.3 adds no field that exists only on a deprecated task. Withdraw from
get_products: refine[].package (and package-forecast-input.json),
refinement_applied[] result_product_id / resolved_start_time /
resolved_end_time, filters.target_audiences, include_collections and
collections, and experimental price_adjustments on pricing options (with
price-adjustments.json, the mismatch error details, and the vectors).
Move include_execution_readiness / execution_readiness to list_products.
Withdraw landing_page_url and trackers from the deprecated sync_creatives
assignments[] row; the assign operation keeps them.

#8866 opened the assignments[] row and the refine[] product entry, so
both now reject the withdrawn request fields by name (not: required),
with a description sentence: the row rejects trackers and
landing_page_url, and every refine[] scope rejects package. The schema
and the training agent's INVALID_REQUEST agree. The response-side
refinement_applied fields are just undefined.

Updates the training agent, the execution readiness storyboard, the v4
registry (canonical_price_adjustments_required_in_4_0), the oneOf
discriminator baseline, docs, and tests. #8866 already removed the
additive-minor baseline rows, and the 3.3 release pages are left to
#8883. counting_mechanisms is left to the create/update_media_buy PR,
which removes it from the shared measurement-terms.json.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…nd update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Bring the release notes, What's new, the 3.2 to 3.3 migration guide, the
prerelease program page, Versions, and the 3.3 rows of Choose your SDK to
the first release candidate. The prerelease page keeps its 3-3-beta URL
and is retitled, as the 3.2 page was at its RC. rc.0 joins the checkpoint
and wire-pin tables with the 3.3-rc documentation selector.

Cover the 2026-11-09 decision to open the schemas that were closed by
accident, and the #8501 triage that followed it: which beta fields stay in
3.3, which leave because they sit on deprecated tasks or would change a
signed term, and which move. The migration guide lists every field; the
other pages summarize it. Record boolean overlay demographics as
deprecated.

Leave the lines that #8866 rewrites alone, and fix the "closed schemas
stay closed" wording it does not touch: the Send-only-to-3.3-peers intro
and proposal-flow correction in the 3.2 to 3.3 guide, the 3.1 to 3.2
guide, optimization reporting, and the daily-budget spec.

Describe deprecated 3.3 features as expected to be removed in 4.0, with
3.3 supported for a window after 4.0 GA, instead of the six-month notice
promise. Record @adcp/sdk 17.0.0-beta.22 and Python adcp 10.0.0b15 on
beta.5, Python adcp 9.6.2 with the A2A input fix on the 3.2 line, no SDK
on rc.0 yet, and no Go or Java support for 3.3.

Content that depends on unmerged PRs or on the rc.0 cut carries a
{/* depends on ... */} marker (HTML comment in the spec markdown) so it
can be re-checked before the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…lease docs

After rebasing onto main with #8866 merged:

- Take #8866's wording for the boolean form of demographics in the
  migration guide's Deprecations section, and align the release notes and
  What's new with it (#8778 tracks the 4.0 removal).
- 3.2.10 shipped without the schema opening, so say "the next 3.2.x patch
  (#8864)" and "3.2.10 and earlier", including in #8866's
  Schemas-are-open-by-default bullet.
- Drop the dependency markers #8866 satisfied, and retarget the rest.
- Cover the other changes merged for rc.0: origin-only authorized_agents
  URLs (#8939), declared-option creative conformance (#8941), TMP cache
  isolation (#7446), creative.supports_registry_policy_enforcement
  (#8857), 3gp/mpeg/m4v containers (#8668), carousel card_image_sizes
  (#8937), and the loosened URL patterns (#8792).
- Refresh the in-review table against the 3.3.0 milestone on 2026-11-12,
  and remove the stray duplicate table header it carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…nd update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
… creative review SLA (#8762)

#8501 entries 11 and 12. core/sla-window.json is held closed with the
commercial terms until 4.0 (DR-0036), and 3.3.0-beta.1 added clock and
business_calendar_id to it, so a strict 3.2 validator rejected a 3.3 SLA.
sla-window goes back to its 3.2.8 publication (only $id differs). The
signed terms reach it through change_terms[].processing_sla, and 3.2.8
says sellers include weekends and non-working periods in the maximum.

clock and business_calendar_id move to core/creative-review-sla.json,
which no longer composes sla-window: it defines its own durations, keeps
completion_max required and the business-clock calendar rule, and is
open. escalation-sla loses clock. An action's sla, a change term's
processing_sla and the escalation SLA are elapsed time only.

Tests pin sla-window to 3.2.8 and check the business clock is rejected on
the four action schemas, the change term and the escalation SLA. The two
sla-window baseline rows go, leaving 2. The MCP parity bound moves to
1_388_000 (measured 1_387_457 on main after #8866). Docs, the migration
guide and a minor changeset name where the fields live now.

Refs #8501

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…porting capabilities (#8501) (#8957)

The experimental available_installment_statuses (media_buy.installment_lifecycle,
#8116) was defined only on core/reporting-capabilities.json, which only the
deprecated get_products product uses, and 3.3 adds no field that exists only
on a deprecated task. It moves unchanged to
core/canonical-reporting-capabilities.json, beside
supports_installment_breakdown, on the canonical product that list_products,
request_proposals and refine_proposals return. #8866 opened that block
(DR-0036), so the move can land in 3.3.

Same items, uniqueItems, description, x-status: experimental and
x-added-in: 3.3.0. The installment lifecycle docs, the get_media_buy_delivery
reference and the experimental status row say where it lives, the docs
example validates against the canonical schema, and the test checks the
declaration there and its absence from the legacy schema. Minor changeset.

Konstantin Mirin handed this move over on #8501.

Refs #8501

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Bring the release notes, What's new, the 3.2 to 3.3 migration guide, the
prerelease program page, Versions, and the 3.3 rows of Choose your SDK to
the first release candidate. The prerelease page keeps its 3-3-beta URL
and is retitled, as the 3.2 page was at its RC. rc.0 joins the checkpoint
and wire-pin tables with the 3.3-rc documentation selector.

Cover the 2026-11-09 decision to open the schemas that were closed by
accident, and the #8501 triage that followed it: which beta fields stay in
3.3, which leave because they sit on deprecated tasks or would change a
signed term, and which move. The migration guide lists every field; the
other pages summarize it. Record boolean overlay demographics as
deprecated.

Leave the lines that #8866 rewrites alone, and fix the "closed schemas
stay closed" wording it does not touch: the Send-only-to-3.3-peers intro
and proposal-flow correction in the 3.2 to 3.3 guide, the 3.1 to 3.2
guide, optimization reporting, and the daily-budget spec.

Describe deprecated 3.3 features as expected to be removed in 4.0, with
3.3 supported for a window after 4.0 GA, instead of the six-month notice
promise. Record @adcp/sdk 17.0.0-beta.22 and Python adcp 10.0.0b15 on
beta.5, Python adcp 9.6.2 with the A2A input fix on the 3.2 line, no SDK
on rc.0 yet, and no Go or Java support for 3.3.

Content that depends on unmerged PRs or on the rc.0 cut carries a
{/* depends on ... */} marker (HTML comment in the spec markdown) so it
can be re-checked before the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…lease docs

After rebasing onto main with #8866 merged:

- Take #8866's wording for the boolean form of demographics in the
  migration guide's Deprecations section, and align the release notes and
  What's new with it (#8778 tracks the 4.0 removal).
- 3.2.10 shipped without the schema opening, so say "the next 3.2.x patch
  (#8864)" and "3.2.10 and earlier", including in #8866's
  Schemas-are-open-by-default bullet.
- Drop the dependency markers #8866 satisfied, and retarget the rest.
- Cover the other changes merged for rc.0: origin-only authorized_agents
  URLs (#8939), declared-option creative conformance (#8941), TMP cache
  isolation (#7446), creative.supports_registry_policy_enforcement
  (#8857), 3gp/mpeg/m4v containers (#8668), carousel card_image_sizes
  (#8937), and the loosened URL patterns (#8792).
- Refresh the in-review table against the 3.3.0 milestone on 2026-11-12,
  and remove the stray duplicate table header it carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…ves assignments (#8501)

3.3 adds no field that exists only on a deprecated task. Withdraw from
get_products: refine[].package (and package-forecast-input.json),
refinement_applied[] result_product_id / resolved_start_time /
resolved_end_time, filters.target_audiences, include_collections and
collections, and experimental price_adjustments on pricing options (with
price-adjustments.json, the mismatch error details, and the vectors).
Move include_execution_readiness / execution_readiness to list_products.
Withdraw landing_page_url and trackers from the deprecated sync_creatives
assignments[] row; the assign operation keeps them.

#8866 opened the assignments[] row and the refine[] product entry, so
both now reject the withdrawn request fields by name (not: required),
with a description sentence: the row rejects trackers and
landing_page_url, and every refine[] scope rejects package. The schema
and the training agent's INVALID_REQUEST agree. The response-side
refinement_applied fields are just undefined.

Updates the training agent, the execution readiness storyboard, the v4
registry (canonical_price_adjustments_required_in_4_0), the oneOf
discriminator baseline, docs, and tests. #8866 already removed the
additive-minor baseline rows, and the 3.3 release pages are left to
#8883. counting_mechanisms is left to the create/update_media_buy PR,
which removes it from the shared measurement-terms.json.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…nd update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…ves assignments (#8501) (#8758)

* fix(schema): withdraw 3.3 additions from get_products and sync_creatives assignments (#8501)

3.3 adds no field that exists only on a deprecated task. Withdraw from
get_products: refine[].package (and package-forecast-input.json),
refinement_applied[] result_product_id / resolved_start_time /
resolved_end_time, filters.target_audiences, include_collections and
collections, and experimental price_adjustments on pricing options (with
price-adjustments.json, the mismatch error details, and the vectors).
Move include_execution_readiness / execution_readiness to list_products.
Withdraw landing_page_url and trackers from the deprecated sync_creatives
assignments[] row; the assign operation keeps them.

#8866 opened the assignments[] row and the refine[] product entry, so
both now reject the withdrawn request fields by name (not: required),
with a description sentence: the row rejects trackers and
landing_page_url, and every refine[] scope rejects package. The schema
and the training agent's INVALID_REQUEST agree. The response-side
refinement_applied fields are just undefined.

Updates the training agent, the execution readiness storyboard, the v4
registry (canonical_price_adjustments_required_in_4_0), the oneOf
discriminator baseline, docs, and tests. #8866 already removed the
additive-minor baseline rows, and the 3.3 release pages are left to
#8883. counting_mechanisms is left to the create/update_media_buy PR,
which removes it from the shared measurement-terms.json.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(schema): readiness binds to buy_products purchases, not legacy packages (#8501)

execution_readiness moved to list_products, whose next step is buy_products,
but binding_field examples still taught the legacy create_media_buy paths,
including packages[].catalogs[], which a purchase does not define. Teach
purchases[].optimization_goals[].event_sources[].event_source_id and
purchases[].catalog_ids[] in the spec, list_products docs, the readiness and
requirement schemas, and the readiness fixtures; label the remaining
packages[] paths as legacy. The readiness text no longer claims buy_products
rejects unmet purchases: only create_media_buy's rule is specified, and the
purchase-side rule stays with adcp#7763.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(v4): price_adjustments shipped through beta.5 (#8501)

The canonical_price_adjustments_required_in_4_0 section of the 4.0 page
still said the table shipped in 3.3.0-beta.1 through beta.4 and that the
beta.1 to beta.4 bundles keep the schemas. beta.5 shipped with it too, and
the changeset, the registry entry and pricing-models.mdx already say so.
The section now also says canonical-pricing-option.json is held closed
with the commercial terms until 4.0, matching the registry entry, rather
than "closed in 3.x".

Found by the Ladon review.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…nd update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Bring the release notes, What's new, the 3.2 to 3.3 migration guide, the
prerelease program page, Versions, and the 3.3 rows of Choose your SDK to
the first release candidate. The prerelease page keeps its 3-3-beta URL
and is retitled, as the 3.2 page was at its RC. rc.0 joins the checkpoint
and wire-pin tables with the 3.3-rc documentation selector.

Cover the 2026-11-09 decision to open the schemas that were closed by
accident, and the #8501 triage that followed it: which beta fields stay in
3.3, which leave because they sit on deprecated tasks or would change a
signed term, and which move. The migration guide lists every field; the
other pages summarize it. Record boolean overlay demographics as
deprecated.

Leave the lines that #8866 rewrites alone, and fix the "closed schemas
stay closed" wording it does not touch: the Send-only-to-3.3-peers intro
and proposal-flow correction in the 3.2 to 3.3 guide, the 3.1 to 3.2
guide, optimization reporting, and the daily-budget spec.

Describe deprecated 3.3 features as expected to be removed in 4.0, with
3.3 supported for a window after 4.0 GA, instead of the six-month notice
promise. Record @adcp/sdk 17.0.0-beta.22 and Python adcp 10.0.0b15 on
beta.5, Python adcp 9.6.2 with the A2A input fix on the 3.2 line, no SDK
on rc.0 yet, and no Go or Java support for 3.3.

Content that depends on unmerged PRs or on the rc.0 cut carries a
{/* depends on ... */} marker (HTML comment in the spec markdown) so it
can be re-checked before the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…lease docs

After rebasing onto main with #8866 merged:

- Take #8866's wording for the boolean form of demographics in the
  migration guide's Deprecations section, and align the release notes and
  What's new with it (#8778 tracks the 4.0 removal).
- 3.2.10 shipped without the schema opening, so say "the next 3.2.x patch
  (#8864)" and "3.2.10 and earlier", including in #8866's
  Schemas-are-open-by-default bullet.
- Drop the dependency markers #8866 satisfied, and retarget the rest.
- Cover the other changes merged for rc.0: origin-only authorized_agents
  URLs (#8939), declared-option creative conformance (#8941), TMP cache
  isolation (#7446), creative.supports_registry_policy_enforcement
  (#8857), 3gp/mpeg/m4v containers (#8668), carousel card_image_sizes
  (#8937), and the loosened URL patterns (#8792).
- Refresh the in-review table against the 3.3.0 milestone on 2026-11-12,
  and remove the stray duplicate table header it carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…nd update_media_buy (#8501) (#8767)

* fix(schema): keep 3.3 additions off the deprecated create_media_buy and update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(schema): retire audience evidence targets now that no 3.3 wire form remains (#8501)

With filters.target_audiences withdrawn from get_products (#8758) and the
package copy withdrawn from create_media_buy and update_media_buy, the
experimental media_buy.audience_evidence_targets has no 3.3 wire form.

- Delete core/audience-evidence-target.json and
  enums/audience-evidence-relationship.json and their index.json entries.
  The stable inline relationship enums on audience evidence stay.
- Drop the feature from the changeset. Its experimental-status row went
  with the previous commit, and the 3.3 release pages are left to #8883.
- Move the target-matching rules from get_products.mdx into the preserved
  4.0 design under purchase_target_audiences_required_in_4_0, keeping a short
  withdrawal notice at the old anchor; the check keeps its id and its
  detection no longer keys off the retired feature id.
- Retire tests/audience-evidence-targets.test.cjs (preserved at d9b5417)
  and stop reading the deleted package-forecast-input.json in
  tests/creative-start-policy.test.cjs.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(schema): leave the 3.3 release pages to #8883

The release notes, What's new, the 3.2 to 3.3 migration guide and the 3.3
beta page belong to #8883. This PR no longer edits them, so its test stops
asserting their "Withdrawn from the deprecated tasks" heading.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Bring the release notes, What's new, the 3.2 to 3.3 migration guide, the
prerelease program page, Versions, and the 3.3 rows of Choose your SDK to
the first release candidate. The prerelease page keeps its 3-3-beta URL
and is retitled, as the 3.2 page was at its RC. rc.0 joins the checkpoint
and wire-pin tables with the 3.3-rc documentation selector.

Cover the 2026-11-09 decision to open the schemas that were closed by
accident, and the #8501 triage that followed it: which beta fields stay in
3.3, which leave because they sit on deprecated tasks or would change a
signed term, and which move. The migration guide lists every field; the
other pages summarize it. Record boolean overlay demographics as
deprecated.

Leave the lines that #8866 rewrites alone, and fix the "closed schemas
stay closed" wording it does not touch: the Send-only-to-3.3-peers intro
and proposal-flow correction in the 3.2 to 3.3 guide, the 3.1 to 3.2
guide, optimization reporting, and the daily-budget spec.

Describe deprecated 3.3 features as expected to be removed in 4.0, with
3.3 supported for a window after 4.0 GA, instead of the six-month notice
promise. Record @adcp/sdk 17.0.0-beta.22 and Python adcp 10.0.0b15 on
beta.5, Python adcp 9.6.2 with the A2A input fix on the 3.2 line, no SDK
on rc.0 yet, and no Go or Java support for 3.3.

Content that depends on unmerged PRs or on the rc.0 cut carries a
{/* depends on ... */} marker (HTML comment in the spec markdown) so it
can be re-checked before the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
Konstantin's review of #8866 rejects signed commercial terms as a
structural reason to keep a schema closed: terms_digest covers open
members at every depth, including ext. Describe the nodes inside
commercial_terms, and proposal-budget-constraint, as held closed until
4.0 in the triage tables and summaries, the release notes, What's new,
Versions, and the daily-budget spec, and drop the claim that the digest
stops a 3.2 buyer from accepting a term it ignored. The triage reason is
renamed from signed meaning to held closed until 4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 12, 2026
…lease docs

After rebasing onto main with #8866 merged:

- Take #8866's wording for the boolean form of demographics in the
  migration guide's Deprecations section, and align the release notes and
  What's new with it (#8778 tracks the 4.0 removal).
- 3.2.10 shipped without the schema opening, so say "the next 3.2.x patch
  (#8864)" and "3.2.10 and earlier", including in #8866's
  Schemas-are-open-by-default bullet.
- Drop the dependency markers #8866 satisfied, and retarget the rest.
- Cover the other changes merged for rc.0: origin-only authorized_agents
  URLs (#8939), declared-option creative conformance (#8941), TMP cache
  isolation (#7446), creative.supports_registry_policy_enforcement
  (#8857), 3gp/mpeg/m4v containers (#8668), carousel card_image_sizes
  (#8937), and the loosened URL patterns (#8792).
- Refresh the in-review table against the 3.3.0 milestone on 2026-11-12,
  and remove the stray duplicate table header it carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ladon/needs-human-review Ladon has escalated this PR for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants