You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fbf13c9
Browse filesBrowse the repository at this point in the historyBrowse files
Version literals: the capabilities signing gate parses bundle-precision
versions (3.3.0-beta.1 read as pre-3.2), PrincipalService accepts 3.3
async payload shapes by default, and account key continuity reduces from
the SDK's own release instead of 3.2.
sales-fixed-rate rolls up to media_buy in SPECIALISM_TO_PROTOCOLS, so a
seller claiming only that specialism advertises supported_protocols.
Advertised measurement terms: get_products and list_products refuse a
product whose measurement_window names no declared
reporting_capabilities.measurement_windows[].window_id, and
TermsRejectedError refuses to reject a buyer replaying advertised terms.
Property domain identifiers: create/update_property_list reject malformed
domain and subdomain identifiers with INVALID_REQUEST, the MCP list
resolver rejects a snapshot carrying one instead of canonicalizing it, and
normalize_property_list_identifiers converts values before submission.
Counterparty-asserted domain lists: bound_counterparty_domains cuts
publisher_domains / data_provider_domains to 100 entries, 253 characters
and the 8 KiB / 16 KiB byte budgets, and the capabilities projection
truncates an oversized list and sets *_complete: false.
CreativeMergeRejectedError, RightsChannelViolationError and their
details narrowing helpers join the typed errors.
BREAKING CHANGE: create_property_list / update_property_list fail with
INVALID_REQUEST on mixed-case, trailing-dot or URL-shaped domain
identifiers, and MCPPropertyListFetcher fails a resolution carrying one.
get_products / list_products fail with INTERNAL_ERROR when a product
advertises an undeclared measurement_window. get_adcp_capabilities
truncates oversized publisher_domains / data_provider_domains.
PrincipalService accepts "3.3" async versions by default.
Part of #1668
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: MIGRATION_v9_to_v10.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,6 +19,10 @@ the SDK-relevant inventory is [docs/adcp-3.3-sdk-inventory.md](docs/adcp-3.3-sdk
19
19
|`reporting_webhook.operation_id` is a generated field | The field, its constraints and its never-null marker come from the 3.3 schema. The SDK 9 runtime patch is gone; nothing changes on the wire. |
20
20
| RFC 9421 signing warns by default | AdCP 3.3 deprecates the `adcp/request-signing/v1` and `adcp/webhook-signing/v1` profiles for Web Bot Auth. Constructing `SigningConfig` or `RequestSignatureVerification` without Web Bot Auth emits a `DeprecationWarning`; both profiles keep working through 3.x. |
21
21
|`evaluator_id` is gone from evaluator specs | AdCP 3.3 removes the experimental `build_creative.evaluator.evaluator_id` source form. Use inline `exemplars` or `agent_url`; put the seller's evaluator in `creative_policy.accepted_verifiers[]`. |
22
+
| Property-list domain identifiers must be lowercase ASCII hostnames | AdCP 3.3 rejects `Example.com`, `example.com.` and URL-shaped `domain` / `subdomain` identifier values. `PlatformHandler.create_property_list` and `update_property_list` now fail such a request with `INVALID_REQUEST` (`field` names the value) before your platform runs, and `MCPPropertyListFetcher` fails a resolution whose pages carry one (`SERVICE_UNAVAILABLE`, cached snapshot kept) instead of canonicalizing it. Senders call `adcp.property_lists.normalize_property_list_identifiers(request)` before submitting; it lowercases, converts IDNs to A-labels, strips a trailing dot and raises `PropertyListIdentifierError` for anything else. |
23
+
| Advertised `measurement_window` must be a declared window | AdCP 3.3 requires `measurement_terms.billing_measurement.measurement_window` on a product to name a `reporting_capabilities.measurement_windows[].window_id`. `get_products` and `list_products` on `PlatformHandler` now fail with `INTERNAL_ERROR` when a returned product advertises an undeclared window; declare the window or drop it. When rejecting buyer terms, raise `TermsRejectedError(proposed_terms=..., advertised_terms=...)`: it refuses (`ValueError`) to reject a buyer replaying the advertised terms. |
24
+
| Oversized `publisher_domains` / `data_provider_domains` are truncated | AdCP 3.3 bounds these counterparty-asserted capability lists (100 unique entries, 253 characters each, 8,192 bytes per field, 16,384 combined). The decisioning `get_adcp_capabilities` projection truncates a list that exceeds them, sets `publisher_domains_complete` / `data_provider_domains_complete` to `false` and logs a warning. Declare the publishers you represent rather than mirroring `adagents.json`; `adcp.decisioning.bound_counterparty_domains` bounds a list and reports `complete`. |
25
+
|`PrincipalService` accepts `3.3` async payloads | The default `accepted_async_adcp_versions` is `("3.2", "3.3")` (was `("3.2",)`), since the SDK emits 3.3-line payloads. A seller pinned to 3.2 passes `accepted_async_adcp_versions=("3.2",)`. |
22
26
| Schema defaults appear in dumps for new 3.3 fields |`GetProductsRequest.include_collections` (`false`) and `proposal_refinement.hold_extension` (`false`) carry schema defaults, so a dumped model declares them. Tests that compare whole dictionaries need the new keys; a 3.3 → 3.2 downgrade drops them with a recorded loss. |
23
27
| 3.3 → 3.2 downgrades apply semantic rules | A buyer below 3.3 of a seller answering in 3.3 no longer gets `VERSION_UNSUPPORTED` for these responses: `by_spot` rows without `aired_at` (`scheduled` / `preempted`) and delivery rows without `impressions` are omitted (losses `row_omitted_not_aired`, `row_omitted_impressions_not_measured`), never sent with `impressions: 0`; `media_buy.features.catalog_ingestion` and a `price_breakdown` carrying an `operator_fee` adjustment are dropped; `age_determination_bases` moves to `ext.adcp.age_determination_bases`, and a 3.2 response upgraded to 3.3 reads it back into an absent top-level field. Requests the 3.2 contract cannot express fail with `ADCPVersionConversionError` (`UNSUPPORTED_FEATURE` on the client) before sending: a `reporting_webhook` / `artifact_webhook` without `authentication` (keep sending it while you buy from 3.2 sellers; the SDK never invents one) and a daypart with `start_time` / `end_time` (use `start_hour` / `end_hour`; the SDK never rounds). The downgrade's final check now validates formats as the SDK validators do: earlier betas let such a request through invalid when it carried `start_time: "asap"`. See [docs/cross-version-conversion.md](docs/cross-version-conversion.md#33--32-semantic-rules). |
24
28
| Delivery rows may omit `impressions`| Every `by_*` delivery-metrics row makes `impressions` optional. Treat absence as "not measured", never as zero. |
Copy file name to clipboardExpand all lines: docs/adcp-3.3-sdk-inventory.md
+10-10Lines changed: 10 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,7 @@ it adopted the bundle, and what is left to the codegen/wire-fidelity (2) and
27
27
| Negotiation |`negotiate_version` matches prereleases exactly. The client's outgoing conversion treats the SDK's served prerelease as its line (`is_convertible_version`), so a 3.3-beta.0 buyer still negotiates down to a 3.1 or 3.2 seller. | done (1) |
28
28
| Translation |`convert_payload` steps 3.3-beta.0 ↔ 3.2 ↔ 3.1 ↔ 3.0 through the bundled schemas; the 3.3 step uses the `3.3.0-beta.0` bundle. Downgrades go through `_require_target_valid`, so a converted payload the older schema refuses fails as `ADCPVersionConversionError` (#1621 / #1630). | done (1); per-field rules below are (3) |
29
29
| Restricted servers | A server that lists `supported_versions` without `adcp_version` now pins to the newest listed release (`version_policy.default_adcp_version`), instead of refusing because the SDK default (3.3-beta.0) is outside the list. | done (1) |
30
-
| Handler gate |`PlatformHandler.get_adcp_capabilities` used `startswith("3.2")` for the proposal-manager projection; it is now "3.2 or later". Audit every other `"3.2"` literal (`accounts.py`, `dispatch.py`, `signing/*`, `server/principal.py accepted_async_adcp_versions`) for 3.3 inclusion. | (3): #1668|
30
+
| Handler gate |`PlatformHandler.get_adcp_capabilities` used `startswith("3.2")` for the proposal-manager projection; it is now "3.2 or later". Audit of every other `"3.2"` literal: `dispatch.py` legacy-format gate, `accounts.py` key continuity, `server/principal.py` relationship gate and the `signing/*` profile map (`signing_profile_for_adcp_version` maps 3.3 to the 3.2 RFC 9421 profile) already include 3.3; the remaining `"3.2"` literals in `signing/*` and `governance.py` name the 3.2 signing / JWS profile, not a release floor. Fixed: the capabilities signing gate (`_is_adcp_32_or_newer`) now parses bundle precision (`3.3.0-beta.1` read as pre-3.2); `PrincipalService` accepts `3.3` async payload shapes by default (`("3.2", "3.3")`); account key continuity reduces from the SDK's own release rather than `3.2`. Open: `media_buy_actions._supports_change_term_id` treats `3.3-beta.N` (N < 9) as pre-3.2-beta.9. | done (3), #1668; `media_buy_actions` follow-up|
31
31
|`adcp_version` on `list_products` responses |`ListProductsResponse1/2` gained `adcp_version`. | generated |
|`sync_creatives``merges[]`, `AssignmentOperations4`|`sync_creatives` response `Merge`; error `CREATIVE_MERGE_REJECTED` with `error-details/creative-merge-rejected.json`; enum `creative-merge-rejection-reason`; capability `creative.supports_assignment_merge`| Creative merge. | generated; `CreativeMergeRejectedError` mints schema-valid details (field defaults to the first rejected `assignment_operations` entry) and `creative_merge_rejected_details` narrows them: done (3), #1668|
66
66
|`list_creatives``platform_id`, `provenance`, `seller_revision`, `status_as_of`; request filter `provenance`|`creative/list-creatives-response.json`; `x-entity-types``creative_seller_revision`; capability `creative.stable_creative_ids`|`platform_id` is native in 3.3 (adcp#8175). There was no forward-compat patch for it in this SDK; nothing to retire. | generated; `stable_creative_ids` seller support and `delete_missing` exclusion: (3), #1638|
67
67
|`validate_input``Warning.field`|`creative/validate-input-result.json`|`field` is now declared as a string (#8212). | generated |
68
68
|`build_creative``errors`|`BuildCreativeResponse1/3`| Errors array on build responses. | generated |
@@ -101,7 +101,7 @@ it adopted the bundle, and what is left to the codegen/wire-fidelity (2) and
|`signals.data_provider_domains_complete`, `media_buy.portfolio.publisher_domains_complete`| capabilities; byte budgets 8,192 per field / 16,384 combined, 100 entries, 253 chars each; absence is never a denial |generated; bound enforcement in `property_lists` / portfolio readers: (3), #1668|
104
+
|`signals.data_provider_domains_complete`, `media_buy.portfolio.publisher_domains_complete`| capabilities; byte budgets 8,192 per field / 16,384 combined, 100 entries, 253 chars each; absence is never a denial |`adcp.decisioning.bound_counterparty_domains` cuts a list to the bounds and reports `complete`; `get_adcp_capabilities` projection truncates an oversized declared list and sets `*_complete: false`. The SDK has no buyer-side reader that treats either list as an allowlist: done (3), #1668|
105
105
106
106
### Accounts and identity
107
107
@@ -119,7 +119,7 @@ it adopted the bundle, and what is left to the codegen/wire-fidelity (2) and
119
119
|`error-details/unsupported-targeting-dimension.json`| under `UNSUPPORTED_FEATURE`; adapters minting `UNSUPPORTED_TARGETING_DIMENSION` / `DEPRECATED_TARGETING_DIMENSION` should migrate || generated; decisioning error minting: (3), #1642|
120
120
|`error-details/agent-permission-denied.json``Reason`| new nested enum || generated |
121
121
|`brand.json` fetch cap 2 MiB | all fetch paths; `MAX_JWKS_BYTES`, `MAX_CAPABILITIES_BYTES` unchanged | 3.2 verifiers may reject files between 256 KiB and 2 MiB. | done (3), #1654: 2 MiB, depth 32, 10 s total deadline, bounded concurrent fetches; follow-ups on #1635|
| One agent-resolution rule | request signing, webhook signing, governance JWS `iss`, response signing, rights attestations; pinned `signing_keys` published in JWKS; RFC 7638 thumbprints; `key_origins`; `agent_url_match: canonical`||`adcp.signing` audit: (3) |
124
124
| RFC 9421 profile deprecation |`adcp/request-signing/v1`, `adcp/webhook-signing/v1` deprecated (removal no earlier than 4.0) in favour of Web Bot Auth |`rfc9421_deprecation_active()` keys on a 3.3 line in `COMPATIBLE_ADCP_VERSIONS`, so SDK 10 warns by default on legacy `SigningConfig` / `RequestSignatureVerification` construction. | done (1) |
125
125
@@ -144,24 +144,24 @@ Every new declaration is optional; 3.2 behaviour stands when undeclared.
| specialisms |`sales_fixed_rate` (new specialism for fixed-price, non-guaranteed sellers); `sales-broadcast-tv` 1.1.0 | generated; `adcp.decisioning.specialisms`: (3), #1668|
147
+
| specialisms |`sales_fixed_rate` (new specialism for fixed-price, non-guaranteed sellers); `sales-broadcast-tv` 1.1.0 | generated; `sales-fixed-rate` has `REQUIRED_METHODS` / recommended methods / advertised tools and rolls up to `media_buy` in `SPECIALISM_TO_PROTOCOLS`. The packaged compliance assets carry no specialism storyboards, so `sales_fixed_rate` runs from the protocol's compliance tree: done (3), #1668|
148
148
|`canonical_creatives`| still not declared by 3.3 | the `_forward_compat` capability patch stays |
149
149
150
150
## 5. Error codes and error details
151
151
152
152
| Code / detail | Schema | Where it fires | SDK status |
153
153
| --- | --- | --- | --- |
154
154
|`REFERENCE_DEFINITION_CHANGED`|`error-details/reference-definition-changed.json`|`accept_proposal` when a pinned definition drifted; send only to 3.3 peers | generated; until then the 3.2 downgrade keeps it, since 3.2 `error.code` is open (#1667); minting and 3.2 downgrade mapping: (3), #1641|
|`TERMS_REJECTED`| must not fire for replayed advertised measurement terms; windows reference `reporting_capabilities.measurement_windows[].window_id`||decisioning: (3), #1668|
164
-
|`COMPLIANCE_UNSATISFIED`|`build_creative` refinement that narrows inherited `required_disclosures` / `prohibited_claims`||(3), #1668|
163
+
|`TERMS_REJECTED`| must not fire for replayed advertised measurement terms; windows reference `reporting_capabilities.measurement_windows[].window_id`||`get_products` / `list_products` refuse a product advertising an undeclared window (`INTERNAL_ERROR`, `check_advertised_measurement_terms`); `TermsRejectedError(proposed_terms=, advertised_terms=)` refuses to reject a replay (`is_advertised_terms_replay`): done (3), #1668|
164
+
|`COMPLIANCE_UNSATISFIED`|`build_creative` refinement that narrows inherited `required_disclosures` / `prohibited_claims`||not applicable: the SDK passes `build_creative` (including `refine_from_build_variant_id`) to the platform and retains no leaf compliance inputs, #1668|
165
165
|`ACCOUNT_NOT_FOUND`| discovery with an unresolved `account`|| done (#1288); storyboard confirmation: (3) |
166
166
167
167
## 6. Enum changes
@@ -191,7 +191,7 @@ Every new declaration is optional; 3.2 behaviour stands when undeclared.
191
191
192
192
| Item | Detail | SDK status |
193
193
| --- | --- | --- |
194
-
|`evaluator_id` source form removed |`core/evaluator-spec.json`: `EvaluatorSpec3` gone, `EvaluatorSpec2` gains `agent_url` and loses `evaluator_id`; `list_evaluators` withdrawn; the seller's evaluator goes in `creative_policy.accepted_verifiers[]`. No alias. | generated; any SDK helper that minted `evaluator_id`: (3), #1668; migration note in `MIGRATION_v9_to_v10.md`|
194
+
|`evaluator_id` source form removed |`core/evaluator-spec.json`: `EvaluatorSpec3` gone, `EvaluatorSpec2` gains `agent_url` and loses `evaluator_id`; `list_evaluators` withdrawn; the seller's evaluator goes in `creative_policy.accepted_verifiers[]`. No alias. | generated; no SDK helper mints `evaluator_id` (only the 3.1 / 3.2 versioned views keep it): nothing to remove, #1668; migration note in `MIGRATION_v9_to_v10.md`|
195
195
|`seller_id` on event source and audience results | deprecated for `platform_id`; sellers emit both with identical values | generated; seller dual emission and buyer preference: (3), #1639|
196
196
| Natural-key `AccountRef` after provisioning | deprecated; `account_id` with `account.stable_account_id`| (3), #1478|
197
197
| RFC 9421 signing profiles | deprecated for Web Bot Auth; verifiers keep accepting through 3.x | warning: done (1) |
0 commit comments