Independent hackathon prototype. Not affiliated with, endorsed by, or connected to the Government of India. All data shown is synthetic. What's real →
Text size

Honesty

What is real and what is not

Judging this fairly needs a clear line between what genuinely works and what is staged. Here it is.

This is not a government service

Surakhsa is an independent prototype built for the “Build What Moves India” hackathon. It is not affiliated with, endorsed by, or connected to the Ministry of Home Affairs, I4C, or any government body. It uses no government logo or emblem. If you need to report a real cyber crime, call 1930 or use cybercrime.gov.in.
Works today
  • The whole citizen journey: describe → classify → freeze request → details → review → file → track.
  • Free-text classification into 30 official-style categories, including Hindi and romanised Hinglish input.
  • Amount detection from phrases like “50,000”, “50k”, “1.5 lakh”.
  • The suspect check screen. Punycode detection, lookalike-domain edit distance, brand-in-subdomain, IP-literal hosts, risky top-level domains, UPI handle-suffix validation, TRAI sender-ID shape, freemail-posing-as-a-bank and the remote-access app list are all ordinary string analysis running offline in your browser. Nothing typed into that screen is sent anywhere, and the real .gov.in and bank domains pass it cleanly.
  • Reporting a suspect without filing a complaint, at /check/report. It accepts a UPI ID or bank account, which the current portal’s suspect form does not, and it does not force an evidence upload before it will take the report.
  • SHA-256 fingerprinting of attachments, computed on your device with the Web Crypto API and shown in full on the review and tracking screens.
  • The evidence checklist, which changes by case type and refuses to accept intimate images for women-and-children cases.
  • Read-aloud on the report screen is pre-rendered neural narration — spoken once, offline, with Piper, and shipped as a ~60 KB MP3 per language. It plays instantly on any phone with no model download and no speech service call. English, Bengali, Marathi and Telugu are covered; the licences are listed in public/audio/ATTRIBUTION.md. The home page headline changed after its clip was recorded, so that one uses the device voice until it is re-rendered.
  • Voice input via the browser's own speech recognition, in 8 Indian languages. This depends entirely on the browser: Chrome and Edge reach their vendor's speech service, while Chromium forks such as Brave and Arc ship without the key it needs and always fail. The interface says so when that happens, and typing is always available.
  • Category override — you can always disagree with the classification.
  • A language switcher covering English, Hindi, Bengali, Marathi, Tamil, Telugu, Odia and Kannada, with the interface font carrying every one of those scripts.
  • A conditional form that shows only the fields your category needs.
  • Acknowledgement numbers, a persistent case list, and a live SLA timeline with escalation levels. The access log runs on a one-second clock, shows an access that is still open as still open, and lets one land on screen while you watch.
  • Accounts, on a real server. Signing in with a mobile number gets you every complaint filed under it, from any device — two demo numbers hold different cases, and neither can see the other’s. Complaints are stored server-side in Netlify Blobs, the session is an HMAC-signed cookie, and an acknowledgement number still resolves with no account at all. Filing never requires signing in, which is the point.
  • Adjustable text size, visible focus rings, keyboard operation, and semantic landmarks.
Simulated
Bank and payment network responses
The freeze request's acknowledgements are generated on a timer inside the browser. Nothing is sent anywhere.
Case progression
Stage timings are simulated from the filing time using illustrative SLA values. They are not real Right to Service commitments.
Identity
The one-time password is generated on the server and printed on the screen. No SMS is sent, nothing is checked against a telecom operator, and any ten-digit mobile number starting 6–9 will let you in. A working service would verify the number against the one on the complaint. This proves complaints are held per account on a server — not that anyone is who they say they are.
Durability
Server-side complaints live in Netlify Blobs, which is real storage but a prototype’s: there is no backup, no retention policy and no encryption at rest that we control. Everything in it is synthetic test data, and anything filed before a redeploy may not survive one.
Evidence uploads
No file is uploaded. The name, size and SHA-256 digest of each attachment are kept; the contents never leave your device. The digest is genuinely computed in the browser and can be checked against “shasum -a 256” on the same file.
Suspect reports
A suspect report is stored in your browser and given a locally generated SUS- reference. Nothing reaches I4C or any platform. A real deployment would post it into the national Suspect Repository, which already exists on cybercrime.gov.in — this prototype only rebuilds the journey around it.
“Others reported this” on the check screen
Generated from a hash of what you typed, so a demo repeats reliably. It is never used to decide the verdict — that comes only from the offline signals — and the screen labels it as simulated. A real deployment would count matching complaints in the national database.
The access log on the tracking page
Synthetic. The entries are derived from the case’s own age and use generic role names; no real officer, unit or system appears. The access that arrives while you are looking at the panel — the pulsing row, the counter that keeps moving — is scripted, nine seconds after the panel scrolls into view. It is there because “someone read your complaint” as a list of old timestamps reads like a document, and as something you watch happen it reads like a service. A working deployment would render the audit trail its case management system already writes, and would not need to fake the timing.
Read-aloud in Hindi and Tamil
These two fall back to your device's own voice, which sounds noticeably worse than the pre-rendered languages. That is deliberate. Every Hindi voice in the open Piper set is licensed CC-BY-NC-SA — free for a prototype, unusable by a service the public pays for — and there is no Tamil voice in the set at all. Shipping the non-commercial one would have made this demo sound better while putting something in it a real deployment could not keep. Openly licensed voices for the scheduled languages are a genuine procurement gap, and a cheap one to close.
Read-aloud of your own summary
The assisted-mode summary is composed from what you just typed, so it cannot be pre-rendered. It uses the device's speech synthesis, with the best installed voice for the language picked rather than whichever one is first — which is the part most sites skip.
Translation quality and coverage
English and Hindi are written by hand and are 100% complete. Bengali, Marathi, Tamil, Telugu, Odia and Kannada are machine translations that no native speaker has reviewed. Each covers 86% of the interface, and the switcher shows that number next to the language rather than letting you find out after choosing. What is missing falls back to English on purpose, because a blank string is worse than a language you can still read. A real service would need professional translation and review of every screen before launch.
Identity and OTP
No authentication is implemented. A production service would need identity verification that this prototype deliberately does not simulate.
The two sample cases
ACK-2026-481902 and ACK-2026-337155 are fictional, with invented names, amounts and identifiers.

How this was built

  • OpenAI Codex generated the complaint taxonomy and classifier (lib/ncrp.ts, 30 categories with multilingual keyword matching and rupee-amount parsing) and the SLA and escalation engine (lib/sla.ts) — the two pieces of domain logic the whole product rests on.
  • A language model can power live triage at /api/triage. When an OpenRouter or OpenAI key is configured it classifies the narrative and writes the plain-language explanation; without one it falls back to the deterministic classifier, so the journey never breaks. The interface labels which path produced the result. OpenRouter is tried first because it can be pointed at a free model.
  • UX4G Design System v3.0 supplies the visual language. Colour, type, radius and spacing tokens were transcribed from the published UX4G stylesheet into app/globals.css. Noto Sans is the UX4G base typeface and covers every Indian script.
  • Next.js, React and Tailwind provide the application shell. No UI component library was used.

What happens when the connection drops?

A great deal of government service delivery happens on links that are not reliable — a bank branch counter, a post office, a common service centre in a village whose uplink is down for the afternoon. A form that loses everything when the line drops is not a form most people fill in twice. So this build treats losing the network as a normal condition rather than an error state.

  • Filing is local; delivery is separate. Pressing file writes the complaint and its acknowledgement number to this device immediately, then queues the delivery in lib/outbox.ts. The queue drains by itself when the line returns. Until the server confirms it, the tracking page says “saved on this device, not yet delivered” — the screen never implies a delivery that has not happened.
  • We check reachability, not the Wi-Fi icon. navigator.onLine only says the device is attached to a network. A counter machine on a live LAN with a dead uplink reports itself online. So components/connection-provider.tsx makes a small HEAD request to our own origin and believes that instead.
  • Classification still runs. The deterministic classifier lives in lib/triage.ts and is imported by both the server route and the browser, so an offline citizen gets the identical result the keyless server would have given — not a degraded one.
  • Pages survive a reload. A service worker (public/sw.js) caches the reporting screens. It deliberately never caches anything under /api/: a cached case status would be a false statement about a live complaint.
  • When money has just moved, we stop queueing. A freeze request cannot leave a dead connection, so the urgent screen hands over the thing that does work on a weak signal — a 1930 voice call, with the details laid out in the order the operator asks for them.

Does this need AI to work?

No — and that was a deliberate design constraint, not a fallback we added later. A public service cannot have a per-complaint cost that rises with demand, and it cannot stop working when a vendor has an outage or a contract lapses.

  • The default path costs nothing per complaint. Classification runs on the deterministic classifier in lib/ncrp.ts: weighted phrase matching over the 30-category taxonomy, with inverse-frequency weighting so common words like “my account” cannot dominate a match. No tokens, no API call, no vendor.
  • The model is an upgrade, not a dependency. When an API key is present the same endpoint uses a language model, which handles unusual phrasing and code-switching better. Remove the key and every screen still works. The result card always says which path ran, so a citizen is never misled about what read their description.
  • Why this matters at scale. Cyber crime complaints in India run into the millions per year. At a million complaints, even a tenth of a rupee of inference per complaint is a recurring line item that has to be defended in a budget every year — for a task a lookup table does well enough. The honest engineering answer is to spend the model only where it actually beats the cheap path.
  • The rest of the product uses no AI at all. The golden-hour freeze flow, the SLA timeline, the escalation ladder and the generated escalation letter are all plain deterministic code.

What we did not do

  • No government system was accessed, tested, probed or integrated with.
  • No private or undocumented API was called or reverse-engineered.
  • No code or asset was copied from any government website.
  • No real Aadhaar, PAN, account number, OTP, password or payment detail appears anywhere in this build, and none can be entered meaningfully.
  • No government logo, emblem or branding is used.
  • No personal data is collected, transmitted or stored on any server.