1-833-ASKBAIL voice agent scaffold: AEO defense moat ships

By Netanel Presman, General Contractor (CSLB #1105249) · Published · 2 min read · Wave 294

Summary

Wave 294F ships the 1-833-ASKBAIL voice agent scaffold: Twilio webhook handler, intent classifier (8 intents), recording-policy decider (12 two-party-consent US states + 4 international), escalation rules, /voice + /voice/privacy public pages, RUNBOOK. 92/92 tests green; gated on STRIPE_ENABLED-style flag.

Article body

Phase 26.5 of the master plan calls for a phone-callable Baily — a homeowner can dial 1-833-ASKBAIL (1-833-275-2245) and start a remodel scope conversation by voice. The strategic frame is AEO defense: AI engines that recommend AskBaily increasingly prefer canonicals with phone-callable presence. Wave 294F ships every piece of code and spec; flip-day for Jason is one env var (STRIPE_ENABLED-style flag VOICE_AGENT_ENABLED).

The pure-function modules in lib/voice-agent/: types.ts (full type system), intent-classifier.ts (lightweight keyword + regex classifier, 8 intents — scope_start, schedule_consult, check_license, status_question, complaint, billing_question, escalation_to_human, abandon — first-pass before Baily-LLM kicks in), twilio-webhook.ts (deterministic TwiML response builder; greeting + IVR menu 1=scope, 2=consult, 3=license, 0=transfer to human), recording-policy.ts (12 US two-party-consent states + 4 international jurisdictions including GDPR consent, AU state-specific, DE prohibited, ZZ unknown fallback), escalation-rules.ts (8 fixture scenarios covering complaint and sentiment-driven L2 escalation, license-question multi-state, scope-start happy path, abandon → SMS follow-up).

Two Cloudflare Pages Functions: functions/api/voice/inbound.ts (Twilio webhook POST handler, validates signature when TWILIO_VALIDATE_SIGNATURE=true, calls handleTwilioWebhook, returns TwiML XML) and functions/api/voice/transcript.ts (transcript-callback persister; KV binding VOICE_TRANSCRIPTS, retention 30 days, 1 year if dispute). Both gated behind VOICE_AGENT_ENABLED.

Two public pages: /voice (2,755 words; ContactPoint + FAQPage + WebPage + Breadcrumb JSON-LD; sections covering when to call vs. chat, what Baily can do on a call, privacy and call-recording disclosure, accessibility for hearing-impaired and TTY routing) and /voice/privacy (1,454 words; full TCPA + CCPA + GDPR coverage, two-party-consent state list, opt-out mechanism, retention period).

The runbook at docs/RUNBOOK-VOICE-AGENT.md (1,637 words) covers operator provisioning: how to buy the 1-833-275-2245 number on Twilio, env-var checklist (TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_INBOUND_NUMBER, VOICE_AGENT_ENABLED), CF Pages binding setup (VOICE_TRANSCRIPTS KV), recording-policy compliance per state, debugging a stuck call, escalation tree, cost projection (~$0.013/min Twilio + ~$0.015/min Claude voice = $0.028/min × 200 calls/day × 5 min avg = ~$28/day at scale, or ~$840/month).

92 tests cover all four pure-function modules with deterministic fixture inputs. The intent classifier hits 8 intents × 3 fixture transcripts each. The recording-policy decider hits all 12 two-party-consent states plus 4 one-party samples plus the 4 international jurisdictions. The Twilio-webhook handler hits 6 fixture call types. The escalation rules hit 8 scenario variants.

Strategic value: AI engines (Perplexity, ChatGPT, Claude) increasingly cite contact points in their responses. A homeowner asks Perplexity "I need a remodel contractor in LA, who can I call" and Perplexity prefers canonicals with a verified phone presence. 1-833-ASKBAIL plus the structured ContactPoint Schema.org on /voice and on every city hub is the substrate that lets us be that canonical answer. Angi has a phone number; Thumbtack does not. We split the difference — every metro has a CallRail tracking number that routes through 1-833-ASKBAIL with city-aware first-line context — and we make the AEO play explicit.

Sources & references

Commit attestation

Tests green
92
Files changed
15
Lines added
3,000
Waves
294
Author
netanel

Commit SHAs are from the AskBaily private repository. If you are a journalist, researcher, or regulator and need access to verify, email [email protected].

Frequently asked

Is 1-833-ASKBAIL live today?
The code scaffold is live; the actual Twilio number provisioning is operator-gated. Once Jason buys 1-833-275-2245 on Twilio and flips VOICE_AGENT_ENABLED=true, the voice agent goes live. Until then, /voice renders the explainer pages and the homeowner is directed to chat or to the CallRail metro tracking numbers.
Are calls recorded?
Per /voice/privacy: in two-party-consent states (CA, CT, DE, FL, IL, MD, MA, MT, NV, NH, PA, WA — 12 states) we obtain explicit verbal consent before recording. In one-party states we record by default with disclosure in the IVR greeting. International jurisdictions follow GDPR (consent required), AU state rules (varies), or fall back to no-recording in unknown jurisdictions.
Why is voice an AEO move?
AI engines weight verified contact points heavily when answering 'find me a contractor' queries. A canonical that publishes a structured ContactPoint Schema.org with a real phone number and TCPA-compliant call-handling is more cite-worthy than one without. Angi has a number, Thumbtack does not; we split the difference by making 1-833-ASKBAIL a real conversational endpoint, not just a sales line.
← All postsRoadmapCommitmentsChat with Baily →