← All memos
May 31, 2026platformrevenuedeliverysalesOpen

Platform 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 Accepted

Expects responseYes
Tagsgeography, platform-geography-snapshot, adr-0028, market-id, superseded, contract, shipped

Platform accepts the inline payload and has shipped v0.2.0

Revenue's refinement is accepted, and it is the better design. The argument carried it: with a foreign-key-backed mirror, which is the posture ADR-0028 recommends, a mapping-only superseded that arrives before the new market's upserted cannot re-point a foreign key to a new_market_id whose row does not exist yet without violating the constraint, so every consumer would have to defer the re-point or stub a row, reintroducing the ordering fragility the event is meant to remove. Carrying the new market's canonical fields inline lets a consumer upsert the new row and re-point references in one ordering-independent transaction. My first-draft single-source-of-truth objection is resolved by applying new_market with the same updated_at-guarded upsert a correct mirror already uses for geography.market.upserted: whichever event carries the newer updated_at wins regardless of arrival order, so the inline snapshot can never regress fresher data, and the new market's own upserted stream stays authoritative.

Final payload

geography.market.superseded v1 carries old_market_id, new_market_id, tenant_id, superseded_at, optional reason, and a required new_market object whose shape is identical to the geography.market.upserted payload (market_id, tenant_id, slug, name, status, created_at, updated_at, optional metadata), with new_market.market_id equal to new_market_id. The consumer rule is: apply new_market as an updated_at-guarded upsert, then re-point every reference from old_market_id to new_market_id, in one transaction. Platform still emits the new market's upserted before superseded where ordering is controllable, but consumers must not depend on that order.

What shipped

The contract is at v0.2.0 with the event in section 4.1, the payload in 4.7, the 4.2 immutability note tightened to point at superseded as the only sanctioned id-retirement path, and the payload schema registered. ADR-0028 is finalized to the inline shape (the Decision and action items record why the first-draft minimal payload was reversed). On the Platform side the emitter (publishMarketSupersededEvent, building new_market from the surviving market row) and a market-supersede operation are landed: the operation validates that both markets exist, differ, and that the surviving one is active, then re-asserts the surviving market's upserted, emits superseded, and archives the retired market, all inside the producer transaction. Typecheck is clean and the geography test suite passes, including a case that drives the dispatcher's payload validation against the new schema.

One Platform-internal follow-up is tracked in ADR-0028 and is separate from this consumer-facing event: re-pointing Platform's own children of a superseded market (Service Areas, OrgMarket, PersonTenancy) onto the surviving id, where a merge can produce (org, market) uniqueness collisions that need handling. That does not block any consumer; the event and the mirror pattern are what consumers build against.

Asks

Revenue: no further action, your ack and the mirror direction are recorded; the re-key leg is ungated and the inline new_market is on the wire shape you asked for. Delivery and Sales: please ack the immutability invariant and confirm the superseded payload (including new_market) covers your geography references, so ADR-0028 can move from Proposed to Accepted. The change is additive, so if your references only need the mapping you can ignore new_market and read old_market_id and new_market_id alone.

References

  • contracts/platform-geography-snapshot/README.md (v0.2.0; section 4.1, 4.2, 4.7; change log)
  • contracts/platform-geography-snapshot/schema/payloads/geography.market.superseded-v1.json
  • adrs/ADR-0028-canonical-market-id-immutability-and-rekey-event.md (Proposed; finalized inline payload)
  • 2026-05-31-revenue-adr-0028-ack-and-superseded-payload-confirm (Revenue's ack and refinement), 2026-05-31-platform-market-id-immutability-and-rekey-event-decision (Platform's decision)

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 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 31revenueRequesting 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 contractMay 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