{"slug": "show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating", "title": "Show HN: Judicex – Open-source legal AI that abstains instead of hallucinating", "summary": "Judicex, an open-source legal AI platform, launched today with a system that abstains from answering when evidence is insufficient rather than generating false information. The software operates on a local SQLite knowledge base, allowing lawyers to ingest official sources and private files, run deterministic workflow checks, and generate drafts while keeping all matter data on the user's own hardware. Unlike closed SaaS products or generic RAG demos, Judicex enforces a structured evidence model where citations are bound only to retrieved documents, ensuring the AI cannot improvise legal answers.", "body_md": "Open-source\n\nlegal AI softwarefor evidence-grounded drafting, matter management and AI-assisted legal work — with an answer contract that fails closed instead of hallucinating.\n\nJudicex is a workspace for lawyers and legal teams. You can ingest official sources and private matter files, run deterministic workflow checks, generate drafts in a Word-style split-view editor, and chat with an LLM whose answers are bound to the evidence in a SQLite knowledge base you control.\n\nThe project ships with a Flask web UI, a CLI, and an MCP stdio server, and talks to Ollama, OpenAI, Anthropic, OpenAI-compatible providers — or runs with no LLM at all.\n\nOpen-source vs. cloud.This repository is the open-source build of Judicex: install it on your laptop, on a workstation, or on a private server inside the firm. A managed cloud version with hosted multi-tenant deployment, SSO and audit features is on the roadmap as a separate offering; this codebase is and will remain Apache-2.0.\n\nMost legal AI products today are either:\n\n**Closed SaaS** that ship your client data to a vendor (Harvey, Legora, …), or**Generic RAG demos** that paste retrieved chunks into a prompt and hope.\n\nJudicex takes a different bet. In legal work, the value is not in the\nprompt — it is in the **structured, verifiable evidence the answer stands\non**. So the codebase is organised around that idea:\n\n**Two evidence layers, never confused.** Legal sources (`documents`\n\n,`document_versions`\n\n,`legal_atoms`\n\n,`entities`\n\n,`edges`\n\n) are the only thing that can produce**citations**. Operational notes (`agent_memories`\n\n) store preferences, decisions and lessons — they shape*how*the agent works, but are never cited as law.**Versioned official sources.** Real ingestion from Normattiva with URN extraction, versioned over time (`effective_from`\n\n/`effective_to`\n\n) so you can ask “what did this article say on date X?” instead of pretending the law is timeless.**Answer contract that fails closed.**`answer_contract.py`\n\n+`numeric_verifier.py`\n\n+`confidence.py`\n\nenforce the states`grounded`\n\n/`limited`\n\n/`abstain`\n\n/`chat`\n\nwith JSON-schema validation, citations bound to retrieved`document_id`\n\ns only, and temperature 0. If evidence is insufficient, Judicex abstains. It does not improvise.**Workflow packs as data.** Matter-analysis profiles (e.g. civil debt recovery, opposition to injunctions, generic file review) are JSON workflow packs, versioned and swappable per vertical / firm — not application logic.**You control where it runs.** SQLite, Flask, vanilla JS, no external build step. The same codebase runs on a single workstation or on a private server inside the firm. Matter data lives in the SQLite database and the attachment directory you point Judicex at — nothing leaves the host until**you** explicitly point a chat at a hosted LLM.\n\nThis repository is `v0.2.0-alpha`\n\n: a usable prototype, not production SaaS.\n\n**Sources & evidence**\n\n- Local SQLite knowledge base with versioned document history and legal atoms.\n- One-click import of official source bundles (Normattiva-driven).\n- Two-tier evidence model: legal sources (citable) and operational notes (style and decisions).\n\n**Matters & files**\n\n- Private matters, folders, versioned matter documents.\n- Upload PDF, DOCX, text, markdown, CSV, JSON, images.\n- PDF / image preview, stored-text viewer, OCR via Ollama.\n- Matter facts, timelines, parties, amounts and deadlines extracted deterministically.\n\n**Workflows & analysis**\n\n`matter_analysis`\n\nagainst a thesis: explicit proof profile, present / partial / missing elements, next actions.- Built-in workflow packs and a custom workflow builder.\n- Tabular review with editable cells, filtering, sorting, saved views and CSV / XLSX / DOCX export.\n\n**Drafting**\n\n- Built-in templates plus a custom template editor.\n**Split-view drafting page**(Claude- / ChatGPT-artifact style): instruction column on the left, live Word-style document preview on the right.- Generate, save into the matter, copy, export to DOCX / PDF.\n\n**AI surface**\n\n- Persisted chat sessions (sidebar, deletable).\n- Multi-provider: Ollama, OpenAI, Anthropic, OpenAI-compatible, no-LLM.\n- Grounded answer engine with citations bound to evidence.\n- MCP stdio server for integration with MCP-aware clients.\n- CLI utilities (\n`judicex`\n\n,`judicex-mcp`\n\n,`judicex-agent`\n\n,`judicex-web`\n\n).\n\n**Privacy & ops**\n\n- Local password gate, backup and restore, optional matter-file encryption.\n- API keys stay in\n`.env`\n\n/ shell, never in the browser.\n\nDrop PNGs into\n\n`docs/screenshots/`\n\nand reference them here once you publish:`docs/screenshots/drafts-split-view.png`\n\n,`docs/screenshots/matter-analysis.png`\n\n, etc. They are intentionally not committed yet — the repository is currently text-only to keep diffs clean.\n\n```\n┌──────────────────────────────┐    ┌──────────────────────────────┐\n│  Web UI (Flask + vanilla JS) │    │  CLI / MCP stdio / Agent     │\n└──────────────┬───────────────┘    └──────────────┬───────────────┘\n               │                                   │\n               ▼                                   ▼\n        ┌─────────────────────────────────────────────────┐\n        │            agent_runtime + answering            │\n        │  intent router → tools → answer_contract → out  │\n        └────────────┬───────────────────────┬────────────┘\n                     │                       │\n                     ▼                       ▼\n        ┌──────────────────────┐  ┌────────────────────────┐\n        │  llm_provider.py     │  │  store.py (SQLite)     │\n        │  ollama / openai /   │  │  documents, atoms,     │\n        │  anthropic / oai-c / │  │  entities, edges,      │\n        │  none                │  │  matters, agent notes  │\n        └──────────────────────┘  └────────────────────────┘\n```\n\nSee [docs/ARCHITECTURE.md](/JustVugg/judicex/blob/main/docs/ARCHITECTURE.md) for the full layer\ndescription and database tables, and\n[docs/JUDICEX_PRODUCT_STRATEGY.md](/JustVugg/judicex/blob/main/docs/JUDICEX_PRODUCT_STRATEGY.md) for\nthe product thesis.\n\n```\ngit clone https://github.com/JustVugg/judicex.git\ncd judicex\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -e \".[crypto]\"\ncp .env.example .env\n\njudicex init-db --db ./memory.db\njudicex web --db ./memory.db --area civile --port 5051\n```\n\nThen open [http://127.0.0.1:5051](http://127.0.0.1:5051).\n\nFor OCR on scanned PDFs:\n\n```\npip install -e \".[crypto,ocr]\"\n```\n\nJudicex reads provider settings from the in-app **Settings** page and from\nenvironment variables. API keys are kept out of the frontend on purpose.\n\n**Local Ollama** (default, fully offline):\n\n```\nollama serve\nollama pull qwen2.5:7b\nJUDICEX_LLM_PROVIDER=ollama\nOLLAMA_HOST=http://127.0.0.1:11434\nOLLAMA_MODEL=qwen2.5:7b\nJUDICEX_OCR_MODEL=glm-5:cloud\n```\n\n**OpenAI:**\n\n```\nJUDICEX_LLM_PROVIDER=openai\nOPENAI_API_KEY=...\nOPENAI_MODEL=gpt-4.1-mini\n```\n\n**Anthropic / Claude:**\n\n```\nJUDICEX_LLM_PROVIDER=anthropic\nANTHROPIC_API_KEY=...\nANTHROPIC_MODEL=claude-3-5-sonnet-latest\n```\n\n**OpenAI-compatible** (LocalAI, vLLM, hosted compatible APIs):\n\n```\nJUDICEX_LLM_PROVIDER=openai_compatible\nOPENAI_COMPATIBLE_API_KEY=...\nOPENAI_COMPATIBLE_BASE_URL=http://127.0.0.1:8000/v1\nOPENAI_COMPATIBLE_MODEL=local-model\n```\n\n**No-LLM mode** also works: deterministic matter analysis, draft templates,\nsearch and audit still run.\n\nSynthetic demo database:\n\n```\npython scripts/create_demo.py --db ./memory.demo.db\njudicex web --db ./memory.demo.db --area civile --port 5051\n```\n\nCLI examples:\n\n```\njudicex matter-create   --db ./memory.db --title \"Recupero credito Beta\" \\\n                        --client-name \"Alfa S.r.l.\" --area civile\njudicex matter-add-doc  --db ./memory.db --matter-id \"matter:...\" \\\n                        --file ./examples/demo_matter.md --kind memo\njudicex matter-context  --db ./memory.db --matter-id \"matter:...\" \\\n                        --query \"fattura pagamento\"\njudicex list-workflow-packs --db ./memory.db\njudicex matter-analyze  --db ./memory.db --matter-id \"matter:...\" \\\n                        --thesis \"ricorso per decreto ingiuntivo\"\njudicex ask             --db ./memory.db --provider ollama --model qwen2.5:7b \\\n                        --area civile --matter-id \"matter:...\" \\\n                        --question \"Che elementi mancano?\"\n```\n\nOperational notes are separate from legal sources. Legal sources hold statutes, official documents, legal atoms and citations; operational notes hold how the assistant should work — preferences, decisions, lessons, recurring strategies, and matter-specific notes.\n\n```\njudicex memory-add    --db ./memory.db --kind preference \\\n                      --title \"Stile recupero crediti\" \\\n                      --content \"Per recupero crediti B2B usa tono pratico.\" \\\n                      --tag recupero_crediti --importance 0.9\njudicex memory-search --db ./memory.db --query \"recupero crediti\"\n```\n\nThe open-source build is designed to run wherever you install it:\n\n- On a single workstation, with a local LLM via Ollama, for a sole practitioner who wants zero recurring cost.\n- On a private server inside the firm, behind a real WSGI stack, VPN and\nbackups (see\n[SECURITY.md](/JustVugg/judicex/blob/main/SECURITY.md)for the hardening checklist). - On any cloud you operate yourself — the codebase has no hard dependency on a specific provider.\n\nA managed cloud version of Judicex (multi-tenant, SSO, hosted upgrades) is on the roadmap as a separate offering. This repository remains Apache-2.0; the cloud product is built on top of it, not in place of it.\n\n```\njudicex/\n├── judicex_memory_os/        # Python package (engine, store, agent, web)\n│   ├── store.py              # SQLite schema, persistence, search\n│   ├── web_app.py            # Flask routes & JSON APIs\n│   ├── agent_runtime.py      # tool-calling agent loop\n│   ├── answering.py          # grounded answer pipeline\n│   ├── answer_contract.py    # claim/citation/numeric validation\n│   ├── matter_analysis.py    # deterministic matter workflow analysis\n│   ├── llm_provider.py       # Ollama / OpenAI / Anthropic / compatible\n│   ├── mcp_stdio.py          # MCP stdio server entry point\n│   ├── cli.py                # `judicex` CLI\n│   ├── workflow_packs/       # JSON workflow packs\n│   ├── templates/            # Flask + draft templates\n│   └── static/               # Vanilla JS UI\n├── tests/                    # unittest suite\n├── benchmarks/               # public benchmark fixtures\n├── docs/                     # architecture, strategy, installers\n└── scripts/                  # dev / test / installer / demo helpers\n```\n\nThe Python package is named `judicex_memory_os`\n\nfor historical reasons; the\nproduct is just **Judicex**.\n\nFor local development, install the package in editable mode and run the\nstandard test script. The tests use Python's built-in `unittest`\n\n; no pytest\ndependency is required.\n\n```\npip install -e \".[crypto,test]\"\nscripts/dev.sh\nscripts/test.sh\npython scripts/run_public_benchmark.py --db ./memory.benchmark.db\n```\n\nThe web UI is server-rendered Flask plus static JavaScript. There is **no\nTypeScript, Next.js, Supabase or external frontend build step** — and there\nis no plan to add one. Contributions that require one will be politely\ndeclined.\n\n- Windows:\n`powershell -ExecutionPolicy Bypass -File .\\scripts\\install_windows.ps1`\n\n- macOS:\n`bash scripts/install_macos.sh`\n\nSee [docs/INSTALLERS.md](/JustVugg/judicex/blob/main/docs/INSTALLERS.md).\n\nThe included `.gitignore`\n\nexcludes the things that *must not* end up on\nGitHub. Before your first push, double-check that none of these are\ntracked:\n\n`.env`\n\n`memory.db`\n\nand any other`*.db`\n\n/`*.sqlite*`\n\nfiles`memory_files/`\n\n,`uploads/`\n\n,`private/`\n\n- API keys, real client documents, screenshots with private data\n\nA pre-publish checklist is documented in [SECURITY.md](/JustVugg/judicex/blob/main/SECURITY.md).\n\nSee [ROADMAP.md](/JustVugg/judicex/blob/main/ROADMAP.md). Highlights:\n\n- Better PDF viewer with page thumbnails and annotation coordinates (\n`v0.3`\n\n) - Rich document editor with version diff and accept/reject (\n`v0.4`\n\n) - Optional auth layer + desktop packaging (\n`v0.5`\n\n) - Multi-user workspace + RBAC + audit export (later)\n\nContributions are welcome — see [CONTRIBUTING.md](/JustVugg/judicex/blob/main/CONTRIBUTING.md). The\ngeneral rules:\n\n- Keep the stack Flask / Python / HTML / JavaScript / SQLite.\n- Never commit private legal documents, real databases, uploads or API keys.\n- Add or update tests for changes touching API behavior, persistence or workflows.\n- Keep provider integrations behind\n`llm_provider.py`\n\n.\n\nApache License 2.0 — see [LICENSE](/JustVugg/judicex/blob/main/LICENSE) and [NOTICE](/JustVugg/judicex/blob/main/NOTICE).\nApache-2.0 was chosen because it is permissive **and** includes an\nexplicit patent grant, which matters for a domain that intersects\nregulated work.\n\nJudicex is a software assistant for legal drafting, document organization\nand evidence-grounded answering. **It does not provide legal advice and\ndoes not replace a qualified legal professional.** Outputs may be\nincomplete, incorrect, outdated or unsuitable for a specific\njurisdiction. See [DISCLAIMER.md](/JustVugg/judicex/blob/main/DISCLAIMER.md).\n\nTo report a vulnerability, please follow [SECURITY.md](/JustVugg/judicex/blob/main/SECURITY.md). Do\nnot open public issues with exploit details.\n\nIf you build something on top of Judicex — a vertical pack for criminal law, a richer drafting UI, an integration with case-management software — please open an issue or a PR. The point of an open-source legal AI is that the verticals are built in the open, not behind a sales NDA.", "url": "https://wpnews.pro/news/show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating", "canonical_source": "https://github.com/JustVugg/judicex", "published_at": "2026-05-26 10:09:09+00:00", "updated_at": "2026-05-26 10:40:24.790512+00:00", "lang": "en", "topics": ["ai-products", "ai-tools", "ai-startups", "large-language-models", "generative-ai"], "entities": ["Judicex", "Harvey", "Legora", "Ollama", "OpenAI", "Anthropic", "Flask", "SQLite"], "alternates": {"html": "https://wpnews.pro/news/show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating", "markdown": "https://wpnews.pro/news/show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating.md", "text": "https://wpnews.pro/news/show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating.txt", "jsonld": "https://wpnews.pro/news/show-hn-judicex-open-source-legal-ai-that-abstains-instead-of-hallucinating.jsonld"}}