diff --git a/.changeset/adcp-major-version-removal-reminder.md b/.changeset/adcp-major-version-removal-reminder.md new file mode 100644 index 00000000000..795e8abcc11 --- /dev/null +++ b/.changeset/adcp-major-version-removal-reminder.md @@ -0,0 +1,5 @@ +--- +"adcontextprotocol": patch +--- + +Docs: restate in the 3.3 release notes and the 3.2 → 3.3 migration guide that `adcp_major_version` and `adcp.major_versions`, deprecated since 3.1, are removed in 4.0 (DR-0035). Buyers send `adcp_version` on every request and keep the integer mirror through 3.x; in-house clients that send only the integer should switch now. Per DR-0034 (ratified), a request carrying only `adcp_major_version` is served the oldest supported release in that major; the versioning docs and the version-negotiation spec now say so. diff --git a/docs/reference/migration/3-2-to-3-3.mdx b/docs/reference/migration/3-2-to-3-3.mdx index 29d5eb933b9..0d57b1c48ca 100644 --- a/docs/reference/migration/3-2-to-3-3.mdx +++ b/docs/reference/migration/3-2-to-3-3.mdx @@ -59,6 +59,7 @@ Everything else is an optional declaration or a clarification. Agent identity (D | 29 | Creative agents that advertise `creative.supports_refinement` | Retain each leaf's compliance inputs for as long as the leaf, apply them to every refinement, and never treat a refined leaf as approved ([details](#refinement-carries-compliance-forward)). | | 30 | Sellers that hold buys for review | Keep a provisional buy (`confirmed_at: null`) in `pending_start` at flight start until you confirm or reject it ([details](#flight-start-activates-committed-buys-only)). | | 31 | Sellers reporting qualified metrics | Omit a metric's flat carrier from buy and window `totals` when packages report it under more than one qualifier set ([details](#multi-qualifier-metrics-omit-flat-totals)). | +| 32 | Buyers and in-house clients | Send `adcp_version` on every request, with the deprecated `adcp_major_version` mirror through 3.x. 4.0 removes `adcp_major_version` and `adcp.major_versions` ([details](#deprecations)). | ## Required to claim 3.3 behavior @@ -580,6 +581,8 @@ Adopters of these patches have already seen these; their changesets reappear in Existing 3.2 deprecations keep their published removal windows. +One earlier deprecation is worth restating before 4.0. The integer request field `adcp_major_version` and the `adcp.major_versions` capability field, deprecated in 3.1 in favor of `adcp_version` and `adcp.supported_versions`, keep working through 3.x and are **removed in 4.0** ([DR-0035](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0035-adcp-major-version-removed-in-4-0.md)). Buyers send `adcp_version` on every request and keep the integer mirror until then. Sellers keep emitting `adcp.major_versions` alongside `adcp.supported_versions` through 3.x. In-house clients that send only the integer should move to `adcp_version` now. The [v4 compatibility checks](/docs/reference/migration/v4-compatibility#major_versions_removed_in_4_0) flag sellers that still rely on the integer list. + ## Compliance and grading - `version_negotiation` gains an optional scenario for 3.1-pinned response shapes. Its checks stay advisory until runners can validate against the served release's schema bundle. diff --git a/docs/reference/release-notes.mdx b/docs/reference/release-notes.mdx index 5aa4cb558c7..ebe82794741 100644 --- a/docs/reference/release-notes.mdx +++ b/docs/reference/release-notes.mdx @@ -78,8 +78,9 @@ Each beta is immutable. The `3.3-beta` documentation selector advances to the la - **Deprecated: RFC 9421 signing profiles (#8162).** `adcp/request-signing/v1` and `adcp/webhook-signing/v1` keep working through 3.x and are removed in 4.0. The replacement is the experimental Web Bot Auth profile; see the [agent identity migration guide](/docs/reference/migration/agent-identity-3-3). - **Deprecated: `seller_id` on event source and audience results (#8290).** Use `platform_id`; the alias keeps working through 3.x, removal no earlier than 4.0. - **Deprecated: natural-key account references after provisioning (#8123).** They keep working through 3.x and are planned for removal in 4.0; sellers SHOULD declare `account.stable_account_id`. See [Deprecations](/docs/reference/migration/3-2-to-3-3#deprecations). +- **Reminder, not new in 3.3: `adcp_major_version` is removed in 4.0 ([DR-0035](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0035-adcp-major-version-removed-in-4-0.md)).** The integer request field and the `adcp.major_versions` capability field have been deprecated since 3.1. They keep working through 3.x, and 4.0 removes both. Send `adcp_version` on every request, keeping the `adcp_major_version` mirror through 3.x. In-house clients that still send only the integer should switch before 4.0. The compliance grader already blocks sellers that do not echo `adcp_version` or emit `adcp.supported_versions`, and at 4.0 rejects the legacy fields. -Each is detailed in the [migration guide](/docs/reference/migration/3-2-to-3-3#required-to-claim-3-3-behavior) and recorded in [3.3 exceptions to 3.x compatibility](/docs/reference/versioning#3-3-exceptions-to-3-x-compatibility-beta). Fields that a 3.2 validator rejects, and so are sent only on a negotiated 3.3 version, are listed in [Send only to 3.3 peers](/docs/reference/migration/3-2-to-3-3#send-only-to-3-3-peers). Schema-shape changes for SDK generators are in [SDK and code-generator maintainers](/docs/reference/migration/3-2-to-3-3#sdk-and-code-generator-maintainers). 3.3 deprecates no stable field, task, or enum value; it deprecates one usage and the RFC 9421 signing profiles, listed above. +Each is detailed in the [migration guide](/docs/reference/migration/3-2-to-3-3#required-to-claim-3-3-behavior) and recorded in [3.3 exceptions to 3.x compatibility](/docs/reference/versioning#3-3-exceptions-to-3-x-compatibility-beta). Fields that a 3.2 validator rejects, and so are sent only on a negotiated 3.3 version, are listed in [Send only to 3.3 peers](/docs/reference/migration/3-2-to-3-3#send-only-to-3-3-peers). Schema-shape changes for SDK generators are in [SDK and code-generator maintainers](/docs/reference/migration/3-2-to-3-3#sdk-and-code-generator-maintainers). 3.3 deprecates no stable field, task, or enum value; it deprecates one usage and the RFC 9421 signing profiles, listed above. The `adcp_major_version` reminder restates an existing 3.1 deprecation. ### Experimental surfaces in 3.3 diff --git a/docs/reference/versioning.mdx b/docs/reference/versioning.mdx index 27d301663a8..6dce8007a93 100644 --- a/docs/reference/versioning.mdx +++ b/docs/reference/versioning.mdx @@ -44,7 +44,7 @@ Buyers and sellers negotiate at **release precision** (VERSION.RELEASE, e.g. `"3 - Same major, no exact match, at least one server release ≤ buyer's pin → downshift to highest supported release ≤ the pin. Covers both "server's max < pin" and gap-cases (e.g. server `["3.0", "3.2"]` + pin `"3.1"` → serve `"3.0"`). - Same major, no server release ≤ buyer's pin (sub-min: every supported release is strictly greater) → return `VERSION_UNSUPPORTED` with `supported_versions` in `error.data`. - Different major → return `VERSION_UNSUPPORTED` with `supported_versions` in `error.data`. - - Omitted → server uses its default release (or, if only `adcp_major_version` was sent, the highest supported release in that major). + - Omitted → server uses its default release. If only `adcp_major_version` was sent, the server serves the oldest supported release in that major ([DR-0034](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0034-major-only-requests-are-served-the-oldest-release.md)): in practice that buyer is a 3.0 buyer. 4. **Server echoes**: `adcp_version` on every response tells the buyer which release the seller actually served. The echoed value is the **release served**, never the seller's own latest release — a 3.1 seller serving a 3.0 buyer at 3.0 echoes `"3.0"`. Buyers SHOULD validate the response against that release's schema, not against their pin. The seller MUST shape the response to that release; see [Serving an older pin](#serving-an-older-pin). When the response omits `adcp_version` (a legacy 3.0 seller that doesn't read the field — `additionalProperties: true` makes it invisible there), buyers SHOULD validate against their own pin and treat the seller as 3.0-only for capability inference. The buyer's SDK falls back to its constructor pin in this case. @@ -115,7 +115,7 @@ The legacy `adcp_major_version` (integer per-request) and `adcp.major_versions` **Dual-emit during 3.x:** a buyer that emits `adcp_version` SHOULD also emit `adcp_major_version` (with the major component of its pin) on the same request. This lets legacy 3.x sellers that only read the integer keep negotiating correctly. When both fields are present and disagree at the major level, the server MUST treat the request as malformed and return `VERSION_UNSUPPORTED`. When only major-precision is provided: -- Buyer sends `adcp_major_version: 3` → server serves the highest supported release in major 3. +- Buyer sends `adcp_major_version: 3` → server serves the oldest supported release in major 3, which is 3.0 when supported ([DR-0034](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0034-major-only-requests-are-served-the-oldest-release.md)). - Server emits `adcp.major_versions: [3]` → buyer can negotiate at major precision but loses release-level information. ### Migration timeline @@ -128,7 +128,7 @@ The spec stays at SHOULD on both sides through all of 3.x. The [3.x stability gu | **3.2** | (unchanged from 3.1) | (unchanged from 3.1) | Blocking failure when sellers don't echo `adcp_version` or don't emit `supported_versions` on capabilities. | | **4.0** | MUST emit `adcp_version`. `adcp_major_version` removed. | MUST honor and echo `adcp_version`. `adcp.major_versions` and `extensions.adcp.adcp_version` removed. | Blocking failure on absence; legacy fields rejected. | -In-house clients that haven't moved to the SDK yet can keep sending `adcp_major_version` only through all of 3.x — the server falls back to it. Adding `adcp_version` becomes the certifiable behavior at 3.2 (via the grader); the spec itself doesn't require it until 4.0. +In-house clients that haven't moved to the SDK yet can keep sending `adcp_major_version` only through all of 3.x — the server falls back to it and serves the oldest supported 3.x release, so newer fields need `adcp_version`. Adding `adcp_version` becomes the certifiable behavior at 3.2 (via the grader); the spec itself doesn't require it until 4.0. ### Relationship to MCP `protocolVersion` diff --git a/governance/decisions/DR-0034-major-only-requests-are-served-the-oldest-release.md b/governance/decisions/DR-0034-major-only-requests-are-served-the-oldest-release.md new file mode 100644 index 00000000000..90477dd1b0e --- /dev/null +++ b/governance/decisions/DR-0034-major-only-requests-are-served-the-oldest-release.md @@ -0,0 +1,34 @@ +--- +id: DR-0034 +title: A request carrying only adcp_major_version is served the oldest supported release of that major +class: breaking +status: accepted +date: 2026-10-22 +decided: 2026-10-26 +decided_by: WG Session C, 2026-10-26 +refs: ["#8373", "#8410", "DR-0024", "DR-0035"] +supersedes: DR-0024 +dissent: none +--- + +## Decision + +A request that carries `adcp_major_version` and no `adcp_version` is served the **oldest** release the server supports in that major, and the response echoes it. For a major-only `adcp_major_version: 3` request to a server supporting 3.0, that is 3.0. A buyer that wants a newer release's behavior sends `adcp_version`. + +`adcp_major_version` is deprecated and is removed in 4.0 ([DR-0035]). + +This replaces only the "Unpinned requests" paragraph of [DR-0024]. The rest of DR-0024 stands. A request carrying neither field is still served the server's default release. + +## Rationale + +Every 3.1+ SDK sends `adcp_version`, so in practice a major-only request comes from a 3.0 buyer, and its payload is 3.0-shaped. Serving it the oldest release reads the request in the shape it was written in, and answers in the shape the buyer can validate, which is what [DR-0024] demands of every pinned response. Serving the newest release instead answers a 3.0 buyer with a 3.2 response that a strict 3.0 validator rejects (closed shared types, the removed media-buy `status` alias). An earlier view that serving the newest release is safe was corrected in the session. + +## Implications + +- **Changes a default.** `specs/version-negotiation.md` §4 and `docs/reference/versioning.mdx` ("Omitted" and the major-only example) say a major-only request is served the highest supported release. Both are updated to this rule. +- **In-house clients** that stay on `adcp_major_version` are served the oldest supported 3.x release, and they lose newer fields until they send `adcp_version`. They should move to `adcp_version` now; the field is removed in 4.0 regardless ([DR-0035]). +- **3.x only.** The rule ends with `adcp_major_version` at 4.0. In 4.x a request without `adcp_version` is served the server's default release. +- The TypeScript server framework already serves the oldest release for major-only requests (`@adcp/sdk` `selectServedAdcpRelease`). The Go SDK serves the newest and aligns (adcontextprotocol/adcp-go#588). + +[DR-0024]: ./DR-0024-responses-conform-to-served-release.md +[DR-0035]: ./DR-0035-adcp-major-version-removed-in-4-0.md diff --git a/governance/decisions/DR-0035-adcp-major-version-removed-in-4-0.md b/governance/decisions/DR-0035-adcp-major-version-removed-in-4-0.md new file mode 100644 index 00000000000..4ee73619dac --- /dev/null +++ b/governance/decisions/DR-0035-adcp-major-version-removed-in-4-0.md @@ -0,0 +1,32 @@ +--- +id: DR-0035 +title: adcp_major_version and adcp.major_versions are deprecated through 3.x and removed in 4.0 +class: breaking +status: recorded +date: 2026-10-22 +decided: ~2026-04 +decided_by: maintainer practice (release-precision negotiation, #3493; v4 compatibility checks, #3572) +refs: ["#3493", "#3572", "#8373", "DR-0024", "DR-0034"] +dissent: none +--- + +## Decision + +The integer request field `adcp_major_version` and the capability field `adcp.major_versions` are **deprecated** in favor of the release-precision `adcp_version` and `adcp.supported_versions`. They are **removed in 4.0**. + +- **Through 3.x:** buyers SHOULD send `adcp_version` and SHOULD also send `adcp_major_version` as a mirror. Servers MUST honor `adcp_major_version` when it is the only version field. Sellers MUST keep emitting `adcp.major_versions` alongside `adcp.supported_versions`. +- **In 4.0:** neither field exists. A 4.x buyer sends `adcp_version`, a 4.x seller advertises `adcp.supported_versions`, and a request without `adcp_version` is served the seller's default release. +- A 3.x SDK keeps dual-emitting for its whole support window, including after 4.0 GA. A 4.x SDK emits only `adcp_version`. + +## Rationale + +Release-precision negotiation is what lets a buyer and a seller agree on the exact minor release a payload is shaped for. An integer major cannot say which minor that is, so it cannot drive negotiation, validation against the served release ([DR-0024]), or translation between minors. It stays through 3.x only so that 3.0 peers keep working. + +## Implications + +- This records a decision already stated in the schema (`core/version-envelope.json` marks the field `deprecated` and says "Removed in 4.0"), in `specs/version-negotiation.md` §6, in `docs/reference/versioning.mdx`, and in the `major_versions_removed_in_4_0` check of the v4 compatibility guide. +- The major-only serving rule ([DR-0034]) applies to 3.x only. +- In-house clients that still send only `adcp_major_version` should move to `adcp_version` before 4.0. Under DR-0034 they would otherwise be served the oldest 3.x release. + +[DR-0024]: ./DR-0024-responses-conform-to-served-release.md +[DR-0034]: ./DR-0034-major-only-requests-are-served-the-oldest-release.md diff --git a/specs/version-negotiation.md b/specs/version-negotiation.md index 9bc15a14c05..97c1bbacf67 100644 --- a/specs/version-negotiation.md +++ b/specs/version-negotiation.md @@ -156,7 +156,7 @@ A server MUST honor `adcp_version` when present, falling back to `adcp_major_ver | `adcp_version` present, same major, no server release ≤ client's pin (sub-min: every supported release is strictly greater) | `VERSION_UNSUPPORTED`. The seller is not obligated to maintain validators for releases below its supported window. | | `adcp_version` present, different major | `VERSION_UNSUPPORTED`. | | both fields present, majors disagree | `VERSION_UNSUPPORTED` (treat as malformed). | -| `adcp_version` absent, `adcp_major_version` present | Serve highest supported release in that major. Echo response. | +| `adcp_version` absent, `adcp_major_version` present | Serve the oldest supported release in that major (DR-0034). Echo response. | | both absent | Serve in server's default release. Echo on response. | In all non-error cases, the response's `adcp_version` is authoritative — it tells the client exactly what contract was served. Clients SHOULD validate the response against that release's schema, not against their pin. The seller's `adcp_version` on the response is the **release served**, never the seller's own latest release: if a 3.1 seller serves a 3.0 buyer at 3.0, the response echoes `"3.0"`.