Repository navigation
Conversation
….2.x backport of #8547) (#8567) * fix(schemas): compose the protocol envelope on every task response The envelope notes say task response schemas define only body fields and the envelope supplies the rest, but 43 of the 118 tool response and async status schemas did not compose core/protocol-envelope.json, and adcp_version and adcp_major_version reached responses only through a direct core/version-envelope.json composition or a hand-copied $ref. - core/protocol-envelope.json composes core/version-envelope.json, so the served version fields are envelope fields on every response. Both descriptions now say so; the version envelope is part of the payload only on a request. - Every tool response and async status schema, and the shared compact components, compose the protocol envelope through the root allOf. Response schemas no longer compose the version envelope directly, and request_proposals and refine_proposals drop their hand-copied adcp_version $refs. - Response roots and status branches stay open (DR-0019), so the envelope reaches every response through that allOf with no build step. The two get_reporting_status failure branches, the last closed response nodes (experimental on 3.2.x), are opened. A failed lookup forbids each body field of the success view by name, the rejection its closure provided, so it still reveals no resource data. - decline_proposals lets its completed branch carry status completed, as refine_proposals and request_proposals do, instead of forbidding status. - Governance responses, async status payloads and webhook result examples carry the envelope status the envelope already required, and the list_products examples, the MCP guide's envelope field list and the versioning page say the same. Test fixtures, compliance vectors and doc examples carry status. The reporting regression test validates the dispatched wire response, with the status the dispatcher stamps, instead of injecting one. tests/response-envelope-composition.test.cjs enumerates every tool's response and async status schemas through discoverTools and checks that each composes the protocol envelope through its root allOf, that none composes the version envelope directly, and that no response root or status branch is closed. Every root and branch is compiled on its own and accepts each envelope property, with single-fault vectors; a vector is shown to fail a closed node on exactly one error. It runs from npm test as test:response-envelope-composition. * fix(training-agent): keep task outcomes out of the envelope status from 3.1 Every task response now composes the protocol envelope, so a top-level status must be a task status. Four handlers put a domain outcome there: acquire_rights (the rights status), check_governance (the verdict), creative_approval (the approval decision) and report_plan_outcome (the outcome state). 3.1 renamed those to rights_status, verdict, approval_status and outcome_state (#4897). served-outcome-status.ts holds the one table of those renames, found by comparing the 3.0 and 3.1 schemas. Handlers emit the 3.1 shape: status completed, with the outcome only in its renamed field. The transport adapters project it onto a served 3.0 before the SDK shapes the response, carrying the outcome in status as the 3.0 schemas define it and keeping the 3.1 field beside it: the governance and brand platforms, the custom tools, the legacy dispatcher, and the in-process MCP server on the legacy route, for fresh and replayed results alike. Caches keep the release-neutral result. acquire_rights at a 3.0 pin used to answer status completed where the 3.0 schema requires acquired, pending_approval or rejected. The served release comes from the SDK request context on the tenants and from the dispatcher on the legacy route. Custom tools always declare adcp_version and adcp_major_version and forward the served release to their handlers. servesOutcomeInEnvelopeStatus uses the shared parseAdcpReleaseVersion, now in types.ts. The governance tests assert the verdict and the task status separately, and the smoke test covers report_plan_outcome at a 3.0 pin with its replay, and acquire_rights at the current release and at 3.0. Fixes #8553. * fix(schemas): declare envelope fields only on the envelope, and task_id once Response schemas restated envelope fields inline, and some copies narrowed them without a reason: the compact proposal-flow responses pinned replayed to const true, and the compact branches, the core/compact-task-* payloads and the submitted branches and async submitted payloads of the other tasks capped message at 2,000 characters while the envelope, the MCP webhook payload and the response wrapper declared no bound. The envelope's replayed is a boolean that defaults to false, so the replayed pins rejected conforming responses, and the message bound depended on the delivery path. - Remove the inline copies of envelope fields from 35 response schemas: task_id, message, replayed, governance_context, adcp_error, the version and correlation fields, and context declarations with a local description. A status const or enum that discriminates a branch, a context $ref identical to the envelope's, and a const that pins a fixed value (the message and adcp_error of an unavailable get_reporting_status lookup, which keep it from revealing whether a resource exists) stay. - A task-level message has one definition, core/task-message.json: type string, maxLength 2000, untrusted input to the receiver, and a seller with longer text truncates it rather than fail the task. The protocol envelope, the MCP webhook payload and the response wrapper refer to it, so the 2,000 that 3.2.7 published on the compact and submitted responses is the one bound on every carrier. The envelope's replayed says that an absent replayed means false and that a response may carry replayed: false. - task_id has one definition, core/task-id.json: type string, minLength 1, x-entity task, x-max-length-4.0 128, registered in the schema index. Every task_id declaration refers to it: the protocol envelope, tasks/get and get_task_status requests and responses, the tasks/list and list_tasks responses and task_ids filters, the MCP webhook payload, and the compliance controller's request and response, which keep their own maxLength 128. A task_id is the handle a caller polls and a webhook references, and 3.2.7 already published minLength 1 on core/compact-task-submitted.json. - core/task-submitted.json is the one place a submitted response requires task_id: status const submitted and a required task_id (core/task-id.json). Code generators ignore an if/then, so the envelope states no conditional rule of its own. Every submitted body and branch composes it through allOf: core/compact-task-submitted.json, the eight *-async-response-submitted.json bodies that do not go through it, and the ten inline submitted oneOf branches. They no longer restate status submitted or a required list, except control_media_buy and the buy_products/accept_proposal commitment, whose OpenAPI discriminator on status needs the local const. Completed branches keep their not: {required: [task_id]} exclusions. - core/task-working.json and core/task-input-required.json pin the working and input-required status the same way, and every working and input-required body composes its own, so an async status payload accepts only its status. The MCP webhook example that carried a create_media_buy result now carries a complete one. - The oneOf audit fuses a variant's allOf members before classifying it, as code generators do, so the submitted branches stay discriminated. - The storyboard context-output lint follows every composition keyword of a node, and the branch an expected_arm selects carries its document's root allOf, so a capture of task_id from a submitted branch resolves through the envelope. Both storyboard path lints find an expected_arm const through a branch's allOf, as the submitted branches now carry it. The composition test checks that no response node copies an envelope field, pins replayed or bounds message, that task_id has one definition, that every submitted, working and input-required body composes its core/task-<status>.json, that no response schema keys task_id on status through if/then, and that the envelope, webhook payload and wrapper message refer to core/task-message.json. Its per-node vectors add replayed: false and a 2,000-character message, and each is shown to fail a replayed pin or a lower message bound on exactly one error. Every response document and both other message carriers accept a 2,000-character message and reject 2,001 characters on maxLength only. Every response document rejects an empty task_id on its length only; every document with a submitted body or branch rejects a submitted response without task_id on task_id only; and every request that carries a task_id rejects an empty one on its length only. Structural tests and the MCP schema analysis counts follow the shared definition. The media-buy model-context budget moves from 443 to 444 KiB: the inputs that reach core/task-id.json come to 453,646 bytes, 14 over the former budget. The parity compile limit moves from 1,265,000 to 1,266,000 bytes: the comply_test_controller request reaches the shared task definitions through its forced task results and comes to 1,265,334.
…ponse (3.2.x backport)" (#8567) (#8612) Merged with red checks: the 3.2.x branch reports no required checks, so the pre-merge gate missed failing Build and static checks, TypeScript Build and /sales storyboards (the 3.2.x-pinned SDK still strips status). Revert to keep 3.2.x green; re-land once 3.2.x pins an SDK with the gated envelope fix. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… (3.2.x backport) (#8706) typed_proposal_negotiation and refine_frequency_cap_negotiation seeded products[2] with format_kind "native" and channels ["native"], neither of which is valid. Use native_in_feed with the params every format declaration requires, and the display channel. Both storyboard files now match main byte for byte. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs: explain optional gender targeting on 3.2 * docs(media-buy): make the 3.2 gender bridge self-contained
Records 3.2.x's maintenance commits since the 3.2.8 forward-merge (#8566) as ancestors of main, so the automatic forward-merge after 3.2.9 sees only release metadata. Every fix in this range already landed on main first; the resolved tree equals main's tree. Resolutions: - docs/media-buy/advanced-topics/targeting.mdx: main's file. The 3.2.x side is only #7926, a 3.2-only optional ext.adcp gender agreement. Main carries experimental core gender targeting (#7925) and removed that binding, so none of #7926 belongs on main. - static/compliance/source/universal/error-compliance-signals.yaml: main's file. The backport (#8581) matches main's #8579; main also has #8601's version 1.0.2 and supported_protocols gate. - tests/sdk-runner-capability-gates.test.cjs: main's file. Three of the backport's four tests are identical on main; the fourth is the SDK 14 variant (bundle rolls up partial). Main's #8579 asserts passing on its current SDK. - .changeset/native-in-feed-negotiation-fixtures.md and .changeset/signals-error-compliance-applicability.md: not carried. They describe 3.2.9 backports of b70de1e and 0d3697b, which main's CHANGELOG already records; main's changeset pool is independent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Superseded by #8872. It forward-merges the 🤖 Generated with Claude Code |
Forward-merges the published 3.2.9 release (v3.2.9 = 39e9353) and every 3.2.x maintenance commit before it. Supersedes the a4af1a1 forward-merge in adcontextprotocol#8820, which is an ancestor of v3.2.9. Release records: - dist/compliance/3.2.9, dist/schemas/3.2.9 and the signed dist/protocol/3.2.9.tgz tuple are taken from v3.2.9 unchanged. - dist/schemas/index.json and latest.json are regenerated (forward-merge-release-records.cjs schema-discovery). - CHANGELOG.md is main's file plus the 3.2.9 block. - package.json, package-lock.json, static/schemas/source/index.json: main's. - static/compliance/published-versions.json: main's. 3.2.x's only extra entry is 3.2.9, which is registered in a separate commit after qualification. Content conflicts, all resolved to main's file: - docs/media-buy/advanced-topics/targeting.mdx: the 3.2.x side is exactly adcontextprotocol#7926, 3.2-only optional gender agreement docs; main carries core gender targeting (adcontextprotocol#7925) instead. - static/compliance/source/universal/error-compliance-signals.yaml: main's is the adcontextprotocol#8581 backport content plus main-only adcontextprotocol#8601 (version 1.0.2 and the signals capability gate). - tests/sdk-runner-capability-gates.test.cjs: the only 3.2.x-only test is the SDK 14 variant of main's "signals discovery error bundle passes" test. - server/tests/unit/storyboards.test.ts: adcontextprotocol#8825's 3.2.x-shaped 3.1.32 integration tests; main already integrated 3.1.32 and 3.1.33 with its own test shape, and the non-conflicting adcontextprotocol#8825 hunk is already on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR is superseded. I recommend closing it. It forwards
The 3.2.x commits since 3.2.10 (#8873, #8938, #8864) will forward through one fresh 🤖 Generated with Claude Code |
|
Closing as superseded: everything this branch forwards from 3.2.x is already on main (via #8872/#8904), so it carries nothing new — see the analysis above. The post-3.2.11 forward-merge goes in a fresh PR. 🤖 Generated with Claude Code |
Manual forward-merge of
3.2.x@a4af1a1dc3intomain@fafe043b50. The automaticforward-merge-3.2.ymlrun has failed on every 3.2.x push since Oct 29 (latest: run 42520604328), with content conflicts it correctly refuses to auto-resolve. Until 3.2.x's maintenance commits are ancestors ofmain, the run after 3.2.9 hits the same conflicts, and 3.2.9's release records can't reachmain.Land with a merge commit, not squash or rebase. The second parent is what records the ancestry (see #8051 for what a squash does).
What this is
A real two-parent merge,
080a80127d: first parentmain@fafe043b50, second parent3.2.x@a4af1a1dc3. Its tree is identical tomain's, so it changes zero files. Every fix on 3.2.x since the 3.2.8 forward-merge (#8566; merge base65fef6f40d) is a backport of a change that landed onmainfirst. The only 3.2.x content main doesn't have is 3.2-only documentation and the 3.2.9 changesets, and neither belongs on main.3.2.x commits brought into ancestry:
Conflict resolutions
docs/media-buy/advanced-topics/targeting.mdx: main's file.ext.adcp.demographics.genderagreement for 3.2 implementations. By its own description, it is 3.2-only: the 3.3 coherence decision removed that binding from main.static/compliance/source/universal/error-compliance-signals.yaml: main's file.version: "1.0.2"and therequires_capability: supported_protocols contains signalsgate.tests/sdk-runner-capability-gates.test.cjs: main's file.partial. Main's current SDK grades itpassing, which main's test asserts..changeset/native-in-feed-negotiation-fixtures.mdand.changeset/signals-error-compliance-applicability.md: not carried. They merged cleanly, but they are 3.2.9's changesets for backports of fixes main's CHANGELOG already records (b70de1e, 0d3697b). Carrying them would put both entries in main's pending pool and log them twice in the next 3.3 beta. This matches the workflow rule that main's changeset pool is independent.Verification
main^{tree};git diff fafe043b50 080a80127dis empty.node scripts/forward-merge-release-records.cjs schema-discovery: no change.4eac700ef7) intoa4af1a1dc3.CHANGELOG.md,package.json,package-lock.json,dist/schemas/index.json,static/compliance/published-versions.json,static/schemas/source/index.jsonand one.changeset/pre/path conflict. All are on the workflow's auto-resolve list..changeset/pre/one is a rename/delete. Git pairs main's archived.changeset/pre/signals-error-compliance-applicability.mdwith the 3.2.x file the release deletes. StatusUDsends it tocheckout --ours, which keeps main's archive.tests/billing/stripe-client.test.tsunder load; it passed alone (57/57) and on the retry. Normal pre-push ran; the docs and storyboard checks skipped because the range has no tree change.No changeset:
forward-merge/branches are exempt, and there is no tree change.🤖 Generated with Claude Code