Daily report · Wednesday 19 August 2026
Four teams worked at the same time today and all of it landed. Josh can now tell a recorded sales call from a customer, and he refuses to confirm anything to it — which is the rule that stops an old invoice scam. Ted’s line passed every single test. The three calls that came back blank last night were never Josh failing; the phone was asked to answer ten calls in the same two seconds. The early adopter door is open, the replay of Ken’s call is live, and a bug that would have hit all thirteen testers at once was caught before any of them arrived. Fourteen sets of changes went live.
A robocall is a phone call from a machine that plays a recording. The common one for a business says your listing is about to expire. Josh used to treat those like customers, or take a message an inspector then had to read. He now spots them, tells them nothing, and files them where the inspector never sees them.
Ted’s phone passed all ten test calls. Yesterday three of those came back blank. We found out why, and it was not Josh.
The early adopters can sign up, and the recording of Ken’s Tuesday call is online for the ones who missed it.
One thing we learned the hard way: the server had quietly run out of memory five times and killed a program each time. Nobody knew. Both halves of the phone are now protected.
Four separate pieces of work, all finished, all live.
Ken and Dil asked for it in one line: “handle robo calls — we need to add this so Josh will know that it’s not a booking.” Built, tested and live. We then went and read what other people do about this, and found a free setting we are not using.
Ten scripted calls into Quality Home Inspections. Ten passed. The three that came back blank last night were re-run and all three are clean.
The sign-up page, the name Ken chose, one short link he can read out loud, and the replay of Tuesday’s call. Plus a bug that would have broken the phone for every one of the thirteen.
We found the machine had been running out of memory and killing programs. Five times since 30 July. Both halves of the phone now protect themselves.
Before today he only knew two kinds of call. A machine is a third.
Josh answers the phone. Until today he knew two things a caller could be. Someone who wants an inspection, so he books it. Or someone who wants something else, so he takes a message and passes it on.
A machine wants neither. So Josh did one of two wrong things. He treated the robot like a customer and tried to sell it a home inspection. Or he took a message — and that message landed in the inspector’s list, and a busy man had to open it.
The second one is quieter and worse. A message list only works while everything in it is worth reading. Fill it with junk and the inspector stops looking. Then he also misses the one that says a gate code changed.
Josh now knows the signs. It talks over him. It never answers his questions. It offers a menu — press one for a representative. The call opens with a click or a beep. It wants to confirm something about the business instead of booking anything. If two or more of those are true, he is talking to a machine.
If Josh is not sure, he treats the caller as a person. A real customer can sound like a machine for a few seconds — nervous, on a bad line, reading off a printed sheet, driving.
So he asks one plain question: “Sorry, are you calling to book an inspection?” A person answers that. A machine talks straight past it.
The two mistakes do not cost the same. A robot treated like a person wastes one minute. A customer treated like a robot loses the whole job. He is also never allowed to tell a caller they sound like a recording.
Robot calls are counted, never shown. They are saved in our records, but they are never sent to the inspector, never appear in his message list, and never count as something needing attention. He gets a number instead — Josh took 40 junk calls off you this month. The number is worth having. The list is not.
This is why we did more than just ignore the robot.
The directory listing call is one of the oldest scams aimed at small trades. It works like this. The robot calls. It asks whoever answers to confirm the business name and the address. The person says yes. That yes is recorded. An invoice arrives later for a listing nobody ordered, and the recording is held up as proof.
He is recorded. And he is built to be helpful and agreeable. That is a bad mix.
So the rule is not be careful. The rule is confirm nothing. Not the company name. Not the address. Not the hours. Not the owner’s name. Not even a plain yes. He says “I’m not able to confirm any of that” every time, even when the question sounds harmless.
He presses nothing either — not one to reach a person, and not two to be taken off the list. Pressing anything proves a real person answers this number, and that gets the number sold on to the next list. That is the FTC’s own advice.
Then he says one short line, “thanks, we’re not interested”, and stops talking. If the robot keeps going, he stays quiet. There is nobody there to argue with.
We test both sides. Two new practice calls were added. One is a recording pitching a Google listing. The other is a real home buyer whose opening sounds like a robot — she goes quiet, then reads a flat scripted line off a sheet. She must still get booked. Without her, Josh could pass the first test simply by refusing everybody.
The biggest find of the day, and it is a checkbox rather than a build.
Telnyx carries our calls. They have a feature called Inbound Call Screening. It checks every incoming call against known junk-caller lists before the call ever reaches us. Those lists come from companies that run thousands of decoy phone numbers just to collect robocalls.
It used to cost money. It has been free on any number since 17 March 2026. It is a checkbox in the Telnyx control panel. There is nothing for us to build.
It has two settings. Flag lets the call through but marks it, so we know. Reject stops it at the phone company, and it never reaches us at all.
Why that beats what Josh does. Josh going quiet saves the cost of him talking. It does not save the rest. The moment we answer, four meters are already running whether he says a word or not:
| What it is | Cost per minute |
|---|---|
| The phone line | $0.0020 |
| Sending audio to our server | $0.0035 |
| Recording the call | $0.0020 |
| Turning speech into text | $0.0048 |
| Total once we answer | $0.0123 |
The money is small and it is not the real point. A robot on the line is a line a real customer cannot get through on.
These lists are not perfect. If a client’s line is set to reject and it gets one call wrong, that is a home buyer who rings Chad and gets nothing — no ring, no voicemail, no message, and no record on our side that it ever happened.
One lost buyer is worse than a whole year of robocalls. So nothing has been switched on. The suggested order is: flag mode on the 888 test line only, look at one flagged call, watch the junk count for a while, and only then talk to Chad or Ted about their own numbers.
We also said no to two ideas on purpose. A press one to continue gate would stop every robot — and would hand every real buyer exactly the annoyance this whole product exists to remove. And a home-made block list of robot numbers would not work, because robot diallers fake their caller ID and change it constantly. It would eventually block a real person whose number was copied.
Ten scripted calls into Quality Home Inspections, on his real line.
We wrote ten test calls for Ted’s line and ran them. All ten passed. Nothing failed. The overall score was 95%.
Three of them are worth naming, because these three came back blank yesterday and were re-run today:
| Test | Length | Result |
|---|---|---|
| Who is coming to my house | 2m 53s | Passed |
| A big house, over the package ceiling | 4m 33s | Passed |
| A service they do not sell | 2m 50s | Passed |
The first one mattered most. It checks that Josh never mixes up one client with another — that a caller to Ted’s Delaware line never hears about Chad’s Texas company. It was the one thing on the board we genuinely did not know. Twenty turns of real conversation, and it passed.
The server log settled it in one screen.
Last night three of the ten came back with nothing at all. Five minutes of call time, zero seconds of anyone speaking, no conversation recorded. It looked like Josh had gone mute.
The server log shows what really happened. All ten calls arrived in nine seconds — nine of them inside two and a bit. Then the phone program went completely still for 1.67 seconds and dumped six greetings in two thousandths of a second.
That gap and burst is what a program looks like when it freezes and then catches up. And a caller who hears nothing for six seconds is a caller who has been let down.
Today’s re-run, with the calls spaced out, tells the other half of the story:
| How the calls arrived | Time before Josh spoke |
|---|---|
| Ten at once, last night | 8 to 10 seconds |
| One at a time, today | about 2 seconds |
Same code, same server, same morning. The only thing that changed is that the calls did not land on top of each other. The test service’s own scoring agreed — the time before Josh speaks was the only measurement it marked as a problem. Everything else passed.
Less than it looks, but not nothing. Chad and Ted will never make ten calls ring at the same instant. Every ordinary call in that log is answered in about a second.
But it is the thing that bites on the day it matters — a storm, a busy Monday, or the twentieth client. We know where to look now, and there is a free setting at ElevenLabs worth checking first before anyone writes code.
A month-old mystery closed as a side effect.
Some test calls had Josh saying his opening line twice. We had never been able to explain it, and the note in the code said as much.
It was our own safety net doing its job. If six seconds pass with no sound, a watchdog assumes the voice engine has died and says the greeting again. On the calls that piled up, the first greeting took eight or nine seconds — so the watchdog fired, and then the original one arrived too.
The test service suggested we rewrite Josh’s instructions to fix it. We are not doing that. The instructions were never the problem. Change them and we would break something that works to paper over something underneath it.
He was following our instructions exactly. The instructions were wrong.
One test kept failing because Josh read the street back to the caller but skipped the town and the ZIP code. That matters. The same street name exists in every town he covers, and the read-back is the last moment a wrong town can be caught.
We went looking for the fault and found it in our own writing. The instruction said to recap “the street address”. Josh was doing exactly what he was told.
Both halves of Josh — the phone one and the website one — now say street, town and ZIP, with a note explaining why the street alone is not enough. Confirmed live on the server.
Not a Josh problem. A scoring problem, and it needs one click.
Our test service has a rule that says weekend appointments must be refused. Josh offered Ted a Saturday morning — and Ted works Saturday mornings. So the rule marked correct behaviour as a failure.
This has now happened on four runs. It was first reported on 28 July. It cannot be fixed from our side; it is a setting in the test service, and someone with a login has to change it. The exact replacement wording is written and waiting.
Free sign-up, the name Ken chose, and one short link he can say out loud.
Dil asked whether we should add a “free” plan to the normal enrollment page. We did not need to. A free page was already built on 17 August. Four questions, agree to the terms, straight into the setup form. No plan, no price, no payment.
We deliberately did not put a free option on the public enrollment page. That page is a shop window. A free plan sitting in it is a different product from the one we sell.
Dil asked what to call the testers. Ken said: “We call them early adopters.” Every word a person reads now says early adopter.
Under the surface nothing changed. The web address, the record flag and the labels in our customer system still say tester. Renaming those would break every record already saved and every list Beth has already sorted. No customer ever sees those words.
bookedsolidinspector.com/early-adopters — new, short, and easy to say on a call. The old link still works too, because Beth has already sent it to people.
Ken planned to put the setup form link on screen when someone says they are in. But the setup form cannot be the first door — it looks people up by an account the sign-up page creates. Anyone opening it cold got a screen saying:
“We couldn’t find an enrollment for that email. Use the address you paid with.”
Ken had just told that room there is no payment and no fee. The one dead end in the whole flow was also the one sentence that argued with the offer.
It now says something sensible and offers a Start here button. And it only says it when the account truly does not exist — not when the server hiccups, which would otherwise send someone who already has an account off to make a second one.
Chad and Ted would have kept working perfectly the whole time.
Josh learns a company’s real prices, hours and services from their setup form. The website half of that was already fine — checked against the live server, and Ted’s account came back complete.
The phone half could not be connected at all.
Here is how a phone number normally gets hooked up. Beth buys the number. Dil points it at our voice system. Then we tell our code which company that number belongs to. There is a setting that does that last step in one line, with no software release.
That setting had a rule allowing exactly two companies: Chad’s and Ted’s. So an early adopter could sign up, spend twenty minutes on the questions, get a number from Beth — and Josh would answer their line with no company name and no prices.
Chad’s and Ted’s lines would have worked perfectly throughout. They are the two written into the code by hand. Everything you would think to test still worked. Only the new people would break.
Fixed, and proved against the old code first. The safety rule that stops a number being moved to the wrong company by editing a settings file is untouched — that is the rule that stops a Delaware caller getting Texas prices, which actually happened on 28 July.
One old test had the bug written into it as though it were correct behaviour, under a heading that said an unknown brain is refused. It was rewritten to test the fix, with a note explaining why, rather than quietly deleted.
His layout, his fonts, his tables. Only the wrong words changed.
Ken wrote twenty test call cards in Word. The format is good — each card gives a tester a character, an address, an email, house details and what should happen, so nobody has to invent a story before they dial. A tester who has to make one up makes one call and stops.
Three things were wrong, and each would have wasted twenty people’s time:
| What was wrong | Why it mattered |
|---|---|
| The agent was called Austin, thirteen times | Josh says “this is Josh.” Every tester would have failed card one on the greeting alone |
| Well and septic marked as not offered | GC does offer it, at $50 added. Twenty false fault reports |
| The 5‑Star card named no expected price | A card with no expected number cannot fail. It now says $622 for a 2,900 sq ft home |
Two cards also used the names of people who were never real clients. Our own rules say that ban covers test characters too. Replaced.
Josh reads a company’s prices from their setup form first, and only falls back to the version in our code if there is no form. Chad’s form is a draft — he has never pressed submit — and a draft still counts.
So Chad’s half-finished form is what Josh actually uses. The prices in our code are not what a caller hears. Always read the live system before believing a price.
For the people who came, and the people who missed it.
Ken asked for one link Beth could send. It is live at bookedsolidinspector.com/early-adopters/replay. It has the video, the full written transcript, a search box and thirteen chapter links. It is public — Dil’s call: “Make it public please. If they want to join they will.”
The page is written for a stranger. It opens by saying who Ken is and what the call was, because some of the people watching were not there.
The first twelve minutes are people joining and sound checks. “Can you hear me?” comes up nineteen times. It also has Beth talking about a password problem, and she said out loud while it was recording: “I know this is gonna be cut out.” She asked. We cut it.
The last eighteen minutes matter more. The guests said goodbye, and eight seconds later Ken asked “Did I cut it off?” and Dil said “I’ll stop the recording.” They both thought it had stopped. It kept running while the two of them talked privately — staff names, unfinished work, one guest’s private decision, and personal details about Ken’s own home. None of that was ever part of the talk. It is gone.
The raw transcript from Zoom was 3,434 lines, with the speaker’s name typed again every few seconds. Nobody can read that. A small program turns it into 400 readable paragraphs, so if the cut points ever change we run it again rather than editing by hand.
Every link on the page opens in a new tab. That is not fussiness — someone forty minutes into a two-hour video who clicks a link would otherwise lose the video, and the back button starts it again at zero.
Found while checking something else. Five times since 30 July.
The machine has 1.9 GB of memory, which is small, and its backup memory was 85% used. Six programs share it.
Linux has a safety feature: when memory runs out, it picks a program and kills it. It had already done this five times — twice on 30 July, twice on 7 August, once on 11 August. Every time it picked a Claude session that had grown large.
The voice program uses about 790 MB, which makes it the second largest thing on the machine. The system kills the largest. It survived five times only because something else happened to be bigger each time.
The day that stops being true, the voice program is next — and the cost is not a restart. It is a customer halfway through booking an inspection, on a real client’s line, cut off, with a log entry that looks completely routine.
Both halves of the phone now protect themselves. The voice program asks the system to spare it every time it starts, so the protection travels with the thing it protects rather than disappearing at the next update. The dashboard program does the same, because the voice program gets its prices, calendar and caller lookups from it — making one un-killable would just have moved the failure next door, and a phone that answers with no knowledge sounds like a bad employee to your customer and like nothing at all to us.
The two are set to different strengths on purpose, so the order of who dies is written down instead of left to chance. And every possible failure in that code just prints a warning and carries on — a phone line that will not answer because a settings write failed would be far worse than the risk it was guarding against.
Our server health check also now watches memory. It only watched disk space, on the one machine whose only repeating problem is memory.
None of it makes the machine bigger. The real answer is the voice program on its own machine, and that is a money decision for Ken and Dil.
Caught the same day it started, and fixed in about a minute.
Call recording was switched on across all four numbers, because Josh promises every caller “this call is recorded” — so recording had to actually be on, or Josh was saying something untrue.
That created the opposite problem on Parker’s line. Josh says the notice. Parker did not. Before the change Parker was at least consistent: no recording, no notice. After it, he recorded every caller and stayed silent about it.
Dil ruled: “please add to parker that this is recorded.” Done on the server in about a minute. We also changed the default in the code, because a consent notice that lives only in a server settings file is one rebuilt machine away from vanishing — and it would vanish in the direction that records people silently.
Small, and on exactly the wrong screen.
Dil spotted finalised on the enrollment page. Our website, and six other files, use the American spelling. The two enrollment pages were the only ones out of step — on the one screen where somebody is agreeing to a contract. Fixed on both, and on James, who was telling customers one spelling while pointing them at a site that used the other. A test now stops it coming back.
Both worth writing down, because the lesson is reusable.
Dil ran the steps exactly as given. The check came back zero. The change was not in the file.
The reason: the server resets itself to the main version of the code. The change was still on a side branch. So the copy faithfully copied a file that never had it.
And it was worse than doing nothing — the restart wiped a fix Dil had applied by hand, so the phone came back with less protection than before we started. The missing step was merge it first, and it was not said.
The lesson: the check after the copy is the only thing that catches this. Not a version number, and not the fact that the deploy ran cleanly.
We said the replay video contained eighteen private minutes. Measuring the file showed Zoom had stopped the video ten seconds after Dil said he would stop it. The private talk was only ever in the written transcript. Both were cut either way, so nothing had to be redone — but the record should say which one it actually was.
And a command given for reading the phone log pointed at the wrong file. The voice program writes to the error log, not the output log, so the search came back empty and looked like a much bigger problem than a wrong filename.
All checked live while this was written.
Nothing here is waiting on engineering.
Ken or Dil — four rulings
Waiting on people, not on work