An engineering tour, told one text at a time
Sous is a meal-planning service you talk to over text message. There is no app to install and no feed to check — it plans your family's week, writes your grocery list, and checks in on Wednesday, all in one SMS thread. This page walks through what's underneath: the machinery between the moment you hit send and the moment Sous texts back.
Part 01 · The wire
When you text Sous, Twilio — the carrier-grade SMS provider — delivers your message to a single webhook in the Sous application, a Next.js app running on Vercel. In the first few milliseconds, the request is rate-limited, cryptographically verified as genuinely coming from Twilio, and schema-validated. Carrier compliance keywords like STOP and HELP are handled before any AI ever sees a word.
Sous identifies you by your phone number, stored in strict E.164 form so lookup is an exact match. Then comes idempotency: carriers retry webhook deliveries, so duplicates are caught twice over — once in application code and once at the database — and quietly ignored. Your text is logged to the conversation thread before anything else happens to it.
Then the part most SMS products get wrong: Twilio only waits about fifteen seconds for a webhook to respond, but a real conversational turn — reasoning about your week, editing a plan, refreshing a grocery list — can take longer. So Sous acknowledges the carrier in milliseconds and runs the actual turn in the background, on durable infrastructure.
Every household gets its own serialized queue lane on Inngest, a durable-execution platform: turns run one at a time in order, and a crashed step retries automatically. The queue itself never sees your data — events carry only opaque IDs, and message content is re-read from Sous's own Postgres inside the step (anything that must travel rides encrypted). And if the queue is ever unavailable, Sous degrades gracefully rather than going silent. The rule is written into the source: a queue outage may never silence Sous.
SMS has physics. A single em-dash or curly quote silently flips a message from the standard encoding (160 characters per segment) to a wide one (70 per segment), more than doubling carrier cost and splitting texts unpredictably. So every outbound message passes through one normalization choke point: markdown stripped, typographic punctuation transliterated, emoji removed except where they're the point (the calendar itinerary). Multi-part replies are paced from real carrier throughput — the delay before each part is computed from the segment count of the part before it — so long messages arrive in order instead of scrambled. And every send is written to a delivery ledger that Twilio's status callbacks later confirm, message by message: Sous knows the difference between sent and delivered.
Part 02 · The brain
Every message — from the phone or the web — flows into a single function: the conversation engine. It walks a routing ladder of roughly ten structured intents before anything freeform: are you answering the weekly calendar review? Confirming a proposed plan? Making a mid-week correction? Asking for the grocery list, tonight's menu, a recipe? Each of these is a dedicated, mostly deterministic path. Only when nothing structured matches does the message fall through to open conversation.
As you talk, a fast extraction pass quietly reads your messages for durable facts — a new allergy, a kid's age, "pizza Fridays are sacred" — and files them into your household's structured profile, with careful rules about what's permanent versus what's just about this week. Sous learns from ordinary conversation, and everything it learns is visible and editable on your Preferences page. It also keeps short notes on how your household likes to communicate, distilled from past conversations, so replies match your tone.
Replies are grounded, never improvised: the model is handed the actual stored plan, the confirmed week outline, your preferences, and the correct local date and time in your timezone. When you ask "what's Thursday again?", the answer is read from the database — the model is never asked to remember.
The engine keeps a per-turn ledger of every database write it actually made — a preference saved, a slot edited, a grocery list recalculated. Before any reply is sent, a deterministic gate checks the model's prose against that ledger. If the text claims work the ledger can't back — "Done, I've updated your list!" when nothing changed — the claim is replaced with honest copy before it ever reaches your phone. A prompt is a plea; this is a gate.
A consistent design rule runs through the engine: AI makes judgment calls, deterministic code produces the artifacts. The grocery list you receive is never improvised in the moment — a tiny classifier decides whether you asked for it, and the text renders from stored rows. Models help build those rows (estimating purchase quantities, proposing merges), but deterministic code verifies every merge, proves nothing was lost or invented, and does all the unit math. Recipe texts are answered from the stored plan so they can't drift. Calendar-conflict messages are assembled from templates, because a model asked to editorialize about someone's calendar will eventually say something alarming about a medical appointment.
Plan edits are routed by a pure, exhaustively tested module built around an explicit cost asymmetry: a surgical edit regenerates one slot and leaves every other day byte-identical, while a full rework re-runs the planner. Ambiguous requests deliberately route surgical — a wrong surgical edit costs one recovery message; a wrong rework burns a full plan generation. And every Sous-initiated rewrite snapshots the previous plan first, so "go back to what we had" is a deterministic one-step restore, never an AI reconstruction.
Part 03 · Two surfaces
Sous has a full web dashboard — but it isn't a second product. The SMS webhook and the web chat call literally the same engine function, and every message from both surfaces lands in one thread per person, tagged only with the channel it arrived on. Start a thought on your phone in the checkout line, finish it at your desk; the web chat shows your texts inline, marked "via text."
The loop closes in both directions. If you plan in the browser, Sous waits until the web conversation has been quiet for a while, then texts a short recap to your phone — watermarked so nothing repeats, and guarded so a recap can never assert a change that didn't actually happen.
The dashboard itself is a live window onto the same data your texts are built from: Your Week with every meal on an editable card (drag a meal to another day; the plan updates for everyone), a toggle that overlays your real calendar onto the menu, per-person ratings, an aisle-organized grocery list, a distraction-free recipe companion scaled to your household's exact serving count, and a Preferences page that shows everything Sous has learned in conversation — human-editable, because the AI's memory should be correctable.
Sign-in is passwordless: Google, Microsoft, Apple, or an emailed magic link. Onboarding verifies your phone with a one-time code, captures your timezone silently from the browser, and connects your calendar read-only if you choose — then hands you off to the conversation, where everything else happens.
Part 04 · The rhythm
The week has a rhythm, and Sous initiates every beat of it. "Sunday morning" means 9 a.m. where you live, not 9 a.m. on a server — a rule enforced all the way down: every wall-clock helper in the codebase requires the household's timezone as its first argument, so a Pacific household getting a 3 a.m. text is a compile error, not a runtime surprise.
At your planning moment, Sous reads your merged calendars — Google Calendar via read-only OAuth, Outlook, or any subscribable ICS link, with real recurring-event expansion — and classifies each day of the coming week: normal, busy, away, dinner out, solo-parent night. A week-long "Shore Week" banner sets the scene without cancelling dinner; a single-day wedding does. Sous texts you that read of the week as a friendly itinerary and asks you to confirm, because calendars are never 100% accurate. If you go quiet, it nudges once — the clock resets whenever you reply, because a person mid-correction hasn't vanished — and after a day it proceeds on its own, so a plan always arrives. Quiet hours are enforced in your local timezone: Sous does not text at night.
Delivery is proposal-first. Before you see a single dish, Sous names the batch-cook anchor — the meal whose components feed two other dinners that week — and asks which day suits cooking it. The full menu releases on your yes; the grocery list follows on your thumbs-up. Refinement happens before you're attached to a menu, and timed backstops make sure the question is never a blocker. From the list, one tap builds a shoppable Instacart cart from whatever you haven't checked off.
Wednesday evening, in your local window, Sous asks about a specific dinner it knows you cooked — in two-adult households, each person gets asked about a different night, and whoever was down to cook gets an effort question, capped so it never feels like an interrogation. Just before that check-in, Sous silently diffs your live calendar against the snapshot the week was planned around. If something new landed on a cooking night, it raises the conflict only after you've answered — or the next morning if you never do.
The conflict detector's rules are mostly about not texting: at most one conflict message per day, each conflicting day mentioned once ever, nothing early in the morning, silence if the plan was already reworked today. Conflicts are never stored — every pass re-detects against live data, so a conflict you quietly resolved simply stops being mentioned.
Under it all, three independent scheduler engines, on separate infrastructure, fire on their own clocks against the same pass. They can all run at once without double-texting anyone, because every state transition in the weekly loop is an idempotent compare-and-swap: extra runs are free, and an outage of any one engine is covered by the other two. A pure, property-tested "next-wake computer" calculates the earliest instant each household could possibly be owed work, so at scale Sous wakes exactly who's due.
Part 05 · The library
Everything a user experiences rests on one Postgres database — 27 models under a fully versioned migration history, hosted on Supabase and accessed through Prisma. The design principle throughout: store facts with provenance, and never let the AI be the only safeguard between a stated allergy and a plate.
The meals themselves draw on an owned recipe corpus, ingested from professionally tested recipe cards across multiple publishers. Every recipe carries its source, its ingredients and steps as structured rows, batchable components with food-safety metadata — safe internal temperatures, fridge life, reheat guidance — and a lifecycle: recipes enter through an automated quality gate, get arranged into real dinner plans, and are promoted or retired purely by what happens at the table: ratings, swaps, and check-in sentiment.
Households are first-class too: two adult logins per household, partner invites whose link tokens are stored only as hashes — and the link alone is never enough, because the joiner must also verify the invited phone number. Each member controls only their own notification switches; muting your partner's texts is structurally impossible, not merely hidden in the UI.
Part 06 · Trust
An AI that plans your family's dinners holds two kinds of trust: what it cooks and what it says. Sous puts an independent, deterministic gauntlet behind each.
Equal engineering went into not over-alarming. The allergen parser grades severity from how people actually talk — "my son is allergic to peanuts" is treated as a hard constraint the assertion checks every plan against; "we're trying to cut back on dairy" doesn't strip a week of dinners — and its false-positive fixes are documented in the code: coconut milk is not dairy, peanut-free granola is not peanuts, butter lettuce is not butter. A safety feature that cries wolf gets switched off; this one is engineered not to.
Appendix · The roster
One deliberately boring foundation, so the interesting engineering can live in the product.