What the platform does

Everything the system already does for the gym, in plain English — grouped by the outcome it moves. Tap a card to open it. Rendered live from the same file our nightly checks guard, so this page can never disagree with reality.

33live now
4on the roadmap
11awaiting a screen

🧲Lead nurture 10

LIVE Comment a keyword on a post → the guide lands in their DMs bookings

When someone comments a keyword (like SUMMER) on your Instagram or Facebook post, the system sends them one private message with the guide — a button to tap, and a link if the button does not show. This is your own version of the feature Meta retired, and it works across both channels with one set of rules.

Triggera keyword comment on a post.
The AIreplies privately with the guide, posts a short public "sent you a DM" once, and never double-sends to the same person.
You seenothing to action — it just runs; the conversation appears in Messages if they reply.

Proofship-register probe `comment-dm-engine` counts guide DMs sent in the last 7 days; the Facebook leg is tracked by `fb-comment-dm-funnel`.

comment-dm-funnel · since 2026-07-16 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE Someone downloads the SUMMER guide → they enter an 8-week nurture bookings

The SUMMER guide page captures a name and phone, tags the person, and starts an eight-week check-in clock (weeks 1, 2, 4, 6 and 8). It turns a guide reader into a tracked lead with a nurture rhythm aimed at the September sign-up window.

Triggera guide download.
The AIcaptures the lead, anchors the start date, and sends the timed check-ins.
You seethe lead in your pipeline; replies come into Messages.

Proofship-register probe `summer-guide-capture` counts people tagged in the window (zero before launch is expected).

summer-guide-drip · since 2026-07-13 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE Facebook/Instagram ad leads captured the moment they enquire bookings

When an ad delivers a lead, the enquiry is captured server-side straight away and reported back to Meta so your ad reporting is accurate. No lead sits in a Facebook inbox waiting to be noticed.

Triggeran ad lead / message-template delivered.
The AIrecords the lead event end-to-end with a tracking id.
You seethe lead enters the pipeline and shows on the lead-capture chain.

Proofno live counter card yet — verified by the capture smoke test `crm/scripts/smoke-test-capture-chokepoint.js` and the lead-capture chokepoint decision doc.

paid-lead-capture · since 2026-05-19 · surfaced in: /chain-health · portability: config-extractable

LIVE Every ad click carries its source through to the conversation bookings no UI yet

A click on a "message us" ad on Messenger or Instagram is stamped with which ad it came from, so you know which campaign actually produced a conversation, not just a click.

Triggera click-to-message ad.
The AIattaches the ad source to the new contact.
You seenothing to action — the source is on the contact for reporting.

Proofno live counter yet — verified by commit `726c0c4` and the concept doc `ctm-ctwa-attribution.md`.

ad-click-attribution · since 2026-05-17 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

LIVE Ready-made landing pages for each audience bookings

A set of tailored landing pages (women, mums, men, dads) that ad traffic lands on and converts into enquiries, live on the join subdomain.

Triggerad traffic to the funnel.
The AIn/a — these are the capture pages the rest of the engine feeds from.
You seethe leads they produce, in your pipeline.

Proofno live counter here — verified by deployment to join.crossfitbodmin.com (commits `c09758a`, `2671f12`).

landing-pages · since 2026-05-19 · surfaced in: join.crossfitbodmin.com (funnel) · portability: config-extractable

LIVE Spam and time-wasters never reach you bookings

Obvious spam and non-lead first contacts are filed away at the door — no reply, no card, no wasted attention. If there is any doubt, it treats the message as a real lead (it fails safe toward the human), so a genuine enquiry is never binned.

Triggera brand-new first message.
The AIclassifies it; clear spam is filed as "not a lead", anything ambiguous is kept as a lead.
You seeonly the real leads; filed contacts are reversible from the contact screen.

Proofship-register probe `ingest-never-respond` counts filings in the last 7 days; the real safeguard is the fail-open rule (a real person filed as spam is the watched failure).

spam-never-respond · since 2026-07-04 · surfaced in: / (Messages / conversation thread) · portability: portable

LIVE Draft campaigns and marketing copy on demand bookings

The Marketing view generates campaign and content copy in your brand voice, so a promotion goes from idea to draft in minutes.

Triggeryou ask for a campaign/post.
The AIdrafts the copy.
You seethe draft in the Marketing view to edit and use.

Proofno live counter — verified by `crm/marketing-prompt.js` (the generation module) and the weekly campaign-feedback loop.

marketing-copy · since 2026-05 · surfaced in: / (Marketing view) · portability: config-extractable

LIVE The AI answers every enquiry, on any channel bookings

Every inbound message is read, understood, and replied to by the AI following your conversation rules — the core "someone messages, they get a good answer" engine.

Triggerany inbound message.
The AIdrafts and (where confident) sends a reply.
You seethe thread in Messages; anything it is unsure of comes to you as a card.

Proofno isolated counter — verified by live production traffic through `crm/conversation.js` and `crm/chat/entry.js`.

message-engine · since 2026-05 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE Every AI message is fact-checked before it sends bookings

Before an AI reply goes out, a separate checker reads it against the known facts and blocks anything that claims something untrue (a wrong price, a class that does not exist). It holds bad drafts rather than rewriting them.

Triggerevery AI-drafted reply.
The AIverifies each claim; a failing draft is held.
You seeheld drafts surface as a card instead of a wrong message reaching the lead.

Proofno live counter — verified by `crm/scripts/test-verifier-blocks-not-rewrites.js`.

message-verifier · since 2026-04-21 · surfaced in: / (Messages / conversation thread) · portability: portable

LIVE No quiet lead is ever forgotten bookings

A lead who replied but never got a clear next step is caught by a safety net and surfaced with a ready-to-send nudge, so warm leads do not quietly go cold.

Triggera lead who engaged then went quiet with no plan.
The AIraises a one-tap "send this" card.
You seethe card on your Focus deck.

Proofship-register probe `ghost-net-survival` counts safety-net cards that stayed alive long enough to be actioned. ---

ghost-risk-net · since 2026-06-21 · surfaced in: /focus-stack · portability: portable

📅Bookings 11

LIVE The AI offers real free times and books hands-free bookings

For a warm lead the AI offers genuine open times — a morning and an evening across two days — and when the lead says yes to one, it can book the slot in the same conversation with no tap from you. Only real, available slots are ever offered.

Triggera warm lead ready to book.
The AIoffers real slots, and books a clear acceptance automatically.
You seea heads-up card for each auto-booking; nothing to do unless you want to.

Proofship-register probe `slice3-offer-window` counts AI slot-offers in the window; auto-booking is tracked by `agreed-time-autobook` and `gate12-book-first`.

grounded-offers · since 2026-07-12 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE Capture a booking in one tap bookings

When someone books with you off to the side — a text, a call, in person — you capture it in one tap from their record. You pick from genuinely free slots only, and the system writes the roster or calendar entry, sends the confirmation, and puts it on your Google Calendar. The same record now also lets you cancel a roster booking or reopen a closed lead in one tap. No more re-typing a booking into PushPress and hoping your CRM caught it.

Triggeryou tap "Capture booking" on a contact.
The AIbooks it atomically through the same safe path as every other booking and confirms the lead.
You seethe booking on the record and your calendar; a confirmation goes to them.

Proofship-register probe `capture-booking` counts one-tap captures in the last 7 days (zero reads as adoption-pending, not a fault).

capture-booking · since 2026-07-18 · surfaced in: / (contact record) · portability: config-extractable

LIVE Bookings only ever land inside your real working hours bookings no UI yet

The AI can only offer or book 1:1s and calls inside the hours you actually work — never a Sunday, never your lunch break, never with less than your notice period. Ask for a closed time and it apologises and re-offers real ones, instead of booking something you cannot make.

Triggerany AI booking or offer.
The AIchecks the request against your hours before it books.
You seenothing — a wrong-time request becomes a polite re-offer, never a bad booking.

Proofship-register probe `working-hours-availability-floor` is an invariant check — it reads healthy while zero autonomous bookings land outside your hours.

working-hours-floor · since 2026-07-12 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

LIVE A missed call is answered by the AI — which can book the caller bookings no UI yet

When a call to you goes unanswered, the AI assistant picks up, introduces itself, answers questions, and can book a taster or a call — handing off to a human for anything off-script.

Triggera missed inbound call.
The AIanswers, converses, and books through the same booking path as everything else.
You seethe call outcome in the voice-call review (a backend surface today).

Proofship-register probe `ai-voice-answer-book` counts missed calls the AI answered (zero missed calls reads as legitimately quiet).

voice-answer-book · since 2026-07-16 · surfaced in: backend-only — needs a UI handle · portability: bodmin-specific

LIVE Every missed call gets an instant text back bookings

A missed call triggers an immediate "sorry we missed you" text, so the caller does not go to a competitor while you are on the gym floor.

Triggera missed call.
The AIsends the rescue SMS and opens a conversation.
You seethe new thread in Messages.

Proofno live counter yet named — verified by commits `508f05e` and `f4a3953` (shipped 2026-06-10).

voice-rescue-sms · since 2026-06-10 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE See exactly how many bookings the AI made vs you bookings

A running split of how many bookings the AI handled by itself versus how many needed you — the single number that proves the system is doing the work. An alarm fires if the AI ever stops booking.

Triggerevery booking.
The AIattributes each to AI or operator and watches the ratio.
You seethe split on the Chain Health screen; an alarm card if AI bookings go silent.

Proofship-register probe `ai-booking-measurement-wired` confirms the health sweep is evaluating the alarm each day.

booking-scoreboard · since 2026-07-02 · surfaced in: /chain-health · portability: config-extractable

LIVE The AI only ever quotes classes that actually exist bookings no UI yet

Your live class timetable is mirrored from PushPress every hour, so the AI never offers a class that was cancelled or moved. A daily check flags any drift between what it thinks and what is really scheduled.

Triggerthe hourly schedule pull.
The AIquotes and books only against the mirrored real timetable.
You seea "timetable drift" card only if the two ever disagree.

Proofship-register probe `pushpress-mirror-live` confirms the hourly pull is running.

schedule-mirror · since 2026-07-04 · surfaced in: backend-only — needs a UI handle · portability: bodmin-specific

LIVE First-timers get a day-before reminder members no UI yet

A non-member booked into a class gets a reminder the day before and again the morning of — the simple nudge that lifts the show-rate.

Triggera non-member class booking for tomorrow.
The AIsends the day-before and morning-of reminders.
You seenothing to do — it just runs.

Proofship-register probe `coach-taster-headsup` (combined) counts reminder marks and coach heads-ups.

class-reminders · since 2026-07-15 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

LIVE Coaches are told who is new before class members no UI yet

The evening before, each coach gets a direct message listing the first-timers on tomorrow's classes, so nobody walks in unwelcomed — the hospitality gap that loses new faces.

Triggerfirst-timers on tomorrow's roster.
The AImessages the coach directly (never the nurture pipeline).
You seethe coach gets the message; you do not need to relay it.

Proofship-register probe `coach-taster-headsup` counts heads-up sends.

coach-headsup · since 2026-07-15 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

LIVE PT sessions booked and billed against a real credit ledger £

Personal-training sessions are booked against credit packs — each booking decrements a credit, cancellations refund, packs expire on a schedule, and a "one credit left" prompt catches the rebuy moment.

Triggeryou book a member's PT session.
The AIdecrements the credit, syncs the calendar, and flags low balances.
You seethe ledger and the low-balance card in the PT & Coaching view.

Proofship-register probe `pt-credits-ledger-live` confirms the nightly expiry sweep is running plus counts new packs.

pt-credits · since 2026-07-12 · surfaced in: / (PT & Coaching view) · portability: config-extractable

LIVE The coach calendar can never double-book £

Two bookings can never land on the same coach at the same time, even under simultaneous taps — the calendar can be trusted at scale, and a clashing attempt gets a clean "slot just taken".

Triggerany PT booking write.
The AIa database-level guard rejects overlaps outright.
You seea clean refusal instead of a clash.

Proofship-register probe `pt-bookings-overlap-floor` is a structural invariant — it reads healthy while zero overlapping bookings exist. ---

pt-overlap-floor · since 2026-07-12 · surfaced in: / (PT & Coaching view) · portability: portable

💛Members & the app 5

LIVE A taster attendee who has not signed up gets followed up automatically members

The morning after someone attends a taster but has not joined, the AI opens a warm follow-up (day 1, then 3 and 7) to convert the warmest moment there is — someone who already came in.

Triggera non-member's logged class attendance.
The AIsends the conversion opener, then qualifies and routes the reply to a plan.
You seethe thread in Messages; you only step in if asked.

Proofship-register probe `attended-conversion-trigger-v2` counts follow-up decisions in the window.

attended-conversion · since 2026-07-14 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

LIVE See whether members are staying — the retention curve members

A survival curve built from your full membership history shows how long members typically stay, with recent cohorts plotted against the baseline — so a dip in retention is visible early, not a year late.

Triggerthe weekly snapshot (plus the full history baseline).
The AIcomputes the curve and four retention stat cards.
You seethe curve in the Metrics view.

Proofno live counter — verified by commit `267cee4` and `crm/metrics-retention.js` (baseline n=448).

retention-curve · since 2026-06-26 · surfaced in: / (Metrics view) · portability: config-extractable

LIVE Progression maths for the strength programme members

Percentage-of-max load progressions are generated for members, with a personal load-grid lookup — the number-crunching behind a structured strength programme, done automatically.

Triggerprogramming a strength block.
The AIgenerates the progression and per-member loads.
You seethe load grid the member uses.

Proofno live counter — verified by commits `2a4e930`, `8d9a0d3` and the member-app %TM lookup `9c531e2`.

strength-progression · since 2026-05-16 · surfaced in: /strength-club (load grid) · portability: portable

LIVE Build and reorder programming visually members

A drag-and-drop editor for building the week's or month's programming, with warm-ups generated to match — you design the sessions, the system keeps them organised and exportable.

Triggeryou plan programming.
The AIgenerates matching warm-ups; you own the session design.
You seethe week/month editor in the Programming view.

Proofno live counter — verified by commits `1e09afa`, `37836df`, `92f1579`.

programming-editor · since 2026-05-21 · surfaced in: / (Programming view) · portability: config-extractable

LIVE Know your true member number and which way it is moving members no UI yet

One honest count of active members and the net movement each month (joins minus leaves) against a growth floor — the fundamental number, computed one consistent way instead of three.

Triggerrun on demand.
The AIcomputes roster, net change and gap-to-target.
You seethe figure on request (a dashboard widget is the next step).

Proofno live counter card — verified by `crm/scripts/member-movement.js`, run on production 2026-06-25 (active 75, six-month net +9). ---

member-movement · since 2026-06-25 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

⚙️Running your day 7

LIVE One deck of exactly what needs you bookings

Instead of ten screens, you get one deck of decisions the AI could not make alone, each with a suggested reply and three buttons — follow up, take over, or close. An empty deck means the system handled everything.

Triggerthe AI hits something it wants a human on.
The AIdrafts the suggested action and stacks the card.
You seethe Focus deck (phone-friendly), one card at a time.

Proofno live counter — verified by `crm/scripts/smoke-focus-resolution.js` and `smoke-focus-edit-suggestion.js`.

focus-board · since 2026-05-22 · surfaced in: /focus-stack · portability: config-extractable

LIVE The board clears stale cards by itself bookings

When a lead becomes a member, gets closed, or is already booked, any now-pointless cards about them are cleared automatically — so your board only ever shows live decisions, not fossils. Acting anywhere clears the board everywhere.

Triggera booking, a status change, or the nightly sweep.
The AIre-checks open cards and retires the moot ones.
You seea cleaner board; every clear is reversible.

Proofship-register probe `action-chokepoint-card-triage` counts action-time triage decisions in the window.

card-triage · since 2026-07-14 · surfaced in: /workboard-v2 · portability: config-extractable

LIVE It never messages a closed or dead lead bookings no UI yet

Leads that have gone silent both ways for 30 days are automatically closed, and closed contacts are never messaged again. Getting the status right is what structurally prevents spam — the system cannot message someone it should not.

Triggerthe nightly sweep.
The AIcloses genuinely dead threads (future-intent and holds are exempt).
You seenothing — it is a safety backstop; reversible with one command.

Proofship-register probe `auto-close-30d-sweep` confirms the nightly sweep ran.

auto-close-guard · since 2026-07-02 · surfaced in: backend-only — needs a UI handle · portability: portable

LIVE A built-in guard that halts sending if anything looks like spam bookings no UI yet

A watchdog checks the system's own outbound behaviour and, if a message ever heads to someone it should not, demotes auto-send to review mode and raises a critical alert — the system polices itself.

Triggerevery outbound signal.
The AImonitors continuously and auto-halts on a bad send.
You seea critical card if it ever trips; otherwise silence.

Proofno live counter card — verified by the runbook `crm/docs/SELF-MONITOR.md` and in-container leak-to-halt tests.

self-monitor-halt · since 2026-06-21 · surfaced in: backend-only — needs a UI handle · portability: portable

LIVE An overnight check that tells you only when something looks off bookings

Every time your brief is built, the system checks itself over — did the engine actually make decisions, did anything send while review mode was on, is any lead sitting behind two cards at once, and has any deferred piece of work finally become ready to do. A clean check says nothing at all.

Triggerevery brief build — the on-demand Today page and thread see it daily, the Monday message carries it weekly.
The AIruns the checks and writes them in plain English, worst first, at most three.
You seenothing when it is clean; a short "system check" block on Monday when it is not.

Proofno live counter — verified by `crm/scripts/test-daily-brief.js` §15 and by the `ops_audit_error` stamp on the `daily-brief-morning` scheduler log row. Folded out of its own 8am cron on 2026-07-30 (`digest-brief-fold-debt`).

morning-digest · since 2026-05 · surfaced in: the Monday message + the Today page · portability: config-extractable

LIVE Reply to your AI and it does the work bookings

You run the business by replying to the AI in plain English on your own thread. Small, undoable things just happen and you get a receipt with an undo; anything a customer would see waits for your one clear yes; your pause, cancel and refund policy is offered back to you automatically (7-day pause, 30-day cancel, a one-month refund cap read live from your prices); the big or irreversible things stay in the app on purpose. It replies four short lines at a time, one question at a time, and its receipts never claim something happened when it didn't.

Triggeryou reply to the AI's message or its morning brief.
The AIdoes the undoable thing and tells you, or proposes the customer-facing thing and waits for your exact yes.
You seea short honest receipt — done (with an undo) or "not sent, and why".

Proofship-register probe `reply-floor` counts your reply-driven actions in the last 7 days; the tiered rules are gated by `crm/scripts/test-reply-floor.js`.

reply-floor · since 2026-07-18 · surfaced in: WhatsApp/Messenger thread + /focus-stack · portability: config-extractable

LIVE Every channel in one inbox bookings

WhatsApp, SMS, Instagram, Messenger and email all land in one place, and replies go back out on whichever channel the lead prefers — one conversation, not five apps.

Triggerany inbound on any channel.
The AIthreads it into one conversation and replies on the right channel.
You seeevery channel in the Messages view.

Proofno isolated counter — verified by the channel modules (`crm/whatsapp.js`, `crm/sms.js`, `crm/instagram.js`, `crm/messenger.js`, `crm/email-channel.js`) all in production and the smart-routing logic in `crm/send/index.js`. ---

unified-inbox · since 2026-05 · surfaced in: / (Messages / conversation thread) · portability: config-extractable

🗺️On the roadmap 4

PARKED Spot members who are about to quit members no UI yet

A pattern that flags members drifting toward cancelling, so a coach can reach out before they leave rather than after. Built as a decision tree, not yet switched on.

Trigger(when live) a member's attendance/engagement dropping.
The AIwould raise an at-risk card.
You see(when live) a "reach out" card.

Proofbuilt-flag-off — verified by `crm/scripts/test-tree-router.js` and the concept doc `proposed-member-at-risk-tree.md`; not promoted.

member-at-risk · since 2026-05-15 · surfaced in: backend-only — needs a UI handle · portability: portable

PARKED A searchable workout bank members

A reusable library of workouts you can search, drag into programming, and import from — full feature, currently gated off.

Trigger(when live) building a session.
The AIn/a — an authoring tool.
You see(when live) the bank panel in Programming.

Proofbuilt-flag-off — verified by commit `54b029f` ("full feature, flag-gated OFF").

workout-bank · since 2026-05-16 · surfaced in: / (Programming view) · portability: portable

PLANNED Turn gym moments into a content pipeline bookings no UI yet

A pipeline that tags and retains gym media so it can be reused into posts and campaigns — the asset layer under the content engine. Scoped, not yet built.

Trigger(when built) new media.
The AIwould tag and file it for reuse.
You see(when built) a media pool feeding Marketing.

Proofscoped only — verified by the memory scope `project_content_flywheel.md`; no code yet.

content-flywheel · since 2026-07 · surfaced in: backend-only — needs a UI handle · portability: config-extractable

PLANNED Enforced attendance outcomes on every booking bookings

Every booking would be required to record an outcome — attended, no-show, or cancelled — so show-rate is always real and no-show follow-ups always have a trigger. The rule is designed but not yet enforced in the schema.

Trigger(when built) a booking passing its time.
The AIwould force an outcome to be captured.
You see(when built) a one-tap outcome card.

Proofscoped only — verified by decision doc `2026-05-03-three-pillar` invariant (d); the schema invariant is a named gap, not yet enforced.

outcome-capture · since 2026-05-03 · surfaced in: / (Focus / Calendar) · portability: config-extractable