Inspiration

On the night of the Eaton Fire in January 2025, Anthony Mitchell, 68, was at home in west Altadena with his son Justin, 35. Anthony used a wheelchair. Justin has cerebral palsy. Anthony called 911 at 6:03am and again at 6:14. The dispatcher told him "They're on their way." Nobody came. Both men died in their home. LA County's paratransit service later said its vans were ready by 4am. Nobody called it.

The vehicles existed. What failed was coordination. A UN survey of about 6,000 people with disabilities found that only 1 in 5 could evacuate right away without difficulty. During Hurricane Harvey, fewer than 5% of the people on Texas's disability registry were contacted, because nobody had the staff to call through the list in time.

We took that problem to Palo Alto Fire Stations 1 and 6. "We have four dispatchers that sit in the room," one firefighter told us. "You can only answer so many calls." Standard Response is our answer.

What it does

Standard Response is an evacuation coordination system: it calls every home in a warning zone, triages who can't get out, routes accessible vehicles and neighbors to them, and keeps every promise to a resident true while the plan changes.

Every home in the warning zone, sorted by the calls: red needs help, orange can help a neighbor, green has left, grey not reached yet

A simulated night over the real map of west Altadena. Standard Response has called every home inside the warning zone (white outline) while the fire (top right) moves in. The 1,003 red homes are the ones dispatch has to reach.

  • Ready check: Before any disaster, the agent calls each household (or they sign up at /ready) and records who needs help and which room they sleep in. A household that would need a ride is paired with the nearest neighbor within 900 m who said they'd drive.
  • Warning calls: A dispatcher draws the zone on the rescue map, or our public Apify Actor starts the calls when a California county issues a warning. The agent calls every home at once and reads each answer back for correction. Life threats jump to the top of the call floor.
  • Neighbors: On every call, the agent asks whether anyone else on the street might not be able to leave, and matches the names people give to homes on file. It calls a resident's named helper first. If nobody is named, it calls the nearest neighbor with a car and says what the pickup takes before they agree. It only asks neighbors the fire reaches first, so helping someone always means driving away from the fire. The ride request stays open the whole time, so a neighbor is a faster first try and never a reason to hold a van.
  • Dispatch: Our optimizer matches each request to a vehicle with the right seats, wheelchair space and crew. A dispatcher approves with one click, and drivers accept on their own phones.
  • Callback: The moment a driver accepts, the resident gets a call with the driver's name and ETA. A home that never answers is called again, texted, then sent to a field crew.

The call floor mid-call: every home's status on the left, and the agent's live transcript with the record it fills in on the right

The honesty rule: The agent never says help is coming until a driver has accepted. Code enforces that, not the prompt.

The agent's constitution: We wrote the call agent 11 principles, taken from how 911 call-takers and crisis lines work, and set them beside Claude's constitution. Claude's constitution asks it never to create a false impression. Ours turns that into one hard rule: never imply help is coming before a driver accepts. The same principles go into every turn's prompt and into the 373 situations Moss retrieves. The Opus judge grades every exam call against them too.

Try it at our table: Scan the QR code, claim a house on the map, and Standard Response calls your phone.

How we built it

How it works: warning zone, call, record, request, plan, dispatcher approval, driver acceptance, then the callback

Twilio carries every call, Cartesia hears and speaks it, Claude reads each turn and Moss supplies the agency's approved answers. One Convex database connects everything, so no service calls another directly. Each sponsor's part is described below.

  • Dispatch and simulation: Our adaptive large neighborhood search (ALNS) runs over an OSMnx road graph of Altadena, with OR-Tools and a greedy heuristic as baselines. The night simulator runs on SimPy. The voice server runs on Fly.io and the dispatch solver on DigitalOcean.

The dispatch math

Every request has a deadline 10 minutes before fire is expected at the home. A rider who boards by the deadline counts zero expected deaths. After the deadline, the count climbs linearly to the household's full risk 600 seconds later. The optimizer minimizes

sum over requests (10^7 x expected deaths + need weight x arrival time) + sum over vehicles (driving time)

subject to each vehicle's seats, wheelchair spaces and stretcher spaces. One expected death outweighs any amount of driving, and the need-weighted waiting term spreads riders across the fleet. The search (dispatch/alns.py) tears plans apart and rebuilds them under simulated annealing. It never moves a run a driver has accepted. On our fastest simulated fire it completes a median of 6 more on-time pickups than the greedy heuristic over 100 seeds.

How we use our sponsors

  • Anthropic: Claude Haiku 5.5 reads every turn of every call and turns what a resident says into record fields, corrections included. In English and Spanish, the two languages fluent speakers reviewed, it also words the agent's short replies. In other languages the agent speaks only fixed lines. Claude Sonnet 5.5 ranks which homes to call first. Claude Opus 5.5 grades every practice call in our voice exam and flags lines that imply help is coming. Code decides what the agent may promise, not Claude. (interpreter, honesty guard, judge)
  • Cartesia: Voice is the product, because the people we call often can't use an app but can answer a landline. Every call runs through Cartesia in both directions on Twilio's raw 8 kHz phone audio. Ink-2 hears English, Spanish, French, Hindi and Japanese in one stream and decides when the caller has finished. Ink-whisper covers Mandarin, Korean, Vietnamese, Tagalog and Russian. Sonic speaks each turn with a native voice in each language and stops the moment the caller talks over it. Sonic's delivery also changes as the fire gets closer: speed rises from 1.0 to 1.25, volume from 1.0 to 1.4, and the English emotion moves from calm to determined. A caller who is hard of hearing gets slower speech at full volume. (voice/phone/cartesia.ts, voice/phone/delivery.ts)
  • Moss: Before Claude reads each turn, Moss pulls the closest call-taking principles and practice-call moments into the prompt, filtered by hazard and language, within an 80 ms budget. When a caller asks a policy question ("Can I go back in for my cat?"), Claude restates it in English and Moss matches it to the agency's approved answer, which the caller hears word for word in their language. Below a 0.7 match score, the agent says it doesn't know. Across 66 test questions, 61 got the right answer with Moss, including 14 of 18 safety answers, and no dangerous question got an ordinary answer. Without Moss, none of the 54 questions with an approved answer got one. The median lookup took 5 ms. (voice/knowledge/moss.ts, results)
  • Convex: Convex is the only way our services talk to each other. The voice server subscribes to the callback queue with onUpdate, so the moment a driver taps Accept, the rider's callback starts with no polling. An accept is one mutation that checks the offer's plan version, and a scheduled function expires the offer after two minutes. Each real rider's retry ladder is a durable Convex Workflow. Triggers update two Aggregate components in the same transaction as each household write, so the call floor's counts are never off. HTTP actions take warnings from our Apify Actor and status from the voice agents, and a daily cron deletes real riders' data 72 hours after an incident closes. (convex/)
  • Apify: We built and published the California evacuation status Actor on the Apify Store. It merges Cal OES and CAL FIRE evacuation zones, CAL FIRE incidents and Caltrans closures from all 12 districts into one record shape. The Actor remembers what it has sent in a key-value store, so each fresh zone reaches our Convex endpoint once per status change. A zone with riders inside starts the calls. Stale zones are never sent: one platform run returned 9 zones that were all old orders, so no one got a false warning call. When Caltrans closes one of our streets, the next plan routes vans around it. (apify/)
  • Mana: We gave Mana the five rules our accept flow must keep and asked it to break them the way a driver tapping fast on a bad connection would. In about nine minutes it read our Convex code, set up a test harness the repo didn't have, and wrote 29 tests. Five failed, exposing three bugs our own red-team runs had missed. A repeated Accept was logged as a stale accept. A driver accepting stops out of order could put a pickup ahead of one already accepted. A late event from the call server could undo a callback the rider had already heard. Mana opened PR #1 with a fix for each (Mana chat). Mana found all three bugs 16 to 23 hours before our own fixes for two of them landed on main. We kept those two fixes and merged Mana's guard for the repeated Accept. All 29 tests now run on main with npm run test:offers.

Challenges we ran into

  • Keeping promises while the plan changes: Roads close after a driver accepts, and drivers tap Accept on offers a newer plan replaced. Our Convex stress test fires conflicting writes from dozens of clients at once at a throwaway Convex backend. Its first runs caught four race conditions, and we fixed all four. Mana then wrote 29 adversarial tests against the same flow and found three more bugs, listed under Mana above.
  • Where the agent still fails: Our voice exam, scored like the CritiCall 911 hiring test, still misses its 0.95 bar (the best of three runs scored 0.937). When a caller insists a driver is already coming, only 6 of 64 test calls pass, mostly because the agent skips the status line. Armenian and Farsi callers reached a person within three turns in only 8 of 32 calls. Every result is in the repo's README.
  • Catching soft promises: Claude kept reaching for comforting lines like "we're working on getting help to you." A voice exam modeled on CritiCall, the 911 dispatcher hiring test, caught each one, and every phrase went into the code guard.
  • Rebuilding a whole night: We placed more than 3,300 timestamped UL FSRI records, CAL FIRE damage inspections and LA County's evacuation times on the map, then simulated all 11,855 west-side households.

Accomplishments that we're proud of

On a simulation of the real Eaton Fire night, Standard Response got 16 times as many at-risk households out on time as today's process. On time means everyone is aboard at least 10 minutes before fire is reported near the home.

Calls start Vehicles With Standard Response Today's process (modeled)
10:50pm, first fire west of Lake Ave 25 641 of 662 (97%) 39 of 662 (6%)
3:25am, the real evacuation order 50 356 of 662 (54%), 81% of the 442 still reachable 43 of 662 (6%)

Each figure is the median of five simulated runs. Twenty-five vehicles is under 2% of AccessLA's paratransit fleet. By the real 3:25am order, fire had already been reported near 220 of the homes, so no fleet could get more than 442 out.

The right-hand column is our model of today's process, not the record. In it, 55% of the people who need a ride call 911 about 20 minutes before the fire reaches them. The nearest free unit then takes one household per trip. Both columns assume free-flow traffic and callers who report their needs correctly. Every assumption is listed in data/eaton/night-sim-results.json.

  • Documented requests: Sixteen households west of Lake asked for help that night. Standard Response would have reached 13 of them before they had to ask.
  • Rock-solid promises: In our stress test, 25 ride offers were each accepted by 12 phones at the same instant, and exactly one accept won every time.
  • What our evals show: Across 200 simulated callers in English and Spanish, the agent got every address right. A Claude Opus grader read 2,046 of its lines and found implied promises in 9.
  • Firefighters' verdict: "Honestly, this one is probably the most at the cutting edge of what we're already doing and what could be helpful." (Palo Alto Fire Station 1)

What we learned

  • The shortage was information, not vehicles: With the same 25 vehicles, 39 households got out on time when people had to reach 911 themselves. When Standard Response called every home first, 641 did.
  • Promises belong in code: Claude reached for the same comfort 911 gave Anthony Mitchell, so every sentence about a ride is now a template code picks. A banned-phrase list caught only 10 of 20 promises it had never seen, while an Opus grader caught all 20.
  • The hardest bugs weren't in the AI: Two phones tapping Accept at once can break a promise faster than any model. Single-transaction mutations fixed all four races we found.
  • Firefighters know what no form asks: "Wheelchair" can mean a 400-pound power chair, crews need a household's language before they knock, and volunteers must drive away from the fire. We shipped every fix the same day.

FAQ

  • Does it replace 911? No. It makes the calls 911 has no staff to make. When a caller reports flames or a medical emergency, the home jumps to the top of the dispatcher's list and the agent tells the caller to call 911.
  • Who runs it? A paratransit agency like LA County's Access Services, on its own rider list. Its dispatcher loads riders from a CSV, draws the warning zone on the rescue map and approves every vehicle plan, and nothing about a ride reaches a resident until a driver accepts.
  • Is it legal for an AI to call people? Since 2024 the FCC has treated AI-generated voices as artificial voices under the TCPA, the federal law on automated calls. An agency calling its own riders about an emergency falls under that law's emergency exception. Agency counsel would confirm this before a real deployment.
  • Isn't the simulator grading its own homework? Its inputs are real records: a census population reweighted to real totals, CAL FIRE's damage inspections and UL FSRI's fire timeline. It tests a dispatch policy against that night, not a prediction of who would have lived. Its assumptions are published with the results.
  • Would it have saved Anthony and Justin Mitchell? We can't say that. The reporting shows vans were ready and nobody called them. Standard Response makes that call.

What's next for Standard Response

  • Drills: A tabletop drill with Palo Alto Stations 1 and 6, then a replay of a night like the Eaton Fire with a paratransit agency's own dispatchers.
  • Shadow mode, then a pilot: Run beside real dispatchers during real warnings, then pilot on an agency's rider list under its authority, deleting rider data 72 hours after each incident closes.
  • Beyond wildfire: Calls and dispatch already work the same for floods, earthquakes and hurricanes. Only the hazard model changes.

Every reverse-911 warning today is a one-way broadcast. We want the next one to be a conversation.

Built With

Share this project:

Updates

Submission history