Skip to content

feat(schemas): unify outcome measurement into the row-shape vocabulary (closes #3857)#3884

Merged
bokelley merged 2 commits into
mainfrom
bokelley/outcome-measurement-restructure
May 2, 2026
Merged

feat(schemas): unify outcome measurement into the row-shape vocabulary (closes #3857)#3884
bokelley merged 2 commits into
mainfrom
bokelley/outcome-measurement-restructure

Conversation

@bokelley

@bokelley bokelley commented May 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #3857. Collapses outcome_measurement (a separate field with free-form strings) into the unified row-shape vocabulary established by #3576 / #3848 / #3877.

The conceptual case: outcome_measurement was always the same category as the seller-reported attribution-derived metrics already in delivery-metrics.json (conversions, conversion_value, roas, cost_per_acquisition). Two surfaces describing overlapping subject matter, split because the protocol predated the unified vocabulary. With the qualifier slot proven generalizable (#3877's completion_source joining viewability_standard), the collapse is mechanical.

What changes

New schemas:

  • enums/attribution-methodology.json — closed enum: deterministic_purchase | probabilistic | panel_based | modeled

Vocabulary additions (available-metric.json):

  • incremental_sales_lift, brand_lift, foot_traffic, conversion_lift, brand_search_lift
  • No attributed_sales — that's conversion_value with qualifier.attribution_methodology: "deterministic_purchase". The unified pattern handles the methodology split via qualifier, not parallel metric IDs.

Qualifier slot expanded at all five sites (committed_metrics, buyer-side committed_metrics, metric_aggregates, missing_metrics, performance-feedback.metric) with two new keys:

  • attribution_methodology ($ref attribution-methodology.json)
  • attribution_window ($ref duration.json) — first object-valued qualifier key. Establishes that qualifier values can be structured, not just string enums. The join-on-(metric_id, qualifier) pattern handles same-metric-different-window correctly.

Deprecation:

  • core/outcome-measurement.json — title and description marked deprecated; migration table in description
  • core/product.json outcome_measurement field — deprecated, points at the new pattern
  • Schema retained for one-minor backwards compatibility; removed at the next major

Doc updates:

  • commerce-media.mdx — new pattern alongside legacy field for the transition window
  • media-products.mdx — field description deprecation note
  • create_media_buy.mdx — qualifier section adds attribution_methodology + attribution_window with conditional-required semantics
  • get_media_buy_delivery.mdx — qualifier vocabulary names all four keys

Migration

Retail-media sellers using outcome_measurement continue to work for one minor. New implementations:

{
  "reporting_capabilities": {
    "available_metrics": [
      "conversions", "conversion_value", "roas",
      "incremental_sales_lift", "units_sold"
    ]
  }
}

…and on commit, qualifier carries methodology + window:

{
  "scope": "standard",
  "metric_id": "conversion_value",
  "qualifier": {
    "attribution_methodology": "deterministic_purchase",
    "attribution_window": { "interval": 14, "unit": "days" }
  }
}

Seller-as-measurement-vendor remains the dominant retail-media topology — vendor identity is implicit (the seller) when no separate performance_standards.vendor BrandRef is set. No retailer adoption gap: the get_adcp_capabilities.measurement.metrics[] surface already exists; retailers just populate it with their existing metric definitions.

What's deferred

reporting_frequency / reporting_format (the outcome_measurement.reporting field's dimensions) move to a follow-up extension on reporting_capabilities — they're a property of the seller's reporting infrastructure (daily API, weekly dashboard) rather than a per-metric concern. Existing outcome_measurement.reporting payloads continue to work for one minor.

Test plan

  • Schema validates (build:schemas during commit hook)
  • TypeScript build passes
  • Doc renders cleanly

Related

🤖 Generated with Claude Code

bokelley and others added 2 commits May 2, 2026 16:00
closes #3857)

Outcome metrics (incremental_sales_lift, brand_lift, foot_traffic,
conversion_lift, brand_search_lift) collapse into the existing
available-metric.json + qualifier-slot pattern. Attribution methodology
and window become qualifier keys. outcome_measurement field on product
is deprecated.

Why: outcome_measurement was always the same conceptual category as the
seller-reported attribution-derived metrics already in delivery-metrics
(conversions, conversion_value, roas). The two surfaces existed because
the protocol predated the unified row-shape vocabulary established by
#3576 / #3848. With the qualifier slot proven generalizable (#3877),
the collapse is clean.

Schemas added:
- enums/attribution-methodology.json:
  ["deterministic_purchase", "probabilistic", "panel_based", "modeled"]

Schemas updated:
- available-metric.json: adds 5 outcome metrics
- delivery-metrics.json: adds 5 scalar properties
- Qualifier slot expanded at all 5 sites (committed_metrics, missing_metrics,
  metric_aggregates, package-request, performance-feedback) with
  attribution_methodology (string enum) and attribution_window (structured
  duration — first object-valued qualifier key)
- outcome-measurement.json: deprecated, migration table in description
- product.json outcome_measurement field: deprecated

No separate attributed_sales metric — that's conversion_value with
qualifier.attribution_methodology: "deterministic_purchase". The unified
pattern handles the deterministic/probabilistic/modeled split via
qualifier, not parallel metric IDs.

attribution_window in the qualifier slot is the first object-valued
qualifier key. Established that qualifier values can be structured
(not just string enums). Window isn't disambiguating "which version" the
way viewability_standard does — it's parameterizing — but the join-on-
(metric_id, qualifier) pattern handles same-metric-different-window
correctly so placement works.

Doc updates: commerce-media.mdx shows new pattern alongside legacy field;
media-products.mdx, create_media_buy.mdx, get_media_buy_delivery.mdx
reflect the four-key qualifier vocabulary.

Migration: existing outcome_measurement payloads work for one minor.
New implementations use reporting_capabilities.available_metrics +
qualifier on commit. Removed at next major.

Deferred: reporting_frequency / reporting_format migration to a
reporting_capabilities extension (separate concern from per-metric).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lization + Walmart migration

Three fixes per protocol + product review on PR #3884:

1. (Product, real bug) brand_lift as scalar oversimplifies — Kantar,
   Upwave, Cint, DV all report awareness/consideration/favorability/
   purchase_intent/ad_recall as separate measurements with their own
   sample sizes. Single scalar would force vendors to pick one or
   composite. Fix: add lift_dimension qualifier key (5th key in the
   slot). Same pattern as completion_source / viewability_standard.

2. (Protocol) Object-valued qualifier canonicalization — first
   object-valued qualifier (attribution_window) needs a canonicalization
   rule for the join. Added to qualifier description: heterogeneous
   value types; consumers MUST dispatch on key name; structured-value
   qualifiers join on canonical (key-sorted) deep equality. Schema
   description on attribution_window explicitly forbids shorthand
   strings ("14d") and calls out the object shape.

3. (Protocol) attributed_sales discoverability — buyer agents searching
   available_metrics for "attributed_sales" won't find conversion_value.
   Fix: outcome-measurement.json migration table now explicitly maps
   Walmart Connect's attributedSalesIn14Days → conversion_value +
   qualifier.attribution_methodology + qualifier.attribution_window
   with the canonical example. Same pattern called out for Amazon DSP,
   Kroger Precision, Criteo Retail Media.

Plus: rate-style metric inheritance note in qualifier description
(per protocol expert) — when a rate carries attribution_methodology
qualifier, it applies to the underlying conversions/events.

Plus: third-party retail measurement guidance (Circana, NielsenIQ, IRI
for retail MMM; Kantar/Upwave for brand lift on retail-media inventory)
in outcome-measurement migration description — performance_standards.
vendor is the escape hatch for non-seller-vendor cases.

Files updated:
- enums/lift-dimension.json (new)
- core/package.json: qualifier description tightened, lift_dimension added
- core/delivery-metrics.json: brand_lift description updated
- core/outcome-measurement.json: migration table expanded
- core/performance-feedback.json: lift_dimension added to metric.qualifier
- media-buy/package-request.json: lift_dimension added
- media-buy/get-media-buy-delivery-response.json: lift_dimension added
  to metric_aggregates and missing_metrics qualifier blocks
- get_media_buy_delivery.mdx: qualifier vocabulary updated to 5 keys
- changeset: reflects all three fixes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 6776ce4 into main May 2, 2026
18 checks passed
@bokelley bokelley deleted the bokelley/outcome-measurement-restructure branch May 2, 2026 20:14
bokelley added a commit that referenced this pull request May 2, 2026
…ation-context open question (#3891)

Two doctrinal additions surfaced from analysis of ChatGPT's ad-serving
architecture in the context of post-#3884 measurement work.

1. New "Closed-loop topologies: seller-as-measurement-agent" subsection
   in the Verification layer. Names retail-media closed loop (Walmart
   Connect, Kroger Precision, Amazon DSP, Criteo) and AI-native channels
   (ChatGPT and agentic-conversation surfaces) as a structurally
   different topology where the seller IS the measurement vendor — not
   a degraded case of third-party verification.

   Documents how the existing primitives (BrandRef, qualifier slot,
   atomic-unit row shape) handle both topologies cleanly without
   channel-specific schemas. Notes that the seller-provided merchant-
   side SDK pattern (OAIQ on advertiser pages for ChatGPT) is the one
   missing primitive — tracked as #3889.

2. New "Where does conversation-context targeting fit?" open question
   in the Boundaries section. AI-native channels target using the
   conversation prompt itself as the targeting signal — closer to
   walled-garden engagement-signal targeting than traditional
   contextual. AdCP's existing Signals taxonomy doesn't directly model
   this; whether it warrants a new signal type or fits within
   Contextual signals is open. Documented so future signals-layer RFCs
   have a frame for it.

No schema changes. Doc-only update keeping the taxonomy current with
AI-native channel reality.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restructure outcome-measurement.json onto BrandRef + measurement-agent pattern

1 participant