feat(reporting): add leaf metric identities for nested delivery values - #6618
feat(reporting): add leaf metric identities for nested delivery values#6618bokelley wants to merge 2 commits into
Conversation
quartile_25..quartile_100 and the viewability leaves (viewable_rate, viewable_impressions, measurable_impressions, viewed_seconds) become first-class metric identities in available-metric and sort-metric, resolving to their nested canonical values with no duplicate flat fields. Closes the existing contradiction where committed-metric qualifier rules and the delivery-metric-aggregate viewable_rate conditional referenced unrepresentable metric_ids and shipped examples failed their own schemas. Also restores sort-metric's claimed coverage of flat numeric delivery metrics (cpm, cost_per_completed_view, downloads, units_sold, new_to_brand_units, plays, commissionable_value), with lift scalars documented as intentionally sort-excluded. Adds a metric-identity coherence contract test enforcing enum/schema/example agreement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated-path change requires human/CODEOWNERS review.
This PR modifies three files under static/schemas/source/**, which are under a hard, path-based approval gate (gated_paths: true). Because review_decision is REVIEW_REQUIRED (not APPROVED), decision-table row 2 fires: the gate is not yet satisfied and the PR cannot be auto-approved.
Gated files requiring review:
- static/schemas/source/core/delivery-metrics.json
- static/schemas/source/enums/available-metric.json
- static/schemas/source/enums/sort-metric.json
On the merits, the reviewer surfaced no blocking or Medium findings: the change is additive/Normative — it adds leaf metric identities and missing flat scalars to close a real contradiction where delivery-metric-aggregate referenced metric_ids the closed available-metric enum did not contain. The changeset is a correct minor, docs match the schema mappings, and a new coherence test locks enum/schema/example agreement. Once a human/CODEOWNERS approval lands (review_decision: APPROVED), this PR would fall through to a clean approve.
Escalation reasons
- Touches gated schema source files under
static/schemas/source/**; human/CODEOWNERS approval required before merge (review_decision is REVIEW_REQUIRED).
Why human review
- Modifies gated schema source files (static/schemas/source/core/delivery-metrics.json, static/schemas/source/enums/available-metric.json, static/schemas/source/enums/sort-metric.json) under a hard approval gate; review_decision is REVIEW_REQUIRED, so human/CODEOWNERS approval is required before merge.
- This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/delivery-metrics.json (modified) matches
static/schemas/source/**; static/schemas/source/enums/available-metric.json (modified) matchesstatic/schemas/source/**; static/schemas/source/enums/sort-metric.json (modified) matchesstatic/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
Leaf identities split the metric vocabulary into container and leaf tokens, which made token-equality set operations ambiguous: a product declaring viewability could be silently excluded by a required_metrics filter for viewable_rate, and a format/product intersection of mixed declarations could yield the empty set. State the rule once in available-metric (container subsumes its leaves; leaf selects its carrier; a leaf implies neither siblings nor the carrier's other fields) and cite it from required_metrics, reported_metrics, and requested_metrics. Also: sellers MUST populate viewability.standard when the commitment carries a viewability_standard qualifier, and the leaf-identity docs paragraph no longer splits the metric bullet list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated schema-source files require human/CODEOWNERS approval before merge.
This PR threads a single container-subsumption rule through the metric-set operations (available-metric enum, required_metrics, reported_metrics intersection, requested_metrics), adds one conditional MUST to the viewability description, and hardens the coherence test. The reviewer's delta pass found no Critical/High/Medium findings: subsumption directionality is consistent across all five files, the new MUST references real fields (viewability.standard, committed_metrics.viewability_standard) and layers on the existing SHOULD without contradiction, and the test change closes a latent crash-on-undefined without altering assertions. Clean diff.
However, this PR modifies files under static/schemas/source/**, a hard, non-overridable approval gate (gated_paths: true), and the current review_decision is REVIEW_REQUIRED, not APPROVED. Per decision-table row 2, the gate is not satisfied, so the outcome must be escalate — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is. The prior escalation stands for the same reason.
Escalation reasons
- Modifies gated schema-source files (delivery-metrics.json, format.json, product-filters.json, reporting-webhook.json, available-metric.json, sort-metric.json) under
static/schemas/source/**;review_decisionis REVIEW_REQUIRED, so human/CODEOWNERS approval is required before merge.
Why human review
- Touches gated paths under static/schemas/source/** (delivery-metrics.json, format.json, product-filters.json, reporting-webhook.json, available-metric.json, sort-metric.json) and review_decision is REVIEW_REQUIRED, not APPROVED — hard approval gate requires human/CODEOWNERS review before merge.
- This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/delivery-metrics.json (modified) matches
static/schemas/source/**; static/schemas/source/core/format.json (modified) matchesstatic/schemas/source/**; static/schemas/source/core/product-filters.json (modified) matchesstatic/schemas/source/**; static/schemas/source/core/reporting-webhook.json (modified) matchesstatic/schemas/source/**; static/schemas/source/enums/available-metric.json (modified) matchesstatic/schemas/source/**; static/schemas/source/enums/sort-metric.json (modified) matchesstatic/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
|
Stack merge mechanics for reviewers. Merge order: #6618 → #6622 → #6626 → #6627 (GitHub retargets each as its base merges); #6620 and #6621 base directly on this PR; #6616 is independent. Two things to expect at retarget time: (1) the stacked PRs add request/response fields, so |
Summary
Makes the numeric values nested inside
quartile_dataandviewabilityindividually addressable as metric identities — declarable inavailable_metrics, committable incommitted_metrics, aggregatable inmetric_aggregates, and sortable in breakdownsort_by— without adding duplicate flat response fields. The nested objects remain the canonical carriers of the values.New identities:
quartile_25/quartile_50/quartile_75/quartile_100(→quartile_data.q1_views–q4_views) andviewable_rate/viewable_impressions/measurable_impressions/viewed_seconds(→ the same-namedviewabilityfields).This is a bug fix, not just an enhancement
The spec already depends on these identities existing:
core/committed-metric.jsonrequiresqualifier.viewability_standard"whenmetric_id∈ {viewable_impressions,viewable_rate,measurable_impressions}" — none of which were representable in the enum the field$refs.core/delivery-metric-aggregate.jsoncarries anif metric_id == "viewable_rate"conditional that could never fire.committed_metricsexample incore/package.jsonand themetric_aggregatesexample inget-media-buy-delivery-response.jsonwere invalid against their own schemas.core/optimization-goal.jsonlets buyers optimize towardviewed_seconds, which had no reporting identity — the same optimize-without-reportable-contract incoherence the spec explicitly disallows for vendor metrics.Also in this PR
sort-metric.jsonclaimed to cover "delivery-metrics fields that are flat numeric values" but was missing 12 of them. This adds the seven transactional scalars (commissionable_value,plays,cost_per_completed_view,cpm,downloads,units_sold,new_to_brand_units) — "top keywords by units_sold" is bread-and-butter retail media. The five survey/model-based lift scalars are documented as intentionally sort-excluded (package-grain estimates, not row orderings).quartile_100counts VASTcomplete(100% of duration) and is distinct fromcompleted_viewsat a shorter billable threshold — prevents agents filing phantom discrepancies.tests/metric-identity-coherence.test.cjs: contract test enforcing flat-numeric ↔ enum agreement, sort ⊆ available, leaf-identity resolution (including the no-flat-duplicate rule), aggregate conditionals referencing representable metric_ids, and shipped examples validating against their own schemas. Fails 5/7 checks against the pre-change schemas.Design decision (WG visibility)
Sort identity ≠ response shape:
sort_by: "quartile_75"orders rows byquartile_data.q3_views. This resolves RFC #6431's dual-source-of-truth fork with neither option — no flat duplicates, no deprecation of the nested carriers. Relates to #6431 and #6434 (the qualified-selector half of #6434 — sorting by MRC-vs-GroupM viewable_rate specifically — is deliberately not in this PR; theviewability_standardqualifier already exists on the commitment surface and a request-side selector can ride a later minor if demand materializes).Out of scope, noted deliberately:
dooh_metricsleaves (waiting on the static-OOHooh_metricsdesign in #6241 so the leaf vocabulary is designed once), forecastable-metric additions (no platform forecasts quartile curves).🤖 Generated with Claude Code