0145 — An emergency always escalates, whatever we know about the location

Context

On 2026-10-18 a Western Slope resident called about a garbage disposal leaking a lot of water. The address she gave was a real unit in one of the company's buildings, but the unit's street differs from the building's, and the voice address lookup read only building addresses (fixed for that one lookup by #20946). With no confirmed home, the prompt allowed only a callback note. The emergency tool was never called, no on-call call, text or email went out, and the team got a plain " — callback" email. The after-call classifier then tried to open a work order, was refused for "which home unclear", and did not start the on-call chain either. The company's maintenance call center (MCC, its answering service) received the call only because Clara forwarded it. Numbers come from the read-only scoping in the plan (prod reads, 2026-10-19).

Production logs (2026-10-19) show the after-call chain never ran because the classifier did not return "emergency". Why is unknown. Replaying the exact production input with Western Slope's emergency list gives "emergency" 20 out of 20, and the list loads correctly against production with the same arguments, so an earlier theory that the list never reached the classifier was retracted. What is left is model variance or something unobserved, and it cannot be settled because the verdict was never recorded. That is why decision 5 (a server-side content check that does not depend on the cause) comes right after the after-call start, and why decisions 6 and 7 require the verdict, the list lookup and every failed read to be recorded and alarmed.

The location gate made one failure (an address we could not place) silence a second, unrelated one (a leak nobody was told about). Western Slope's property manager expected an emergency response.

Decision

  1. Location is a field on the alert, not a gate. If the content is an emergency (the company's list, or the built-in life-safety rules), the emergency path runs: the on-call chain starts and the emergency notices go out, whether the location is confirmed, a best guess, or unknown. The chain must be startable from the company and the dialled line's phone number alone, with no property id. Today three places require one (voice-postcall-intake.ts:508, handle-escalate-to-human.ts:371, and the hunt ticket's propertyId in emergency-alert-chain.ts:667); each is changed to fall back to the line's company.
  2. Recognized callers are confirmed, never asked. When the caller's unit is known (from the phone, or the line's building has one unit), Clara confirms it (This is at your unit, <unit>?) and does not ask for an address. If the caller names a different place, nothing is blocked. The work order goes to the unit on file with a note, "caller said it's at X", and the alert carries both the unit on file and the place the caller named, so the technician is never sent to only one of two doors.
  3. Unrecognized callers are asked once, then given a best guess. Order: phone match, name plus street, closest home from the address index (ADR-0147), the line's building. A best guess is never a reason to wait. A "likely" result with two candidate homes never files a work order on its own: the alert carries both, and the work order waits for a person or a confirmed answer.
  4. Every alert states its location confidence. Each alert carries locationConfirmed, the unit as "probably, not confirmed" when unconfirmed, the address as the caller said it, and why we think so. The SMS, email, call script and #emergency post all render it. The alert goes to the same on-call chain as any emergency (live on-call first where the company has it, then the saved list). An unconfirmed location adds no extra recipients and removes none.
  5. The server checks content, not only the voice model's rating. Note text from calls, texts and emails runs through the classifier's emergency rules (the classifier, never a keyword list: a keyword rule paged on a water bill), and an emergency verdict starts the chain even when the model chose a lower urgency.
  6. Every fail-closed read on the chain path alarms. The company-switch read (company-switch.ts:57-66) and the will-it-ring check (emergency-alert-chain.ts:155) fail closed with only a log warning. The emergency-list read (emergency-definition-read.ts) has three branches: its catch at :114 warns; the success path where no list resolves (:112, returning null) logs nothing; and the outlook catch at :118 is swallowed. The quiet branches are the ones to cover. Each read that stops or weakens a chain must raise the same ops alarm as "nobody was called" (alertOpsNobodyCalled), and the verdict and whether the company's list resolved are recorded on the dispatch log. A quiet failure on this path is a missed emergency.
  7. A missed-emergency detector runs continuously. An emergency verdict, or a note marked urgent, with no chain start within a few minutes raises an alarm. Zero emergency notices across every real company for 60 days should have been red; this makes it red.
  8. Any active leak is an emergency. An active leak is water escaping from plumbing, a fixture, an appliance or the roof that is still running, or is pooling or spreading onto a floor, ceiling or wall, or that the caller can't stop. It is routine only when both hold: the water is fully caught (a bucket, a pan) and is not spreading, or the supply is shut off and it has stopped. A caller who says "a lot of water" is never asked to justify it before the chain starts.
  9. Team emails say how urgent it is and what was already done, in the plain staff-email shape (the subject names the person and the thing, no banner prefix). For example: <name>: emergency leak at <street> #<unit>, forwarded to your answering service (address not confirmed). The word "emergency" is part of the thing being named, not a banner. The bare " — callback" subject is retired.

A piece of code violates this ADR if it refuses, defers or downgrades an emergency because a home, unit or building could not be confirmed.

Consequences

Alternatives considered

Amendment 2026-10-20 — every emergency on a call pages on-call after the call, gas, fire and police included

Decision. On a live call at a confirmed building, a gas, fire or police emergency no longer rings the on-call list mid-call. escalate_to_human still fires at once, still stamps the conversation, and still answers Clara right away; the chain's start is held with the office notice (Conversation.heldOfficeNotice.chain, office-notice-hold.ts) and started when the call ends, from the call-ended route, the end of the after-call sweep, or the durable 10-minute fallback if the call-ended webhook never arrives. A chain that takes the emergency is the office's one email; a chain that refuses (switch off, nobody on the list, no line) pages the office, as the mid-call refusal did.

What this reverses, and what it does not. "Escalate only after the call" was rejected above for two reasons. The second, "an emergency should not wait for the call to end", is reversed outright by this amendment: the founders now judge the extra seconds worth the context. The first, that the after-call path on 2026-10-18 depended on the classifier, which did not return "emergency", still stands, and this design keeps it: the held chain does not depend on the classifier: it is Clara's own confirmed escalation, written during the call, and it starts whatever the classifier, the content check or the work-order sweep decide. The classifier path (liftMissedEmergency, the missed-emergency detector) still runs on top of it and is unchanged. The emergency still always escalates; only the moment the on-call list is rung moves, by the length of the rest of the call.

What does not change.

Consequences. The on-call person hears about a gas leak at the end of the call, later than before by the rest of the call plus, when the work-order sweep runs, the classifier's run before the release. The chain's name and spoken-address rows are read from the conversation when the chain starts, so what the caller said after the escalation reaches on-call. A later, weaker escalation on the same call never drops a held chain: the chain and its tier are carried forward. A call still going ten minutes after the escalation is rung by the fallback at the ten-minute mark, mid-call. A lost call-ended webhook costs up to ten minutes, where the mid-call start cost nothing; the fallback is armed before the hold is recorded, so a held chain with no timer cannot exist.

A piece of code violates this amendment if a confirmed gas, fire or police emergency on a call ends with neither the on-call chain started nor the office paged.