1. Nightly Attendance Recalculation and Risk Scoring
Trigger: scheduled, 2:00am daily, iterating every contact tagged member-active.
Conditions: skip contacts tagged member-frozen or member-onboarding, and skip any contact whose Membership Start Date is less than 30 days ago.
- Action 1: count attendance events in the trailing 7, 14 and 30 days and write Visits Last 7 Days, Visits Last 14 Days, Visits Last 30 Days.
- Action 2: write Days Since Last Visit from the most recent attended event.
- Action 3: compute Attendance Ratio = Visits Last 14 Days / (2 × Baseline Weekly Visits). Where the baseline is below 1, floor the divisor at 2 so a once-a-two weeks member does not produce a meaningless ratio.
- Action 4: compute Risk Score 0-100 from weighted components. The ratio carries the most weight, then Days Since Last Visit relative to the member's normal gap, then no-shows in the last 30 days, then a declining class-booking trend, then any failed payment in the last 60 days.
- Action 5, derive the band: ratio at or above 0.8 sets Healthy; 0.5 to 0.79 sets Softening; 0.2 to 0.49, or Days Since Last Visit over 14, sets At Risk; below 0.2, or Days Since Last Visit over 28, sets Critical. Thresholds are configurable and should be tuned against the first two weeks of silent running.
- Action 6, on change only: if the derived band differs from Risk Band, copy the old value into Previous Risk Band, write the new Risk Band, set Risk Band Changed On = today, move the Member Health opportunity to the matching stage, and swap the risk- tags.
- Action 7: enqueue the band-change event for the relevant touch workflow. Nothing in this workflow sends a message. It runs at 2am and must never be able to text anyone.
Exit: completes per contact each night. A contact that errors is logged to an internal exceptions list for the owner rather than skipped silently.
2. Weekly Baseline Recalculation and Onboarding Graduation
Trigger: scheduled, Sunday 11:00pm.
- Action 1: for every member-active contact with at least 8 weeks of history, write Baseline Weekly Visits = mean weekly attended visits over the trailing 8 weeks, excluding any full week where the contact was tagged member-frozen.
- Action 2: recompute Favorite Class as the most-booked class type in the trailing 12 weeks, and Usual Days as the two most frequent weekdays. These two fields are what make every message in this build specific.
- Action 3, graduation branch: where Membership Start Date is exactly 30 days ago, remove member-onboarding, set the initial Baseline Weekly Visits from the first 30 days, and move the opportunity from Onboarding - First 30 Days to Healthy.
- Action 4, ramp check for onboarding members: where member-onboarding is present and Visits Last 14 Days is fewer than 2, create a task for the assigned coach: "{{first_name}} has been in {{days_since_join}} days and trained {{visits_last_14_days}} times. First month sets the habit. Reach out personally today." No automated member-facing message; new members get a human.
- Action 5: reset Intervention Count This Quarter to 0 on the first Sunday of each quarter.
Exit: completes weekly.
3. Softening Touch and Barrier Check
Trigger: Risk Band changed to Softening with Previous Risk Band = Healthy.
Conditions: suppress if touch-suppressed is present, if Last Human Touch Date is inside 14 days, if Intervention Count This Quarter is at the cap, or if cancellation-requested or save-attempt-active is present.
- Action 1, immediate: apply risk-softening, increment Intervention Count This Quarter.
- Action 2, wait until the next permitted send window: SMS from BO. "Morning {{first_name}}, BO here from {{business_name}}. Noticed we haven't seen you in {{favorite_class}} for a bit. There's a spot {{usual_day}} at {{next_class_time}} if you want it: {{booking_link}}"
- Action 3, wait 2 days: if no booking and no reply, send the one-tap Barrier Check. "Quick one, {{first_name}}, what's getting in the way at the moment? Tap one and I'll see what I can do. {{barrier_check_link}}"
- Action 4, branch on the answer. Time: "Totally fair. We run {{short_format_name}} sessions that are done in 30. Here's what's on this week: {{short_session_link}}" Schedule: "Let's find a slot that actually works. These three have space outside your usual time: {{alternate_times}}. Want me to move your standing booking?" Motivation: offer a Coach Check-In with the assigned coach: "Happens to everyone. {{assigned_coach}} has 15 minutes this week to reset the plan with you: {{checkin_link}}" Something physical: send one acknowledgement only: "Thanks for telling me, {{first_name}}. I'll let {{assigned_coach}} know and they'll come back to you directly." Then apply touch-suppressed, create an urgent coach task, and stop all automated messaging for this contact. BO offers no guidance, no reassurance and no suggestions of any kind on that branch.
- Action 5, wait 5 days: if still no attendance and no reply, exit quietly. Do not send a third message at this band. The next step is the band escalation, which is a human.
Exit: any attendance event, any booking, band change in either direction, touch-suppressed applied, or STOP received.
4. At Risk Escalation and Coach Human Touch
Trigger: Risk Band changed to At Risk.
Conditions: none that block the internal task. The coach is always told. The member-facing message is suppressed by the same guards as workflow 3.
- Action 1, immediate: apply risk-at-risk, remove risk-softening, move the opportunity to At Risk.
- Action 2, immediate: create a task for Assigned Coach, due today, with the full picture on the task body: baseline, visits in the last 7 and 14 days, Days Since Last Visit, Favorite Class, Usual Days, the Barrier Check answer if one exists, and the date and author of the last human touch. The task instruction is explicit: "Send a personal message in {{first_name}}'s own thread. Do not use a template."
- Action 3, immediate: post the name to the coach's channel in the daily digest and to the manager's At Risk list.
- Action 4, wait 48 hours: if Last Human Touch Date has not been updated, escalate the task to the manager and re-notify. This is the accountability loop; without it the build degrades into a dashboard nobody reads.
- Action 5, wait 5 days: if there has still been no human touch and no attendance, send one BO message as a backstop. "{{first_name}}, it's been a few weeks. No pressure at all, but if something's changed and the membership isn't working as it stands, tell me and I'll get {{assigned_coach}} to call you." Increment Intervention Count This Quarter.
- Action 6, on any human touch: stamp Last Human Touch Date and Last Human Touch By, apply touch-suppressed for 14 days, and close the task.
Exit: attendance resumes, band changes, Goal Reset or Coach Check-In booked, or the member moves to Cancellation Requested.
5. Critical Intervention and Goal Reset
Trigger: Risk Band changed to Critical, or Days Since Last Visit reaches 28.
- Action 1, immediate: apply risk-critical, move the opportunity to Critical, notify the owner directly rather than only the coach.
- Action 2, immediate: create an owner task: "{{first_name}}, {{days_since_last_visit}} days, member since {{membership_start_date}}, {{membership_type}}. Decide the approach before any message goes out."
- Action 3, wait 1 day, then send one message with a real option in it: "{{first_name}}, it's {{owner_name}} at {{business_name}}. You've not been in for a while and I'd rather ask than assume. If the plan you're on isn't fitting your life right now, there are other shapes it can take, including pausing it. Can we put 30 minutes in? {{goal_reset_link}}" No figure is quoted in this message or any other; options are described, and the conversation prices them.
- Action 4, on booking: send the Goal Reset Prep form, move to Save Attempt Active, apply save-attempt-active, write Save Offer Made = today, and give the senior coach the member's full history on the appointment record.
- Action 5, wait 4 days with no booking: email from the owner, same substance, longer form, with the freeze and downgrade options named as options and a direct line to reply to.
- Action 6, wait 10 days with no response: stop member-facing messaging entirely. Apply nothing further, leave the opportunity in Critical, and create a single quarterly review task. A member who has ignored an owner-level approach is not helped by a fourth message.
Exit: goal reset attended, plan changed, freeze applied, cancellation requested, or messaging stopped by the 10-day rule.
6. Recovery Detection and Closure
Trigger: nightly, after workflow 1, on contacts carrying any risk- tag.
Conditions: Visits Last 7 Days is greater than or equal to Baseline Weekly Visits for two consecutive weekly evaluations.
- Action 1: set Risk Band = Healthy, remove risk-softening, risk-at-risk, risk-critical, save-attempt-active and touch-suppressed; apply risk-recovered for 30 days for reporting.
- Action 2: move the opportunity to Recovered and record which band it entered from, so recovery rate can be reported by entry band.
- Action 3: notify the assigned coach. "{{first_name}} is back to {{visits_last_7_days}} a week. Worth saying something next time you see them." The acknowledgement comes from a person in the room, not from an automated congratulations message.
- Action 4, wait 14 days: one short BO message only where the recovery followed a Critical intervention. "Good to see you back in, {{first_name}}. Anything you need from us to keep it going?"
- Action 5, wait 30 days: remove risk-recovered, close the opportunity to Healthy, and clear Save Offer Made so the next cycle starts clean.
Exit: band falls again (which re-enters at the appropriate workflow), or 30 days elapse.
7. Cancellation Request Interception
Trigger: Cancellation Request form submitted, inbound message matching cancel intent, or a subscription-canceled event from the payment processor.
- Action 1, immediate: apply cancellation-requested, move the opportunity to Cancellation Requested, and stop every other sequence on the contact. A member who has asked to leave must not receive a scheduled retention nudge the next morning.
- Action 2, immediate: acknowledge properly and without friction. "Got it, {{first_name}}, I've logged your request and it's with {{owner_name}}. Before it's processed, two things you might not know are available: you can pause instead of canceling, or move to a lighter plan. If either is worth a conversation: {{cancellation_call_link}}. If not, just reply cancel and we'll finish it, no hard feelings."
- Action 3, immediate: owner task with the member's attendance history and Churn Reason from the form, due same day.
- Action 4, branch on reason. Cost: route to the owner with downgrade options; BO names them without figures. Moving away: no save attempt, process cleanly, offer a referral or transfer where the business has reciprocal arrangements. Schedule or time: offer the freeze and the off-peak plan. Not getting results: offer a Goal Reset with a senior coach. Health or injury: acknowledge, process without resistance, and make no save attempt at all: route straight to the owner.
- Action 5, wait 2 days: if the member replied cancel or did not engage, process the cancellation, confirm it in writing with the effective date, and send the Exit Interview.
- Action 6, on confirmed churn: apply churned, remove member-active, move to Churned, write Churn Reason from the exit interview, and remove the contact from every list except the one that workflow 8 governs.
Exit: cancellation processed, save accepted (returns to Save Attempt Active), or freeze applied.
8. Suppression Guard, Frequency Cap and Win-Back Gate
This is the workflow that keeps the other seven from becoming harassment. It is built as a set of always-on rules evaluated before any send.
Trigger: any outbound send attempt from workflows 3, 4, 5 or 6; plus a scheduled daily pass.
- Rule 1: block the send if touch-suppressed is present. The tag is applied on any human touch, any inbound reply, any mention of a physical or health reason, and any member request to be left alone; it expires after 14 days.
- Rule 2: block if Intervention Count This Quarter is at or above the configured cap. Instead of sending, create a task so a human decides whether this member needs a conversation.
- Rule 3: block if Last Human Touch Date is inside 7 days, whatever the band. A coach's message takes precedence over the system's.
- Rule 4: block if the send would land inside quiet hours, and queue it to the next permitted window in the member's own timezone rather than dropping it.
- Rule 5: block if cancellation-requested, churned or do-not-remarket is present.
- Rule 6, daily pass: expire touch-suppressed tags older than 14 days, and risk-recovered tags older than 30 days.
- Rule 7, win-back gate: 60 days after churned, if Churn Reason is not health, moved away or complaint, and do-not-remarket is absent, apply winback-eligible and send one message. "{{first_name}}, {{owner_name}} here. Two months since you left us. No sales pitch, just checking how training's going. If you ever want to come back, you know where we are." Then wait 45 days, send one final email with whatever has changed at the business, and remove the contact from active sequences permanently.
Exit: these rules are permanently resident; the win-back branch exits after its two sends, on any reply, or on STOP.