<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.dura-lex.org/index.php?action=history&amp;feed=atom&amp;title=Architecture</id>
	<title>Architecture - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.dura-lex.org/index.php?action=history&amp;feed=atom&amp;title=Architecture"/>
	<link rel="alternate" type="text/html" href="https://wiki.dura-lex.org/index.php?title=Architecture&amp;action=history"/>
	<updated>2026-04-23T05:46:04Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.dura-lex.org/index.php?title=Architecture&amp;diff=56&amp;oldid=prev</id>
		<title>Nicolas: Architecture page — from spec/ARCHITECTURE.md, full faithful conversion (via create-page on MediaWiki MCP Server)</title>
		<link rel="alternate" type="text/html" href="https://wiki.dura-lex.org/index.php?title=Architecture&amp;diff=56&amp;oldid=prev"/>
		<updated>2026-04-23T02:18:20Z</updated>

		<summary type="html">&lt;p&gt;Architecture page — from spec/ARCHITECTURE.md, full faithful conversion (via create-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== What Dura Lex is ==&lt;br /&gt;
&lt;br /&gt;
An open-source platform for international legal data. MIT license, ODbL data.&lt;br /&gt;
&lt;br /&gt;
Structures public legal data (legislation, case law, company registries, administrative guidance) into a jurisdiction-agnostic corpus, queryable by AI agents via MCP and by humans via a web portal.&lt;br /&gt;
&lt;br /&gt;
== OS metaphor ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! OS concept !! Dura Lex equivalent&lt;br /&gt;
|-&lt;br /&gt;
| Kernel || duralex — protocols, data models, unified schema&lt;br /&gt;
|-&lt;br /&gt;
| Drivers || Country packages (duralex-fr, duralex-eu, future duralex-gb, duralex-de)&lt;br /&gt;
|-&lt;br /&gt;
| File system || Document IDs, jurisdiction-scoped URIs&lt;br /&gt;
|-&lt;br /&gt;
| System calls || search(), get(), browse(), guidelines(), quality_check()&lt;br /&gt;
|-&lt;br /&gt;
| Package manager || Compiled SQLite packages for the knowledge graph&lt;br /&gt;
|-&lt;br /&gt;
| Applications || duralex-mcp (MCP server), duralex-portal (web), duralex-graph (future)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Package overview (8 packages, 6 repos) ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Package !! Repo !! Role !! Depends on&lt;br /&gt;
|-&lt;br /&gt;
| duralex || duralex/ || Core protocols, data models, temporal, corpus schema, DocumentStore, SearchEngine, FTS. Specs + docs. || nothing&lt;br /&gt;
|-&lt;br /&gt;
| duralex-fr || duralex-jurisdictions/ || French jurisdiction plugin: tag schema, formatters, reference resolver, synonym thesaurus. || duralex&lt;br /&gt;
|-&lt;br /&gt;
| duralex-eu || duralex-jurisdictions/ || EU jurisdiction plugin: EUR-Lex, CJEU, ECHR references. || duralex&lt;br /&gt;
|-&lt;br /&gt;
| duralex-ingest || duralex-ingest/ || Schema DDL, universal BatchWriter, state management, HTML sanitizer. || duralex&lt;br /&gt;
|-&lt;br /&gt;
| duralex-ingest-fr || duralex-ingest/ || French parsers: DILA, Judilibre, BODACC, RNE, BOFiP, CADA, CE, CNIL. || duralex, ingest, fr&lt;br /&gt;
|-&lt;br /&gt;
| duralex-ingest-eu || duralex-ingest/ || EU parsers: EUR-Lex (Cellar), CJEU, ECHR. || duralex, ingest&lt;br /&gt;
|-&lt;br /&gt;
| duralex-mcp || duralex-mcp/ || MCP server: 5 tools (search, get, browse, guidelines, quality_check). Plugin discovery. Docker infra. || duralex, fr/eu&lt;br /&gt;
|-&lt;br /&gt;
| duralex-portal || duralex-portal/ || Web portal for human consultation of the corpus. || duralex&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Future: duralex-graph (knowledge graph compiler, separate repo).&lt;br /&gt;
&lt;br /&gt;
== Dependency graph ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
duralex                           no dependencies&lt;br /&gt;
     |&lt;br /&gt;
     +----&amp;gt; duralex-fr            depends on: duralex&lt;br /&gt;
     +----&amp;gt; duralex-eu            depends on: duralex&lt;br /&gt;
     |&lt;br /&gt;
     +----&amp;gt; duralex-ingest        depends on: duralex&lt;br /&gt;
     |           |&lt;br /&gt;
     |           +----&amp;gt; duralex-ingest-fr    depends on: duralex, ingest, fr&lt;br /&gt;
     |           +----&amp;gt; duralex-ingest-eu    depends on: duralex, ingest&lt;br /&gt;
     |&lt;br /&gt;
     +----&amp;gt; duralex-mcp           depends on: duralex, fr, eu (via plugin discovery)&lt;br /&gt;
     +----&amp;gt; duralex-portal        depends on: duralex&lt;br /&gt;
     +----&amp;gt; duralex-graph         depends on: duralex (future)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Two PostgreSQL schemas ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
corpus.*    -- source documents, citations, tag stats, source metadata&lt;br /&gt;
graph.*     -- concepts, annotations, compiled edges, compilation metadata (future)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Separate schemas in the same database. Different lifecycle:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;corpus&amp;#039;&amp;#039;&amp;#039;: source data, precious (days to re-ingest), stable after ingestion.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;graph&amp;#039;&amp;#039;&amp;#039;: compiled knowledge, reproducible (hours to recompile), write-heavy during compilation.&lt;br /&gt;
&lt;br /&gt;
Benefits: separate VACUUM/ANALYZE, separate backup strategies, &amp;lt;code&amp;gt;DROP SCHEMA graph CASCADE&amp;lt;/code&amp;gt; to recompile without touching corpus.&lt;br /&gt;
&lt;br /&gt;
== Core composition pattern ==&lt;br /&gt;
&lt;br /&gt;
Three levels:&lt;br /&gt;
&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Core protocol&amp;#039;&amp;#039;&amp;#039; (duralex): defines WHAT can be done (DocumentStore protocol, SearchEngine protocol).&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Country implementation&amp;#039;&amp;#039;&amp;#039; (duralex-fr): implements HOW for a specific jurisdiction (formatters, reference resolvers, tag schemas).&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Application&amp;#039;&amp;#039;&amp;#039; (duralex-mcp): composes protocols + implementations at startup.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Reference resolution&amp;#039;&amp;#039;&amp;#039; uses &amp;lt;code&amp;gt;TagQuery&amp;lt;/code&amp;gt; as the universal interface between jurisdiction parsers and the store. This is a core architectural decision — all reference resolution across all jurisdictions flows through TagQuery. There are no typed reference classes per jurisdiction.&lt;br /&gt;
&lt;br /&gt;
* Core defines: &amp;lt;code&amp;gt;TagQuery&amp;lt;/code&amp;gt; dataclass (&amp;lt;code&amp;gt;language&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kind&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tag_filters: TagFilterSet&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;should_sort_in_force_first&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;at_date&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;TagFilterSet&amp;lt;/code&amp;gt; (immutable tuple of &amp;lt;code&amp;gt;TagFilter&amp;lt;/code&amp;gt; predicates with operators EQ/IN/NOT_IN/ILIKE/EXISTS/NOT_EXISTS/NORMALIZE). See [[MCP/Reference resolution]].&lt;br /&gt;
* Jurisdiction plugin (e.g., duralex-fr): parses &amp;quot;article 1240 du code civil&amp;quot; into &amp;lt;code&amp;gt;TagQuery(language=&amp;quot;fr&amp;quot;, kind=&amp;quot;legislation&amp;quot;, tag_filters=TagFilterSet.from_tags({&amp;quot;article_number&amp;quot;: &amp;quot;1240&amp;quot;, &amp;quot;code&amp;quot;: &amp;quot;Code civil&amp;quot;}))&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Store: translates &amp;lt;code&amp;gt;TagQuery&amp;lt;/code&amp;gt; to SQL via the shared &amp;lt;code&amp;gt;build_tag_filter_conditions&amp;lt;/code&amp;gt; builder (generic, zero jurisdiction knowledge).&lt;br /&gt;
&lt;br /&gt;
== MCP tools: 5 ==&lt;br /&gt;
&lt;br /&gt;
search, get, browse, guidelines, quality_check. Each tool is jurisdiction-agnostic. The jurisdiction plugins provide tag schemas, formatters, and reference resolvers — not tools.&lt;br /&gt;
&lt;br /&gt;
== Language boundary ==&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Code&amp;#039;&amp;#039;&amp;#039; (protocols, classes, functions, variables, docstrings): English.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Content&amp;#039;&amp;#039;&amp;#039; (concept names, article text, court names, legal vocabulary): jurisdiction language.&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
</feed>