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.jsonadrs/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)