GC test calls · 19–20 August · read 21 August
Miss Patty's notes, sorted by what actually caused each one. They are not one problem. They are five, and only two of them are ours to fix in code.
The headline
Every other complaint in the run is “he misheard me.” One is “he never asked.”
#6 “Forgot to ask for my email address” · #9 “He forgot to ask for my email address” · #12 “Did not ask me for the email” · #16 “he closed the call without getting my last name or email” · #18 “it only asked for the client’s name… did not ask for an email” · #23 “Josh did not ask for my email” · #33 “it caused him to forget to ask me my last name and my email”
The cause was the tool, not the prompt. save_contact
required firstName and phone and nothing else, so a
booking missing both fields was a perfectly valid call. The prompt carries pages
on how to read an email back and not one line that makes asking
unskippable — and a prompt rule is precisely what had already failed seven times.
✅ Fixed 21 August. The booking tool now refuses once
with an instruction to go and ask, then saves on the second attempt whatever
happens. Not a hard requirement: the escape hatch — three tries at a difficult
address, then “we’ll confirm your email before the agreement goes out”, book,
chase it later — has to survive, or we start losing jobs over a name the
recogniser cannot hear. One nudge, then out of the way. In both
brains. test/ask-before-you-book.test.mjs.
bot.py is deployed by hand
cp to /opt/austin-voice/bot.py then
pm2 restart austin-voice. The web brain went out with the push.
All 36, by cause
| Cause | Calls | Whose | State |
|---|---|---|---|
| Never asked for the email or the last name | #6 #8 #9 #12 #16 #18 #23 #33 — 8 | Ours — the tool schema | Fixed 21 Aug |
| Audio cut out / went silent mid-call | #1 #3 #5 #7 #8 #14 #19 #23 #35 #36 — 10 | Infrastructure | Ran on 2GB; now 8GB, and measured |
| Digits misheard — phone numbers, ZIPs | #3 #12 #13 #17 #22 #27 #34 — 7 | Recogniser | Open — see below |
| Street names misheard | #19 (NASA Road One) #22 #31 — 3 | Recogniser · keyterms | Open — a keyterm fix exists |
| Wrong availability — offered a filled slot | #30 #31 #32 — 3 | Not a code bug — see below | Cause established |
| Quoted where he should have handed off | #15 #21 — 2 | Chad’s own price table | Needs Chad’s ruling |
| Pool / services gaps | #20 #29 #32 — 3 | Chad’s onboarding form | Ken has asked Chad to fill it |
| Went well / went as intended | #2 #4 #10 #11 #24 #25 #26 #28 — 8 | — | Good |
The three that look like our worst bug and are not
“He’s still saying we have an availability at 1 o’clock on Tuesday. That may be because I have scheduled 12 to 2:00 already and it is just not seeing a number one slot filled.”
Miss Patty, call #32 — and she is right
She diagnosed it herself and the code agrees with her. Josh reads GC’s GoHighLevel contacts to know what is booked. A job Miss Patty enters directly in ISN never reaches GoHighLevel, so it does not exist as far as availability is concerned. Josh then offers 1pm — correctly, by the only diary he can see, and wrongly by the one she is looking at.
A clash is defined as the same start time. Overlap is
deliberately not modelled — the note in api/ghl/slot-claim.js says
so and says why: inventing a duration rule a client never agreed to would refuse
bookings they want. But GC’s own form now supplies one —
“Typical inspection length: 2.5–3 hours” — so the objection that it would
be invented no longer holds. This is a decision for Ken, not a change to
slip in.
What already exists and would have prevented all three: the portal’s Block times. A job booked outside our system should be blocked in the calendar, and then Josh cannot sell it. That is a habit, not a build.
Ken answered two of these on the call
“Some of the errors were caused by his onboarding form wasn’t complete. The $75 pool. Who was doing the inspections when Chad’s no longer doing them and Greg is doing them. That all failed… He’s a source of truth for his own business, and we don’t feel comfortable producing his source of truth.”
Ken, 20 August
| Call | What Patty saw | What the record actually says |
|---|---|---|
| #20 · #32 | “Josh is still telling me $75” for the pool | $75 is correct for the plain Pool/Spa add-on. What he is not offering is the Pool Inspection with Leak Detection at $147, which is in the same record. Josh names the cheaper one and stops. |
| #29 | Never asks about well/septic, outbuilding, lawn irrigation | All three are in GC’s add-on list with prices ($50 / $25 / $25). He has them and does not offer them. |
| #15 · #21 | Quoted $972 on a 6,200 sq ft home instead of handing off | ⚠️ $972 is what Chad’s own table says. Standard stops at 5,500 sq ft (“do NOT quote”); the 5-Star table runs to 7,000, and 6,001–6,500 is $972. Josh followed the table. The two tables disagree about where the hand-off starts — that is a question for Chad, not a bug. |
| #21 | Quoted $622 first, then corrected | He heard “2600” for “6200”. A digit failure, not a pricing one. |
| #13 · #22 | Told a caller they were out of the area | He misheard the ZIP, then correctly applied the out-of-area rule to the wrong ZIP. #22 hung up. The cost of a digit error is a lost job. |
“Josh was promising text he couldn’t send.” Fixed 20 August — the web booking line said “an email and text”; it now says an email. We do not text homeowners.
“Whose name owns Queen City?” Done — the demo greets Ray Whitfield.
“It looks pretty thin with $7,000.” Done — the demo now carries 36 jobs and $24,175.
The 10 cut-outs
“I’m sorry, I didn’t get that” · “I’m having problems with the line” · going quiet until the caller asks whether he is still there.
Neither is proven to be the cause of any specific cut-out, and I am not going to claim it is. What is fair to say: the two conditions that would produce exactly this are both gone or reduced, and the next run is the test. Ask Chad’s team to re-run a handful on a quiet server with nothing deploying, and compare.
The RoseHosting invoice paid on 20 August reads “NVMe 2GB ⇒ NVMe 8GB”. So the entire 36-call run happened on two gigabytes, running Pipecat, Deepgram, Silero VAD, Smart Turn, ElevenLabs, the Node app and PM2’s monitoring at once. That is tight enough that the memory explanation stops being one of several and becomes the likeliest one.
It is still not proven, and that is the point. Nobody measured memory during a single one of those calls, so “it ran out of RAM” and “Deepgram dropped the socket” fit the evidence equally well. A plausible cause repeated often enough becomes a fact nobody checked.
✅ So it is now measured. Every call logs available memory at the
start and at the end, and shouts when it is tight. After the next run the question
is answerable from pm2 logs austin-voice instead of arguable. No new
dependency — it reads /proc/meminfo, so the server’s Python
environment is untouched.
free -h should show 8GB total. A plan change in
the billing panel usually needs a reboot before the guest actually sees it.pm2 logs austin-voice should print its Pipecat version on boot —
confirm it came back up after any reboot, and that it is still
1.6.0. Never pip install -U: 1.7.0 put a
nine-second hole in a ten-digit read-back.Digits — 7 calls, and one of them hung up
“Josh could never get the phone numbers correct (4 times). I was getting frustrated… I called back. He couldn’t get the numbers correct again… I never finished the call because I was so frustrated.”
Call #22
Keyterms are what make digits and local street names accurate, and they are measured: with them off, “1827 Willow Bend” came back as “187 Willow Bend” and “lockbox 4217” as “four to 21 up and seen”. With them on, both were right.
The phone line runs English only (Ken’s ruling, 13 August), which
is the mode where keyterms work best. What is worth checking on the server
before the next run is that AUSTIN_MULTILINGUAL_KEYTERMS is not
off and that GC’s keyterm list actually carries the street and town names Patty was
reading out — NASA Road One is exactly the kind of name that needs to be in it
and, on the evidence of #19, is not.
Item 4
| State | |
|---|---|
| Can Josh create a new one? | No — slot-claim.js gates all
three booking paths (phone Josh, web Josh, portal reschedule) and
test/double-booking.test.mjs proves it in 28 checks. That went in
12 August. |
| So what are the four on Ted’s 3 August? | Dated 3 August — nine days before the gate. They are Hamming test bookings from the run Dil reported as “multiple schedules got booked in the same time.” The fix stopped new ones; it did not clean up the old. |
| Can we see them all in one place? | Now yes — the Watch Board lists every clash across GC, Quality and the demo. Each portal only ever showed its own, to its own inspector, which is why four sat there. |
| Is it one press to fix? | Now yes — the work order’s Reschedule bar has a “Next opening” button. It asks the diary for that job’s own inspector and fills the fields. The person still presses “Move it.” |
| Have they been moved? | No — see below. |
Two reasons, and the first one is just a fact: this session has no GoHighLevel credentials, so it cannot write to Chad’s or Ted’s CRM at all.
The second is the rule Ken put on the portal himself — “Nothing has been moved for you.” Moving four of a client’s live bookings without them watching is the one thing every other part of this system refuses to do, because the customer at the old time was never told.
It is now two clicks each: open the job → Reschedule → Next opening → Move it. Under two minutes for all four. If you would rather I did it, give me a token and say so and I will.
Block, in the portal, any job that was booked outside our system. That is what stops #30/#31/#32 happening again, and it needs no code.
Item 3 · counter-check
The board holds 200 items — 192 done, 8 blocked, none open. Everything below was asked for on the call and is on none of the 8.
| # | What was asked | Who |
|---|---|---|
| 1 | ⭐ Ken gets access to Dil’s Claude Code account. The longest single thread on the call. Ken: “I just cannot be hamstrung… we’re still 12 hours behind, behind, behind, not including the weekends, when we have a product to get on the market by the end of the month.” Dil: “I’ll do research on how to make my account accessible.” | Dil |
| 2 | The onboarding form error that blocked testers. Ken: “they filled in their stuff and tried to go to the next level, and it had an error message that the onboarding form wasn’t available to them… one of the ladies, Gazelle, sent Beth a screenshot.” Cause fixed 20 August; Beth is re-messaging them. | Claude |
| 3 | Text consent taken on the call and recorded. Ken: “is it okay for us to text you the information? And then we record that… there couldn’t be any doubt that the person approved it.” And if they say no, “that needs to be marked, and we cannot do it” — they come out of Engine 1 and 2. He calls it a legal safeguard: “otherwise we can get sued.” | Ken → build |
| 4 | Resend buttons on the work order. If the agreement is unsigned, a button that sends it again; the same for an unpaid payment link. Ken: “that’s really super customer experience” — plus the legal reason, that an inspector who starts without a signed agreement has broken what he warranted to his insurer. | Build |
| 5 | Onboarding form asks: text or email the agreements? Per inspector. “That should be on the onboarding form.” | Build |
| 6 | Email verification tool wired into the import. Ken: “run the list through here via the API code” before anything is sent, to stop the bounces that got the sending domain penalised. | Dil |
| 7 | Import columns fixed: first name, last name, date last inspected (clients) and date last served (agents). “That would tell us what we needed to know to keep us safeguarded.” | Beth |
| 8 | Review page wording — Ken ruled on it. “Send us direct feedback” beside “Leave a Google review”; no single star; five stars each side; the Google button surrounded by real reviews. Plus: pull up two or three live client review pages and check they actually look like that. | Beth |
| 9 | Review responses are a content rule now. Thank the person, name the service, name the town. “If you have just a canned answer, thanks for your kind words, that’s worse than doing nothing at all.” And the reason it matters: most people only read reviews from the last two weeks. | Ken |
| 10 | GHL spam / unsubscribe threshold that alerts us when one client’s list starts misbehaving. | Dil + Knox |
| 11 | Landline check on the number we take. Dil’s point: ISN asks specifically for a mobile. A booking alert to a landline goes nowhere. | Build |
| 12 | Chad fills in his onboarding form. Ken has asked him and James was sitting with him. It is the direct cause of three of the call failures above. | Chad |
| 13 | More Hamming runs through Josh so the demo keeps filling. (The $7,000 complaint is already closed — it is $24,175 now — but the request for runs stands.) | Dil |
| 14 | The rest of Ken’s new homepage. Section 1 is up at /section. Ken: “my goal is to eliminate the original site.” | Ken |
The cause was found and fixed on 20 August: the sign-up page fired its text-message consent and the sign-up at the same moment, both wrote to the same file, the second one lost, and the customer saw an error. The fix does not create the accounts that were never written, so those who were blocked have no account yet.
Dil, 21 August: “do not worry about the early adopters — Beth will message them again.” The sign-up page works now, so a fresh attempt goes through. Nothing is needed from engineering, and this is not on anyone’s open list.
Already closed, so nobody re-raises them
| Raised | Answer |
|---|---|
| “There are two privacy policies” | There is one policy, linked twice, and both links are load-bearing. The agreement box must link it because it is one of the three documents that tick accepts; the SMS box must link it because carriers read the opt-in statement itself. Removing either breaks something. Ken had already reached the same place: “these two places may be completely fine.” |
| Ken: “they need to initial that they know that they can’t upload” | Withdrawn by Ken in the same breath — “we took that exposure away because now they can’t upload… so they don’t really need to sign that.” The list tick box that is live says the list is their own past customers. |
| Slots per day on the calendar | Approved — “Yeah, let’s do it” — with the mobile caveat. The calendar was also clipping Friday and Saturday off every desktop; fixed 21 August. |
| “Whose name owns Queen City?” | Ray Whitfield. |
| Server memory | Upgraded to 8GB. Dil: “this is done.” |