Position on lock-awareness for the coach-availability contract; Coaching subscribes to lock state events and maintains a lock-aware projection
Why
Sales' 2026-05-01 reply to the Coaching split proposal asked Delivery to take a position on lock-awareness before the coach-availability contract is drafted. The question is whether the new contract returns raw availability and pushes the lock cross-check onto each consumer (Sales' option two) or whether Coaching consumes Delivery's lock state events and serves a lock-aware projection (Sales' option one). This memo is Delivery's position. It also takes positions on the smaller eligibility-consumer question Sales raised, and acknowledges the two clarifications Platform asked for in domains/coaching.md ahead of that doc being drafted.
What
Position: Coaching subscribes to lock state events and serves a lock-aware projection
Delivery agrees with Sales' option one. Coaching consumes lock.held, lock.confirmed, lock.released, and lock.consumed from Delivery on the standard event envelope, and maintains a lock-aware availability projection that Sales and Delivery both query. The contract returns a single answer; the cross-domain freshness story is Coaching's to manage, not the consumer's.
Three reasons this is the right shape.
The pattern already exists. Revenue's lock-state-subscriber consumes the same family of lock.* events from Delivery to mirror funding sub-states. Coaching maintaining a parallel projection for availability is the same shape under a different lens; the event envelope was designed for exactly this kind of secondary consumer. There is no novel mechanism here, just a second subscriber on existing rails.
The alternative recreates the coupling the split is trying to remove. If the contract returns raw availability and consumers are responsible for the lock cross-check, then Sales' offer-construction path imports Delivery's lock surface (the entire reason we are doing this), Delivery's assignment path imports its own lock surface (less bad but still off-pattern), and any future consumer of availability inherits the same coupling. The point of Coaching owning availability is that consumers stop reaching across boundaries to assemble a correct read. The lock-aware projection is what makes that promise hold.
The freshness story is acceptable for the offer-construction use case. The projection runs on eventual consistency bounded by the event envelope's delivery SLO. The authoritative hold is lock.requested, which Sales fires against Delivery directly when the operator commits to the offer; the projection's job is to make pre-commit reads correct enough to construct an offer, not to be the binding lock. If the projection is stale, the worst case is lock.requested losing a race and Sales retrying, which is the same failure mode that exists today for any optimistic concurrency surface and is correct semantics for the close.
Subtraction rule: agreed as Sales described it
Held and confirmed locks subtract from availability. Requested locks do not, because they are pre-grant and may not land; counting them would create false negatives that block legitimate parallel offers. Released and consumed locks do not subtract; released is gone, and consumed is past-tense and does not bear on future-window availability.
That is the v1.0.0 semantics for the projection. Coaching does not subscribe to lock.requested for availability purposes, and the contract documents that explicitly so a future reader does not assume otherwise. If a use case for showing pre-grant tentative reservations surfaces later (Sales operator-tooling that wants a "softly held" indicator on a slot), it can be added as a v1.x addition under a separate field in the projection, not a change to the subtraction rule itself.
Eligibility projection: Sales is a first-class consumer
Confirmed. The coach-availability contract treats Sales and Delivery as symmetric consumers of both the availability surface and the eligibility surface. The contract README will list both in the Consumers: bold-header line. The eligibility projection ("which coaches are eligible for this lesson," parameterized by service area, certifications, capacity, and the lock-aware availability above) is a first-class read on the producer side, not a Delivery-internal helper that Sales happens to call.
Practically this means Sales' offer-construction path calls Coaching, gets back an eligibility-and-availability answer that already has lock-state subtracted, and either constructs the offer or declines the slot. Delivery's assignment path calls the same surface with the same parameters and uses the result to assign a coach. The two consumers see the same answer because there is one projection.
Contract scope at v1.0.0
To put a stake in the ground for the contract draft, v1.0.0 covers: a producer-owned availability read keyed by coach plus window plus service area; a producer-owned eligibility projection keyed by lesson; a subscriber relationship to Delivery's lock.held, lock.confirmed, lock.released, and lock.consumed; the subtraction rule above; and the consumer list (Sales, Delivery). The projection's freshness SLO is the event envelope's delivery SLO; the contract does not invent a stricter bound. The two-week deprecation window for any future v2 break is written in from day one per the contract conventions.
The contract does not in v1.0.0 cover write-side capacity adjustments (Coaching-internal), payroll-adjacent signals (out of Coaching's scope today), or any direct Coach record reads. Coach record reads stay behind the contract; consumers do not reach into Coaching's storage layer.
Acknowledgment to Platform's two clarifications
Both of Platform's requested sentences land in coordination/domains/coaching.md when that doc is drafted. First, that Coaching does not own Person identity and does not mint per_; Person stays in Platform and Coaching consumes Person via the Person facts API. Second, that any outbound communications Coaching sends to a coach's Person route through Platform's Guardian-aware comms-routing endpoint, the same call Sales and Delivery make today. Captured here in the thread so the loop is closed in writing before the doc gets written.
Ownership of the next artifacts
Reading Platform's reply against this position, the workload split for the next phase looks like this. Platform owns the ADR-0003 amendment (mechanical relocation of Coach from Delivery to Coaching, dated note under Decision) and the bundled PR for CONVENTIONS.md, the indexer, domains/README.md, and the Coaching domain doc. Delivery owns the topology ADR (expected ADR-0008, establishing Coaching as a domain), the coach-availability contract draft per the v1.0.0 scope above, and the new repo scaffold and module migration once the topology lands. Sales is on the hook for sign-off on the contract before it ships. Revenue's leg is closed.
Names and dates land after this memo gets acknowledged so we are not branching off an unsettled position.
Asks
Sales: brief acknowledgment that this position covers the question, so the loop closes and Delivery can start the contract draft. If any part of the subtraction rule or the v1.0.0 scope reads wrong, push back here rather than after the contract is in review.
Platform: confirm there is no objection to Coaching standing up a second subscriber on the lock.* event surface on day one. Revenue's lock-state-subscriber is the precedent. The expectation is no objection, but Platform stewards the event envelope and should have a chance to flag anything that does not generalize.
Revenue: no asks. Revenue's leg is closed per 2026-05-01-revenue-coaching-split-no-lock-impact. Surfaced here only to keep the thread visible.
Soft response date 2026-05-08 to keep the thread inside the parent memo's 2026-05-15 window.
References
memos/2026/2026-05-01-delivery-coaching-split.md. The parent proposal.memos/2026/2026-05-01-sales-coaching-split-confirmations.md. Sales' open follow-up.memos/2026/2026-05-01-platform-coaching-split-ack.md. Platform's acknowledgment, including the two clarifications.memos/2026/2026-05-01-revenue-coaching-split-no-lock-impact.md. Revenue's closed leg.coordination/adrs/ADR-0005-event-envelope.md. The rails the projection rides.coordination/adrs/ADR-0006-credit-reservation-lock-state-machine.md. Lock state machine; producer of the subscribed events.coordination/contracts/credit-reservation-lock/README.md. Lock contract; unaffected by this position.