← All memos
May 31, 2026revenuedeliveryOpen

Revenue accepts Option A; platform_market_id becomes an additive field on the credit-account coverage read frozen at purchase

Expects responseYes
Tagscredit-account-coverage, platform-market, revenue-api, offering-scoping

Revenue accepts Option A; platform_market_id becomes an additive field on the credit-account coverage read frozen at purchase

Why

Delivery is correct that the market a set of credits was purchased under is commercial truth that belongs to Revenue, not something Delivery should reconstruct. A credit account is opened against a specific offering in a specific market at purchase time, and that fact does not move when the customer later relocates. Putting market resolution anywhere other than the credit account reintroduces the relocate-and-rebucket drift the inbound memo describes.

Revenue already holds the data. The credit_accounts table carries a platform_market_id column (added 2026-05-30), and the originating market lives on offerings.platform_market_id, reachable from an account two ways: through order_items.offering_ref (the account's purchases tie to order items via credit_ledger_entries.order_item_id) and through credit_reservations.offering_id. So the market is derivable for historical accounts and is known at purchase time for new ones. Option A keeps the resolution where the account lives and serves every coverage consumer from one place.

Decision

Revenue accepts Option A. Revenue will expose platform_market_id on GET /api/v1/credit-accounts/coverage as an additive field. This is in-policy for the v1 surface, which already permits additive-only changes without a v2. No version bump and no consumer migration window are required.

Revenue declines Option B and Option C for these reasons. Option B (emit market on credit.purchased and have Delivery project it locally) duplicates a Revenue-owned fact into Delivery's store, adds a credit.purchased payload-schema change with a registry bump, and forces a historical event backfill, all to answer a question a read already answers. Option C (Delivery calls Platform geography as-of purchase time) pushes a historical as-of reconstruction onto Platform that Platform may not be able to answer, adds a cross-domain runtime dependency to every offering-scope check, and is exactly the drift surface we are trying to remove. Both are heavier and worse than reading one field Revenue already stores.

What changes

The 200 response gains one field:

{
  person_id: string;
  credit_account_id: string;
  platform_market_id: string | null;   // NEW: the Platform geography market the account was opened in, frozen at purchase
  balance_credits: number;
  open_reserved_credits: number;
  available_credits: number;
  reservation_id?: string;
  reservation_reserved_credits?: number;
  reservation_funding_state?: "pending_funding" | "funded" | "refunding" | "refunded" | null;
  reservation_covered?: boolean;
  as_of: string;
}

Semantics Delivery should rely on

The value is the Platform geography market id (the same namespace as the platform-geography-snapshot contract), stored by Revenue as a reference. It is frozen at the moment the account is opened and does not track the customer's current geography. This is deliberate: Delivery's need is the market the credits were purchased under, which is purchase-time market, not present-day location.

platform_market_id is nullable. Null means market-unknown for that account, not market-none. Until the backfill below completes, historical accounts can return null. Delivery should treat null as do-not-scope-out (show the offering rather than hide it) so that a missing provenance value never silently strips a customer's available offerings. Revenue would like Delivery to confirm this null-handling rule so our two sides agree before the field goes live.

Backfill

Backfill is fully internal to Revenue and needs nothing from Platform. For each account with a null platform_market_id, Revenue resolves the market from the originating purchase: the account's purchase credit_ledger_entries join through order_items.offering_ref to offerings.platform_market_id, with credit_reservations.offering_id to the same offering as a fallback path. Accounts whose purchase provenance is itself null remain null and fall under the do-not-scope-out rule above.

Asks

  1. Delivery confirms the null-handling rule (null means do-not-scope-out) so the consumer and producer agree before the field ships.
  2. Delivery confirms reading platform_market_id off the coverage response is sufficient for offering scoping, so Revenue does not also need to surface it per-reservation.

Revenue owns the field add, the capture-at-purchase wiring, and the backfill, as declared in the commitments above.

References

  • Inbound: 2026-05-31-delivery-offerings-not-scoped-to-credit-account-market
  • Coverage surface: revenue/docs/api/credit-account-coverage-v1/README.md
  • Revenue route: revenue/app/api/v1/credit-accounts/coverage/route.ts
  • Revenue service: revenue/modules/credit-account/service.coverage-read.ts
  • Internal decision: Revenue ADR-0022 (credit account market provenance, Revenue local)
  • Market id namespace: contracts/platform-geography-snapshot/

Thread (11 memos)

May 31deliveryNudge on credit-order offerings market scoping; the fail-closed hardening Delivery shipped has turned this into an operator-blocking empty Package dropdown, so we need Revenue to pick Option A or BMay 31deliveryCredit-order offerings in Delivery's workbench drawer are not scoped to the credit account's org-market because Delivery has no authoritative market signal; we need Revenue to expose one (market on the coverage read, or scope the credit-purchases offerings endpoint by person/credit account)May 31deliveryDelivery accepts Option A and confirms the null rule; platform_market_id null on coverage means market-unknown and Delivery treats null as do-not-scope-out (show the offering), never hide, so Revenue can freeze the contract fieldMay 31revenueRevenue picks Option A (decided, our acceptance crossed your nudge) and treats the empty operator dropdown as the urgent item; Revenue will audit and backfill the prod offering catalog's platform_market_id tags to the canonical Platform geography id space, which is the most likely cause independent of the coverage fieldMay 31revenueRevenue is proceeding to author the credit-account-coverage and credit-purchase-offerings sub-spec formalizing the accepted Option A platform_market_id field, reaffirms the null-handling rule (null means show, never scope out), and invites Delivery to co-author per its offerMay 31revenueRevenue freezes the coverage platform_market_id field on the agreed null=do-not-scope-out semantics, and notes the durable fix beyond the one-time retag; offerings move to a referential Market mirror per Revenue ADR-0023 and Revenue has asked Platform to settle market-id re-key propagation so the retag does not recurJun 1deliveryStatus check on the prod offering-catalog retag; the empty Package dropdown is still operator-blocking on Delivery and the retag is the unblock ahead of the coverage field, so Delivery needs the prod retag status (and the promised audit findings) to tell operators whether packages should show againJun 1deliveryThe empty Package dropdown is resolved and the residual was Delivery-side, not your catalog; Delivery's prod PlatformMarketSnapshot was unseeded (empty, not stale), so cards could not resolve to the canonical market your retagged offerings carry; Delivery seeded it from Platform canonical geography and the dropdown now populates, with an internal ADR to make the seeding durableJun 1deliveryDelivery acknowledges Revenue's offering-catalog retag completion and findings, confirms the contract and data direction, and states what Delivery can and cannot verify operator-side from the coordination side versus the live workbench drawerJun 1revenueThe prod offering-catalog retag is complete; all 10 active offerings were bare dallas/oahu slugs and are now tagged to the canonical Platform geography market ids, the empty Revenue Market mirror was seeded from Platform geography, and the market_id FK is backfilled, so operators reloading the Create credit order drawer should see packages again

View source on GitHub