Cadence stage map cross-domain asks and substage-rename FYI
Why
Sales' internal sales/adrs/ADR-0002-cadence-stage-map.md proposes a five-stage cadence map (Intake, Qualified, Scheduling, Onboarded, Won) replacing the current single-cadence behavior. Most of the change is internal to the Sales runtime and lives behind sales/adrs/ADR-0002 plus its execution plan. Two pieces touch other domains and need this memo to open the handshake.
First, the spec's Stage 3b coach-confirmation gate, Stage 4 invoice-and-payment flow, and inbound-customer-reply behavior require new cross-domain dispatcher events that don't exist today. Sales has scaffolded subscribers behind feature flags; flipping the flags on requires producer-side wiring from Coaching, Revenue, Delivery, and Platform respectively. All four edges flow through the dispatcher fanout per ADR-0009; no direct HTTP webhooks between domains.
Second, Sales is renaming two onboarded substages (invoiced → awaiting_payment, paid → payment_confirmed) in place. These strings are operator vocabulary that may have leaked into warehouse dbt models and dashboards consumed by analytics-facing domains. This is FYI only, not an ask.
What
Cross-domain dispatcher events the new model needs
Each below is a new event Sales subscribes to (or produces) as part of Stage 4 / 3b automation. Producer-side wiring is the cross-domain ask in this memo.
coaching.lesson.confirmation_decided— Coaching produces. Sales' Stage 3a → 3b transition emitslead.coach.confirmation.requested(lead-lifecycle contract amendment, v1.1 candidate). Coaching reads, decides confirm-or-deny, emits this event back through the dispatcher fanout. Sales-side subscriber lives insales/modules/coaching-confirmation/behindCOACHING_CONFIRMATION_SUBSCRIBER_ENABLEDflag. Confirm advances 3b → 4a; deny resets to 3a with a new callback scheduled andLead.cadenceProfilepreserved.revenue.payment.received— Revenue produces. Distinct fromcustomer.handoff(which fires on first-lock-per-Person from the credit-reservation-lock state machine per credit-reservation-lock §5). The new event fires per-payment for a specific Lead's first lesson and lets Sales close the Stage 4b → 4c transition. Sales-side subscriber insales/modules/payment-events/behindREVENUE_PAYMENT_RECEIVED_SUBSCRIBER_ENABLEDflag. Subscriber setsLead.substage = payment_confirmed, sends client confirmation Touch, notifies coach via Touch, collapses pending Stage 4 reminder Touch rows, schedules 48h and 24h follow-up Touch rows.delivery.lesson.rescheduled— Delivery produces. Fires when a lesson date changes after Stage 4 entry. Sales reads the new date and updatesLead.lessonDateandLead.lessonDateUpdatedAt; the Stage 4 lesson-date-keyed cron picks up the new date on its next pass. Subscriber lives in the existing dispatcher inbox behindDELIVERY_LESSON_RESCHEDULE_SUBSCRIBER_ENABLEDflag.Inbound-customer-comms path — Platform position requested. The spec's "inbound SMS or call resets cadence" semantics need an arrival path. V1 Sales does not consume any inbound customer event (manual operator log only). V2 question: do inbound SMS / calls land on Sales via a Platform-comms dispatcher event (e.g.,
platform.comms.inbound_sms), or does each Sales V2 inbound wire direct to a telco provider? Convention is the dispatcher path, but the call is Platform's. Sales subscriber stub will sit behindPLATFORM_INBOUND_COMMS_SUBSCRIBER_ENABLEDonce the producer side is committed.
In addition, Sales produces two new dispatcher events as part of the same model:
lead.coach.confirmation.requested(lead-lifecycle contract amendment) on Stage 3a → 3b transition.sales.lead.onboarded(or equivalent name) on Stage 4 entry — the spec's "notify dispatcher" outbound. Sales-side dispatcher emit; if a specific consumer wants this event, declare it on the response memo so the contract can include the consumer list.
Substage rename (FYI)
Lead.substage is a free-form string at v1 per the lead-lifecycle contract framing. The lead-lifecycle events do not carry substage in their payloads, but warehouse dbt models and Looker / Notion dashboards may filter on substage strings. The rename takes effect via the migration filed alongside ADR-0002 phase 1 schema additions (currently pending local apply):
onboarded/invoiced→onboarded/awaiting_paymentonboarded/paid→onboarded/payment_confirmed
The data migration updates both the lead_substage catalog rows and the lead.substage live state in a single transaction. After apply, no row carries the old keys. New substages added alongside (qualified/text_cadence, qualified/callback_cadence, scheduling/text_cadence, scheduling/callback_cadence, scheduling/coach_confirmation, onboarded/confirmed) are pure additions; no rename needed for those.
Analytics consumers should update any dbt models, Looker explores, Notion dashboards, or saved queries that filter on substage = 'invoiced' or substage = 'paid' to use the new keys. No staging migration: the apply is one-shot. If any analytics work needs a coordinated cutover, reply on this thread and Sales can hold the migration until alignment.
Asks
For each cross-domain edge, the ask is: declare a producer-side commitment on a response memo from your domain, with the event name (or your proposed alternative), the rough payload shape, and a target date or "no committed date" under the continuous-deployment discipline.
- Coaching. Producer for
coaching.lesson.confirmation_decided. Open question: extend the lead-lifecycle contract to v1.1 with the confirm/deny event, or create a dedicated coaching-confirmation contract undercoordination/contracts/coaching-confirmation/? Coaching's call. - Revenue. Producer for
revenue.payment.received. Open question: per-payment event distinct fromcustomer.handoff, or extendcustomer.handoffframing? The spec needs a per-payment signal mid-Stage-4, whichcustomer.handoffdoes not cover today. - Delivery. Producer for
delivery.lesson.rescheduled. Plus a small verification ask: confirm the close-orchestration response already includes the lesson date on Stage 4 entry (Sales reads it intoLead.lessonDatefrom this response). - Platform. Position on the inbound-comms path: dispatcher event preferred (
platform.comms.inbound_smsor equivalent), or direct telco webhook into Sales acceptable? Either is implementable; the dispatcher path stays consistent with the existing pattern.
For the substage rename:
- Growth, Finance, Portfolio. FYI only. No response required unless your analytics workload depends on the old substage strings and needs a coordinated cutover; in that case, reply on this thread and Sales will hold the migration apply.
Analytics questions
This memo proposes new dispatcher events whose payloads will be readable by warehouse consumers. The top three analytics questions the events are intended to support:
- Cadence-to-conversion funnel by stage and path. Which Leads transitioned through each Stage (1 → 2 → 3 → 4 → 5) on the text path vs the callback path, and where do they drop off? Answered by joining
lead.stage.changedevents with the new substage values (text_cadence,callback_cadence) and the eventualcustomer.handofflock. Substage column on warehouse Lead snapshots is the predicate field. - Stage 4 payment-to-lesson conversion rate. Of Leads that enter Stage 4 (
onboarded/reserved), what fraction reachpayment_confirmedbefore the 1d-pre-lesson cutoff? Answered byrevenue.payment.receivedevents joined withLead.lessonDateand the Stage 4 cron's auto-cancel events. Existingcustomer.handoffonly fires after lock, which is downstream of payment. - Coach-decline rate and re-engagement. What fraction of Stage 3b coach-confirmations come back as deny? Of those, how many re-engage and reach Stage 4 on a subsequent slot? Answered by
coaching.lesson.confirmation_decidedevents with their decision field, joined with subsequent stage transitions on the same Lead.
If any of these questions matter to your domain, declare the warehouse model dependency on the response memo so Sales' event design (field names, archive semantics) accounts for it.
References
sales/adrs/ADR-0002-cadence-stage-map.md— Sales-internal ADR for the cadence stage map. Status: Proposed.sales/adrs/ADR-0002-plan.md— execution plan with the cross-domain edges flagged in Phase 7 Slice 7.3 and Phase 9 subscriber stubs.sales/adrs/ADR-0002-progress.md— Phase 1 schema additions landed 2026-05-17.coordination/contracts/lead-lifecycle/README.md— the contract that gainslead.coach.confirmation.requested(v1.1 candidate, dependent on Coaching's ack).coordination/contracts/credit-reservation-lock/README.md— the existing Revenue → Sales handoff path that the new payment-received event sits alongside.coordination/adrs/ADR-0009-dispatcher-fanout.md— the cross-domain event fanout primitive these subscriptions ride on.