Reference · 20 August 2026
Written 2026-08-20 for Dil, as the companion to 2026-08-20-the-workflows-in-plain-english.md. That one covers what happens after a booking. This one covers what happens before there is anything to book — how a new inspector goes from saying yes to having a working phone.
Everything here was read out of the live code, not remembered: api/enroll/index.js · api/onboarding/index.js · api/buildboard/index.js · api/austin/config.js · dashboard/onboarding.html · FLOWS.md §① ② ③.
Six steps. Three are automatic, three are a person. The whole thing hangs on step 2 — the setup questionnaire — because that form is what Josh says to callers. And step 2 is where it stops, because nothing in the system ever asks anyone to fill it in. The link appears on one screen, once, right after checkout. If they close that tab, there is no email, no reminder, and no alert to us that they stalled. That is not a small gap: it is the exact reason Chad has been live for weeks on a half-finished form, and the reason the same thing will happen to thirteen early adopters at once unless it is built.
| # | Step | Who does it | How long |
|---|---|---|---|
| 1 | Sign up and pay | the inspector, on enroll.html | 2 minutes |
| 2 | Fill in the setup questionnaire | the inspector, on onboarding.html | 20–40 minutes |
| 3 | Their own CRM account is created | automatic, on submit | seconds |
| 4 | Their accelerant templates are applied | automatic, if they bought any | seconds |
| 5 | Point their phone number at Josh | us | 10 minutes |
| 6 | Issue their portal login, then mark them live | us | 5 minutes |
Ken's rule is built into step 1: "self-serve enrollment, White Glove setup, always both." There is deliberately no demo, no discovery call and no "book a time" anywhere in the sign-up. They buy, and then we do the work for them.
The build board (dashboard/build-board.html) shows all six per account. Five of them are detected from state the system can already see — a submitted form, a created CRM account, applied templates, a mapped number, an issued passcode. Only "marked live" is asserted by a person, because nothing can observe it.
At sign-up (POST /api/enroll/start):
stage-engaged and given a source tag — set once, never overwritten, so we keep knowing where they came from.c4-checkout-started.At submit (POST /api/onboarding) — and only at submit, once:
stage-onboarding + c4-questionnaire-complete.That is the complete list. Every one of those is a tag or a note. Not one of them is a message to the inspector.
After checkout the browser is handed /onboarding.html?inspector=<their-name>. It is on that one screen and nowhere else. No email carries it. Close the tab, and the only way back is knowing the address.
There is a rescue path — /api/onboarding/claim?email=… turns the email they signed up with into their account — but it only helps somebody who has already found their way back to the page.
⚠️ Said precisely: no code in this repo emails that link. Every email our system sends lives in the booking side of the app, and none of it runs at enrolment. If a GoHighLevel workflow sends one, it is not visible from the code and nobody has named it — so before building the email below, spend two minutes checking GHL. The
c4-checkout-startedtag does key an abandoned-checkout sequence, but that chases people who never paid; it is a different problem from a paid customer who never filled in the form.
This is not hypothetical. It is the single highest-value item on the whole board. Chad has never pressed Submit. His prices, his hours and his services reach real callers from a draft. It is what caused the pre-drywall quote fault that lost a job, and it is what the from-price rule had to be written around.
With thirteen early adopters arriving at once, this gap multiplies by thirteen.
There is no day-1, day-3 or day-7 nudge. There is also no alert on our side: no screen says "enrolled four days ago, form still a draft." The build board will show them stuck at 0 of 6 — but only if somebody opens it and looks.
A stall is invisible until a customer complains about what Josh said.
Payment is recorded (paid, paidAt) and reported by the claim endpoint. It is not enforced. That is deliberate right now — Ken is putting the link in front of rooms he has just told "no payment, no fee" — but it should be a decision somebody makes on purpose rather than a default nobody noticed.
BRAIN2_REQUIRE_SUBMITTED is off, so a half-typed form is what callers hear.
That is correct today and wrong soon. It is right for Chad and Ted, because nobody ever told them the form existed and switching it on would drop their prices to a built-in default. It is wrong the moment thirteen people are typing into forms at their own pace, because a half-typed price list would reach their callers. One setting flips it, and the flip should happen the same day the nudges go out.
The questionnaire is not admin. It is Josh's brain. Everything in the left column below comes straight out of it, and there is no other source:
| What the form decides | What breaks without it |
|---|---|
| Packages and prices | Josh quotes a built-in default that is not theirs |
| How they price — square footage, flat fee, or both | The from-price rule cannot tell which branch a job is on |
| Add-ons and their prices | Josh cannot sell them |
| Each inspector's schedule | Josh offers hours they do not work — this is the GC/Quality Saturday fault |
| Service area | Josh books a job two hours away |
| The mobile for booking alerts, and consent | The inspector never hears about the booking |
| Follow-up email timings | ⚠️ Every client is different. Dil: "Ted and Chad have different events — this one goes out after 2 hours, while on Chad it says 1 hour." |
| Their Google review link | The review page has nowhere to send a happy customer |
| The backup number | If our system cannot answer, the call rings nowhere |
Precedence, in one line: a submitted record beats a built-in seed, and a seed beats nothing. A blank field falls through to the seed instead of erasing it — and an empty list counts as blank, so a form showing ten empty price rows cannot wipe a price table.
⚠️ Read the live config, never the seed, before believing a price. GET /api/austin/config?phone=<their number> tells you which brain is actually live.
1. The welcome email, with the link. One email, sent the moment they pay. It is the smallest change on this page and it removes the largest hole.
2. Three nudges, and they stop the moment the form is submitted. Day 1, day 3, day 7. Not a drip campaign — a chase that ends when the job is done.
3. A stall alert to us. Enrolled 72 hours ago, still a draft → it lands in front of Ken or Beth. Thirteen people at their own pace is exactly the situation where nobody notices one has gone quiet.
4. Then flip BRAIN2_REQUIRE_SUBMITTED on. Once people are actually being asked to finish, a draft should no longer be allowed to answer a real caller.
Note the shape. This is not the same shape as the booking sequences in the other document. Those are about noticing when somebody goes quiet over months. This one is a short chase with a finish line: it runs until the form is submitted and then it is over. Sending nudge four to someone who finished on day two is how a system loses trust in one message.
Placeholders. The words are ours to argue with; the timings and the stop rule are the part that matters.
Subject: You're in, Chad — one thing left
Hi Chad,
You're set up. There's one thing we need from you before we can build your system, and it's the only thing we can't do for you: your setup questions.
It's the prices, the services, your hours and your service area — the things Josh will tell your callers. It takes about half an hour, it saves as you go, and you can finish it in two sittings.
[Fill in your setup questions]
Anything you don't have an answer for, type N/A and keep going.
— The Booked Solid team
Subject: Your setup questions are half done
Hi Chad — you've made a start and it's saved. Whenever you've got twenty minutes, picking it back up takes one click.
[Carry on where you left off]
If a question is holding you up, reply to this and tell us which one. We'll answer it or fill it in for you.
Subject: What Josh needs before he can answer your phone
Hi Chad,
Until the setup questions are in, Josh is working from our best guess at your prices rather than your prices. We'd rather he had yours.
[Finish your setup questions]
Prefer to talk it through? Reply with a time and we'll go through it with you on the phone and type it in as you go.
Subject: Last nudge from us
Hi Chad — this is the last reminder we'll send. Your setup questions are still open, and your system is waiting on them.
[Finish your setup questions]
If now isn't the right time, that's completely fine — just reply and tell us when to come back to it.
Subject: ⚠️ GC Home Inspection — setup form still a draft, 3 days
Enrolled: 17 Aug · Last saved: 18 Aug · 14 of 31 questions answered Missing: prices, service area, review link Josh is answering their callers from the built-in default.
Three things, and no persona edits — that is the point of the design.
NUMBER_TO_INSPECTOR.⚠️ Adding a number in Telnyx is only a third of the job. It also needs the row in
NUMBER_TO_INSPECTORand its Telnyx application set toaustin-voice. Miss either and the number silently answers as the wrong company. That is not a warning, it is a report:+1-302-240-3518did exactly this, and a Delaware caller got Texas prices and a weekdays-only rule on a firm that works Saturday mornings.