Status: Filed
Companion to: #5969 (geo_cells / geo_cells_exclude targeting)
Sibling companion: #6013 (Cell Interoperability and Execution Conversion)
Filed by: @EvgenyAndroid, in collaboration with @nwoodman-spec
Design: @EvgenyAndroid (stated on #5969) — write-up, resolution rules, requested/executed/reported model, and the privacy-suppression resolution in section 6 are Nathan Woodman's
Target: a PR against static/schemas/source/core/geo-delivery-metrics.json and get-media-buy-delivery-response.json
0. Provenance
The design here is not Nathan's — it was stated by @EvgenyAndroid on #5969: add
cell as a fifth geo_level and inherit the existing per-level apparatus, rather
than introduce a parallel by_cell[] array, because a parallel array would
duplicate four surfaces that would then drift. Sellers report at the requested,
capability-declared resolution and silent parent-cell rollup is prohibited, so
coarsening becomes the buyer's exact operation over the cell hierarchy.
That design was referenced on #5969 with a placeholder issue number that was
never replaced, leaving gate (b) of the Option X versus Option Y decision open in
the record — the product expert's deferral recommendation on #5969 was
conditioned on this companion existing. Nathan Woodman wrote up the design in
full below; this issue closes that gap.
1. Why the loop has to close
Cell targeting without cell reporting is a half-closed loop. The primary stated
use case for #5969 is geographic incrementality measurement with enforceable
treatment and holdout assignment, and that use case cannot be read out if delivery
comes back at a coarser or different geography than the one assignment was made
in. Targeting at cell grain and reporting at market-code grain measures a
geography that was never targeted.
This is also the single most common platform constraint in practice: delivery and
outcome reporting returned only at a coarser native geography, which makes the
executed-versus-reported gap unmeasurable from reporting alone.
2. Scope
In scope. Adding cell as a reporting dimension, the conditional validation
that comes with it, the capability declaration for it, the rules governing
resolution of the returned rows, and the provenance fields that let a buyer check
delivery against intent.
Out of scope. Any change to geo_cells targeting itself, the conversion rules
that sit in the sibling companion, and any accreditation of measurement
methodology performed on top of these rows.
3. The shape: a fifth level, not a parallel array
The delivery response already carries a complete per-level geographic apparatus:
by_geo with conditional per-level validation, reporting_dimensions.geo,
supports_geo_breakdown, and mandatory truncation flags.
Adding cell inherits all of it:
- one new
geo_level enum value
- one conditional validation branch for the cell case
- one request field addition
- one capability extension
A parallel by_cell[] array would restate four surfaces that would then diverge
from their by_geo equivalents on the first change to either. The conditional
branch is the cheaper and more durable shape.
The cell case requires three fields that other levels do not: the cell system,
the resolution, and the cell identifier. The identifier alone is insufficient
because resolution is only recoverable from the token for systems that encode it,
and the spec should not assume that of a custom system.
{
"geo_level": "cell",
"cell_system": "h3",
"cell_system_id": null,
"resolution": 8,
"cell": "882a100d25fffff",
"impressions": 14203,
"spend": 218.44
}
cell_system_id is required and non-null when cell_system is custom,
matching the custom_system_id treatment on the targeting side.
4. Resolution rules
Report at the requested resolution. A seller returns rows at the resolution
the buyer requested and the seller declared support for, not at a resolution of the
seller's choosing.
Silent parent rollup is prohibited. Returning resolution 6 rows against a
resolution 8 request, with no indication that coarsening occurred, is
non-conformant. Coarsening is the buyer's operation, and it is exact over the cell
hierarchy, so nothing is gained by the seller performing it and information is
lost.
Declared rollup is permitted and is a different thing. Section 6 covers the
one case where a seller must coarsen.
Mixed resolutions in a single response must be explicit. If any row is
returned at a resolution other than the requested one, every such row carries its
own resolution field and a reason, and the response carries a flag that the
result set is not resolution-uniform. A consumer that aggregates a mixed-resolution
set without detecting it will double count, because a parent and its children in
the same set describe the same ground twice.
5. Requested, executed, and reported are three different geographies
This is where this companion and the conversion companion meet, and it is the
reason the two are worth reading together.
A buyer requests a cell. A seller without native cell support executes a polygon,
a circle, or a native identifier. The report then attributes impressions to
something. If the report says "cell" while the media ran against a circumscribed
circle that overshot the cell, or against a postal crosswalk that only
approximates it, the report is not wrong so much as unfalsifiable.
Delivery rows should therefore preserve, alongside the metrics:
| Field |
Why |
| requested cell system, identifier, and resolution |
The ask, unmodified |
| executed geometry type |
Circle, polygon, native identifier, or native cell |
| conversion mode |
Containment mode and circle mode, per the conversion companion |
| effective radius or executed polygon |
What actually ran, including any platform rounding applied on ingest |
| crosswalk source and vintage |
For native-identifier execution, with valid_from and valid_to |
| attribution basis |
Whether impressions were attributed by executed footprint or by re-assignment back to the requested cell |
That last row matters more than it looks. A seller that executes on circles and
then re-assigns impressions back to requested cells is performing an inverse
conversion, and that inverse is not exact. Whether the numbers in a row are
measured or apportioned changes what a lift estimate means, and it should not be
inferable only from context.
For incrementality, frequency management, and treatment-control separation, the
difference between these geographies is material rather than cosmetic. The clean
statement is that the requested unit, the executed footprint, and the reported
attribution unit coincide in a native implementation and diverge during adoption,
which is the entire period this spec is actually for.
6. Privacy suppression collides with the no-rollup rule
This is the one genuine tension in the design and it needs resolving in the spec
rather than in each implementation.
Cell-grain reporting terminates in counts attributable to small areas. Standard
practice is a k-anonymity floor, enforced by suppressing cells below the threshold
or by rolling them up until the merged population clears it. Rollup is exactly what
section 4 prohibits.
Both rules are correct and they are not actually in conflict, because the
prohibition is on silent rollup. The resolution:
- A seller MAY suppress or coarsen a row to satisfy a stated privacy floor.
- It MUST NOT do so silently. A coarsened row carries its actual resolution and a
reason distinguishing privacy coarsening from every other cause.
- Suppression and truncation are different states and MUST be distinguishable.
Truncation means the response was cut for size. Suppression means the data
exists and was withheld. A buyer computing coverage needs to tell these apart,
and a suppressed-cell count must be reported rather than inferred from absence.
- The privacy floor itself should be declarable in capability, so a buyer can
discover before spending that a design will not be readable at the resolution
they intend to analyze at.
Three further constraints follow from the underlying privacy model and are worth
stating so implementers do not reach for resolution alone:
- Resolution is not a privacy control by itself. A resolution floor without an
audience floor still exposes sparse geographies, where a coarse cell holding
three households is as exposed as a fine cell in a dense city. The risk is driven
by the count inside the cell, not its area. Both floors must be enforced together.
- Temporal grain is part of the same problem. A cell that clears a threshold
aggregated over a month can fall below it sliced to one hour of one day. The
minimum aggregation window is a floor on query granularity, not only on spatial
resolution. This matters directly here because the unit this RFC serves is
spatial and temporal.
- Threshold suppression alone is defeated by repeated queries. Differencing
across overlapping cell sets or successive time windows reconstructs a
below-threshold value. Whether the spec addresses query budgets or explicitly
places them out of scope, it should not leave the impression that a per-row
threshold is sufficient.
7. Capability declaration
Supporting cell targeting does not imply supporting cell reporting, and the
reverse also holds. The two are declared independently, consistent with the Fix 3
prose already accepted on #5969.
A reporting capability declaration needs the systems supported, the resolutions
supported per system, whether the seller can report at the requested resolution or
only at a floor of its own, and the privacy floor from section 6. Resolutions
should follow the same absence-means-all and minItems: 1 semantics that Option C
established on the targeting side, so the two halves do not diverge in style.
8. Open questions for the WG
- Should a seller that supports cell targeting but not cell reporting be required
to say so explicitly in capability, or is absence sufficient? Absence is
consistent with the targeting side, but the asymmetry is more consequential here
because the buyer discovers it only after delivery.
- Is attribution basis, measured against executed footprint versus apportioned
back to requested cells, a required field or a recommended one? It is required
in this draft, which is a stronger position than the rest of the document takes.
- Does the privacy floor belong in this companion or in a separate privacy
section applying to all reporting dimensions? Cell grain surfaces it most
sharply but does not own the problem.
- Should the temporal dimension be addressed here at all, or does it wait for the
separate temporal convention work? Section 6 touches it because suppression is
jointly spatial and temporal, but the unit's time axis is a larger subject.
9. Supporting material
The requested-versus-executed model, the conversion quality metrics that make the
gap in section 5 measurable, and the privacy and minimum-aggregation material
behind section 6 are documented elsewhere with tested reference implementations.
That documentation is being prepared for publication and will be linked here once
it is up.
Offered as input, not as a dependency.
Status: Filed
Companion to: #5969 (
geo_cells/geo_cells_excludetargeting)Sibling companion: #6013 (Cell Interoperability and Execution Conversion)
Filed by: @EvgenyAndroid, in collaboration with @nwoodman-spec
Design: @EvgenyAndroid (stated on #5969) — write-up, resolution rules, requested/executed/reported model, and the privacy-suppression resolution in section 6 are Nathan Woodman's
Target: a PR against
static/schemas/source/core/geo-delivery-metrics.jsonandget-media-buy-delivery-response.json0. Provenance
The design here is not Nathan's — it was stated by @EvgenyAndroid on #5969: add
cellas a fifthgeo_leveland inherit the existing per-level apparatus, ratherthan introduce a parallel
by_cell[]array, because a parallel array wouldduplicate four surfaces that would then drift. Sellers report at the requested,
capability-declared resolution and silent parent-cell rollup is prohibited, so
coarsening becomes the buyer's exact operation over the cell hierarchy.
That design was referenced on #5969 with a placeholder issue number that was
never replaced, leaving gate (b) of the Option X versus Option Y decision open in
the record — the product expert's deferral recommendation on #5969 was
conditioned on this companion existing. Nathan Woodman wrote up the design in
full below; this issue closes that gap.
1. Why the loop has to close
Cell targeting without cell reporting is a half-closed loop. The primary stated
use case for #5969 is geographic incrementality measurement with enforceable
treatment and holdout assignment, and that use case cannot be read out if delivery
comes back at a coarser or different geography than the one assignment was made
in. Targeting at cell grain and reporting at market-code grain measures a
geography that was never targeted.
This is also the single most common platform constraint in practice: delivery and
outcome reporting returned only at a coarser native geography, which makes the
executed-versus-reported gap unmeasurable from reporting alone.
2. Scope
In scope. Adding
cellas a reporting dimension, the conditional validationthat comes with it, the capability declaration for it, the rules governing
resolution of the returned rows, and the provenance fields that let a buyer check
delivery against intent.
Out of scope. Any change to
geo_cellstargeting itself, the conversion rulesthat sit in the sibling companion, and any accreditation of measurement
methodology performed on top of these rows.
3. The shape: a fifth level, not a parallel array
The delivery response already carries a complete per-level geographic apparatus:
by_geowith conditional per-level validation,reporting_dimensions.geo,supports_geo_breakdown, and mandatory truncation flags.Adding
cellinherits all of it:geo_levelenum valueA parallel
by_cell[]array would restate four surfaces that would then divergefrom their
by_geoequivalents on the first change to either. The conditionalbranch is the cheaper and more durable shape.
The cell case requires three fields that other levels do not: the cell system,
the resolution, and the cell identifier. The identifier alone is insufficient
because resolution is only recoverable from the token for systems that encode it,
and the spec should not assume that of a
customsystem.{ "geo_level": "cell", "cell_system": "h3", "cell_system_id": null, "resolution": 8, "cell": "882a100d25fffff", "impressions": 14203, "spend": 218.44 }cell_system_idis required and non-null whencell_systemiscustom,matching the
custom_system_idtreatment on the targeting side.4. Resolution rules
Report at the requested resolution. A seller returns rows at the resolution
the buyer requested and the seller declared support for, not at a resolution of the
seller's choosing.
Silent parent rollup is prohibited. Returning resolution 6 rows against a
resolution 8 request, with no indication that coarsening occurred, is
non-conformant. Coarsening is the buyer's operation, and it is exact over the cell
hierarchy, so nothing is gained by the seller performing it and information is
lost.
Declared rollup is permitted and is a different thing. Section 6 covers the
one case where a seller must coarsen.
Mixed resolutions in a single response must be explicit. If any row is
returned at a resolution other than the requested one, every such row carries its
own
resolutionfield and a reason, and the response carries a flag that theresult set is not resolution-uniform. A consumer that aggregates a mixed-resolution
set without detecting it will double count, because a parent and its children in
the same set describe the same ground twice.
5. Requested, executed, and reported are three different geographies
This is where this companion and the conversion companion meet, and it is the
reason the two are worth reading together.
A buyer requests a cell. A seller without native cell support executes a polygon,
a circle, or a native identifier. The report then attributes impressions to
something. If the report says "cell" while the media ran against a circumscribed
circle that overshot the cell, or against a postal crosswalk that only
approximates it, the report is not wrong so much as unfalsifiable.
Delivery rows should therefore preserve, alongside the metrics:
valid_fromandvalid_toThat last row matters more than it looks. A seller that executes on circles and
then re-assigns impressions back to requested cells is performing an inverse
conversion, and that inverse is not exact. Whether the numbers in a row are
measured or apportioned changes what a lift estimate means, and it should not be
inferable only from context.
For incrementality, frequency management, and treatment-control separation, the
difference between these geographies is material rather than cosmetic. The clean
statement is that the requested unit, the executed footprint, and the reported
attribution unit coincide in a native implementation and diverge during adoption,
which is the entire period this spec is actually for.
6. Privacy suppression collides with the no-rollup rule
This is the one genuine tension in the design and it needs resolving in the spec
rather than in each implementation.
Cell-grain reporting terminates in counts attributable to small areas. Standard
practice is a k-anonymity floor, enforced by suppressing cells below the threshold
or by rolling them up until the merged population clears it. Rollup is exactly what
section 4 prohibits.
Both rules are correct and they are not actually in conflict, because the
prohibition is on silent rollup. The resolution:
reason distinguishing privacy coarsening from every other cause.
Truncation means the response was cut for size. Suppression means the data
exists and was withheld. A buyer computing coverage needs to tell these apart,
and a suppressed-cell count must be reported rather than inferred from absence.
discover before spending that a design will not be readable at the resolution
they intend to analyze at.
Three further constraints follow from the underlying privacy model and are worth
stating so implementers do not reach for resolution alone:
audience floor still exposes sparse geographies, where a coarse cell holding
three households is as exposed as a fine cell in a dense city. The risk is driven
by the count inside the cell, not its area. Both floors must be enforced together.
aggregated over a month can fall below it sliced to one hour of one day. The
minimum aggregation window is a floor on query granularity, not only on spatial
resolution. This matters directly here because the unit this RFC serves is
spatial and temporal.
across overlapping cell sets or successive time windows reconstructs a
below-threshold value. Whether the spec addresses query budgets or explicitly
places them out of scope, it should not leave the impression that a per-row
threshold is sufficient.
7. Capability declaration
Supporting cell targeting does not imply supporting cell reporting, and the
reverse also holds. The two are declared independently, consistent with the Fix 3
prose already accepted on #5969.
A reporting capability declaration needs the systems supported, the resolutions
supported per system, whether the seller can report at the requested resolution or
only at a floor of its own, and the privacy floor from section 6. Resolutions
should follow the same absence-means-all and
minItems: 1semantics that Option Cestablished on the targeting side, so the two halves do not diverge in style.
8. Open questions for the WG
to say so explicitly in capability, or is absence sufficient? Absence is
consistent with the targeting side, but the asymmetry is more consequential here
because the buyer discovers it only after delivery.
back to requested cells, a required field or a recommended one? It is required
in this draft, which is a stronger position than the rest of the document takes.
section applying to all reporting dimensions? Cell grain surfaces it most
sharply but does not own the problem.
separate temporal convention work? Section 6 touches it because suppression is
jointly spatial and temporal, but the unit's time axis is a larger subject.
9. Supporting material
The requested-versus-executed model, the conversion quality metrics that make the
gap in section 5 measurable, and the privacy and minimum-aggregation material
behind section 6 are documented elsewhere with tested reference implementations.
That documentation is being prepared for publication and will be linked here once
it is up.
Offered as input, not as a dependency.