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
format_ids[] entry exists that no format_options[].v1_format_ref
covers, it surfaces as LEGACY_FORMAT_ID_DROPPED_UNMAPPED — the gap
the projection path can't see.
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 aformat_ids[]entry exists that noformat_options[].v1_format_refcovers, it surfaces asLEGACY_FORMAT_ID_DROPPED_UNMAPPED— the gap the projection path can't see.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.