Project a single Product to the canonical-only shape: format_options[]
present, format_ids[] dropped.
Dropping legacy never silently loses a format. Every input
format_id is either represented in the returned format_options[] or
surfaced in diagnostics — never discarded without a trace:
v1-shaped input (format_ids[], no format_options[]): runs the
v1 → v2 projection. Mapped refs become format_options[]; any ref
the projection can't map is surfaced as FORMAT_PROJECTION_FAILED.
v2-native input (format_options[] already present): keeps the
seller's canonical surface and drops the redundant v1 fallback. If a
legacy routing entry exists that no canonical option covers, it
surfaces a canonical-safe LEGACY_FORMAT_ID_DROPPED_UNMAPPED
diagnostic without echoing the routing identifier.
neither shape: returns format_options: []; there is nothing to
project and nothing to lose.
Pure and subtractive: unlike augmentProductWithFormatOptions
(which preserves format_ids[]), this drops it — the opt-in narrowing for
a consumer that has fully migrated. Complements the write-side
non-invertibility tracked at adcontextprotocol/adcp#4842 — this is the
read-side transparency half.
Project a single Product to the canonical-only shape:
format_options[]present,format_ids[]dropped.Dropping legacy never silently loses a format. Every input
format_idis either represented in the returnedformat_options[]or surfaced indiagnostics— never discarded without a trace:format_ids[], noformat_options[]): runs the v1 → v2 projection. Mapped refs becomeformat_options[]; any ref the projection can't map is surfaced asFORMAT_PROJECTION_FAILED.format_options[]already present): keeps the seller's canonical surface and drops the redundant v1 fallback. If a legacy routing entry exists that no canonical option covers, it surfaces a canonical-safeLEGACY_FORMAT_ID_DROPPED_UNMAPPEDdiagnostic without echoing the routing identifier.format_options: []; there is nothing to project and nothing to lose.Pure and subtractive: unlike augmentProductWithFormatOptions (which preserves
format_ids[]), this drops it — the opt-in narrowing for a consumer that has fully migrated. Complements the write-side non-invertibility tracked at adcontextprotocol/adcp#4842 — this is the read-side transparency half.