You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A recurring shape is emerging across the storyboard scenarios: for every non-trivial capability an agent declares, there should be a requires_capability-gated scenario that proves the claim is honest end-to-end.
Without this, the capability surface in get_adcp_capabilities and product-level capabilities (metric_optimization, conversion_tracking, etc.) is a self-attestation with no contract test. An adapter can declare `media_buy.conversion_tracking` and still silently drop log_event calls; a product can declare `supported_reach_units: ["households"]` and still ignore reach_unit on the goal.
The pattern that closes this:
Buyer establishes the precondition (sync the thing the capability is about).
Buyer creates a buy whose goal/targeting references the precondition.
Buyer references an invented value → seller MUST reject with INVALID_REQUEST and error.field set (anti-façade).
Delivery reporting carries the metric/breakdown that the goal asked for.
This is the same logic as the upstream_traffic anti-façade check, generalized from "did you forward the bytes" to "did the buy mode connect end-to-end."
Tracking backlog
Scenario
Gate
What it certifies
media_buy_seller/performance_buy_flow (CPA)
media_buy.conversion_tracking present
Draft in flight per #4569. sync_event_sources → buy → log_event → CPA delivery + per-creative conversion breakdown.
media_buy_seller/performance_buy_flow_roas
media_buy.conversion_tracking.supported_target_kinds includes per_ad_spend
ROAS / value-max buy works end-to-end. Delivery returns roas + conversion_value. Requires a new capability bit — see "Capability bits to add" below.
media_buy_seller/audience_buy_flow
audience-sync specialism OR product accepts targeting_overlay.audience_ids
sync_audiences → buy references audience_id → unknown id rejected → delivery breaks down by audience_id. Sibling to performance_buy_flow on the audience side.
Two event sources fire the same event_id → exactly one attributed conversion. Catches sellers who advertise dedup but don't actually dedupe.
media_buy_seller/reach_buy_flow
product metric_optimization.supported_metrics includes reach
Reach goal with reach_unit in supported_reach_units accepted. Mismatched reach_unit rejected. target_frequency band honored. Delivery returns reach + frequency.
media_buy_seller/completed_views_buy_flow
product metric_optimization.supported_metrics includes completed_views
Goal with view_duration_seconds in supported_view_durations accepted. Mismatched duration rejected. Delivery returns completed_views + completion_rate.
media_buy_seller/clicks_buy_flow
product metric_optimization.supported_metrics includes clicks
CPC target accepted. Delivery returns clicks + cost_per_click + per-creative click breakdown. Universal but valuable — many sellers report clicks at buy level without per-creative attribution.
media_buy_seller/frequency_cap_enforcement
(TBD — depends on whether a frequency-cap capability bit exists)
Buy with targeting_overlay.frequency_cap set; delivery shows observed frequency ≤ cap.
media_buy_seller/attention_buy_flow
product supported_metrics includes attention_seconds / attention_score + vendor declaration
Vendor-attributed attention reported in delivery. Vendor-gated; not all sellers participate.
Capability bits to add (small follow-up RFCs)
These are blockers for some of the scenarios above. Filing them separately so the storyboards can land on stable gates:
media_buy.conversion_tracking.supported_target_kinds: [\"cost_per\", \"per_ad_spend\", \"maximize_value\"] — parallels the product-level metric_optimization.supported_targets declaration. Without it, the runner can't gate performance_buy_flow_roas distinctly from CPA.
media_buy.frequency_capping (or similar) if not already present — gate for frequency_cap_enforcement.
Runner dependency
All of these depend on the runner accepting a present: matcher on requires_capability for presence-only capability objects (e.g., conversion_tracking). Filed as adcp-client#1811.
event_dedup_flow — cap bit already exists (multi_source_event_dedup); only the scenario is missing. Highest leverage for least spec change.
audience_buy_flow — paired with performance_buy_flow as the two halves of "what kind of non-guaranteed buy is this." Shipping one without the other only certifies half the story.
reach_buy_flow — upper-funnel's equivalent of "performance." supported_reach_units already exists.
performance_buy_flow_roas — blocked on the supported_target_kinds cap bit (1) above.
clicks_buy_flow, completed_views_buy_flow — useful but lower urgency; they're variants of "metric goal X works."
attention_buy_flow, frequency_cap_enforcement — vendor-gated and cap-bit-blocked respectively; ship when constituency is real.
What this issue is for
A single tracking issue so scenario adds reference a coherent pattern rather than being filed as one-offs. Sub-issues link back here. Closing this issue is contingent on the priority-1-through-4 scenarios shipping.
Pattern
A recurring shape is emerging across the storyboard scenarios: for every non-trivial capability an agent declares, there should be a
requires_capability-gated scenario that proves the claim is honest end-to-end.Without this, the capability surface in
get_adcp_capabilitiesand product-level capabilities (metric_optimization,conversion_tracking, etc.) is a self-attestation with no contract test. An adapter can declare `media_buy.conversion_tracking` and still silently droplog_eventcalls; a product can declare `supported_reach_units: ["households"]` and still ignorereach_uniton the goal.The pattern that closes this:
INVALID_REQUESTanderror.fieldset (anti-façade).This is the same logic as the
upstream_trafficanti-façade check, generalized from "did you forward the bytes" to "did the buy mode connect end-to-end."Tracking backlog
media_buy_seller/performance_buy_flow(CPA)media_buy.conversion_trackingpresentmedia_buy_seller/performance_buy_flow_roasmedia_buy.conversion_tracking.supported_target_kindsincludesper_ad_spendroas+conversion_value. Requires a new capability bit — see "Capability bits to add" below.media_buy_seller/audience_buy_flowaudience-syncspecialism OR product acceptstargeting_overlay.audience_idsmedia_buy_seller/event_dedup_flowmedia_buy.conversion_tracking.multi_source_event_dedup: truemedia_buy_seller/reach_buy_flowmetric_optimization.supported_metricsincludesreachreach_unitinsupported_reach_unitsaccepted. Mismatched reach_unit rejected.target_frequencyband honored. Delivery returns reach + frequency.media_buy_seller/completed_views_buy_flowmetric_optimization.supported_metricsincludescompleted_viewsview_duration_secondsinsupported_view_durationsaccepted. Mismatched duration rejected. Delivery returns completed_views + completion_rate.media_buy_seller/clicks_buy_flowmetric_optimization.supported_metricsincludesclicksmedia_buy_seller/frequency_cap_enforcementtargeting_overlay.frequency_capset; delivery shows observed frequency ≤ cap.media_buy_seller/attention_buy_flowsupported_metricsincludesattention_seconds/attention_score+ vendor declarationCapability bits to add (small follow-up RFCs)
These are blockers for some of the scenarios above. Filing them separately so the storyboards can land on stable gates:
media_buy.conversion_tracking.supported_target_kinds: [\"cost_per\", \"per_ad_spend\", \"maximize_value\"]— parallels the product-levelmetric_optimization.supported_targetsdeclaration. Without it, the runner can't gateperformance_buy_flow_roasdistinctly from CPA.media_buy.frequency_capping(or similar) if not already present — gate forfrequency_cap_enforcement.Runner dependency
All of these depend on the runner accepting a
present:matcher onrequires_capabilityfor presence-only capability objects (e.g.,conversion_tracking). Filed as adcp-client#1811.Priority order
Strongest signal-to-effort wins first:
performance_buy_flow(CPA) — in flight per RFC: performance-sales specialism — is conversion-driven selling distinct from sales-social? #4569.event_dedup_flow— cap bit already exists (multi_source_event_dedup); only the scenario is missing. Highest leverage for least spec change.audience_buy_flow— paired with performance_buy_flow as the two halves of "what kind of non-guaranteed buy is this." Shipping one without the other only certifies half the story.reach_buy_flow— upper-funnel's equivalent of "performance."supported_reach_unitsalready exists.performance_buy_flow_roas— blocked on thesupported_target_kindscap bit (1) above.clicks_buy_flow,completed_views_buy_flow— useful but lower urgency; they're variants of "metric goal X works."attention_buy_flow,frequency_cap_enforcement— vendor-gated and cap-bit-blocked respectively; ship when constituency is real.What this issue is for
A single tracking issue so scenario adds reference a coherent pattern rather than being filed as one-offs. Sub-issues link back here. Closing this issue is contingent on the priority-1-through-4 scenarios shipping.
Related
present:matcher onrequires_capability(runner dep)