lle Nederlandse wetten, gespiegeld in git
Wetten zijn publiek eigendom, maar op wetten.overheid.nl kun je niet zien welk woord er gisteren veranderde. Daarom spiegel ik ze: elke wet een tekstbestand, elke wijziging een commit. Nu staan er 19.626 geldende regelingen in, bijgewerkt door een robot die elke ochtend om zes uur kijkt of Den Haag iets heeft veranderd.
De wet is publiek en toch onbruikbaar¶
Alle Nederlandse wet- en regelgeving staat officieel op wetten.overheid.nl. Publiek eigendom, gratis toegankelijk, zonder inlog. En toch praktisch onbruikbaar zodra je meer wilt dan één artikel opzoeken.
Wat je krijgt is HTML en PDF. Voor een mens die iets naslaat is dat prima. Voor iedereen die met de tekst zelf wil werken begint daar het probleem. Er is geen leesbaar tekstformaat om uit te knippen en te bewerken. Er is geen diff. Je kunt zien dát er een vorige versie bestaat, als losse pagina onder een eigen datum. Welke woorden er tussen die twee versies zijn gewisseld, blijft onzichtbaar. Je kunt de verzameling niet in één handeling kopiëren om er lokaal mee te experimenteren. En wie wettekst in een tool wil stoppen, in een compliance-script of een taalmodel, krijgt het bestand simpelweg niet in een vorm die je kunt hergebruiken.
Ik wil hier één ding preciezer zeggen dan ik het eerder schreef. Machineleesbare toegang bestáát wel. Er is een SRU-zoekdienst en er is een XML-repository met de officiële brondocumenten, en mijn eigen spiegel draait op precies die twee. Wat ontbreekt is de laag daarboven: een leesbaar formaat, een geschiedenis die je regel voor regel kunt lezen, en een kopie die je zonder toestemming mag doorgeven. Die drie dingen zijn de reden dat ik het zelf ben gaan bouwen.
Dat is een vreemde situatie als je er even bij stilstaat. De tekst van de wet is het meest publieke document dat er bestaat. Iedereen wordt geacht hem te kennen, en niemand kan zich voor de rechter beroepen op onbekendheid ermee. De vorm waarin hij wordt aangeboden sluit precies die mensen buiten die er iets mee willen bouwen: de programmeur, de journalist die wil weten wanneer een zinsnede is ingevoegd, de jurist die twee versies naast elkaar wil leggen.
Elke wet een bestand, elke wijziging een commit¶
Dus spiegelde ik ze. Het idee is zo simpel dat het bijna saai is. Zet elke geldende regeling neer als een Markdown-bestand met een kop van metadata, stop de hele verzameling in git, en laat een robot elke dag kijken of er iets is veranderd.
Wat je dan krijgt is meer dan een kopie. Het is wetgeving met een geheugen.
Een bestand ziet er zo uit: bovenaan een blok met titel, BWB-identifier, categorie, publicatiedatum, laatste wijziging, status en de bron-URL. Daaronder de wettekst als gewone koppen per boek, hoofdstuk en artikel. De opmaak, de navigatie en de cookiebanner blijven achter. Wat overblijft is de tekst.
Omdat het git is, krijg je de rest er gratis bij. Je ziet per commit welk woord veranderde en op welke dag. Je kunt een wet terugspoelen naar hoe hij vorig jaar luidde. Je kunt de hele verzameling forken en er iets mee doen zonder iemand om toestemming te vragen. Het staat op github.com/Apolloccrypt/wetgeving-nl en draait live op vrijewetgeving.nl.
Concreet, voor wie de geschiedenis van één regeling wil lezen:
git clone https://github.com/Apolloccrypt/wetgeving-nl
cd wetgeving-nl
git log --oneline -- <pad-naar-de-regeling>.md
git diff <oude-commit> <nieuwe-commit> -- <pad-naar-de-regeling>.mdDie laatste regel is het hele punt van het project. Twee commits, één diff, en je ziet welke woorden de wetgever heeft gewisseld. Dat is de handeling die op de officiële site ontbreekt, en het is de handeling waar elke programmeur al twintig jaar aan gewend is.
De motor vraagt alleen op wat er veranderd is¶
Het ophalen gebruikt de zoekdienst van de overheid. Aan SRU kun je vragen welke regelingen sinds een bepaalde datum zijn gewijzigd, en alleen die worden opgehaald. Dat scheelt tienduizenden verzoeken per dag, en het scheelt de bron een belasting die ik er niet op wil leggen.
SRU_URL = "https://zoekservice.overheid.nl/sru/Search"
REPO_BASE = "https://repository.officiele-overheidspublicaties.nl/BWB"
params = {
"operation": "searchRetrieve",
"version": "1.2",
"x-connection": "BWB",
"query": f"dcterms.modified>={vanaf_datum}",
"maximumRecords": batch,
"startRecord": start,
}
r = fetch(SRU_URL, params=params)Wat terugkomt is een lijst BWB-identifiers. Per identifier haalt het script de officiële XML op uit het repository, met een halve seconde tussen de verzoeken, en een eigen parser zet die XML om naar Markdown. Daarna volgt een diff tegen wat er al in de repo staat. Alleen wat echt anders is gaat mee in de commit.
Die volgorde is belangrijk. Zonder die laatste stap zou elke run een commit produceren voor elk bestand dat opnieuw is weggeschreven, ook als er niets in staat dat afwijkt. De geschiedenis zou dan vol ruis staan en precies de eigenschap verliezen waar het me om gaat.
De hele keten hangt aan één cron-regel:
on:
schedule:
- cron: '0 6 * * *'Elke ochtend om zes uur UTC. De commit wordt gezet door wetgeving-bot, met in het bericht hoeveel wetten er die dag zijn bijgewerkt. Dat zijn er meestal een stuk of tien.
Wat er in staat¶
De stand op 23 juli 2026, geteld in de repo zelf. Bewijsniveau: gemeten.
- 19.626 geldende regelingen, elk een eigen bestand. Precies evenveel entries in de zoekindex, dus index en bestanden lopen niet uiteen.
- 423.520 commits op de hoofdtak. Dat is de wetgeschiedenis, regel voor regel.
- 15 categorieën. De grootste is bestuursrecht met 4.767 regelingen, de kleinste financieel recht met 135.
- Naar soort: 7.969 ministeriële regelingen, 2.537 wetten, 2.257 verdragen, 1.841 algemene maatregelen van bestuur, en de rest verspreid.
- De oudste regeling die nog geldt dateert van 13 februari 1815. De nieuwste van gisteren.
Dat laatste vind ik het mooiste getal van de hele verzameling. Er is een tekst uit 1815 die vandaag nog steeds recht is, en hij staat in hetzelfde formaat als een ministeriële regeling van deze week. Dezelfde koppen, dezelfde metadatakop, dezelfde git log. Tweehonderd jaar staatsinrichting valt weg tegen het feit dat het allebei gewoon tekst is.
De verhouding tussen die getallen zegt ook iets. Op 19.626 regelingen staan 423.520 commits, dus gemiddeld ruim twintig wijzigingsmomenten per regeling. Let op: dat gemiddelde is scheef. Een deel van die commits komt uit de initiële vulling en uit opruimacties, en de spreiding is ongelijk, want een belastingwet beweegt vaker dan een verdrag uit de vorige eeuw. Ik noem het cijfer als ruwe orde van grootte. Als maat voor wetgevingsdruk deugt het niet.
Bij dat tellen liep ik tegen een fout van mezelf aan. De README claimde 21.407 regelingen. Gemeten zijn het er 19.626. Het verschil is deels te verklaren. In juli zijn er 256 dubbele bestanden opgeruimd, één per BWB-identifier die twee keer was weggeschreven, en het cijfer in de README is daar nooit op bijgewerkt. De rest van het gat komt vermoedelijk uit eerdere opschoningen en uit regelingen die intussen zijn vervallen, en dat heb ik niet uitgesplitst. Bewijsniveau: het verschil is gemeten, de volledige verklaring ervan is afgeleid en incompleet.
Ik schrijf regelmatig over organisaties die in hun documentatie iets beweren dat hun code niet doet. Dan hoor ik het zelf ook te noemen als het mij overkomt. Het is precies dezelfde fout in het klein: een getal dat ooit klopte, dat in een tekst blijft staan terwijl het systeem eronder verandert, en dat niemand controleert omdat het er plausibel uitziet. Zie Label elke bevinding op bewijsniveau.
De burgerlaag is leeg¶
Een spiegel van je eigen project hoort ook de scheuren te tonen.
Het idee was expliciet dat mensen konden meedenken en voorstellen konden doen. Elke burger een potentiële bijdrager, elk voorstel een pull request, elke discussie een issue. In de praktijk zijn er ooit twee pull requests binnengekomen, waarvan één van een buitenstaander over het vastzetten van workflow-versies, en nul issues. Niet één burger heeft ooit een wetsvoorstel ingediend. De techniek staat er, de deur staat open, en er komt niemand door.
Dat is het echte probleem van dit project, en ik heb het niet opgelost. Het is ook geen probleem dat je met code oplost. Ik kan bedenken waarom het leeg blijft. Git is een drempel voor wie geen ontwikkelaar is. Een pull request op een tekst die de Staten-Generaal vaststelt heeft geen enkele juridische route. Misschien is de vraag om mee te schrijven aan wetgeving gewoon veel groter dan de bereidheid van willekeurige voorbijgangers. Dat zijn vermoedens, ik heb er niets aan gemeten, en ik zet ze hier neer als vermoeden.
Wat ik wel gemeten heb is dat de infrastructuur werkt en de deelname nul is. Dat is een resultaat, ook al is het het resultaat waar ik het minst blij mee ben. Ik heb hetzelfde patroon eerder gezien in mijn andere werk. Zie Waarom ben ik de enige die dit doet?.
De stille faalmodus is de gevaarlijkste bug¶
En dan de fout waar ik het meest wakker van lig.
Als de zoekdienst van formaat verandert of de parser klapt, dan commit de robot niets en meldt de dag "geen wetswijzigingen vandaag". Dat ziet er precies hetzelfde uit als een rustige dag in Den Haag. Nul commits is een normale uitkomst in dit systeem, en dat maakt nul commits als storingssignaal waardeloos.
Voor een spiegel die zijn hele waarde ontleent aan volledigheid is dat de ergste bug die erin kan zitten. Een luide fout stopt de boel en dwingt je te kijken. Deze fout laat de site gewoon doordraaien, met tekst die er onberispelijk uitziet en die stilletjes achterloopt. Hoe langer het duurt, hoe geloofwaardiger de verouderde versie oogt.
De oplossing is niet ingewikkeld. Het systeem moet onderscheid maken tussen "de zoekdienst antwoordde en had niets" en "de zoekdienst antwoordde niet of anders dan verwacht", en op dat tweede geval een alarm zetten. Daarnaast een dodemansknop: als er meer dan zoveel dagen achter elkaar nul wijzigingen zijn, is dat op zichzelf verdacht, want de gemeten dagelijkse doorstroom ligt rond de tien regelingen.
Ik heb het nog niet gebouwd. Ik noem het hier omdat ik van andere partijen verwacht dat ze hun eigen faalmodi opschrijven, en die lat geldt voor mij ook.
Wat dit voor mijn andere werk betekent¶
Dit project staat dichter bij de rest van mijn werk dan het lijkt. Ik meet elders wat websites en apps met bezoekers doen, en die metingen zijn pas iets waard als ik ze kan leggen naast wat de wet op dat moment eiste. Wetteksten in git maken die vergelijking mogelijk in de tijd: welke verplichting gold er op de dag van de meting, en wanneer is die zinsnede erin gekomen.
Er zit ook een principe onder dat ik in al mijn projecten terugzie. Publieke informatie die alleen als plaatje wordt aangeboden is formeel openbaar en praktisch gesloten. De aanwezigheid van een pagina is niet hetzelfde als de mogelijkheid om er iets mee te doen. Wie de vorm bepaalt, bepaalt wie er kan meekijken. Zie De maker en de aandeelhouder willen niet hetzelfde.
En de meest bruikbare les zit in de burgerlaag die leeg bleef. Ik kan een systeem bouwen dat technisch precies doet wat ik beloofde, en dat toch zijn doel mist omdat het deel dat van mensen afhangt niet vanzelf op gang komt. Dat is een correctie op mijn eigen reflex om aan te nemen dat een goed gebouwde deur ook wordt gebruikt.
Zie ook Apple, Google en Meta verdienen aan tracking binnen de wet, Randall Munroe verliet NASA en geeft xkcd gratis weg en Dezelfde meetlat voor de overheid en de app in je broekzak.
- SRU-koppeling van wetten.overheid.nlde officiele bron waaruit de spiegel dagelijks wordt bijgewerkt
- Eigen bevinding: wetgeving nl zelfmeting 2026 07 24, 2026-07-24gemeten: 19.626 regelingen, 423.520 commits, stille faalmodus