# Nirnay — a deterministic, CPU-first decision model *Nirnay* (निर्णय / നിർണയം, "decision, determination") answers typed questions about a piece of text or JSON — **choice**, **score** (ordinal rating) and **noul** (yes/no) — with calibrated probabilities, in one pass, without ever generating text. It speaks the same question spec and HTTP wire protocol as TypeSafe **Jev** and Convai **Laya**, so clients written for either work unchanged, and it is built to run fast on this HP Z840 (2x Xeon E5-2630 v3, CPU only). See `REPORT.md` for the head-to-head numbers measured on this machine. ## Results on this machine (summary of REPORT.md) Two models ship: **v2** (default, `nirnay.load()`) — bge-base backbone, trained overnight; **v1** (`nirnay.load("fast")`) — bge-small backbone, 2.7x faster again. Better than Laya here: * **Speed** — the state is encoded once per call. v2: 146 ms for 1 question, 297 ms for 10, 696 ms for 50; v1: 54 / 95 / 258 ms. Laya at its fastest setting: 159 ms / 1.39 s / 6.7 s → v2 **1.1x–9.7x**, v1 **2.9x–26x** faster. * **Footprint** — v2 527 MB, v1 155 MB on disk (Laya 614–804 MB); cold start ~7 s vs 12–16 s. * **Option-order robustness** — reordering options never changes an answer (flip rate 0.000 vs Laya 0.14–0.19, up to 0.44 on banking77). * **Accuracy wins** — banking77 (77 intents) 0.610 vs Laya ≤0.492; toxicity 0.660 vs ≤0.535; SST-5 ratings 0.492 vs ≤0.470; RAG relevance 0.655 vs Laya-en 0.625; email spam 0.995 ≈ 0.998. Against Jev's published figures: AG News 0.925 vs 0.910, emotion 0.550 vs 0.480. * **Instant adaptation** — `learn()` with 16 examples per intent: banking77 **0.853** on CPU (Laya needs RL fine-tuning on a GPU; Jev's independently measured figure is 0.763). Not better (yet): against the best of Laya's three checkpoints, v2 wins 3, ties 1 and loses 8 of 12 tasks (against Laya's default English checkpoint: 4 wins, 2 ties, 6 losses). The clear gaps are SMS spam (0.67 vs 0.94), model routing (0.40 vs 0.66), support triage (0.42 vs 0.54), jailbreak (0.70 vs 0.81), emotion (0.55 vs 0.60) and AG News (0.925 vs 0.953). Laya is a 421M model fully fine-tuned on GPUs; v2 trains 29M parameters on this CPU (one overnight run). ## Quick start ```bat RUN.bat demo :: one example decision RUN.bat serve 8000 :: HTTP server, POST /v1/systemone (Jev / Laya protocol) RUN.bat mcp :: MCP stdio server for Claude Code / Codex / Hermes RUN.bat cli "text" --choice "a,b,c" --ask "Which fits?" RUN.bat bench :: latency on this machine RUN.bat test :: invariants ``` ```python import nirnay m = nirnay.load() # default (models\DEFAULT -> nirnay-v2); nirnay.load("fast") = v1 r = m.predict( {"ticket": {"subject": "Payout failing", "body": "My payouts failed for 3 days, please help ASAP"}}, {"team": {"type": "choice", "instructions": "Which team should handle this?", "criteria": {"billing": "payments", "technical": "bugs and integrations", "sales": "pricing"}}, "urgent": {"type": "noul", "instructions": "Does the customer express urgency?"}, "severity": {"type": "score", "instructions": "How severe is the problem?", "criteria": ["minor", "moderate", "severe"]}}) r["answers"]["team"]["choice"], r["answers"]["urgent"]["noul"], r["answers"]["severity"]["score"] m.predict_batch(list_of_states, questions) # throughput path m.learn("team", questions["team"], [(state, "billing"), ...]) # few-shot memory, instant, no GPU ``` Answers have the Laya/Jev shape: `choice` / `score` / `noul`, `probabilities`, `confidence` (1 − normalised entropy), `answer_confidence` (probability of the reported answer; the calibrated number to gate on), and `abstained` when `min_confidence` is given. ## Architecture ``` state (text / JSON) question " question: " options "