spec(3.1): SHOULD-publish capability_id on every format_options[] entry#4861
Merged
Conversation
#4845 added `PackageRequest.capability_ids[]` so V2-mental-model buyers can author `create_media_buy` without translating back through `v1_format_ref[]`. That path needs sellers to publish `capability_id` on the `format_options[]` entries the buyer targets — but the field is currently REQUIRED only when entries share a `format_kind`. For single-entry products (the 90% case), it's optional, and V2 authoring is silently unreachable. Add a SHOULD: sellers SHOULD set `capability_id` on every entry, not just when forced by a collision. Co-located with the buyer-side change in the same minor so 3.1 release-notes readers see the buyer capability and the seller obligation together. Description-text only — no structural change. The 4.0 cutover will tighten SHOULD → MUST (tracked in #4857). Closes #4856. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
LGTM. Description-only tightening with no wire change, cross-referenced cleanly to the buyer-side rule already shipped in #4845. The right shape: co-locate the seller obligation with the buyer capability in the same minor so 3.1 release-notes readers see both.
Things I checked
static/schemas/source/core/product-format-declaration.json:12— new SHOULD framing oncapability_idis internally consistent with the existing structural rule (REQUIRED only onformat_kindcollisions). Field stays optional at the schema level; happy path is unchanged for sellers shipping today.- Reciprocal contract verified:
static/schemas/source/media-buy/package-request.json:28already carries the failure-mode the new description cites —UNSUPPORTED_FEATUREwitherror.details.reason: capability_ids_not_publishedwhen a product'sformat_options[]entries don't publishcapability_id. The two sides reference each other coherently. docs/creative/canonical-formats.mdxrows 29 and 33 updated in lockstep with the schema. No further drift indocs/media-buy/task-reference/create_media_buy.mdx:189,922— the V2-path docs already describecapability_ids_not_publishedas the fall-back signal.- Changeset present (
patch), correct package, references the upstream PR and the 4.0 cutover issue. - No structural change → no oneOf discriminator regression risk. No required-flag flips. No enum changes.
Follow-ups (non-blocking — file as issues)
- Root description at
static/schemas/source/core/product-format-declaration.json:5still calls capability_id "Optional" and frames it as routing-only-on-collision. That's the pre-3.1 framing. The property-level description (L12) was tightened to SHOULD but the root paragraph one block above still reads as the old story. Worth a one-line fix to keep the schema internally consistent — readers who only skim the top blurb get the old contract. - Manifest-side cross-reference.
creative-manifest.json:18(andcreative-asset.json:27) describe theircapability_idas cleanly "optional in the single-entry case" with no pointer to the new seller-side SHOULD. Not a contradiction — manifest-validation truly is optional there — but a one-sentence "sellers SHOULD publish perproduct-format-declaration.json; manifests still MAY omit whenformat_kindroutes unambiguously" would prevent readers from concluding the optionality is symmetric. canonical-formats.mdx:828-830describes manifest-sidecapability_idas OPTIONAL whenformat_kinds are distinct. Technically a different surface (buyer-side manifest vs. seller-side declaration) so not contradictory, but adjacent prose that reads "recommended habit" undersells the SHOULD that now sits on the product side. A clarifying line about which surface is which would help.
Minor nits (non-blocking)
- Changeset severity.
patchis defensible — no wire shape change, no codegen delta, existing sellers stay conformant. A stricter read of "new normative SHOULD" arguesminor. Worth checking what bucket #4845's changeset landed in — release-notes symmetry between the buyer capability and the seller obligation is the whole point of co-locating them, and a mismatch reads odd. Not blocking.
Test plan in the PR body shows CI-green and Mintlify-render checks unticked; both are passive CI gates rather than manual smokes, and the relevant CI checks are green at review time. The unchecked Mintlify item is the only user-facing surface this PR changes — worth eyeballing the rendered table rows once before merge, but not a hold.
Approving.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #4856.
#4845 added
PackageRequest.capability_ids[]so V2-mental-model buyers can authorcreate_media_buywithout translating back throughv1_format_ref[]. That path needs sellers to publishcapability_idon theformat_options[]entries the buyer targets — but the field is currently REQUIRED only when entries share aformat_kind. For single-entry products (the 90% case), it's optional, and V2 authoring is silently unreachable.Adds a SHOULD on
product-format-declaration.json: sellers SHOULD setcapability_idon everyformat_options[]entry, not just when forced by a collision. Co-located with the buyer-side change in the same minor (3.1) so release-notes readers see the buyer capability and the seller obligation together — splitting them across minors would create a release where buyers ship V2 code against sellers who weren't told to update.Change
Description-text only. The field stays optional at the schema level — no structural change, no break to anyone shipping today. Sellers that don't comply remain 3.1-conformant; their products just aren't V2-authorable until they assign
capability_idvalues.Aligned
docs/creative/canonical-formats.mdxdefinitions (table rows forProductFormatDeclarationandcapability_id) to reflect the SHOULD framing — previously described as purely-optional.Files
static/schemas/source/core/product-format-declaration.json— extendedcapability_iddescriptiondocs/creative/canonical-formats.mdx— 2 table rows updated to match.changeset/should-publish-capability-id-on-every-format-option.md—patch4.0 cutover
The 4.0 cutover (SHOULD → MUST, schema-level enforcement) is tracked in #4857 with a dependency checklist: 3.1 SHOULD (this PR), conformance signal in Verified, adoption telemetry, migration guidance.
Test plan
🤖 Generated with Claude Code