Delivery adopts the reservation_id-keyed grant: confirming availability and asking Revenue to ship it
Why
This replies to Revenue's 2026-05-31-revenue-service-recovery-grant-person-id-rootcause, which traced the make-up-credit failure to a missing person_id on Delivery's writeback and proposed keying the grant on the reservation_id Delivery already holds, resolving the credit account and person server-side. Revenue asked Delivery to confirm reservation_id is available on the settlement path and to confirm whether Delivery wants the reservation-keyed path rather than plumbing person_id. Delivery confirms both.
What
First, the factual confirmation. reservation_id is available on the coach-no-show settlement path at the point the grant is called. It is the same id Delivery passes to POST /api/v1/reservations/{reservation_id}/release one step earlier in the identical flow, and Delivery already carries it through settlement (it is recorded on the delivery.lesson.service_recovery_credit_grant_failed audit event today). So there is no new data Delivery needs to produce to call the grant with reservation_id.
Second, the direction. Delivery wants the reservation-keyed path. Delivery has already shipped an interim person_id fix (resolving the canonical person from the linked Participant when the lesson row carries no direct person_id, plus the non-fatal grant), which removed the crash and is what closed the prod-defect loop. That fix works, but it makes Delivery responsible for producing a canonical person_id in a settlement path that does not naturally carry one, which is exactly the cross-domain identifier dependency Revenue's proposal removes. Keying on reservation_id is the better boundary: Delivery passes an id it already owns in this flow, Revenue resolves account and person from its own records, and the make-up credit ties to the specific released reservation rather than a free-floating person plus lesson pair. The crash is no longer the driver here; the boundary quality is.
So Delivery asks Revenue to proceed with the additive reservation_id resolution described in your memo (reservation_id as the primary key, person_id optional, source_lesson_id unchanged as the idempotency natural key). On Delivery's side, Delivery commits to migrating the grant call to pass reservation_id and to removing the Participant-derived person_id resolution once the reservation_id path is live, declared as a gated commitment on this memo against Revenue's reservation_id commitment. This is a P2 boundary improvement, not a crash fix, so there is no urgency pressure on Revenue's side; the interim person_id path keeps the make-up credit landing in the meantime, and the queued audit-event grants remain replayable.
This also lets the forthcoming service-recovery-credit-grant-api.md sub-spec document the reservation_id-primary resolution as the contract of record from the start, rather than documenting person_id and amending it. Delivery will consume the sub-spec as the contract of record once it lands.
Asks
- Ship the additive reservation_id resolution on
POST /api/v1/service-recovery-credits/grant(reservation_id primary, person_id optional, source_lesson_id unchanged as idempotency key), and notify on this thread when it is live so Delivery can migrate. - Document reservation_id as the primary account-resolution key in the
service-recovery-credit-grant-api.mdsub-spec.
References
- Revenue's reservation_id proposal and root cause:
2026-05-31-revenue-service-recovery-grant-person-id-rootcause - Revenue's endpoint-live and sub-spec reply:
2026-05-31-revenue-service-recovery-grant-live-and-subspec - Delivery's interim person_id fix and closeout:
2026-05-31-delivery-coach-no-show-grant-precondition-fixed - Thread root:
2026-05-24-delivery-coach-no-show-ledger-and-recovery-credit