Summary
@adcp/sdk@13.0.0-rc.11 cannot preserve the deprecated Package.format_ids echo contract when a DecisioningPlatform implements the native media-buy methods.
The runtime canonicalizes a 3.0 create_media_buy request before calling SalesPlatform.createMediaBuy, then validates the platform result as canonical before projecting it back to the negotiated legacy wire. This creates two related failures:
- A platform result containing both stable
format_option_refs and the original format_ids is rejected/normalized before the legacy projector can preserve the original IDs.
serverOptions.legacyHandlers.mediaBuy.{createMediaBuy,updateMediaBuy,getMediaBuys} cannot provide an explicit raw compatibility facade because those handlers are shadowed by the native platform methods.
The package schema says sellers SHOULD echo format_ids whenever supplied, including dual-emission cases where format_option_refs wins selector precedence.
Reproduction
Configure a DecisioningPlatform sales tenant plus legacyHandlers.mediaBuy.createMediaBuy, then send a negotiated 3.0 request with:
{
"adcp_version": "3.0",
"packages": [{
"product_id": "legacy_product",
"pricing_option_id": "fixed_cpm",
"budget": 10000,
"format_ids": [{
"agent_url": "https://creative.adcontextprotocol.org/",
"id": "display_300x250_image",
"width": 300,
"height": 250
}]
}]
}
Observed platform input for a recognized legacy ID contains only a temporary migrated_* format_option_ref. Returning the original format_ids alongside the platform's stable canonical ref does not preserve it through the native platform boundary. The configured legacy handler is not called; rc.11 logs:
opts.legacyHandlers.mediaBuy.{createMediaBuy, updateMediaBuy, getMediaBuys}
are shadowed by platform-derived handlers
For a product combining one canonically mapped legacy ID and one truly legacy-only ID, canonical projection retains only the mapped option. The native response projector therefore cannot reconstruct the full original format_ids selection.
Expected
Provide a supported compatibility channel for native platform methods to retain exact legacy selector metadata across canonical request handling and legacy response projection. Either:
- preserve the original package
format_ids as hidden/request metadata and merge them on the negotiated legacy response;
- allow raw legacy media-buy handlers to take precedence for 3.0 requests; or
- expose an explicit platform response sidecar that the canonical validator ignores and the legacy projector consumes.
The canonical platform result should continue to use stable format_option_refs; temporary migrated_* aliases must not become durable state.
Downstream
adcontextprotocol/adcp#6307 resolves temporary aliases into stable canonical refs, retains original legacy tuples only in compatibility state, and strips legacy metadata at the native canonical platform boundary. Fully mapped selectors round-trip through configured routes, but mixed mapped + truly legacy-only selector echo requires an SDK fix.
Summary
@adcp/sdk@13.0.0-rc.11cannot preserve the deprecatedPackage.format_idsecho contract when aDecisioningPlatformimplements the native media-buy methods.The runtime canonicalizes a 3.0
create_media_buyrequest before callingSalesPlatform.createMediaBuy, then validates the platform result as canonical before projecting it back to the negotiated legacy wire. This creates two related failures:format_option_refsand the originalformat_idsis rejected/normalized before the legacy projector can preserve the original IDs.serverOptions.legacyHandlers.mediaBuy.{createMediaBuy,updateMediaBuy,getMediaBuys}cannot provide an explicit raw compatibility facade because those handlers are shadowed by the native platform methods.The package schema says sellers SHOULD echo
format_idswhenever supplied, including dual-emission cases whereformat_option_refswins selector precedence.Reproduction
Configure a
DecisioningPlatformsales tenant pluslegacyHandlers.mediaBuy.createMediaBuy, then send a negotiated 3.0 request with:{ "adcp_version": "3.0", "packages": [{ "product_id": "legacy_product", "pricing_option_id": "fixed_cpm", "budget": 10000, "format_ids": [{ "agent_url": "https://creative.adcontextprotocol.org/", "id": "display_300x250_image", "width": 300, "height": 250 }] }] }Observed platform input for a recognized legacy ID contains only a temporary
migrated_*format_option_ref. Returning the originalformat_idsalongside the platform's stable canonical ref does not preserve it through the native platform boundary. The configured legacy handler is not called; rc.11 logs:For a product combining one canonically mapped legacy ID and one truly legacy-only ID, canonical projection retains only the mapped option. The native response projector therefore cannot reconstruct the full original
format_idsselection.Expected
Provide a supported compatibility channel for native platform methods to retain exact legacy selector metadata across canonical request handling and legacy response projection. Either:
format_idsas hidden/request metadata and merge them on the negotiated legacy response;The canonical platform result should continue to use stable
format_option_refs; temporarymigrated_*aliases must not become durable state.Downstream
adcontextprotocol/adcp#6307 resolves temporary aliases into stable canonical refs, retains original legacy tuples only in compatibility state, and strips legacy metadata at the native canonical platform boundary. Fully mapped selectors round-trip through configured routes, but mixed mapped + truly legacy-only selector echo requires an SDK fix.