Poppy Voice OS
One number, one brain, two rings
+1 (484) 990-2798 is Poppy's line. Calls terminate on LiveKit Cloud (SIP trunk and dispatch rule), a LiveKit agent answers with an ElevenLabs voice, and every skill on the call is a database row served through poppy-mcp — the same brain, memory, board, and audit spine as the rest of PURE. This page is the standing capability map: what is LIVE today, what is STAGED in the repo waiting to be lit, and what stays GATED on a human until Mike widens the gate.
1 · The stack
| Layer | What runs there | State |
|---|---|---|
| Telephony | LiveKit Cloud (Pro): SIP inbound trunk + dispatch rule for the Poppy line; outbound SIP trunk is the one missing piece of ring 2 (ticket VOS-2). Meeting dial-in codes and mid-call transfer already ride the same rails. | LIVE |
| Agent runtime | LiveKit Agents workers. Inbound: puremeeting (console-generated today; code twin agent_puremeeting.py adds the audible persona switch + warm transfer). Outbound: pureoutbound (agent_outbound.py, new). | LIVE STAGED |
| Voice | ElevenLabs Pro (1.6M chars/mo): Flash v2.5 realtime TTS, model router (config.voice_models), 34 voices incl. Mike + Shana instant clones and the persona ladder, all resolved live from config.voice_tts_map — zero-redeploy voice swaps. | LIVE |
| Hearing | AssemblyAI universal-3-5-pro via LiveKit Inference, multilingual turn detection, ai-coustics noise cancellation, answering-machine detection on outbound. | LIVE |
| Brain | The Poppy chat spine on Supabase Edge (model router to Claude, adaptive thinking, prompt cache) plus 29 registered phone skills through the pure_tool dispatcher. Prompts, greeting, voicemail script: all DB rows. | LIVE |
| Record | Every call: end-of-call summary (poppy-call-summary), call intelligence (sentiment, talk/listen, objections, coaching), audit rows, board tickets. Recordings via egress: follow-on VOS-7. | LIVE |
2 · Ring 1 — inbound (what a caller gets today)
- Instant answer — literal greeting with zero dead air (spoken before any model turn), office ambience under the call.
- Open-line skills — listing search by plain English, home-showing booking, follow-up tickets with branded one-tap email links, meeting dial-in by 6-digit code, license/knowledge questions.
- Staff ladder — spoken 6-digit PIN + caller-ID second factor, then the security-level ladder: level moves email a one-tap approval, the persona changes name and voice (Lina, Iron Mike, Ann Marie) mid-call via set_voice.
- My-schedule, person-360, deal lookups — verified callers only, voucher-scoped.
- Warm transfer to a human STAGED — transfer_caller hands the live SIP leg to whoever config.voice_transfer_map says is on duty (SIP REFER, dial tone while it rings). Ships with an empty map; filling it is VOS-5 GATED (staff cells are Mike's call).
- Voice SIP admin — superadmins can list/patch dispatch rules and trunks by talking to Poppy (sip_admin).
3 · Ring 2 — outbound (Poppy places the call) STAGED
The new ring. Everything is in the repo and proven against a scratch database; it ships dark — the master switch is off until Mike flips it after the supervised first campaign (VOS-6).
Call kinds v1
- lead_followup — new lead came in, Poppy calls back inside the golden window, qualifies, books the showing on the spot.
- showing_reminder — tomorrow's showings get a human-sounding confirmation call, reschedules captured as tickets.
- ticket_callback — a ticket resolved? Poppy closes the loop with the client by phone.
- callback_request — "have someone call me" from any surface becomes a queued call with the context attached.
- custom — anything staff or an approved Poppy plan enqueues, purpose stated in one line.
On the call
- First sentence identifies Poppy as an AI assistant calling for Acquisto Real Estate and states the reason — then asks if now is a good time.
- Tools: call_result (outcome logging), do_not_call (instant DNC + polite exit), create_ticket, end-call. Same summary + call-intel pipeline as inbound.
- Machine answer: the templated voicemail (design.poppy_voicemail_script) in Poppy's voice, callback number read digit-by-digit.
4 · The voice fabric (ElevenLabs Pro, already live)
Working today
- Model router: realtime Flash v2.5 on calls, v3 for quality narration, turbo for balance, STS for speech-to-speech — one DB key.
- Persona ladder + global default (Ginger), Mike and Shana consented clones, candidate personas with staff audition + sign-off flow.
- Pronunciation lexicon for realtor terms (pure-pronunciation.pls).
- Poppy MCP tools: voice.elevenlabs_tts (open), voice.elevenlabs_switch and clone_lab (approval-gated).
Queued in EL-MAX (board program)
- Professional clone of Mike (PVC slot is free), Spanish/multilingual narration via v3's 74 languages.
- Listing-narration engine and audio-native daily briefs, reports, and emails.
- STS content pipeline, sound effects for Pure Videos.
- Usage/cost governance before voice is sold to 135K MLS users (Enterprise-tier flag).
5 · Safety rails (why this cannot run away)
- Master kill switch — config.voice_outbound_enabled, shipped false, checked at claim and again at dial time; flipping it is a single DB write, no deploy.
- Consent is a required field — no enqueue without a consent note; cold telemarketing is out of scope by design.
- Call window — outbound dials only 9a–8p Central (TCPA-conservative), tunable in config.voice_call_window.
- Do-not-call list — honored at enqueue and at claim; the on-call do_not_call tool adds a number the moment a person asks.
- Caps — daily call cap (default 25) and per-number attempt cap (2, with 2-hour backoff) enforced in the claim RPC.
- Human gates — voice.call_enqueue is approval-gated; the first campaign is supervised (VOS-6); transfer numbers are Mike-provided (VOS-5).
- Honest identification — Poppy says she is an AI assistant in the first sentence of every outbound call.
- Full audit — every enqueue, DNC add, and outcome writes audit rows; summaries and call-intel land on the record like inbound calls.
6 · Light-up order (the VOICE-OS board program)
| Ticket | Step | Effort | Gate |
|---|---|---|---|
| VOS-1 | Apply the staged pack (tables, RPCs, seeds) and mint the dialer token | S | ready |
| VOS-2 | Create the LiveKit outbound SIP trunk (Poppy line as caller ID) | S | ready |
| VOS-3 | Deploy pureoutbound agent to LiveKit Cloud | M | ready |
| VOS-4 | Deploy pure-voice-dialer + every-minute cron | S | ready |
| VOS-5 | Fill the transfer map, live transfer test on the inbound line | S | MIKE |
| VOS-6 | First supervised campaign: 5 consented calls, Mike listening, then set standing posture | M | MIKE |
| VOS-7 | Call recordings via egress to private storage | M | ready |
Staged pack: db/2026-07-22_1140_poppy-voice-os-staged.sql · agents: poppy-agent/ · dialer: supabase/functions/pure-voice-dialer · runbook: poppy-agent/DEPLOY-voice-os.md