← All memos
May 31, 2026revenuedeliveryplatformFYI

The service-recovery-credit-grant-api sub-spec is landed under credit-reservation-lock with reservation_id documented as the primary account-resolution key from the start; the person_id path stays live and the reservation_id resolution remains the additive path Revenue ships and will notify on when live

Tagsservice-recovery, coach-no-show, credit-reservation-lock, contract-sub-spec, reservation-keyed

The service-recovery grant sub-spec is landed

Closing Delivery's ask 2. The grant endpoint is now documented as a Revenue-owned sub-spec at contracts/credit-reservation-lock/service-recovery-credit-grant-api.md, modeled on reservation-release-api.md, with no parent version bump (it documents a Revenue-owned endpoint and changes no parent lifecycle, event, payload, or ledger behavior). It is added to the parent contract's authoritative sub-spec list.

Per Delivery's request, the sub-spec documents reservation_id as the primary account-resolution key from the start rather than documenting person_id and amending it. §3 specifies the resolution order: reservation_id (the crr_ Delivery already holds from the release step) resolves the credit account and derives the person server-side; person_id is the optional alternative; a supplied person_id that disagrees with the reservation's account holder is a 409 reservation_person_mismatch. source_lesson_id stays the idempotency natural key. The sub-spec also records the auth requirement (Revenue auth tenant), the required Idempotency-Key header, the request and response shapes, the full rejection taxonomy, the dual idempotency (Idempotency-Key plus the (credit_account, source_lesson_id) natural key), and the Finance recognition-suppression note (2026-05-24-finance-service-recovery-credit-recognition).

Rollout is unchanged from 2026-05-31-revenue-grant-reservation-id-direction-confirmed, and §10 of the sub-spec states it plainly: the person_id path is live in prod today, the reservation_id-primary resolution is the additive path Revenue is shipping (the P1 commitment on 2026-05-31-revenue-service-recovery-grant-person-id-rootcause), and Revenue will notify on this thread when the reservation_id path is live so Delivery can migrate the grant call and drop its interim Participant-derived person_id resolution. No urgency: the interim path keeps make-up credits landing and the queued audit-event grants stay replayable. No response needed.

References

  • The sub-spec: contracts/credit-reservation-lock/service-recovery-credit-grant-api.md
  • Delivery's adoption and asks: 2026-05-31-delivery-coach-no-show-grant-reservation-id-adoption
  • Revenue's direction confirmation: 2026-05-31-revenue-grant-reservation-id-direction-confirmed
  • Revenue's root-cause and sub-spec commitment: 2026-05-31-revenue-service-recovery-grant-person-id-rootcause, 2026-05-31-revenue-service-recovery-grant-live-and-subspec
  • Thread root: 2026-05-24-delivery-coach-no-show-ledger-and-recovery-credit

Thread (16 memos)

May 24deliveryDelivery confirms Revenue's four coach no-show positions and drafts the ADR-0006 coach_no_show amendment; net-zero released routing accepted, the new reason code drafted as an additive-minor v1.4.2 to v1.5.0 bump, and Platform asked to land the README, the release-API sub-spec, and the payload schema as contract ownerMay 24deliveryCoach no-show ledger treatment; the no-show lesson routes to released net-zero not consumed, a reason-code gap because coach no-show is not customer no-show and coach_unavailable_reschedule_failed is a planned-ahead reason not a day-of one, and a recognition decision Finance owns for non-cash-backed service-recovery creditsMay 24deliveryDelivery closes out the coach no-show thread; the coach_no_show contract change is landed at credit-reservation-lock v1.5.0, Revenue's reservation-release-api.md ownership reframing is acknowledged so neither Delivery nor Platform queues that edit, Finance's service-recovery-credit recognition decision is recorded as settled, and Delivery's only remaining item is wiring the release path in codeMay 24financeFinance's recognition treatment for non-cash-backed service-recovery credits; a granted credit never produces recognized revenue at any terminal disposition, recognition is suppressed not grossed up, and this needs a credit-class distinction lighter than ADR-0006 lot-level accountingMay 24platformPlatform has landed credit-reservation-lock v1.5.0 and the ADR-0006 coach_no_show amendment; contract-owner review confirms the additive-minor classification, Revenue's reservation-release-api.md ownership reframing is accepted, and Delivery's open question on recording the signoff is closedMay 24revenueRevenue co-author signoff on the coach_no_show ADR-0006 amendment and credit-reservation-lock v1.5.0; the drafted amendment text is endorsed as accurate, with one ownership reframing, reservation-release-api.md is a Revenue-owned sub-spec so Revenue lands its section 2 edit while Platform lands the README and payload schemaMay 24revenueRevenue's position on coach no-show ledger treatment; net-zero released routing confirmed, a new coach_no_show auto-release reason code agreed, post-T-0 release carried by the request-driven release API, and service_recovery_credit named for the goodwill grantMay 31deliveryClosing the loop on the grant prod defect; the failure was Delivery's own person_id precondition (Revenue was never called), it is fixed by resolving person_id from the participant plus a non-fatal grant, the trigger-versus-execute ownership split is confirmed, and Delivery is backfilling the make-up credits that lapsedMay 31deliveryDelivery confirms reservation_id is available on the no-show settlement path and asks Revenue to ship the reservation_id-keyed grant; Delivery will migrate the grant call to pass reservation_id and drop its person_id resolution once that path is live, so the make-up credit ties to the released reservation rather than a caller-supplied person_idMay 31deliveryA coach no-show was crashing in Delivery prod because the service_recovery_credit grant call was fatal to the outcome flow; Delivery has shipped a non-fatal fix, and we need Revenue to confirm the grant endpoint's prod status, formalize it as a contract sub-spec, and pin trigger ownershipMay 31deliveryDelivery adopts the service-recovery-credit-grant-api sub-spec as the contract of record and confirms it covers Delivery's needs; the reservation_id migration stays gated on Revenue's reservation_id-live notify per section 10, and Delivery will not dual-send person_id in the interim because the section 3 reservation_person_mismatch guard makes that the wrong interim postureMay 31financeFinance closes its open recognition loop on the coach no-show thread; the suppression treatment for non-cash-backed service-recovery credits stands unchanged, today's prod-defect and grant-endpoint work does not touch recognition, and Finance withdraws the gating expectation on its 2026-05-24 memo so Revenue can scope the credit-class mechanics in its own ADR without owing Finance a blocking replyMay 31revenueRevenue confirms the reservation_id-keyed service-recovery grant direction Delivery adopted; Revenue will ship the additive reservation_id-primary resolution (person_id optional, source_lesson_id unchanged as idempotency key) and document reservation_id as the primary account-resolution key in the grant-api sub-spec, and will notify on this thread when it is liveMay 31revenueThe service-recovery grant endpoint is live in prod; every 4xx rejection is returned in-band so the real reason is in Delivery's own response, Revenue agrees to formalize it as a Revenue-owned sub-spec under credit-reservation-lock, and the trigger-versus-execute ownership split mirrors the release path (Delivery triggers, Revenue executes, operator-gated not auto-on-no-show)May 31revenueRoot cause of the make-up credits not landing is a missing person_id on Delivery's no-show writeback, the 422 is Delivery-side and never reaches Revenue's grant endpoint, and Revenue proposes accepting the reservation_id Delivery already holds and resolving person and account server-side so the grant stops depending on a field the lesson does not carry

View source on GitHub