An investigation tool for district education officers in Himachal Pradesh: pick a closing school, compare receiving schools side by side, investigate each with agents, and only then choose one. The LLM never produces numbers or approvals.
Consolidating a low-enrolment school affects children who then have to walk further, over terrain, to a school with enough seats. PathShala gives the officer a structured, referenced investigation — and a hard rule: where there is no data it says “Data unavailable” and nothing is invented.
The diagram above is the whole system. Three design choices shape it:
SQLite compiled to WebAssembly (sql.js) loads seed.sql at boot and persists to localStorage (pathshala.db.v7) after every write. The key includes a seed fingerprint, so stale saves are discarded.
case/findings.js is the only module that writes cases, evidence and approvals. Tools are read-only (SELECT/WITH only; writes, multiple statements and unknown tables are rejected).
SimulatedProvider reproduces the prototype exactly. GeminiProvider builds the request already; a /api/agent proxy streams NDJSON tool calls the browser runs on sql.js.
Click a step. The final choice only appears after every option has been investigated.
Map click or the “needs review” list (≤30 students, or poor/unsafe building). Tick two or more receiving schools. Each candidate gets a 0–100 screening aid — never a recommendation.
Distance and walking time, hazards on the route, free seats (classrooms × planning norm), teachers, building, facilities and citizen feedback — one column per candidate.
Per-candidate evidence, agent findings, field questions and answers, and interventions. Switch with school tabs or Investigate all. Every step is logged to agent_steps with input/output.
Questions answered, concerns confirmed, interventions, cost per year, one-time cost, first-year total. The officer picks last.
Only the chosen school’s report is drafted — every sentence carries a reference — then critiqued, approved and submitted by the officer.
Each agent exports { id, systemPrompt, tools, outputSchema, simulate(ctx) }. Prompts live in src/agent/prompts/*.md, schemas (JSON Schema 2020-12) in src/agent/schemas/*.json. The merge-side agents (planner, success monitor, survey builder) stay deterministic.
merges specialist evidence into findings
Findings
(calls specialists)
students, routes, terrain, transport
EvidenceBundle
sql_query · school_profile · route_calc · gis_overlay · transport_lookup
feedback themes, recurring concerns, field observations
EvidenceBundle
feedback_search · classify_feedback · recurring_concerns · field_observations
evidence gaps → targeted field questions
FieldQuestions
evidence_gaps
field answers → evidence & finding statuses
EvidenceUpdate
apply_field_answers
policy chunks → interventions with costs
Interventions
policy_retrieve · cost_calc
rationale, a reference on every sentence
Draft
get_case_evidence · draft_report
checks references, numbers, wording
Critique
get_case_evidence
Enforced in code and tested with Playwright (tests/agents.spec.js).
Every agent output passes Ajv; on failure the runner retries once, then falls back to the simulated result and logs it.
The Drafter may only use evidence already in the case; the Critic checks references and numbers.
Only the officer approves, selects an intervention, marks evidence verified, or submits.
Values in the demo may be synthetic, but every field must have a real source and gaps are never filled. Tests fail if removed fields come back.
| Shown | Source | Status |
|---|---|---|
| School name, level, UDISE code, enrolment, teachers, classrooms | UDISE+ Know Your School | real for named merge schools, else mock |
| Seat capacity | classrooms × planning maximum (R7) | derived |
| Coordinates | Datameet / India Data Portal UDISE export | approximate |
| Road / walking distance & time, climb | Google Routes + Elevation APIs; Tobler × child pace | mock geometry (Tirthan valley); other pairs labelled straight-line |
| Bridges, steep paths, landslide zones | OpenStreetMap, JRC water, DEM, GSI | mock geometry |
| Citizen feedback (Hindi + English) | synthesised from real complaint patterns | mock |
| Field observations (bridge washed away, unsafe building) | The Tribune reports | real |
| Merge pairs, outcomes, precedents | HP merger list, Tribune, LiveLaw, Scroll, The Federal, The Wire | real |
| RTE Rules, Samagra Shiksha norm, HP PAB cost, HP merger criteria | official texts | real, quoted as stored |
| Bus timetable, “road closures”, per-habitation child counts | no source | removed → “Data unavailable” |
Deploy anywhere: GitHub Pages serves the built single-file index.html (≈1 MB gzipped, no network requests except optional Google Fonts); or docker build (nginx, Cloud Run) or firebase deploy.