Every police officer in Karnataka gets a crime analyst in their pocket — one that speaks Kannada, shows its work, and never invents a number.
KSP Datathon 2026 — Challenge 01 · Full PRD · W1 Spike
Running against an empty database: a jurisdiction-clamped answer with context chips, compiled-SQL provenance, and a tamper-evident audit hash — every app feature works before a single crime record is ingested.
| 🔒 Numeric Firewall | The LLM architecturally cannot state a statistic that didn't come from an executed query. On the common path the model emits a validated JSON FilterSpec — our code writes the SQL. Hallucinated numbers are impossible by construction, not by prompting. |
| 🗺️ Generative Analytics Canvas | Answers materialize as live, interactive widgets — hotspot maps, criminal-network graphs, trend charts — inline in the chat, not text walls. |
| 📜 Court-ready provenance | Every answer carries its SQL, source tables, row counts, officer identity, and a tamper-evident hash-chained audit trail. PDF exports are case-file annexures, not chat logs. |
| 🗣️ Kannada-first, voice-enabled | Ask in English, Kannada, or code-switched Kanglish — by voice or text — and get answers back the same way. |
| 🌅 Morning Brief | KAVAL speaks first: an auto-generated daily situational brief per station/district with anomalies and early warnings. |
| ⚖️ IPC ↔ BNS bridge | Seamless querying across the 2024 IPC → Bharatiya Nyaya Sanhita transition — built into the data model. |
| 📜 BSA §63 certificates | PDF exports ship with an auto-generated court-admissibility certificate under §63, Bharatiya Sakshya Adhiniyam 2023 (successor to IEA §65B). |
| 🔌 Sovereign Mode | One toggle swaps the cloud LLM for an on-prem model — fully functional air-gapped. Crime data never has to leave the building. |
| 📈 Measured, not claimed | A published failure-mode page, live accuracy scoreboard, and a timestamped eval history showing the accuracy growth curve. |
| 🔬 Evidence-backed analytics | Crime-concentration views, near-repeat radar, aoristic time-of-day analysis, repeat-victim flags — each module grounded in replicated criminology research. |
question (en/kn, voice/text)
│
▼
Planner (LLM) ──► FilterSpec JSON ──► deterministic SQL compiler ◄── 80% path
│ (Pydantic-validated — the LLM never writes SQL here)
└─ long tail ──► guarded text-to-SQL (sqlglot AST gate: SELECT-only,
table allowlist, single statement) ◄── 20% path
▼
Executor (read-only, row-capped) ──► Postgres 16 + PostGIS + pgvector
▼
Narrative w/ injected values (Numeric Firewall) + Widget DSL
▼
Provenance + hash-chained audit event ──► React canvas
copy .env.example .env # add ANTHROPIC_API_KEY for the LLM planner
docker compose up --build→ web http://localhost:5173 · API docs http://localhost:8000/docs
# backend
cd backend
pip install -r requirements.txt
uvicorn app.main:app --reload # http://localhost:8000
# frontend (new terminal)
cd frontend
npm install
npm run dev # http://localhost:5173No API key? It still works — an offline rule-based planner handles the
demo phrasings (English and Kannada) so the full pipeline runs keyless.
With ANTHROPIC_API_KEY set, the real LLM planner takes over.
No dataset? Also fine — the app boots against an empty database: all tables self-create and demo users auto-seed on startup. This repo ships no crime data, real or synthetic — ingestion adapters get written only after we see the organizer's actual data format (see data/README.md).
Deployment via Zoho Catalyst is mandatory for all datathon submissions (confirmed 11 Jun). Target: AppSail custom OCI runtime for this repo's Docker API image, Web Client Hosting for the frontend — full service-by-service mapping in PRD §11.5. Local compose stays as the dev environment and the air-gapped Sovereign-Mode build.
| User | Role | Scope |
|---|---|---|
constable_blr |
CONSTABLE | Bengaluru City only (queries auto-clamped; cross-district asks refused + logged) |
io_mysuru |
INVESTIGATOR | Mysuru only |
sp_command |
COMMAND | State-wide + Audit Trail |
auditor |
ADMIN | Audit Trail only — no case data (separation of duties) |
python spike/run_spike.py --offline # deterministic path — must be 12/12 (no data or key needed)
python spike/run_spike.py # LLM planner vs golden setcd backend
pytest tests -qDrop the files into data/raw/ — that directory is gitignored on purpose;
real crime data never goes to GitHub (see data/README.md).
Then profile it before writing any ingestion code:
cd backend
python scripts/profile_dataset.py ..\data\raw\*
# -> data/profile_report.md: rows, nulls, date spans, geo/key candidates per fileThe ingestion adapter (real columns → app/schema.py) is written after
profiling — we don't guess the format before seeing it.
PRD.md ← the contract: features, milestones, demo script
backend/
app/
engine/ ← the crown jewel: FilterSpec → compiler → guarded SQL
routers/ ← auth · chat · meta · audit · export (PDF)
audit.py ← tamper-evident hash chain
auth.py ← JWT + bcrypt + 4-role RBAC
pdf.py ← court-ready export w/ §63 certificate
schema.py ← canonical data model (app + crime tables)
scripts/profile_dataset.py ← Day-1 profiler for the real dataset
tests/ ← compiler + SQL-guard + API tests (executed, not string-matched)
spike/ ← W1 NL→SQL de-risking harness + golden set
frontend/ ← React 18 + TS + Tailwind v4 command-center UI
db/ ← PostGIS + pgvector image, init SQL
data/ ← gitignored landing zone for the real dataset (local only)
- W1 — scaffold, spike harness, golden set v0, dataset profiler
- W1.5 — dataset-independent architecture complete: JWT auth + 4-role RBAC with jurisdiction clamping, server-side sessions + context memory (filter chips), tamper-evident audit viewer with live chain verification, PDF export with §63-style certificate, voice input (en/kn), Sovereign-Mode planner switch, rate limiting, degraded-mode banner
- W1 — Gate G1: LLM spike ≥70% · ✅ Catalyst decision answered 11 Jun: deployment via Catalyst is mandatory — target AppSail (custom OCI/Docker) for the API, Slate/Web Client Hosting for the frontend
- W2 — Catalyst onboarding (credits, AppSail hello-deploy, Data Store ZCQL spike → DB decision), QuickML LLM wired via LiteLLM, real dataset ingestion, semantic views
- W3 — guarded-SQL path live, Widget DSL, network graph (Gate G2: ≥70%)
- W4 — Kannada voice quality tier (Sarvam/Bhashini), hotspots, near-repeat
- W5 — forecasts, Morning Brief, cold-start suggestions (Gate G3: ≥85%)
- W6 — hardening to ≥90%, demo video, submission 24 Jul
Built by Team KAVAL for the Karnataka State Police Datathon 2026 — Challenge 01: Intelligent Conversational AI for KSP Crime Database.
⚠️ This repository contains no crime data — real or synthetic. Thedata/directory is gitignored by design; the organizer-provided dataset stays local-only, behind auth. No real crime records, persons, or PII are present here, ever.