Back to work

Founder

Aug 2025 – present

Dohos

A production voice agent that takes live restaurant phone orders.

Public launch September 2026

Live

real inbound and outbound calls

Telnyx

full call lifecycle, own teardown

Fails closed

the model never owns state

Real telephony, deterministic order state, PCI-safe payment boundary. Architecture decisions published, including what is still unproven.

Role
Founder. Sole engineer.
Started
August 2025. Public launch September 2026.
What it does
Answers a restaurant's phone, takes the order, prices it, and submits it
Telephony
Telnyx call control, Pipecat media pipeline
Models
AssemblyAI speech recognition, neural TTS, Vertex Gemini with bounded Groq and Together fallbacks
Data
PostgreSQL via Supabase

The problem

I ran my family's restaurant for four years. The phone is the bottleneck: calls arrive exactly when the kitchen is busiest, every missed one is lost revenue, and the person answering is the person who should be expediting.

The obvious build is speech to text, a language model, text to speech, and a database write. I tried that first and it failed inside a morning. It took orders for things the kitchen does not make and quoted prices that do not exist, because a language model is producing the most plausible next thing to say, and the plausible answer to almost any customer request is yes.

Architecture

The system is split in two, with a hard boundary between them. This is the whole design.

The model ownsDeterministic code owns
Understanding what the caller saidWhat exists on the menu
Handling corrections mid-sentenceWhat it costs
Interruptions and turn-takingWhich combinations are legal
Proposing what should changeWhether a change is applied
Phrasing the responseWhether an order was accepted

The model proposes typed edits against opaque references. It cannot name a menu item by writing its name, invent an identity, or assert a price. Application code resolves those references against the real catalog, validates the operation, prices it, and persists it.

A rule the model is told to follow is a suggestion. A rule it cannot express is a guarantee.

Design decisions

  • Unsupported configuration fails closed rather than being guessed. The agent will refuse things a human would have allowed, and that is the correct trade: a refusal is recoverable, a silently wrong order is not.
  • Unpriced preparation notes such as "no mayo" stay attached to the line and route the order to manager review, instead of being silently dropped or charged as a modifier.
  • Any material change to an order invalidates prior confirmation, so nobody confirms one total and receives another.
  • Partial speech can trigger a lookup but can never authorise a write. Reads are free to be wrong; writes are not.
  • An interruption stops the agent speaking but does not by itself cancel a business action. Treating those as one event loses orders.
  • Catalog data defines configuration, including defaults, presets, amounts, half-and-half scopes and nested options. A new restaurant is a data-entry job, not a code change.
  • Card data is never collected, logged, or transmitted. Card processing stays disabled until a PCI-contained payment leg is proven; cash and pickup work end to end.
  • Recording and transcript persistence require an explicit yes or no before anything is stored.

Telephony, which is most of the real work

  • Full call lifecycle on Telnyx: initiation, ring, answer, media, playback, hangup, timeout, and provider failure
  • Webhook signature verification and idempotent handling of duplicate event delivery
  • Teardown that runs on success, failure, cancellation, provider error and shutdown alike, with leaked-session detection after every call
  • Both inbound and outbound, sharing one deterministic core and one state model

Status

Proven on real inbound and outbound calls rather than tests alone, including a half-and-half order priced and read back correctly through live telephony with no food-specific code path. Deployment was held uncertified until real calls passed audio, transcript, deterministic-state and teardown checks, because tests do not certify voice.

This one is entirely mine. No NDA, no restrictions. I can walk through any part of the codebase, including the parts I got wrong first.

Dohos voice ordering — live call handling and order state.

I also wrote about this one

The case study is what was built. The essay is what happened, and what I would do differently.

The model should never own business state

Happy to go deeper on any of this.

Including the parts I got wrong the first time, which are usually the more useful conversation.