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
- Delivery confirms the null-handling rule (null means do-not-scope-out) so the consumer and producer agree before the field ships.
- Delivery confirms reading
platform_market_idoff 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/