Build in public
Consent-based calling hours, lead intake moves over, and nothing shipped
Today was short: 1 working session with a coding agent, 2 prompts typed, about 1 hour of active work. It ended with 9 commits and 0 deploys. Everything below is committed but not live yet.
Calling rules that depend on consent
The biggest change was to when the voice agent is allowed to call. Before today it kept to fixed hours. Now it can call a new lead at any hour, but only when two conditions hold:
- the lead has expressly agreed to being called that way
- the call happens within a limited window after their enquiry
Getting the behaviour right was harder than getting the code right. "Call whenever" is a risky default for a sales agent, and I don't want it to be a default at all. The exception only exists because the lead asked for it, and it only lasts for a short time. If someone fills in a form late at night and says yes, call me now, a quick callback makes sense. A week later the same consent shouldn't let us ring them at an odd hour. So the rule is consent plus recency, never just one of them.
Moving lead intake onto the production codebase
I've started moving the initial phase of lead intake onto the production codebase. That covers how leads come in, how call outcomes get recorded and how notifications go out. Up to now some of this sat apart from the main system, and that's fine for testing but awkward to keep running.
Alongside that, I extended the background worker. It now picks up enquiries that arrive from the public intake form and retries any that fail. Retries sound boring, but a lead that silently drops because of one failed step is a lead nobody calls back. For a product built on fast responses, that's the worst failure there is.
Lead sources
I added lead-source management to the backend and a lead sources page to the web app. Businesses need to see where enquiries come from, and the system needs to know so it can treat them properly. I built this with help from subagents: one on the backend side, one on the page. Splitting it up worked well because the two pieces had a clear boundary between them.
Catching the codebase up with reality
The last piece was housekeeping. I brought the tests, scripts and prompts in the codebase into line with what's already running live. Over time they had drifted apart. Tests checked behaviour that had since changed, and prompts in the codebase didn't match the ones in use. That kind of drift makes every later change riskier, because you can't trust what the tests tell you.
What I learned
- Rules about when to contact people are product decisions first. The code is easy once the rule is clear.
- Retries belong in intake from day one, not as a later fix.
- Letting the codebase drift away from what's live costs you quietly until it suddenly doesn't.
None of this is deployed yet. It's committed and waiting.
Written from that day's build log: the work sessions, commits and deploys recorded for it.