▍ A self-hosted legal mind
GDKS: a legal AI that says "I don't know"
This is the system I mentioned in passing in How this started — the agentic, multi-turn RAG that put my first Blackwell to real work. It deserves its own telling, because it never began as a project. It began as a throwaway line.
I was working on a large information system, and a project manager and I were just musing: ideally there’d be a kind of self-hosted NotebookLM — something you could pour an entire organisation’s documents, laws and specifications into, and that would answer only from them, without inventing a thing. Nobody had asked for it. There was no requirement, no ticket, no budget. But that offhand idea is the one that set me on the whole path. I called it GDKS — Grounded Domain Knowledge System.
The one rule: only speak from the source
GDKS answers complex Estonian legal and regulatory questions strictly from verifiable sources — and when it has no grounding, it says so. Out loud. “I don’t know.”
That sounds like a small thing. It is the entire thing. A model that will confidently invent a plausible-sounding statute is worse than useless in legal work; it’s a liability. The whole system is built around the opposite instinct: every claim traces back to a source, or it doesn’t get made. If GDKS can’t ground an answer, the honest “I can’t” is the answer.
Six indexes of Estonian law
The knowledge base is six distinct Estonian legal-source indexes, each one I assembled myself:
- Current law and Supreme Court (Riigikohus) practice from Riigi Teataja — roughly 8 million indexed text chunks
- Tartu’s municipal acts
- Chancellor-of-Justice (Õiguskantsler) opinions
- Riigikogu explanatory memoranda — the legislative intent behind a statute, which is often where the real answer lives
- Spatial-planning guidance — the planning data I scraped from the city’s public interface myself
Building that corpus was its own job: custom scrapers, a dedicated Riigi Teataja XML parser that indexes the in-force consolidated law, PDF parsing for everything that didn’t come clean. Origin says I downloaded 100GB of Estonian legal text — this is where it went.
Not an ask-and-answer box
GDKS isn’t “type a question, get a paragraph.” It works out which of those indexes a question belongs to, breaks the question into sub-questions, and then runs an iterative research loop — taking as many steps as the question actually needs. A typical query is a 5–10 minute deep pass, spinning up parallel search branches when it helps.
Retrieval is hybrid: semantic vector search (bge-m3 embeddings in ChromaDB) fused with keyword search (BM25) via Reciprocal Rank Fusion — so it catches both the meaning and the exact legal terms, which matter enormously when one word changes which paragraph applies. It cross-references statutes against court practice, against Chancellor-of-Justice opinions, against legislative intent.
And — this is the part I’m proudest of — it doesn’t only read its own indexes. Mid-research, it makes live calls into authoritative Estonian state sources. I indexed Supreme Court practice through 2010; anything newer, it searches in Riigi Teataja’s court-decision database in real time. To ground answers in current facts, it can query, live:
- the land register (kinnistusraamat)
- the building register (ehitisregister)
- the national planning database (PLANK)
- the environmental register (EELIS — protected areas, Natura 2000)
- Tartu’s municipal GIS
So an answer isn’t anchored to a frozen snapshot of stored text — it’s anchored to what the registers actually say today.
The Tribunal
A grounded answer still isn’t trusted on sight. Every answer is then checked by a “Tribunal” — a multi-agent cross-examination, an Inspector and a Judge, picking the reasoning apart. For the heaviest questions there’s a multi-instance consensus mode that returns a conviction score and, effectively, jury votes. The system argues with itself before it ever talks to you. (That same multi-agent instinct is the one I later pulled into fleet ops — different domain, same shape.)
Real cases, real people
GDKS isn’t a demo I screenshotted once. I tested it on real cases, with real people:
- My sister, an environmental specialist, used it for an actual environmental pre-assessment — a spatial inventory of wetlands, groundwater and protected species.
- A Tartu city lawyer fed it a genuine administrative-planning dispute (the Emajõe hiking-trail / general-plan case). It produced a strong-versus-weak argument map and predicted a partial grant, citing the directly on-point Supreme Court ruling — RKHKo 3-21-2553/19.
- A homeowner brought a tangled question about a balcony heat pump and splitting an apartment. GDKS broke it into fifteen sub-questions, pulled the property’s actual land- and building-register records, applied three Supreme Court rulings, and correctly flagged that the housing-association vote was void for lack of quorum.
- A forced-easement (sundvaldus) appeal it drafted in filing-ready form, anchored on a Supreme Court decision handed down only weeks earlier — which it found through that live Riigi Teataja court search. That’s the payoff of the live calls: it stays current exactly where a training-frozen model cannot.
It ranged from environmental assessments and planning applications to court filings and even international-document recognition — working out, for instance, that Thailand is outside the Apostille Convention, so foreign documents need full consular legalisation. Always with citations back to the source.
The stack
I built the whole thing, corpus to server.
- Backend: Python + FastAPI, running as systemd services. Frontend on Vercel, public API exposed via a Cloudflare Tunnel.
- Retrieval: hybrid search — BAAI/bge-m3 multilingual embeddings in ChromaDB, fused with bm25s (Rust-optimised BM25) via Reciprocal Rank Fusion.
- Reasoning model: Claude (Opus 4.5 / Haiku 4.5) or Gemini 2.0 Flash — but the architecture is model-agnostic, so it runs just as well on open models self-hosted on my own GPUs, keeping data fully in-house.
- Verification: the Tribunal (Inspector + Judge) plus multi-instance consensus with conviction scoring.
- Live integrations: real-time tools the research agent calls into Estonian state registries — Riigi Teataja court search, kinnistusraamat (via the standard paid citizen access), ehitisregister, MTR, PLANK, EELIS, Tartu GIS — all publicly available services.
- Output: inline citations, export to clean PDF, and for court matters a library of Estonian court-document templates so it produces filing-ready drafts.
Where it stands, honestly
The next step was going to be a GraphRAG layer — linking all of Estonian law into one connected graph, so statutes, amendments, court practice and cross-references resolve logically instead of living in six separate indexes. I’d reached the design. And then I deliberately paused the project — not because it stopped working, but because of where it would have to run.
The blocker is confidentiality. Using Claude or Gemini means the data leaves to a third party’s servers — a non-starter for privileged legal material. The correct fix is obvious: run everything on self-hosted open models, so nothing ever leaves a private environment. I went down that path. The genuine problem was that the open models good enough to self-host were, at the time, noticeably weaker in Estonian than the commercial ones — I was already trialling Estonian-focused open models like TildeOpen. So I was caught between two unacceptable options: good Estonian, but the data leaves, and fully private, but weaker Estonian. For confidential legal work, neither one is OK.
That’s the real lesson, and it’s why GDKS sits where it sits. The hard part of practical AI isn’t building the system — I built it. The hard part is getting it adopted somewhere it can run safely: on the right data, for the right people, with verification and source-citations built in, and without the sensitive material ever leaving the room. Knowing where these tools genuinely help — and where they must not be allowed to touch the data — turned out to be the whole game.
It’s paused, not abandoned. The open-model gap closes a little every month, and the day a self-hostable model is fluent enough in Estonian, GDKS already knows what it wants to be.
The principle
Build AI systems that respect the human and institutional context they operate in.
Two years of working on my own in the AI space have made clear to me what it can do and what it can’t. Twenty years of writing code inside Estonian companies gave me something no AI can replicate. New AI solutions that hold up on contact with real users, real institutions and real failure modes — that’s where I most want to contribute today.