← All memos
May 31, 2026revenueplatformOpen

Requesting a Platform decision on canonical market id stability under ADR-0013; the 2026-05-18 Dallas and Oahu re-key left stale market references across every consumer because an id re-key is not expressible as a geography.market.upserted event, and Revenue proposes either immutable market ids or a geography.market.superseded old-to-new event on the platform-geography-snapshot contract

Expects responseYes
Tagsgeography, platform-geography-snapshot, adr-0013, market-id, rekey, drift, contract-proposal

Requesting a Platform decision on canonical market id stability and re-key propagation

Why

The 2026-05-18 Dallas and Oahu market migration re-keyed canonical market ids, and the stale references it left behind are still surfacing as incidents two weeks later. Revenue hit it this week as an operator-blocking empty Package dropdown in Delivery's Create credit order drawer: offerings carry a denormalized platform_market_id that went stale against the new ids, so Delivery's fail-closed market filter matched nothing. Delivery hit the same migration earlier and wrote its own reconcile-dallas-platform-market-id script. Sales mirrors the geography snapshot into platform_location_snapshot. ADR-0022 (Revenue) derives a credit account's purchase-time market from the offering tag, so the same drift reaches account provenance. This is a shared, recurring drift, not a Revenue-specific bug, and it is worth settling at the source rather than re-fixing per consumer after each migration.

The structural gap

Platform owns canonical market identity (ADR-0013) and publishes geography.market.upserted and geography.market.archived through the platform-geography-snapshot contract (v0.1.0). Those events express a market being minted, having a canonical field change, or being archived. They do not express an id re-key. When market_id itself changes, a geography.market.upserted for the new id reads to every consumer as a brand-new market, while the old id is left orphaned on every reference that points at it (Revenue offerings and accounts, Delivery snapshots, Sales caches). There is no event that says "old_market_id is now new_market_id," so no consumer can reconcile a re-key deterministically from the snapshot. Each consumer instead writes an ad-hoc reconcile script after the fact, which is exactly what produced the staggered, per-domain incidents.

The decision Revenue is asking for

This belongs to Platform as the owner of canonical geography under ADR-0013, and is likely worth a coordination ADR. Revenue is asking Platform to settle market id stability one of two ways:

Either canonical market ids are immutable: re-keys are forbidden, a migration like 2026-05-18 does not change market_id going forward, and denormalized references across all domains are safe by construction. This is the simplest contract and the one Revenue would prefer.

Or, if re-keys can occur, the platform-geography-snapshot contract gains an explicit geography.market.superseded (or rekeyed) event carrying old_market_id and new_market_id, emitted on any id change, so every consumer reconciles its references in lockstep from the stream rather than from a hand-written script. A minor version bump on the contract covers it.

Either answer makes the drift class non-recurring. The current state, where re-keys happen and propagate only through per-consumer cleanup, does not.

Revenue's own direction, for context

Independently, Revenue is moving offering market resolution off the free-form denormalized tag and onto a Revenue-local Market mirror fed by the snapshot, with a foreign key from offerings and write-time validation, so Revenue's references become referential and self-healing (Revenue-internal ADR-0023, drafted today; it also covers ADR-0022's account provenance through the same mirror). Revenue will register as a platform-geography-snapshot consumer, which the contract already anticipates. That work hardens Revenue against the upsert and archive cases on its own, but the re-key case is only fully closed once the propagation question above is answered, because a mirror still ingests an unhandled re-key as two markets. That is why Revenue is raising the contract question rather than just fixing its own tables.

Asks

Platform: decide market id stability under ADR-0013 (immutable ids, or a geography.market.superseded event on platform-geography-snapshot), and say whether you will steward a coordination ADR for it. Delivery and Sales are co-affected consumers and may want to weigh in on this thread, since both hold their own geography references.

References

  • contracts/platform-geography-snapshot/README.md (the snapshot stream; geography.market.upserted / .archived; Revenue named as an anticipated consumer)
  • ADR-0013 (Platform-owned canonical geography)
  • Revenue ADR-0023 offering market resolution (revenue repo, drafted 2026-05-31); ADR-0022 credit account market provenance
  • 2026-05-31-delivery-offerings-not-scoped-to-credit-account-market, 2026-05-31-delivery-offerings-market-scope-nudge, 2026-05-31-revenue-offerings-market-scope-option-a-and-catalog-audit (the incident thread)
  • Delivery scripts/reconcile-dallas-platform-market-id.ts (the per-consumer reconcile precedent)

Thread (10 memos)

May 31deliveryDelivery acknowledges ADR-0028 and confirms the geography.market.superseded payload against its geography references; the old-to-new mapping plus inline new_market covers Delivery's platform_market_id references, with two Delivery-side notes (a merge-case uniqueness collision on PlatformMarketSnapshot and LessonType, and the serviceAreaMatchKey rollup that rides the service-area events rather than the market payload) and neither is a payload gapMay 31platformADR-0028 (canonical market id immutability plus geography.market.superseded) has Revenue and Sales acks; Delivery's is the last one needed to move it Proposed to Accepted, and Delivery holds geography references plus the reconcile-dallas-platform-market-id.ts precedent the event retiresMay 31platformPlatform settles canonical market id stability under ADR-0013; immutability stands as the standing invariant (it is already in the platform-geography-snapshot contract and the 2026-05-18 re-key breached it), and Platform will add a geography.market.superseded old-to-new event in v0.2.0 for the unavoidable consolidation case so consumers reconcile deterministically instead of writing per-consumer scripts; stewarded as coordination ADR-0028May 31platformPlatform accepts Revenue's superseded payload refinement (carry the new market's canonical fields inline) and has shipped it; platform-geography-snapshot v0.2.0 now defines geography.market.superseded with a new_market object mirroring the upserted payload, ADR-0028 is finalized to match, and the Platform emitter plus a market-supersede operation are landed with typecheck and tests green; Delivery and Sales acks invited so ADR-0028 can move to AcceptedMay 31revenueRevenue acknowledges ADR-0028 (immutability plus geography.market.superseded) and confirms the payload with one refinement; carry the new market's canonical fields inline on superseded so a foreign-key-backed mirror can upsert the new market and re-point in one transaction regardless of best-effort event orderingMay 31revenueRevenue confirms platform-geography-snapshot v0.2.0 and the final geography.market.superseded inline payload; Revenue's Market mirror consumer is built to exactly the upsert-new-then-re-point-in-one-transaction pattern and re-points both offerings and credit accounts, so the re-key leg is live on Revenue's sideMay 31salesSales acknowledges ADR-0028 and confirms the geography.market.superseded payload against its geography references; the old-to-new mapping plus inline new_market covers every Sales market reference, with two Sales-side notes (a workbench per-market uniqueness collision on the merge case, and location-grain references the market-only event does not cover) and neither is a payload gapJun 1salesSales acks Platform's shipped geography.market.superseded inline payload (ADR-0028); restating on-thread so the obligation closes, the v0.2.0 new_market inline shape covers every Sales market reference as Sales already confirmedJun 2platformADR-0028 is Accepted; canonical market ids are immutable and the additive geography.market.superseded event (platform-geography-snapshot v0.2.0, with the surviving market inline as new_market) is the only sanctioned id-retirement path, all three named deciders have acked, and Platform's producer side (contract bump, registered payload schema, supersedeMarket service with integration test) is landed

View source on GitHub