CASE STUDY · LEGAL AI · 2026

Offline AI that reads thousands of messages so a competition lawyer reads the right ones.

A desktop tool for a law team that ranks antitrust risk in employees' WhatsApp and e-mail, with the quote, the reasoning and similar Competition Board decisions next to every finding. Nothing leaves the lawyer's laptop.

Role sole engineer, with a practicing competition lawyerSince Sep 2026Stack Python · FastAPI · React · Electron · local LLMs
Review screen: findings ranked by risk score, with the critical quote highlighted, the model's reasoning, and the surrounding messages.
Review screen on a synthetic demo case (fictional company and people). Each finding shows a risk score, category, the highlighted quote verified against the source message, the model's reasoning and the full conversation window. Interface in Turkish, the client's working language.

The problem

In a compliance audit or a dawn-raid preparation, a lawyer has to find the few messages that look like price fixing, market sharing, bid rigging or sensitive information exchange, inside tens of thousands of chats and e-mails.

Cloud AI is off the table: client data is privileged and can't leave the lawyer's machine. So the model has to run locally, on a laptop GPU, and still be good enough to trust.

"Ege tarafındaki zincirlere girmeyin demişler, biz de Karadeniz'e bakmayacağız."
"They said stay out of the Aegean chains, so we won't touch the Black Sea." A synthetic market-sharing message the tool flags at risk 90.

Results on a frozen test set

375 examples (339 from published Board decisions, 36 synthetic negatives), frozen before tuning so every round is measured against the same bar.

0.920
AUC, best local model (Gemma 4 12B, round 10)
0.888
accuracy at the review threshold chosen on validation
1.3 pts
behind Claude Opus, fully offline
10
measured fine-tuning rounds, one change each

AUC by model

Higher is better. Same frozen 375-example test set.
ModelThresholdAccuracyFalse alarmsMissedCategory acc.AUC
Gemma 4 12B, base (no tuning)500.74710850.460.82
Round 8 · Qwen3-8B500.80044310.5690.797
Round 10 · Gemma 4 12B500.83517450.7500.920
Round 10 · Gemma 4 12B30 (val)0.8883210––
Claude Opus (reference)500.90118190.8630.947

Threshold 30 was picked on the validation set, not the test set. It also matches the product's "needs review" band (30-79), so a lawyer sees borderline windows instead of losing them.

How it works

ImportWhatsApp exports and iPhone backups, Gmail mbox, Outlook PST. SHA-256 per file, no duplicates.
Encrypted vaultOne encrypted database per case, hash-chained audit log, secure delete on close.
Windows + pre-filterMessages grouped into 4-hour windows, keyword and competitor watchlist pre-filter.
Local LLM + RAGFine-tuned model scores each window; the most similar Board decisions are retrieved as precedents.
Lawyer reviewRanked findings with quote, reasoning and context. Keyboard-first: R / I / V to decide.
ReportPDF with scope, methodology, findings, statistics and the audit-trail appendix.
Case overview: 800 messages from 8 sources and 4 employees analysed in 217 windows, 12 high-risk findings.
Case overview on the demo case: 800 messages, 8 sources, 217 analysis windows, 12 high-risk findings. Analysis is resumable if the app is closed.

How the model got better

Data

  • Collected all 10,469 published Competition Board decisions (329M characters) as a Turkish competition-law corpus.
  • Extracted the real correspondence the Board treated as evidence, plus synthetic normal business chatter as negatives.
  • Built a 12,049-row training set, including 8,674 windows labelled by Claude as a teacher model (distillation).

Training

  • LoRA / QLoRA with Unsloth on Kaggle T4 and Modal A100 GPUs.
  • Models tried: Qwen3.5-4B, Qwen3-8B, Qwen3-14B, Gemma 4 12B.
  • Served locally through Ollama; bge-m3 embeddings for the precedent library.

Working with the lawyer

  • Five versions of a written rule set, reviewed line by line.
  • A 5-band risk scale and a keyword dictionary from the lawyer's revisions.
  • Error reviews after every round, sorted into "model wrong" and "label debatable".
The biggest gains didn't come from bigger models. They came from fixing labels with the lawyer and changing one thing per round.

Privacy by design

Stack

PythonFastAPISQLCipherOllamaQwen3Gemma 4Unsloth LoRA / QLoRAKaggle · Modal GPUsbge-m3 RAGClaude (teacher labels, baseline)ReactElectronpytest · vitest