feat(media-buy): add identifier-based place targeting - #6093
Conversation
| values: ["2759794"] | ||
| idempotency_key: "$generate:uuid_v4#geo_place_targeting_overlap" | ||
| context: | ||
| correlation_id: "geo_place_targeting--create_with_include_exclude_overlap" |
There was a problem hiding this comment.
Medium: The include/exclude overlap probe uses the same system_version ($context.place_system_version) on both sides, so it only exercises same-version overlap. The spec makes the cross-version case the load-bearing rule — targeting.mdx: "Sellers MUST reject the same (country, system, place_type, value) in both include and exclude lists, even when the include and exclude entries specify different catalog versions: version is not part of stable place identity." A seller that (wrongly) keys place identity on version passes this scenario yet ships the exact ambiguity the rule forbids. The unit suite covers cross-version disjointness (schema-validation.test.cjs ~L1507), but that is not the seller-conformance surface. Add a variant that differs only in system_version and still requires INVALID_REQUEST.
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated schema paths require human/CODEOWNERS approval and review is not yet APPROVED.
Verdict: This PR touches the published protocol surface under static/schemas/source/**, which is under a hard, deterministic approval gate (gated_paths: true), and review_decision is REVIEW_REQUIRED (not APPROVED). Per decision table row 2, this must escalate.
The change itself looks sound: an additive minor introducing identifier-based place targeting (new geo_places/geo_places_exclude overlays, capability declaration, get_products filters, a resolver contract, PLACE_TARGET_UNAVAILABLE, and compliance coverage). Schema↔docs coherence holds across targeting/get_products/capabilities/error-code surfaces, no undiscriminated oneOf, dist/** untouched, changeset is a correct minor for a non-breaking addition, and draft-07-inexpressible constraints are documented via x-adcp-validation and enforced in tests. No critical/high findings.
Medium findings (1, non-blocking on their own):
static/compliance/source/protocols/media-buy/scenarios/geo_place_targeting.yaml:567— Compliance overlap probe only exercises same-version include/exclude, never the cross-version case the spec singles out.
Escalation reason: Human/CODEOWNERS approval is required before merge because the PR modifies gated protocol-schema files under static/schemas/source/** and review_decision is not APPROVED.
Medium findings
- static/compliance/source/protocols/media-buy/scenarios/geo_place_targeting.yaml:567 — Compliance overlap probe never exercises the cross-version include/exclude case the spec singles out
Why human review
- Gated paths: PR modifies protocol schema files under static/schemas/source/** (added: geo-place-*.json, geo-targeting-level.json; modified: product-filters.json, targeting.json, error-code.json, index.json, get-media-buys-response.json, get-adcp-capabilities-response.json) and review_decision is REVIEW_REQUIRED — human/CODEOWNERS approval required before merge.
- This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/geo-place-area.json (added) matches
static/schemas/source/**; static/schemas/source/core/geo-place-catalog-capability.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/geo-place-catalog-entry.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/geo-place-resolver.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/geo-place-support.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/geo-place-system.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/geo-place-type.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/get-geo-place-resolution-request.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/get-geo-place-resolution-response.json (added) matchesstatic/schemas/source/**; static/schemas/source/core/product-filters.json (modified) matchesstatic/schemas/source/**; static/schemas/source/core/targeting.json (modified) matchesstatic/schemas/source/**; static/schemas/source/enums/error-code.json (modified) matchesstatic/schemas/source/**; static/schemas/source/enums/geo-targeting-level.json (added) matchesstatic/schemas/source/**; static/schemas/source/index.json (modified) matchesstatic/schemas/source/**; static/schemas/source/media-buy/get-media-buys-response.json (modified) matchesstatic/schemas/source/**; static/schemas/source/protocol/get-adcp-capabilities-response.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.
What changed
geo_placesandgeo_places_excludetargeting using stable IDs, explicit countries, identifier systems, catalog versions, and place types.get_productsplace coverage and capability filters so buyers can discover support before creating a buy.PLACE_TARGET_UNAVAILABLEfor correctable catalog-rollover failures.Why
Raw city names are ambiguous, localized, and unstable across platforms. Buyers need a portable way to express named-place intent without silently targeting the wrong Bergen, Springfield, municipality, borough, or neighborhood.
The capability shape uses a country-keyed type map to avoid Cartesian false positives. Registered numeric systems have exact semantics, while owner-controlled HTTPS URIs provide collision-safe extensions for private catalogs and types.
Review
Independent product, protocol-interoperability, and JSON Schema experts reviewed the implementation. Their findings on resolver disambiguation, cross-version overlap, exclusion-only behavior, catalog rollover, deterministic compliance, and error recovery were addressed; all three report no remaining blockers.
Validation
Closes #5588.