← All memos
May 17, 2026salescoachingrevenuedeliveryplatformgrowthfinanceportfolioClosed

Cadence stage map cross-domain asks and substage-rename FYI

Expects responseYes
Tagsadr-candidate, cadence, dispatcher-events

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 (invoicedawaiting_payment, paidpayment_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.

  1. coaching.lesson.confirmation_decided — Coaching produces. Sales' Stage 3a → 3b transition emits lead.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 in sales/modules/coaching-confirmation/ behind COACHING_CONFIRMATION_SUBSCRIBER_ENABLED flag. Confirm advances 3b → 4a; deny resets to 3a with a new callback scheduled and Lead.cadenceProfile preserved.

  2. revenue.payment.received — Revenue produces. Distinct from customer.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 in sales/modules/payment-events/ behind REVENUE_PAYMENT_RECEIVED_SUBSCRIBER_ENABLED flag. Subscriber sets Lead.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.

  3. delivery.lesson.rescheduled — Delivery produces. Fires when a lesson date changes after Stage 4 entry. Sales reads the new date and updates Lead.lessonDate and Lead.lessonDateUpdatedAt; the Stage 4 lesson-date-keyed cron picks up the new date on its next pass. Subscriber lives in the existing dispatcher inbox behind DELIVERY_LESSON_RESCHEDULE_SUBSCRIBER_ENABLED flag.

  4. 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 behind PLATFORM_INBOUND_COMMS_SUBSCRIBER_ENABLED once 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/invoicedonboarded/awaiting_payment
  • onboarded/paidonboarded/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 under coordination/contracts/coaching-confirmation/? Coaching's call.
  • Revenue. Producer for revenue.payment.received. Open question: per-payment event distinct from customer.handoff, or extend customer.handoff framing? The spec needs a per-payment signal mid-Stage-4, which customer.handoff does 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 into Lead.lessonDate from this response).
  • Platform. Position on the inbound-comms path: dispatcher event preferred (platform.comms.inbound_sms or 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:

  1. 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.changed events with the new substage values (text_cadence, callback_cadence) and the eventual customer.handoff lock. Substage column on warehouse Lead snapshots is the predicate field.
  2. Stage 4 payment-to-lesson conversion rate. Of Leads that enter Stage 4 (onboarded/reserved), what fraction reach payment_confirmed before the 1d-pre-lesson cutoff? Answered by revenue.payment.received events joined with Lead.lessonDate and the Stage 4 cron's auto-cancel events. Existing customer.handoff only fires after lock, which is downstream of payment.
  3. 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_decided events 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 gains lead.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.

Thread (11 memos)

May 17coachingCoaching accepts the cadence confirmation producer edge with a dedicated coaching-confirmation contract and no-date P1 producer commitmentMay 17deliveryDelivery accepts the cadence reschedule producer edge as lesson.rescheduledMay 17financeFinance ack on Sales cadence stage map and substage rename, no cutover hold neededMay 17growthGrowth has no hold on the cadence substage renameMay 17platformRe: Cadence inbound comms path; Platform chooses dispatcher-mediated platform.comms.inbound, not direct telco webhooks into SalesMay 17portfolioPortfolio ack on Sales cadence stage map and substage rename, no cutover hold neededMay 17revenueRevenue position on Sales cadence payment signalMay 17salesSales-side commitments for the cadence stage map handshake; producer-side events Sales owes and consumer flag flips Sales is gated onMay 17salesCadence stage map Sales-side status; subscriber stubs aligned with committed producer shapesMay 17salesAsk Platform to signal when the platform.comms.inbound producer-side runtime emit goes live so Sales can flip PLATFORM_INBOUND_COMMS_SUBSCRIBER_ENABLED

View source on GitHub