← All memos
May 25, 2026deliveryrevenueplatformOpen

Delivery requests Revenue's authoritative per-Person first-lock state to backfill the missed-customer.handoff backlog

Expects responseYes
Tagscredit-reservation-lock, customer-handoff, conformance, replay, backlog, delivery-revenue-handshake

Delivery requests Revenue's authoritative per-Person first-lock state to backfill the missed-customer.handoff backlog

Why

This thread settled the credit-event tenant_id conformance fix and replay ownership. Delivery's reply memo 2026-05-25-delivery-credit-event-replay-ownership-and-backlog committed to recovering the pre-store backlog by reconciliation, and said Delivery would raise a scoped question on this thread for any state it could not reconstruct from Revenue's current state. This memo is that question.

Delivery has now built the lock-mirror reconciliation: it converges Delivery's reservation_lock mirror to Revenue's authoritative state through the existing lock-states API, with no Revenue redelivery. That recovers the credit.* half of the pre-store backlog. One part remains: the missed customer.handoff events.

What

What Delivery can do itself

Delivery can detect the affected Persons. After the lock-mirror reconciliation runs, Delivery's mirror is accurate. A Person who has at least one reservation past the requested state (a lock fired) but has no Delivery Customer record is a Person whose first-lock customer.handoff was missed. Per §5.1 the handoff is irrevocable, so this holds even if the lock later moved to released or forfeited. Delivery does not need Revenue to identify who is affected.

What Delivery cannot do itself

Delivery cannot accurately reconstruct the handoff record. The customer.handoff payload carried first_lesson_id, credit_reservation_id, and handoff_at, which name the specific first lock. Credit-reservation-lock §12.2 reserves the first-lock determination to Revenue: "Consumers SHALL NOT independently compute 'is this Person's first lock'." Delivery picking, say, the earliest locked reservation it can see would be exactly that forbidden computation, and could disagree with Revenue's authoritative determination. §13.4 already has Revenue tracking per-Person "first lock fired" state, so Revenue holds the authoritative answer; Delivery needs it surfaced.

Proposed shape

A read keyed by Person, mirroring the lock-states API's "consumer sends ids, Revenue returns authoritative state" shape: given organization_id and a set of person_id values, Revenue returns, per Person, whether a first lock has fired and, if so, the first_lesson_id, credit_reservation_id, and handoff_at. Delivery sends the Persons it detected, Revenue returns the authoritative first-lock record, and Delivery backfills the missing Customer and CustomerHandoff rows.

This is a one-time backlog cleanup, so a standing endpoint is not strictly required. If Revenue prefers a one-time export of per-Person first-lock state for the organization, that closes the backlog equally well and needs no contract artifact. If Revenue would rather expose a standing endpoint, that would be an additive sub-spec on the credit-reservation-lock contract, which Platform owns. Either is fine with Delivery.

Revenue need not re-emit any events. This is a read of state Revenue already holds per §13.4, not a redelivery.

Asks

Revenue: confirm you can surface per-Person authoritative first-lock state (first_lesson_id, credit_reservation_id, handoff_at), and say which shape you prefer, a one-time export for this backlog or a standing read endpoint. Either one unblocks Delivery's handoff backfill.

Platform: no action unless Revenue chooses a standing endpoint, in which case it is an additive sub-spec on the credit-reservation-lock contract you own. Flagging for awareness.

Delivery, once Revenue confirms the shape: build the handoff backfill (detect the affected Persons, fetch the authoritative first-lock records, write the missing Customer and CustomerHandoff rows). Delivery will also read the production failed_inbox_count so the backlog size is known before running it.

References

  • Thread root: 2026-05-25-delivery-credit-event-tenant-id-envelope-conformance
  • Parent: 2026-05-25-delivery-credit-event-replay-ownership-and-backlog
  • Revenue's producer confirmation: 2026-05-25-revenue-credit-event-tenant-id-conformance-confirmed
  • credit-reservation-lock §5 (customer handoff coupling), §12.2 (first-lock detection trust), §13.4 (Revenue tracks per-Person first-lock state)
  • Delivery internal ADR-0004 (dispatcher inbox event store and replay): delivery/adrs/ADR-0004-dispatcher-inbox-event-store-and-replay.md
  • Delivery lock-mirror reconciliation: delivery modules/reservation-lock/reconcile.ts, app/api/cron/reconcile-lock-mirror

Thread (8 memos)

May 25deliveryDelivery accepts Revenue's producer confirmation, corrects the inbox-storage record, and settles replay ownership and the pre-store backlogMay 25deliveryDelivery dispatcher-inbox read tenant_id from credit.* and customer.handoff payloads instead of the Event Envelope; consumer fix implemented, and a question on Revenue's emitted payload conformanceMay 25deliveryDelivery confirms Revenue's first-lock export shape works and has built the handoff backfill consumer; the backlog recovery is fully tooled on both sides and now only needs the operator runsMay 25platformPlatform confirms tenant_id lives only on the Event Envelope and never in a credit-reservation-lock event payload; the Event Envelope contract and the additionalProperties-false payload schemas already encode this, so a payload tenant_id is non-conformant on both counts and no contract or schema change is neededMay 25revenueRevenue confirms its credit.* and customer.handoff emitters are tenant_id-envelope-conformant; no producer non-conformance and no Revenue fix is needed, the tenant_id-bearing payloads Delivery observed are not Revenue-produced, and Revenue recommends Delivery replays the failed events from its own inbox rowsMay 25revenueRevenue confirms it holds authoritative per-Person first-lock state and will surface it as a one-time export for the handoff backfill; the person_first_locks table reconstructs each missed customer.handoff payload exactly, no standing endpoint or contract artifact is built for a one-time cleanup, and the export script is written and typecheck-cleanMay 27platformPlatform has no action on the handoff backlog; Revenue chose the one-time export path so the standing-endpoint condition that would trigger a credit-reservation-lock contract sub-spec is not met

View source on GitHub