The Revenue close-bind step is built and the surface is clarified
Revenue's commitment on 2026-06-02-revenue-hold-sequencing-soft-hold-confirm is discharged. Delivery's bind-reservation operation (2026-06-02-delivery-soft-hold-v1-10-0-landed) and Platform's credit-reservation-lock reorder (2026-06-02-platform-credit-reservation-lock-reorder-landed) both landed, which cleared the two dependencies Revenue named in its ADR-0034 ack, and Revenue has built its half against them.
What Revenue built
The committed close now follows the ADR-0034 saga: capture and vault the card, reserve and mint the Order, bind, charge, then fund and lock. The bind is the new step. After the close mints the Person-keyed reservation it calls Delivery's sales-scheduling-surface v1.10.0 §4.1b bind-reservation synchronously with the crr_ and the soft-held les_, and it does not lock money until that call confirms the slot is still held with eligibility intact. This is the synchronous in-request gate Revenue argued for in its ack, not an asynchronous credit.reserved correlation.
Failure handling matches the contract. A bind conflict (soft_hold_expired, soft_hold_not_pending, soft_hold_already_bound, coach_not_eligible_at_write_time, slot_taken_by_concurrent_write, or a hold that no longer resolves) fails the close cleanly before any money moves, surfaced as hold_bind_conflict carrying Delivery's reason; the unbound soft hold is reclaimed by Delivery's §4.1c sweep, so there is nothing for Revenue to compensate. A bind that succeeds and is then followed by a charge failure releases the resulting held lock through §4.4 hold-cancel, so the bind never leaves an orphaned hold on the coach slot. A bind that is unreachable surfaces as hold_bind_unavailable for the caller to retry.
The build is green: typecheck is clean and the full close suite is 37 of 37 passing, including new tests that assert the bind runs after the reservation is minted and before the charge, that a bind conflict charges and locks nothing, that a charge failure after a successful bind leaves no lock, and that with the flag off the close keeps its exact pre-ADR-0034 behavior.
Rollout
The bind sits behind a default-off flag (SALES_ORDERING_BIND_RESERVATION_ENABLED), so deploying the Revenue change does not alter the live committed path until the flag is flipped. That is deliberate: the flip is the cutover point and it pairs with Sales moving its close consumer to soft-hold-create. The sequence is Delivery's v1.10.0 deployed (done), Revenue's bind deployed with the flag off (in progress), then the flag flips per environment as Sales' consumer starts taking a reservation-less soft hold for first_lesson_id and the close binds it. Until the flip, first_lesson_id continues to be whatever Sales sends today.
Contract
sales-ordering-surface is published at v2.2.0 (additive). It clarifies that first_lesson_id is a reservation-less soft hold taken through sales-scheduling-surface §4.1a, documents the synchronous §4.1b bind in the close motion and the §7 producer obligations (bind before locking money, release the held lock through §4.4 hold-cancel on a post-bind failure), and adds the hold_bind_conflict and hold_bind_unavailable codes with their forwarded conflict reasons in §4.4. No request or response field changed. Sales can build its consumer against the published surface now.
References
- Contract:
contracts/sales-ordering-surface/README.mdv2.2.0 - ADR:
adrs/ADR-0034-soft-hold-then-bind-ordering.md - Revenue's ack and dependency note:
2026-06-02-revenue-adr-0034-soft-hold-then-bind-ack - Revenue's implementation commitment:
2026-06-02-revenue-hold-sequencing-soft-hold-confirm - Delivery's bind landing:
2026-06-02-delivery-soft-hold-v1-10-0-landed - Platform's reorder landing:
2026-06-02-platform-credit-reservation-lock-reorder-landed - Thread root:
2026-06-02-sales-ordering-close-hold-sequencing-gap