Inspiration
Algeria publishes its law in the official journal (Joradp.dz) , twice a week, as a PDF. There is no API, no article-level index, and no search worth the name. A citizen asking whether they can register as an auto-entrepreneur, or what the finance law changed about their income tax, cannot find his answer unless he asks a professional or an expert in the field. I myself usually pay for consultations to get insights and usually they are not up to date. Sahla law (DZ Law) exists to close that gap: 3,508 issues, 115,976 pages, 2005 to 2026, ingested, split into 9,001 texts and 69,866 articles, searchable in Arabic and French, and answerable in plain language with a citation attached to every claim.
What it does
A citizen asks a question in Arabic, French, or Algerian derja, gets an answer grounded in the actual text of the law, with the source article one click away. Search across the whole corpus is free and unmetered; the assistant that answers questions spends credits (5 free for all and on sign up, 1000 DZD (Algerian Dinar) for 100 credits, 1 credit per answer). because the archive should never be behind a paywall, only the answer. We tested it so we must give that at least for free.
How we built it
AI does five jobs in production, and each is a decision the system would otherwise get wrong:
- Query planning. A model rewrites the question into the vocabulary the Journal officiel actually uses — an Algerian asking in derja does not write "société à responsabilité limitée", and the corpus never writes anything else.
- Term weighting. Document frequency decides which words in a query are worth searching on. Terms above 6% of the corpus are dropped ("article" 20.5%, "loi" 9.0%) so a query isn't carried by noise words.
- Ranking. Relevance is multiplied by extraction grade — a passage from a text extracted cleanly enough to be cited by article number outranks the same words found in an unsplit blob.
- Model routing. A router picks the answering model across three providers (Cloudflare Workers AI, DeepSeek, Gemini), failing over only while nothing has reached the reader yet.
- Refusal. If the word that made a question specific appears nowhere in the corpus, retrieval returns nothing, and the assistant says so before offering context — instead of quoting whatever happened to contain the word "loi".
That last decision was the hardest to build and the one we're proudest of. Asked about cryptocurrency — a subject this corpus is silent on — the assistant used to return ten confident, irrelevant sources and hedge. The failure wasn't the model; it was retrieval manufacturing noise for the model to reason over. Fixing it meant measuring the corpus rather than tuning prompts: term frequencies, extraction grades, and a flag for the 12,974 articles that are publication formulas rather than rules, not the answer to anything.
The stack: Elixir/Phoenix LiveView for the app, PostgreSQL for storage, Meilisearch (with Charabia for Arabic tokenisation) for full-text search, and the Gemini API for query planning, answering, and the Arabic OCR pipeline used during ingestion, alongside Cloudflare Workers AI and DeepSeek in the free-tier routing chain.
Challenges we ran into
Arabic OCR was the hardest technical problem: Tesseract reverses law numbers, NVIDIA's vision models fail on Arabic legal typography, Surya needs a GPU we don't have, DeepSeek has no vision API. Gemini was the only option that actually worked on real Journal officiel scans. But it costs and the estimate to get the whole thing is around 3000$ which we can't invest yet.
The retrieval failure described above — ten irrelevant sources returned with confidence for an out-of-corpus question — was the failure that reshaped the whole ranking pipeline, moving it from raw text match to a system that weighs extraction quality and knows when to say nothing.
Accomplishments that we're proud of
9 of 9 real legal questions in our end-to-end smoke test (mix assistant.smoke) came back grounded in cited passages, including a deliberate control question (cryptocurrency) that the corpus doesn't cover — the assistant correctly says so instead of hallucinating an answer. Search runs in 6–131ms across 69,866 articles in two languages.
What we learned
A legal assistant that overstates its own coverage is worse than no assistant. The instinct when a corpus is incomplete is to hide the gap; instead we scoped the launch to the 1,066 texts verified article-by-article, print the coverage ratio on the home screen, and label every source with its extraction grade. The hardest part of this project was never the model — it was being honest about what the retrieval layer actually knows.
What's next for DZ Law
Article-level extraction for the Arabic corpus (currently searchable as whole documents only, blocked on OCR billing), re-chunking the 2,618 partially-extracted texts on structural markers instead of raw text blocks, and persisting conversation history (the tables exist; nothing writes to them yet).
Built With
- ai
- api
- cloud
- cloudflare
- deepseek
- elixir
- gemini
- liveview
- meilisearch
- phoenix
- postgresql
- tailwindcss
- workers



Log in or sign up for Devpost to join the conversation.