Back to the warning

Suno · engineering note

How this would actually run

A prototype that only works as a screen is a drawing. This page names the feed it would subscribe to, the office that would operate it, the law that decides who may order an evacuation, the numbers that break at national scale, and the specific things the language model is not permitted to do.

It also states, item by item, what in this build is real and what is invented. That list is first, because everything after it depends on being able to trust it.

01

What is real, and what is not

Nothing in this prototype is connected to any government system. No live feed is polled, no official API is called, and no government database is read or written. The following is exhaustive.

ThingStatusDetail
The 8 warningsSyntheticWritten for this prototype. Modelled field-for-field on CAP v1.2, the format IMD, CWC and Sachet already publish, so replacing them with a live feed is a parser change rather than a redesign. Sender addresses end in .invalid, which is a reserved TLD that can never resolve.
The 13 sheltersSyntheticNames, capacities, occupancy and facility flags are invented. The field list mirrors what a District Disaster Management Authority register actually holds, including the fields current public interfaces do not show — step-free access, whether livestock are accepted, and how many places are left.
Water levels, wind speeds, rainfall, temperaturesSyntheticEvery quantity on every screen is invented. They are internally consistent and plausible in magnitude, and they measure nothing.
The safety registerSyntheticMarking yourself safe writes to your own browser's storage and nowhere else. Nothing is transmitted. No SMS is sent — the verification code is shown on screen precisely so nobody has to enter a real number to try the flow.
The 6-digit verification codeSimulatedDisplayed on screen instead of sent. There is no SMS gateway in this build.
The 10 helpline numbersReal112, 108, 1078, 101, 1070, 1077, 1091, 1098, 14567 and 104 are genuine, currently operating Indian emergency numbers. They are the only numbers in the product, and they are the only numbers the assistant is permitted to say.
The 72 districts and their coordinatesRealReal places at real coordinates. Population figures are Census 2011 district totals.
Language sharesRealCensus 2011 state-level language tables, rounded. Used to state the exclusion as a number rather than as a claim.
The 13 translationsHuman-writtenThe interface strings and the rule table's answers were written by a person, shipped as static files, and work with no network and no API key.
Your locationRealIf you allow it, the browser's actual geolocation is used to pick the nearest district. It is never sent anywhere — the nearest-district calculation runs on your device.
The mapRealNot a tile map. It is a schematic plot of latitude and longitude, drawn as inline SVG from coordinates the app already holds, so it renders with no network and no map library. District coordinates are real; the warnings plotted on them are synthetic. It deliberately depicts no national or state boundaries.
The language modelRealWhen an API key is configured, real OpenAI calls are made for the two jobs described in section 07. With no key the app runs entirely on its rule table and says so on screen.

This prototype approves nothing, dispatches nothing and decides nothing. No officer is bound by anything it displays.

02

Where the warning would come from

India already generates these warnings. Five agencies issue them, each for its own hazard, and NDMA’s Sachet platform already aggregates and broadcasts them in CAP — the Common Alerting Protocol, an OASIS standard. The problem this prototype addresses is not that the warning does not exist. It is what happens to it in the last hundred metres.

IMDcyclone, rain, heatCWCriver levelsINCOISstorm surge, tsunamiNCSearthquakeGSIlandslideSachetNDMA aggregatorCAP v1.2 XMLCell broadcastevery handset in a cell, seconds, no listSMS pushneeds a subscriber list, minutes to hoursTV and radio crawlreaches those already watchingSuno13 languages, spoken, offline-capable

Suno sits in the last box. It is a renderer of alerts that already exist, not a new source of them. That distinction matters legally as much as technically, and section 04 explains why.

The integration is a CAP subscriber: poll or receive the feed, parse identifier, sent, onset, expires, severity, urgency, certainty, areaDesc, instruction, and map severity × urgency onto the four-level citizen scale. The alerts in this build already carry those exact fields, which is what makes the claim testable rather than aspirational.

03

The gap this actually closes

Sachet and IMD issue bulletins in English and Hindi. The Eighth Schedule of the Constitution recognises 22 languages.

That gap is not abstract. Every district in this prototype with an active warning is a district where it bites: Golaghat and Guwahati read Assamese, Puri reads Odia, Wayanad reads Malayalam, Nagpur reads Marathi. A flash-flood warning that reaches a Golaghat household in English is not a warning. It is a notification that something is wrong, in a language somebody in the house now has to go and find a translation for — during the two hours the warning was trying to buy them.

2
languages the upstream bulletin is issued in
13
languages Suno delivers it in
22
languages in the Eighth Schedule
1260M
first-language speakers covered here

Two further things follow from designing for that reader rather than for a reviewer. The warning is spoken aloud, because reading and literacy are different problems and only one of them is solved by translation. And the language is chosen by the district, not by a menu — pick Golaghat and the interface is already in Assamese, because a person in a flood should not have to find a settings screen first.

04

Who is actually allowed to order an evacuation

Under the Disaster Management Act, 2005, the authority runs NDMA → State Disaster Management Authority → District Disaster Management Authority, chaired by the District Magistrate or Collector. In practice the instruction to leave is issued by the District Magistrate, executed by the district administration, and supported by NDRF and SDRF.

Suno never issues one. It renders an order that already exists in the feed, and the language model is explicitly forbidden from originating one — the rule is enforced in code, not in a prompt suggestion. If no evacuation order exists in the data, no evacuation instruction can appear on the screen, in any language, by any path.

The practical consequence for deployment: this would be operated by, or under, a District Disaster Management Authority, and the escalation path for a wrong or stale warning has to be the DDMA control room — which is why 1077, the district control room number, is in the helpline list and not just 112.

05

The safety register is the hard part, and it is not a technical problem

“Mark yourself safe” is four lines of code and a genuinely difficult institutional question. A national register of who is safe means a national register of verified mobile numbers and their status, which touches telecom operators licensed under the Department of Telecommunications, and it means holding location-adjacent personal data about people during the period they are most vulnerable.

Three things would have to be settled before this could exist for real:

  • Who holds it. A register operated by an aggregator is a standing target. One operated per-district under a DDMA is fragmented exactly when families are searching across districts.
  • How long it lives. A safety status is useful for days and dangerous for years. It needs a deletion clock written into the design, not into a policy document.
  • What it is not. The moment it can be queried by anyone for anyone, it becomes a people-tracing tool. The honest design answer is that a status is only ever readable by someone who already knows the number they are searching for — which is what this prototype does.

In this build the register is your browser’s own storage, and nothing leaves the device. That is a limitation, and it is also the only version of this feature that can honestly be shipped in a prototype.

06

What breaks at scale

The interesting failures are not load. They are physical, and this build’s own data makes the first one concrete.

Worked example · Golaghat
10,66,888
district population (Census 2011)
3
shelters listed here
1,250
total shelter capacity
0.12%
of the district that fits

Telling a district to go to a shelter is only useful if the shelters exist. An interface that shows capacity and current occupancy — as this one does — at least makes the shortfall visible instead of sending three thousand people to a hall that seats two hundred and fifty. It does not solve it. Nothing on a phone solves it.

  • The tower goes down first. Which is why this app is a service worker with an offline shell, why the rule table answers with no network, and why the language a person chose is cached rather than fetched. Offline it shows the last warning it received with its timestamp, and says it is stale — it never presents a cached warning as current.
  • The phone is not a smartphone. Roughly a quarter of Indian mobile connections are still feature phones. The honest extension is an IVR line running the same rule table over a voice call, and a 160-character SMS mode. Neither is built here; both are named because pretending an app reaches everyone is the failure mode this whole page exists to avoid.
  • Cell broadcast beats a subscriber list. Cell broadcast reaches every handset in a cell in seconds and needs no registration. Any real deployment should be a renderer for cell broadcast, with the subscribe flow as a fallback — not the other way round, which is how most app-shaped answers to this problem get it backwards.
  • The battery is at 4%. The Level 4 screen is deliberately mostly flat colour, has no looping animation, and runs no timers it does not need.
06b

What it would cost to run, in rupees

“Use a language model” is a cheap thing to propose and an expensive thing to operate, so here is the arithmetic rather than an assurance. The figures below use OpenAI's published gpt-4o-mini rate at the time of writing — $0.15 per million input tokens and $0.60 per million output tokens — and are worked from this build's own behaviour.

Translatable text in one CAP alert~150 words — headline, description, instruction, avoid list
Tokens per language~200 in, ~200 out
Languages added beyond the bulletin's two11
Cost to translate one alert into all of them≈ $0.0017, about ₹0.15
At an assumed 500 alerts a day, nationally≈ $300 a year, about ₹26,000

The number that matters is not the total. It is what the total does not depend on. A translation is produced once per alert per language and then cached and served as static text. The cost therefore scales with how many alerts are issued, not with how many people read them. One flood warning for Golaghat costs the same ₹0.15 whether eleven people open it or eleven lakh do.

That is the property that makes this deployable rather than merely demonstrable. A design that called a model per reader would cost a multiple of the annual figure above during the exact hour a district was evacuating — which is to say it would fail at the only moment it was needed. The 500-alerts-a-day figure is an assumption and is labelled as one; the per-alert cost is not, and the per-alert cost is the one that has to hold.

Two costs are deliberately not in that table because they are the real ones, and pretending otherwise would be the kind of omission this page exists to avoid. Native-speaker review of every string in every language is a salaried, recurring obligation, not a one-off — a mistranslated “do not” is worse than no translation. And someone has to be accountable at 3 a.m. when the pipeline stalls mid-evacuation. Those are staffing questions, they dwarf the compute bill, and no amount of engineering removes them.

07

What the language model does, and what it may never do

The model does exactly one job: it answers a question the rule table did not recognise, using only the warnings and guidance already on the page, in the language it was asked in.

Twenty questions — the ones people actually ask in the first ten minutes — are matched by a deterministic keyword table in every supported language and answered by assembling text that already exists in the data files. No generation happens on that path, so identical input always returns an identical answer, and every number in the answer came from the file it was quoted from. Only unmatched text reaches the model.

Whatever comes back is then validated before any person sees it. It is rejected outright if it:

  • contains a phone number that is not one of the real helplines
  • contains any quantity that does not appear in the source data it was given
  • names a shelter, road or river that is not in the register
  • tells the reader they are safe, or that they are not — it does not decide that
  • claims help has been sent, dispatched or alerted — nothing it does sends anyone
  • originates an evacuation order rather than relaying one already in the feed

A rejected answer is not repaired and shown anyway. The reader gets the rule table’s honest “I could not match that”, and the rejection reason is returned in the response so the failure is visible rather than smoothed over.

With no API key the app still works. It falls back to the rule table, and every answer carries a visible chip saying which of the two produced it — rule table, translated rule table, or model. You never have to guess.

The second job is narrower still: turning an agency bulletin written for a district magistrate into ordered actions, and translating grounded lines into the reader’s language. That translation is checked structurally — same number of lines out as in, and every helpline number identical — and the whole batch is discarded if either check fails.

07b

What each choice cost

Every decision in this build bought something and gave something up. Listing only the upside is how a design review turns into a sales pitch, so here is the other column.

Severity owns the whole page, not a banner

Bought — At Level 4 the ground itself turns red and the header collapses. A red card inside a white page can be scrolled past; a red page cannot.

Cost — The location picker, the settings and the language menu all get pushed below the instructions. Someone who opened the app specifically to change district has further to scroll, and they are penalised for the sake of someone who did not.

A coordinate plot instead of a tile map

Bought — The map renders with no network, no map library and no tile CDN, and it depicts no boundaries — which an independent prototype has no business drawing.

Cost — It is genuinely worse as a map. There are no roads, no rivers, no coastline and no landmarks, so it cannot answer 'is this near me'. It shows where warnings are relative to each other and nothing more.

One script's font loaded at a time

Bought — Roughly a tenth of the font bytes of a thirteen-script family, which is the difference between usable and not on a 2G connection.

Cost — Switching language mid-session triggers a second font fetch and a visible reflow. We optimised for the common case — one person, one language — and made the rarer case worse.

The rule table answers before the model does

Bought — Identical input gives identical output, it costs nothing, it works offline, and the twenty most common questions can never be hallucinated.

Cost — The rule table is rigid and it is ours to maintain. A question phrased just outside its keywords falls through to the model even when the answer was sitting in the dataset, and every new hazard type means writing new rules by hand.

The validator discards rather than repairs

Bought — A rejected answer is visibly rejected, with its reason shown. Nothing is silently patched into looking correct.

Cost — A model answer that was 95% right and named one number wrong is thrown away whole, and the reader gets 'I could not match that' instead of most of an answer. We took that trade knowingly; in this domain a confidently wrong number is worse than no answer.

No login, no accounts, no server-side storage

Bought — Nobody is asked for a phone number to read a flood warning, and there is no personal data to leak.

Cost — Nothing persists across devices. Marking yourself safe on a phone that then dies takes the record with it — which is precisely the scenario a real safety register exists for, and is the strongest argument that this part belongs with the telecom operators rather than in a web app.

08

What would have to be true

The honest list of preconditions, none of which this prototype can satisfy on its own:

  1. 1A CAP feed subscription from Sachet, with an availability commitment. A warning renderer is only as good as its access to warnings.
  2. 2A district-level shelter register that is maintained, with live occupancy. Capacity that is not updated is worse than no number, because it sends people to a full building.
  3. 3An agreement with a DDMA about who answers when the app is wrong, and how a bad warning is retracted within minutes.
  4. 4A translation review process. Machine translation of an evacuation instruction needs a native speaker in the loop before first use, per language, and a way to correct it in production.
  5. 5A cell broadcast path, so the warning does not depend on someone having installed anything.
  6. 6A deletion clock on the safety register, agreed before it holds a single real number.
09

Versions

Rule sets are version-stamped so any answer can be traced to the revision that produced it. These identifiers appear on the answers themselves.

rule table  rules-2026.08.5
plan corpus plan-2026.08.3
alert schema CAP v1.2 (OASIS)