A legal change watch surface that searches Vietnamese legal sources, retrieves relevant law chunks, and turns
them into a static review report for recurring attention.
Type: legal monitoringStatus: live betaRole: retrieval-backed review surface
Context
Vietnamese legal changes are easy to miss until they become operational.
The project watches for law changes across Vietnamese legal sources and turns them into a reviewable report.
It is designed to help surface potentially relevant changes, not to replace legal interpretation or final
professional judgment.
Problem
Search results alone do not explain personal relevance.
A law update can be real but irrelevant, or relevant but buried inside a long document. The useful layer is
a repeatable way to find source material, retrieve the matching passages, and analyze them against a user
profile.
Architecture Walkthrough
How Law Watch turns legal text into a review surface.
The system separates corpus building from profile-specific analysis. One path grows the shared legal corpus;
the other retrieves from that corpus and renders a static report.
The ingest flow searches Vietnamese legal sources such as vbpl.vn and thuvienphapluat.vn, fetches candidate
law text, and stores source URLs so repeated runs can avoid rediscovering the same documents unnecessarily.
Corpus
Fetched laws become local retrieval data.
Source text is split into overlapping chunks, embedded locally, and stored in SQLite. Documents and chunks
stay in the shared corpus so later profile runs can retrieve from local storage instead of starting from a
fresh web search every time.
Analysis
Profile-aware review happens after retrieval.
The per-user run embeds the query, retrieves the highest-scoring chunks, and asks a local Ollama model to
produce a structured relevance and impact assessment before rendering the static report.
Output
The final surface is static GitHub Pages HTML.
The pipeline renders the report with Jinja2 and publishes the generated HTML. The live page is intentionally
simple: the heavier discovery, embedding, and analysis work happens locally before deploy.
Technical Stack
The current version favors local control over hosted infrastructure.
Models
Ollama runs the model stack locally.
The app talks to Ollama through its OpenAI-compatible API. `gpt-oss:20b` handles normalization and legal
impact analysis, while `bge-m3` handles embeddings.
Embeddings
`bge-m3` fits the Vietnamese retrieval problem.
The corpus contains Vietnamese legal text, so the embedding layer uses `bge-m3`, a multilingual model with
1024-dimensional dense vectors and better fit for Vietnamese retrieval than an English-centric embedding
model.
Vector store
SQLite stores chunks and NumPy float vectors.
The current store keeps documents and chunk rows in SQLite, serializing embeddings as NumPy `float32` BLOBs.
That keeps the beta architecture small, inspectable, and easy to run on a local machine.
Retrieval
The beta search is exact cosine scoring.
`corpus.retrieve()` embeds the query, scans stored chunks, calculates cosine similarity in NumPy, sorts by
score, and returns the top matches. That exact scan is acceptable at beta scale and keeps the retrieval
behavior easy to reason about.
Limitations
It is a review surface, not a legal authority.
The system can identify potentially relevant changes and show why they may matter, but it does not make the
final legal call. Source grounding and human review remain part of the workflow.
Next step
Move from exact scan to ANN when scale demands it.
As the corpus grows, the retrieval layer can move from full-table cosine scans to an approximate nearest
neighbor index through `sqlite-vec`, FAISS, or HNSW without changing the product loop: build corpus, retrieve
relevant context, analyze against the profile, publish a static report.