coach-availability v2.0.0 incoming; v1.0.0 enters two-week deprecation when v2 publishes
Why
The slot-based projection model that coach-availability v1.0.0 surfaces is wrong for scheduling. Coaches do not work 30-minute increments; they work continuous bands. The slot model bound availability to a service area at the wrong layer (per-window, not per-coach), and it has no place for the per-coach drive-time eligibility constraints that landed in the 2026-05-16 travel-time work. ADR-0018 lays out the model shift and the consequences for consumers.
The functional changes for Sales and Delivery are small in shape and meaningful in substance. Both already call the eligibility surface to ask "which coaches can take this lesson," and both already pass a service-area-scoped lesson description. The contract's response shape changes from per-slot enumeration to continuous intervals plus a list of bookings overlaying them, and eligibility responses gain a structured why field so debugging "why isn't this coach eligible" stays inside the response payload.
What
coach-availability v2.0.0 publishes from Coaching alongside the new internal model. Endpoint surface:
GET /coaching/v2/availabilityreturns per-coach, per-day continuous free intervals plus the lesson bookings on the same day.GET /coaching/v2/eligibility/by-lessonreturns{eligible_coaches, ineligible}where each ineligible entry carries a structuredwhy(no_band,drive_from_prev_too_long,drive_from_home_too_long,wrong_market,missing_cert).GET /coaching/v2/eligibility/by-descriptionmirrors the by-lesson surface for hypothetical lessons (no lesson ID; passservice_area_id,lesson_start,lesson_end,required_certifications[]).
coach-availability v1.0.0 endpoints stay live for two weeks after v2 publishes. They serve from the new internal model via a quantizing shim that converts continuous intervals to 30-minute slots so legacy consumers see no behavior change.
service_area_id is dropped from AvailabilityTemplate and AvailabilityException columns. Coverage continues to live on coach.serviceAreaIds and coach.homeServiceAreaId. A coach is eligible for a lesson if their coverage includes the lesson's service area, the lesson interval fits a free band, and drive-time constraints (maxDriveMinutesFromHome, maxInterLessonTravelMinutes) are satisfied. The travel-time engine is at coaching/modules/travel-time and uses Google Maps Distance Matrix with a heuristic fallback when the API key is unset; see coordination/adrs/coaching/001-travel-time-engine-and-fallback.md.
ProjectionState is replaced with CoachLessonBooking, keyed by (coach_id, lesson_id). The dispatcher subscriber's contract with Revenue's credit.* event stream is unchanged in semantics; the table it writes into changes shape. Coaching additionally subscribes to Delivery's coach.assigned and lesson.* lifecycle events to fill the new table's lesson-time-range fields. The lesson lifecycle event surface is whatever Delivery already publishes; no new events are requested from Delivery.
Asks
Sales: ack receipt of the v2 spec when it lands at coordination/contracts/coach-availability/README.v2.md. Plan the close-orchestration eligibility-call migration. The shape change at the call site is small: the request payload is the same minus the slot_minutes assumption, and the response gives you the structured why you've been asking for in offer-construction debugging.
Delivery: ack receipt and plan the assignment eligibility-call migration. Same shape note as Sales. Delivery also confirms the lesson lifecycle event surface (coach.assigned, lesson.scheduled, lesson.confirmed, lesson.released, etc.) is stable; if anything is missing for the per-lesson projection use case, flag now rather than after Coaching's subscriber lands.
Platform: read-only; ack receipt. No platform contract changes; this is a downstream-of-Platform model shift. If there's anything in the dispatcher infrastructure or the canonical geography catalog that would be useful to expose for the new eligibility math (e.g., service_area.market_id is already exposed; anything else?), flag.
References
- ADR-0018: continuous availability bands and lesson-level projection.
coordination/adrs/coaching/001-travel-time-engine-and-fallback.md: internal travel-time engine decision.- ADR-0008: original Coaching domain stand-up (partially superseded by ADR-0018 on the projection model).
- ADR-0006: credit reservation lock state machine (unchanged; Coaching still subscribes to
credit.*). coordination/contracts/coach-availability/README.md: v1.0.0 surface (stays live for the deprecation window).coordination/contracts/coach-availability/README.v2.md: v2.0.0 surface (publishing alongside this memo).