feat(schemas): add supported_optimization_metrics seller-level capability (closes #4651)#4669
Merged
Merged
Conversation
…lity (closes #4651) Adds media_buy.supported_optimization_metrics as a seller-level rollup of product-level metric_optimization.supported_metrics. Enum mirrors core/product.json exactly. Optional, additive — sellers without it fall back to per-product inspection. Unblocks metric-buy-mode storyboard gating via requires_capability (#4637). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
bokelley
added a commit
that referenced
this pull request
May 18, 2026
… contains: matcher (#4637) (#4722) Four new storyboard scenarios in the capability-claim contract pattern, all gated via the `contains:` matcher (shipped in @adcp/client 7.70 — adcp-client#1817), all added to `sales-non-guaranteed.requires_scenarios`: - `performance_buy_flow_roas` — gated on `media_buy.conversion_tracking.supported_targets` containing `per_ad_spend` (#4639). Certifies ROAS goal acceptance, rejection of per_ad_spend without value_field, and delivery surfaces `conversion_value` + `roas` alongside `conversions` + CPA. - `reach_buy_flow` — gated on `media_buy.supported_optimization_metrics` containing `reach` (#4669). Certifies reach-unit binding, rejection of unsupported reach_unit, and delivery surfaces `reach` + `frequency`. - `clicks_buy_flow` — gated on `media_buy.supported_optimization_metrics` containing `clicks` (#4669). Certifies click goal acceptance and delivery surfaces `clicks` + `cost_per_click`. No rejection arm — clicks is universal in semantics. - `completed_views_buy_flow` — gated on `media_buy.supported_optimization_metrics` containing `completed_views` (#4669). Certifies view_duration_seconds binding, rejection of unsupported duration (per optimization-goal.json), and delivery surfaces `completed_views` + `completion_rate`. All four grade `not_applicable` against the embedded training agent — the training agent doesn't declare `supported_targets` or `supported_optimization_metrics`. Same anti-façade hygiene as `event_dedup_flow` (#4664): an agent that doesn't claim a capability is not held to its scenario. Refs: #4637, #4639, #4669, #4642, #4664, #4651, adcp-client#1817 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Adds
media_buy.supported_optimization_metricstoget_adcp_capabilitiesresponse — a seller-level rollup of which optimization metrics any of the seller's products support. Mirrors the product-levelmetric_optimization.supported_metricsenum incore/product.jsonexactly.This is the option Y decision from #4651 — a lightweight capability summary that storyboards can gate on via
requires_capabilityplus acontains:matcher, instead of option X (deeper runner support for inspecting per-product capability arrays).Why option Y
get_adcp_capabilitiesfor pre-flight filtering; one more rollup array is cheaper than crawling every product'smetric_optimizationblock.contains:matcher onrequires_capability(filed against adcp-client) — no semantic understanding of nested per-product capability claims.metric_optimization.supported_metricsremains the source of truth for buy-time targeting and product selection. This rollup is a seller-level discoverability convenience.Sync invariant
Sellers MUST keep this in sync with their product catalog: values appear here only if at least one product declares support. If no products support a metric, it MUST NOT appear here. This is a seller responsibility, not a schema-enforced one — enforcement would require cross-document validation which we don't run on capability responses.
Schema details
media_buy.supported_optimization_metrics, placed adjacent to other rollup capabilities (audience_targeting,conversion_tracking)uniqueItems: true,minItems: 1core/product.jsonmetric_optimization.supported_metrics.items.enum—["clicks", "views", "completed_views", "viewed_seconds", "attention_seconds", "attention_score", "engagements", "follows", "saves", "profile_visits", "reach"]media_buy.required.What this unblocks
The metric-buy-mode storyboard scenarios under #4637 (capability-claim contract pattern) —
reach_buy_flow,clicks_buy_flow,completed_views_buy_flow. Those scenarios additionally require acontains:matcher forrequires_capability(filed against adcp-client); this PR is the schema half.What this does NOT do
core/product.jsonmetric_optimizationblock.contains:matcher ships in adcp-client.Refs
Test plan
npm run build:schemassucceedsnpm run build:compliancesucceedscore/product.jsonmetric_optimization.supported_metrics.items.enumtest:unit,test:test-dynamic-imports,test:callapi-state-change,typecheck) green🤖 Generated with Claude Code