<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://yusupov.cloud/index.php?action=history&amp;feed=atom&amp;title=Nomos</id>
	<title>Nomos - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://yusupov.cloud/index.php?action=history&amp;feed=atom&amp;title=Nomos"/>
	<link rel="alternate" type="text/html" href="https://yusupov.cloud/index.php?title=Nomos&amp;action=history"/>
	<updated>2026-05-16T13:18:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://yusupov.cloud/index.php?title=Nomos&amp;diff=411&amp;oldid=prev</id>
		<title>Mvuijlst at 15:42, 20 April 2026</title>
		<link rel="alternate" type="text/html" href="https://yusupov.cloud/index.php?title=Nomos&amp;diff=411&amp;oldid=prev"/>
		<updated>2026-04-20T15:42:17Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:42, 20 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l6&quot;&gt;Line 6:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 6:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 05_genre        = AI-generated legal document archive&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 05_genre        = AI-generated legal document archive&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 06_language     = Python&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 06_language     = Python&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 07_framework    = [[Django]] &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;6.0 &lt;/del&gt;/ [[Wagtail]] &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;7.3&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 07_framework    = [[Django]] / [[Wagtail]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 08_license      = Proprietary&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 08_license      = Proprietary&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l14&quot;&gt;Line 14:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 14:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Technology stack ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Technology stack ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application is built on Django &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;6.0.4 &lt;/del&gt;with Wagtail &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;7.3.1 &lt;/del&gt;as its content management framework and [[SQLite]] as its development database.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;ref name=&quot;requirements&quot;&amp;gt;requirements.txt lists Django 6.0.4, wagtail 7.3.1, openai 2.32.0, requests 2.33.1, python-dotenv 1.2.2, beautifulsoup4 4.14.3, and Pillow 12.2.0.&amp;lt;/ref&amp;gt; &lt;/del&gt;Additional dependencies include the [[OpenAI]] Python client for language-model calls, [[Requests (software)|Requests]] for HTTP communication with the Vlaamse Codex API, [[Beautiful Soup (HTML parser)|Beautiful Soup]] for scraping title inspiration from the Belgisch Staatsblad, [[Pillow (imaging library)|Pillow]] as a Wagtail dependency, and [[python-dotenv]] for environment configuration. The front end uses [[Bootstrap]] &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;5.3.8 &lt;/del&gt;loaded from the jsDelivr CDN with subresource integrity hashes. All user interface text is in Dutch.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application is built on Django with Wagtail as its content management framework and [[SQLite]] as its development database. Additional dependencies include the [[OpenAI]] Python client for language-model calls, [[Requests (software)|Requests]] for HTTP communication with the Vlaamse Codex API, [[Beautiful Soup (HTML parser)|Beautiful Soup]] for scraping title inspiration from the Belgisch Staatsblad, [[Pillow (imaging library)|Pillow]] as a Wagtail dependency, and [[python-dotenv]] for environment configuration. The front end uses [[Bootstrap]] loaded from the jsDelivr CDN with subresource integrity hashes. All user interface text is in Dutch&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. The planned production deployment targets a Hetzner VPS behind [[Nginx]] with [[Gunicorn]] and [[PostgreSQL]]&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Data model ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Data model ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l62&quot;&gt;Line 62:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 62:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 2: Technical mutation ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 2: Technical mutation ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The seed document&#039;s title (&#039;&#039;opschrift&#039;&#039;) is sent to the OpenAI Chat Completions API (&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;default &lt;/del&gt;model&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: GPT-5, &lt;/del&gt;configurable via the &amp;lt;code&amp;gt;OPENAI_MODEL&amp;lt;/code&amp;gt; environment variable). The system prompt instructs the model to behave as an expert in Flemish legislation and to perform a semantic shift: replace the core subject with a plausible but fictional technical equivalent while preserving the exact grammatical structure and bureaucratic tone. If a topic hint was obtained from the Belgisch Staatsblad, it is included as thematic guidance.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;ref name=&quot;temperature&quot;&amp;gt;GPT-5 does not support custom temperature values. All API calls use the model&#039;s default temperature (1).&amp;lt;/ref&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The seed document&#039;s title (&#039;&#039;opschrift&#039;&#039;) is sent to the OpenAI Chat Completions API (&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;the &lt;/ins&gt;model &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;is &lt;/ins&gt;configurable via the &amp;lt;code&amp;gt;OPENAI_MODEL&amp;lt;/code&amp;gt; environment variable). The system prompt instructs the model to behave as an expert in Flemish legislation and to perform a semantic shift: replace the core subject with a plausible but fictional technical equivalent while preserving the exact grammatical structure and bureaucratic tone. If a topic hint was obtained from the Belgisch Staatsblad, it is included as thematic guidance.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 3: Administrative drafting ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 3: Administrative drafting ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l89&quot;&gt;Line 89:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 89:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Text sanitisation ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Text sanitisation ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;All generated text is passed through a sanitisation function that strips Unicode control characters (C0/C1 range, excluding newlines and tabs), applies NFC normalisation, removes empty list items and orphaned list wrappers from the HTML, and cleans whitespace artifacts. This addresses a known issue where &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;GPT-5 &lt;/del&gt;occasionally &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;emits &lt;/del&gt;ASCII control characters in place of Unicode punctuation.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;All generated text is passed through a sanitisation function that strips Unicode control characters (C0/C1 range, excluding newlines and tabs), applies NFC normalisation, removes empty list items and orphaned list wrappers from the HTML, and cleans whitespace artifacts. This addresses a known issue where &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;some language models &lt;/ins&gt;occasionally &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;emit &lt;/ins&gt;ASCII control characters in place of Unicode punctuation.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Persistence ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Persistence ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key yusupov:diff:1.41:old-410:rev-411:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Mvuijlst</name></author>
	</entry>
	<entry>
		<id>https://yusupov.cloud/index.php?title=Nomos&amp;diff=410&amp;oldid=prev</id>
		<title>Mvuijlst: /* Technology stack */</title>
		<link rel="alternate" type="text/html" href="https://yusupov.cloud/index.php?title=Nomos&amp;diff=410&amp;oldid=prev"/>
		<updated>2026-04-20T15:41:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Technology stack&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:41, 20 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l14&quot;&gt;Line 14:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 14:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Technology stack ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Technology stack ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application is built on Django 6.0.4 with Wagtail 7.3.1 as its content management framework and [[SQLite]] as its development database.&amp;lt;ref name=&quot;requirements&quot;&amp;gt;requirements.txt lists Django 6.0.4, wagtail 7.3.1, openai 2.32.0, requests 2.33.1, python-dotenv 1.2.2, beautifulsoup4 4.14.3, and Pillow 12.2.0.&amp;lt;/ref&amp;gt; Additional dependencies include the [[OpenAI]] Python client for language-model calls, [[Requests (software)|Requests]] for HTTP communication with the Vlaamse Codex API, [[Beautiful Soup (HTML parser)|Beautiful Soup]] for scraping title inspiration from the Belgisch Staatsblad, [[Pillow (imaging library)|Pillow]] as a Wagtail dependency, and [[python-dotenv]] for environment configuration. The front end uses [[Bootstrap]] 5.3.8 loaded from the jsDelivr CDN with subresource integrity hashes. All user interface text is in Dutch&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. The planned production deployment targets a Hetzner VPS behind [[Nginx]] with [[Gunicorn]] and [[PostgreSQL]]&lt;/del&gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application is built on Django 6.0.4 with Wagtail 7.3.1 as its content management framework and [[SQLite]] as its development database.&amp;lt;ref name=&quot;requirements&quot;&amp;gt;requirements.txt lists Django 6.0.4, wagtail 7.3.1, openai 2.32.0, requests 2.33.1, python-dotenv 1.2.2, beautifulsoup4 4.14.3, and Pillow 12.2.0.&amp;lt;/ref&amp;gt; Additional dependencies include the [[OpenAI]] Python client for language-model calls, [[Requests (software)|Requests]] for HTTP communication with the Vlaamse Codex API, [[Beautiful Soup (HTML parser)|Beautiful Soup]] for scraping title inspiration from the Belgisch Staatsblad, [[Pillow (imaging library)|Pillow]] as a Wagtail dependency, and [[python-dotenv]] for environment configuration. The front end uses [[Bootstrap]] 5.3.8 loaded from the jsDelivr CDN with subresource integrity hashes. All user interface text is in Dutch.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Data model ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Data model ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key yusupov:diff:1.41:old-409:rev-410:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Mvuijlst</name></author>
	</entry>
	<entry>
		<id>https://yusupov.cloud/index.php?title=Nomos&amp;diff=409&amp;oldid=prev</id>
		<title>Mvuijlst at 15:40, 20 April 2026</title>
		<link rel="alternate" type="text/html" href="https://yusupov.cloud/index.php?title=Nomos&amp;diff=409&amp;oldid=prev"/>
		<updated>2026-04-20T15:40:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:40, 20 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l29&quot;&gt;Line 29:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 29:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;seed_document&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — human-readable label recording the type and title of the source document.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;seed_document&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — human-readable label recording the type and title of the source document.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;generation_notes&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — an LLM-generated human-readable summary describing how the generated document differs from its source.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;generation_notes&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — an LLM-generated human-readable summary describing how the generated document differs from its source.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* &#039;&#039;revision_notes&#039;&#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — an LLM-generated summary of the subtle details introduced during the revision stage (see below); empty if the revision was rejected or produced no changes.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Full-text search is indexed on &amp;#039;&amp;#039;full_title&amp;#039;&amp;#039; and &amp;#039;&amp;#039;body&amp;#039;&amp;#039; via Wagtail&amp;#039;s database search backend.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Full-text search is indexed on &amp;#039;&amp;#039;full_title&amp;#039;&amp;#039; and &amp;#039;&amp;#039;body&amp;#039;&amp;#039; via Wagtail&amp;#039;s database search backend.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l34&quot;&gt;Line 34:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 35:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Generation pipeline ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Generation pipeline ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Generation is driven by the &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; management command, which invokes a &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;five&lt;/del&gt;-stage pipeline implemented in &amp;lt;code&amp;gt;nomos/services/generator.py&amp;lt;/code&amp;gt;. The pipeline retries up to three times if validation fails.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Generation is driven by the &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; management command, which invokes a &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;multi&lt;/ins&gt;-stage pipeline implemented in &amp;lt;code&amp;gt;nomos/services/generator.py&amp;lt;/code&amp;gt;. The pipeline retries up to three times if validation fails.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 1: Structural sourcing ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 1: Structural sourcing ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l57&quot;&gt;Line 57:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 58:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Topic inspiration ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Topic inspiration ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Before generating, the pipeline scrapes the &#039;&#039;Belgisch Staatsblad&#039;&#039; website (&amp;lt;code&amp;gt;ejustice.just.fgov.be&amp;lt;/code&amp;gt;) for a random document title to use as thematic inspiration. Federal and national references in the scraped title are replaced with Flemish equivalents using a table of 17 substitution pairs — for example, &quot;Federale Overheidsdienst&quot; becomes &quot;Vlaamse overheidsdienst,&quot; &quot;Koninklijk besluit&quot; becomes &quot;Besluit van de Vlaamse Regering,&quot; and &quot;België&quot; becomes &quot;Vlaanderen.&quot; If the scrape fails, generation proceeds without a topic hint.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Before generating, the pipeline scrapes the &#039;&#039;Belgisch Staatsblad&#039;&#039; website (&amp;lt;code&amp;gt;ejustice.just.fgov.be&amp;lt;/code&amp;gt;) for a random document title to use as thematic inspiration&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. To avoid reusing the same inspiration across runs, the scraper selects a random publication date from the past 90 days rather than always fetching the current edition&lt;/ins&gt;. Federal and national references in the scraped title are replaced with Flemish equivalents using a table of 17 substitution pairs — for example, &quot;Federale Overheidsdienst&quot; becomes &quot;Vlaamse overheidsdienst,&quot; &quot;Koninklijk besluit&quot; becomes &quot;Besluit van de Vlaamse Regering,&quot; and &quot;België&quot; becomes &quot;Vlaanderen.&quot; If the scrape fails, generation proceeds without a topic hint.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 2: Technical mutation ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 2: Technical mutation ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l73&quot;&gt;Line 73:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 74:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The output is requested as clean HTML using &amp;lt;code&amp;gt;&amp;amp;lt;h2&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;h3&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;p&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;ol&amp;amp;gt;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;amp;lt;li&amp;amp;gt;&amp;lt;/code&amp;gt; elements, without a top-level heading (which is rendered separately on the page).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The output is requested as clean HTML using &amp;lt;code&amp;gt;&amp;amp;lt;h2&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;h3&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;p&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;ol&amp;amp;gt;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;amp;lt;li&amp;amp;gt;&amp;lt;/code&amp;gt; elements, without a top-level heading (which is rendered separately on the page).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== Stage 3b: Subtle revision ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;After drafting, the full text is sent to an additional API call that introduces &#039;&#039;defamiliarisation through precision&#039;&#039;: the model is instructed to locate 3 to 5 passages dealing with execution, control, materials, or conditions, and to make a single local detail in each slightly more specific or procedural than necessary — for example, adding an unexpectedly precise measurement, a format requirement, or a procedural substep. The changes must be strictly additive; no text may be removed or truncated. Two programmatic guards run before the revision is accepted: an identity check rejects revisions that return the text unchanged, and a length check rejects revisions where the word count drops below 95% of the original (indicating deleted content). If a revision fails either guard, it is retried once. A separate validation call (the &#039;&#039;revision scrub&#039;&#039;) then checks whether the revision shifted the main subject, introduced too many or contextually inappropriate details, or deleted content. If the revision is rejected or produced no changes, the unrevised text is used.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 4: Juridical scrub ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 4: Juridical scrub ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l80&quot;&gt;Line 80:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 85:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 5: Generation notes ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Stage 5: Generation notes ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;After successful validation, &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;a final &lt;/del&gt;API call generates a human-readable summary of the transformation. The model is instructed to act as an archivist and to describe in one or two plain-language sentences how the new document&#039;s subject differs from the original, without technical jargon.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;After successful validation, &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;an &lt;/ins&gt;API call generates a human-readable summary of the transformation. The model is instructed to act as an archivist and to describe in one or two plain-language sentences how the new document&#039;s subject differs from the original, without technical jargon&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. If the subtle revision was accepted, a second call compares the pre- and post-revision texts word by word and produces a bullet-point list of the specific passages that were changed, stored as &#039;&#039;revision_notes&#039;&#039;&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Text sanitisation ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Text sanitisation ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l114&quot;&gt;Line 114:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 119:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Visual design ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Visual design ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The interface is inspired by the [[GOV.UK Design System]]. The base template features a dark masthead with a yellow (&amp;lt;code&amp;gt;#ffe615&amp;lt;/code&amp;gt;) accent border, the site name &quot;Nomos&quot; as a navigation link, and a dark/light mode toggle button. The toggle uses CSS custom properties for theming and persists the user&#039;s preference in &amp;lt;code&amp;gt;localStorage&amp;lt;/code&amp;gt;. In dark mode, the masthead shifts to &amp;lt;code&amp;gt;#1a1a1a&amp;lt;/code&amp;gt;, links become lighter, and status tag colours are adjusted for contrast. A responsive layout collapses the summary list key/value pairs into a single column below 576px.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The interface is &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;very loosely &lt;/ins&gt;inspired by the [[GOV.UK Design System]]. The base template features a dark masthead with a yellow (&amp;lt;code&amp;gt;#ffe615&amp;lt;/code&amp;gt;) accent border, the site name &quot;Nomos&quot; as a navigation link, and a dark/light mode toggle button. The toggle uses CSS custom properties for theming and persists the user&#039;s preference in &amp;lt;code&amp;gt;localStorage&amp;lt;/code&amp;gt;. In dark mode, the masthead shifts to &amp;lt;code&amp;gt;#1a1a1a&amp;lt;/code&amp;gt;, links become lighter, and status tag colours are adjusted for contrast. A responsive layout collapses the summary list key/value pairs into a single column below 576px.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Administration ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Administration ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application uses the standard Wagtail admin interface &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;at &amp;lt;code&amp;gt;/admin/&amp;lt;/code&amp;gt;&lt;/del&gt;. &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; content panels expose the instrument type, full title, body, publication date, and status. A separate &quot;Generatie-informatie&quot; settings panel groups the seed ID, seed reference URL, seed document description, and &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;generation &lt;/del&gt;notes — metadata that is recorded automatically during generation and is accessible to editors but not displayed on the public site.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The application uses the standard Wagtail admin interface. &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; content panels expose the instrument type, full title, body, publication date, and status. A separate &quot;Generatie-informatie&quot; settings panel groups the seed ID, seed reference URL, seed document description&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, generation notes&lt;/ins&gt;, and &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;revision &lt;/ins&gt;notes — metadata that is recorded automatically during generation and is accessible to editors but not displayed on the public site.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The Django admin is available &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;at &amp;lt;code&amp;gt;/django-admin/&amp;lt;/code&amp;gt; &lt;/del&gt;for lower-level database access.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The Django admin is available for lower-level database access.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Logging ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Logging ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l132&quot;&gt;Line 132:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 137:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;! Command !! Purpose&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;! Command !! Purpose&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; || Run the full &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;five-stage &lt;/del&gt;pipeline: fetch seed, tilt title, draft decree, validate, generate notes, and publish as a Wagtail page&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; || Run the full &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;generation &lt;/ins&gt;pipeline: fetch seed, tilt title, draft decree&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, apply subtle revision&lt;/ins&gt;, validate, generate notes, and publish as a Wagtail page&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;setup_index_page&amp;lt;/code&amp;gt; || Create the &amp;lt;code&amp;gt;DecreeIndexPage&amp;lt;/code&amp;gt; as the site root (idempotent); removes the default Wagtail welcome page if present&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;setup_index_page&amp;lt;/code&amp;gt; || Create the &amp;lt;code&amp;gt;DecreeIndexPage&amp;lt;/code&amp;gt; as the site root (idempotent); removes the default Wagtail welcome page if present&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key yusupov:diff:1.41:old-408:rev-409:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Mvuijlst</name></author>
	</entry>
	<entry>
		<id>https://yusupov.cloud/index.php?title=Nomos&amp;diff=408&amp;oldid=prev</id>
		<title>Mvuijlst: Created page with &quot;{{Infobox | 01_name         = Nomos | 02_url          = https://nomos.yusupov.cloud | 03_developer    = Michel Vuijlsteke | 04_released     = 2026 | 05_genre        = AI-generated legal document archive | 06_language     = Python | 07_framework    = Django 6.0 / Wagtail 7.3 | 08_license      = Proprietary }}  &#039;&#039;&#039;Nomos&#039;&#039;&#039; is a web application hosted at &lt;code&gt;nomos.yusupov.cloud&lt;/code&gt; that generates and publishes AI-created Flemish administrative legislation. Each...&quot;</title>
		<link rel="alternate" type="text/html" href="https://yusupov.cloud/index.php?title=Nomos&amp;diff=408&amp;oldid=prev"/>
		<updated>2026-04-19T23:18:18Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{Infobox | 01_name         = Nomos | 02_url          = https://nomos.yusupov.cloud | 03_developer    = Michel Vuijlsteke | 04_released     = 2026 | 05_genre        = AI-generated legal document archive | 06_language     = Python | 07_framework    = &lt;a href=&quot;/index.php?title=Django&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Django (page does not exist)&quot;&gt;Django&lt;/a&gt; 6.0 / &lt;a href=&quot;/index.php?title=Wagtail&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Wagtail (page does not exist)&quot;&gt;Wagtail&lt;/a&gt; 7.3 | 08_license      = Proprietary }}  &amp;#039;&amp;#039;&amp;#039;Nomos&amp;#039;&amp;#039;&amp;#039; is a web application hosted at &amp;lt;code&amp;gt;nomos.yusupov.cloud&amp;lt;/code&amp;gt; that generates and publishes AI-created Flemish administrative legislation. Each...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Infobox&lt;br /&gt;
| 01_name         = Nomos&lt;br /&gt;
| 02_url          = https://nomos.yusupov.cloud&lt;br /&gt;
| 03_developer    = Michel Vuijlsteke&lt;br /&gt;
| 04_released     = 2026&lt;br /&gt;
| 05_genre        = AI-generated legal document archive&lt;br /&gt;
| 06_language     = Python&lt;br /&gt;
| 07_framework    = [[Django]] 6.0 / [[Wagtail]] 7.3&lt;br /&gt;
| 08_license      = Proprietary&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Nomos&amp;#039;&amp;#039;&amp;#039; is a web application hosted at &amp;lt;code&amp;gt;nomos.yusupov.cloud&amp;lt;/code&amp;gt; that generates and publishes AI-created Flemish administrative legislation. Each day, the system fetches a real document from the Vlaamse Codex open-data API, performs a semantic shift on its subject matter using a large language model, and produces a structurally faithful but entirely fictional legal text — a decree, ministerial order, or circular — that reads as if it were published in the &amp;#039;&amp;#039;Belgisch Staatsblad&amp;#039;&amp;#039;. The generated documents are stored in a [[Wagtail (CMS)|Wagtail]] content management system and presented through a GOV.UK-inspired Dutch-language public interface. The name &amp;#039;&amp;#039;Nomos&amp;#039;&amp;#039; derives from the [[Ancient Greek|Greek]] word νόμος, meaning &amp;quot;law.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Technology stack ==&lt;br /&gt;
&lt;br /&gt;
The application is built on Django 6.0.4 with Wagtail 7.3.1 as its content management framework and [[SQLite]] as its development database.&amp;lt;ref name=&amp;quot;requirements&amp;quot;&amp;gt;requirements.txt lists Django 6.0.4, wagtail 7.3.1, openai 2.32.0, requests 2.33.1, python-dotenv 1.2.2, beautifulsoup4 4.14.3, and Pillow 12.2.0.&amp;lt;/ref&amp;gt; Additional dependencies include the [[OpenAI]] Python client for language-model calls, [[Requests (software)|Requests]] for HTTP communication with the Vlaamse Codex API, [[Beautiful Soup (HTML parser)|Beautiful Soup]] for scraping title inspiration from the Belgisch Staatsblad, [[Pillow (imaging library)|Pillow]] as a Wagtail dependency, and [[python-dotenv]] for environment configuration. The front end uses [[Bootstrap]] 5.3.8 loaded from the jsDelivr CDN with subresource integrity hashes. All user interface text is in Dutch. The planned production deployment targets a Hetzner VPS behind [[Nginx]] with [[Gunicorn]] and [[PostgreSQL]].&lt;br /&gt;
&lt;br /&gt;
== Data model ==&lt;br /&gt;
&lt;br /&gt;
The data model uses Wagtail&amp;#039;s page tree. A singleton &amp;lt;code&amp;gt;DecreeIndexPage&amp;lt;/code&amp;gt; (limited to &amp;lt;code&amp;gt;max_count = 1&amp;lt;/code&amp;gt;) serves as the parent of all generated documents. Each document is a &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; with the following fields:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;instrument&amp;#039;&amp;#039; — one of four types: Decreet, Besluit, Omzendbrief, or Reglement.&lt;br /&gt;
* &amp;#039;&amp;#039;full_title&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — the complete title, unlimited in length. The standard Wagtail &amp;#039;&amp;#039;title&amp;#039;&amp;#039; field (255-character limit) holds a truncated copy for internal use.&lt;br /&gt;
* &amp;#039;&amp;#039;body&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;RichTextField&amp;lt;/code&amp;gt;) — the full HTML text of the generated legislation.&lt;br /&gt;
* &amp;#039;&amp;#039;publication_date&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;DateField&amp;lt;/code&amp;gt;) — set to the generation date.&lt;br /&gt;
* &amp;#039;&amp;#039;status&amp;#039;&amp;#039; — either &amp;#039;&amp;#039;Geldig&amp;#039;&amp;#039; (valid) or &amp;#039;&amp;#039;Gearchiveerd&amp;#039;&amp;#039; (archived); defaults to Geldig.&lt;br /&gt;
* &amp;#039;&amp;#039;seed_id&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;IntegerField&amp;lt;/code&amp;gt;, unique, nullable) — the numeric ID of the source document in the Vlaamse Codex, used for deduplication to ensure no seed is used twice.&lt;br /&gt;
* &amp;#039;&amp;#039;seed_reference&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;URLField&amp;lt;/code&amp;gt;) — direct API link to the source document.&lt;br /&gt;
* &amp;#039;&amp;#039;seed_document&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — human-readable label recording the type and title of the source document.&lt;br /&gt;
* &amp;#039;&amp;#039;generation_notes&amp;#039;&amp;#039; (&amp;lt;code&amp;gt;TextField&amp;lt;/code&amp;gt;) — an LLM-generated human-readable summary describing how the generated document differs from its source.&lt;br /&gt;
&lt;br /&gt;
Full-text search is indexed on &amp;#039;&amp;#039;full_title&amp;#039;&amp;#039; and &amp;#039;&amp;#039;body&amp;#039;&amp;#039; via Wagtail&amp;#039;s database search backend.&lt;br /&gt;
&lt;br /&gt;
== Generation pipeline ==&lt;br /&gt;
&lt;br /&gt;
Generation is driven by the &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; management command, which invokes a five-stage pipeline implemented in &amp;lt;code&amp;gt;nomos/services/generator.py&amp;lt;/code&amp;gt;. The pipeline retries up to three times if validation fails.&lt;br /&gt;
&lt;br /&gt;
=== Stage 1: Structural sourcing ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;pick_random_seed()&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;nomos/services/codex.py&amp;lt;/code&amp;gt; fetches up to 200 recent documents from the Vlaamse Codex open-data API (&amp;lt;code&amp;gt;codex.opendata.api.vlaanderen.be&amp;lt;/code&amp;gt;). Candidates are filtered to four allowed document types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Codex type !! Mapped instrument&lt;br /&gt;
|-&lt;br /&gt;
| Decreet || DECREET&lt;br /&gt;
|-&lt;br /&gt;
| Besluit van de Vlaamse Regering || BESLUIT&lt;br /&gt;
|-&lt;br /&gt;
| Ministerieel besluit || BESLUIT&lt;br /&gt;
|-&lt;br /&gt;
| Omzendbrief || OMZENDBRIEF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Documents whose &amp;lt;code&amp;gt;seed_id&amp;lt;/code&amp;gt; already exists in the database are excluded. The remaining candidates are grouped by type, and a weighted random selection favours types that have been used less frequently in the preceding seven days. For each recently used instrument, the selection weight is reduced by two per occurrence (minimum weight of 1). Once a seed is selected, the system fetches its full detail and chapter/section structure from the API.&lt;br /&gt;
&lt;br /&gt;
=== Topic inspiration ===&lt;br /&gt;
&lt;br /&gt;
Before generating, the pipeline scrapes the &amp;#039;&amp;#039;Belgisch Staatsblad&amp;#039;&amp;#039; website (&amp;lt;code&amp;gt;ejustice.just.fgov.be&amp;lt;/code&amp;gt;) for a random document title to use as thematic inspiration. Federal and national references in the scraped title are replaced with Flemish equivalents using a table of 17 substitution pairs — for example, &amp;quot;Federale Overheidsdienst&amp;quot; becomes &amp;quot;Vlaamse overheidsdienst,&amp;quot; &amp;quot;Koninklijk besluit&amp;quot; becomes &amp;quot;Besluit van de Vlaamse Regering,&amp;quot; and &amp;quot;België&amp;quot; becomes &amp;quot;Vlaanderen.&amp;quot; If the scrape fails, generation proceeds without a topic hint.&lt;br /&gt;
&lt;br /&gt;
=== Stage 2: Technical mutation ===&lt;br /&gt;
&lt;br /&gt;
The seed document&amp;#039;s title (&amp;#039;&amp;#039;opschrift&amp;#039;&amp;#039;) is sent to the OpenAI Chat Completions API (default model: GPT-5, configurable via the &amp;lt;code&amp;gt;OPENAI_MODEL&amp;lt;/code&amp;gt; environment variable). The system prompt instructs the model to behave as an expert in Flemish legislation and to perform a semantic shift: replace the core subject with a plausible but fictional technical equivalent while preserving the exact grammatical structure and bureaucratic tone. If a topic hint was obtained from the Belgisch Staatsblad, it is included as thematic guidance.&amp;lt;ref name=&amp;quot;temperature&amp;quot;&amp;gt;GPT-5 does not support custom temperature values. All API calls use the model&amp;#039;s default temperature (1).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stage 3: Administrative drafting ===&lt;br /&gt;
&lt;br /&gt;
The tilted title, the seed document&amp;#039;s full text (up to 4,000 characters), and its structural outline are sent to a second API call. The system prompt instructs the model to act as a legislative jurist of the Flemish government and to rewrite the source document about the new subject. Strict structural parity rules are enforced:&lt;br /&gt;
&lt;br /&gt;
* The output must contain the exact same number of chapters (&amp;#039;&amp;#039;hoofdstukken&amp;#039;&amp;#039;), sections (&amp;#039;&amp;#039;afdelingen&amp;#039;&amp;#039;), and articles (&amp;#039;&amp;#039;artikelen&amp;#039;&amp;#039;) as the source.&lt;br /&gt;
* If the source has no chapter divisions, the output must not introduce them.&lt;br /&gt;
* The total length must be comparable to the source.&lt;br /&gt;
* Content must be entirely original — only the form is emulated.&lt;br /&gt;
&lt;br /&gt;
The output is requested as clean HTML using &amp;lt;code&amp;gt;&amp;amp;lt;h2&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;h3&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;p&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;ol&amp;amp;gt;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;amp;lt;li&amp;amp;gt;&amp;lt;/code&amp;gt; elements, without a top-level heading (which is rendered separately on the page).&lt;br /&gt;
&lt;br /&gt;
=== Stage 4: Juridical scrub ===&lt;br /&gt;
&lt;br /&gt;
The generated HTML is submitted to a validation call in which the model acts as a quality controller. It checks for the presence of narrative, poetic, or metaphorical language; references to fiction, imagination, or art; and humor or irony. Documents that do not read as authentic administrative texts are rejected with a reason. If all three attempts fail validation, the pipeline raises an error.&lt;br /&gt;
&lt;br /&gt;
=== Stage 5: Generation notes ===&lt;br /&gt;
&lt;br /&gt;
After successful validation, a final API call generates a human-readable summary of the transformation. The model is instructed to act as an archivist and to describe in one or two plain-language sentences how the new document&amp;#039;s subject differs from the original, without technical jargon.&lt;br /&gt;
&lt;br /&gt;
=== Text sanitisation ===&lt;br /&gt;
&lt;br /&gt;
All generated text is passed through a sanitisation function that strips Unicode control characters (C0/C1 range, excluding newlines and tabs), applies NFC normalisation, removes empty list items and orphaned list wrappers from the HTML, and cleans whitespace artifacts. This addresses a known issue where GPT-5 occasionally emits ASCII control characters in place of Unicode punctuation.&lt;br /&gt;
&lt;br /&gt;
=== Persistence ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;save_decree()&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;nomos/services/storage.py&amp;lt;/code&amp;gt; creates a &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; as a child of the &amp;lt;code&amp;gt;DecreeIndexPage&amp;lt;/code&amp;gt;. The slug is derived from the title (truncated to 200 characters) and made unique by appending a numeric suffix if necessary. The page is published immediately via Wagtail&amp;#039;s &amp;lt;code&amp;gt;save_revision().publish()&amp;lt;/code&amp;gt; mechanism. The publication date is set to the current date and the status defaults to &amp;#039;&amp;#039;Geldig&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Anti-sameness system ==&lt;br /&gt;
&lt;br /&gt;
To prevent the archive from becoming repetitive, the system employs two mechanisms:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Seed deduplication&amp;#039;&amp;#039;&amp;#039;: the &amp;lt;code&amp;gt;seed_id&amp;lt;/code&amp;gt; field (unique integer) ensures that no Vlaamse Codex document is used as a source more than once. Before selecting a seed, the pipeline queries all existing &amp;lt;code&amp;gt;seed_id&amp;lt;/code&amp;gt; values and excludes them from the candidate pool.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Type-weighted selection&amp;#039;&amp;#039;&amp;#039;: the &amp;lt;code&amp;gt;_get_recent_type_counts()&amp;lt;/code&amp;gt; function counts how many times each instrument type has appeared in the last seven days. Types with higher recent counts receive proportionally lower selection weights, encouraging the system to alternate between decrees, orders, and circulars.&lt;br /&gt;
&lt;br /&gt;
== Public interface ==&lt;br /&gt;
&lt;br /&gt;
=== Index page ===&lt;br /&gt;
&lt;br /&gt;
The index page lists all published &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; children ordered by publication date (newest first). A search bar and an instrument type dropdown filter are provided. Search uses Wagtail&amp;#039;s database search backend, querying the &amp;#039;&amp;#039;full_title&amp;#039;&amp;#039; and &amp;#039;&amp;#039;body&amp;#039;&amp;#039; fields. The type filter applies an exact match on the &amp;#039;&amp;#039;instrument&amp;#039;&amp;#039; field. Each list entry displays the full title, publication date, instrument type label, and a colour-coded status tag (green for &amp;#039;&amp;#039;Geldig&amp;#039;&amp;#039;, grey for &amp;#039;&amp;#039;Gearchiveerd&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
=== Document detail page ===&lt;br /&gt;
&lt;br /&gt;
Each decree page displays:&lt;br /&gt;
&lt;br /&gt;
* A breadcrumb navigation link back to the index page.&lt;br /&gt;
* The full title as a top-level heading.&lt;br /&gt;
* A GOV.UK-style summary list with key/value rows for document type, publication date, and status (rendered as a tag badge).&lt;br /&gt;
* The full decree body rendered as rich text.&lt;br /&gt;
&lt;br /&gt;
=== Visual design ===&lt;br /&gt;
&lt;br /&gt;
The interface is inspired by the [[GOV.UK Design System]]. The base template features a dark masthead with a yellow (&amp;lt;code&amp;gt;#ffe615&amp;lt;/code&amp;gt;) accent border, the site name &amp;quot;Nomos&amp;quot; as a navigation link, and a dark/light mode toggle button. The toggle uses CSS custom properties for theming and persists the user&amp;#039;s preference in &amp;lt;code&amp;gt;localStorage&amp;lt;/code&amp;gt;. In dark mode, the masthead shifts to &amp;lt;code&amp;gt;#1a1a1a&amp;lt;/code&amp;gt;, links become lighter, and status tag colours are adjusted for contrast. A responsive layout collapses the summary list key/value pairs into a single column below 576px.&lt;br /&gt;
&lt;br /&gt;
== Administration ==&lt;br /&gt;
&lt;br /&gt;
The application uses the standard Wagtail admin interface at &amp;lt;code&amp;gt;/admin/&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;DecreePage&amp;lt;/code&amp;gt; content panels expose the instrument type, full title, body, publication date, and status. A separate &amp;quot;Generatie-informatie&amp;quot; settings panel groups the seed ID, seed reference URL, seed document description, and generation notes — metadata that is recorded automatically during generation and is accessible to editors but not displayed on the public site.&lt;br /&gt;
&lt;br /&gt;
The Django admin is available at &amp;lt;code&amp;gt;/django-admin/&amp;lt;/code&amp;gt; for lower-level database access.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
Application logging is configured with two handlers: console output and a rotating file log (&amp;lt;code&amp;gt;nomos.log&amp;lt;/code&amp;gt; in the project root). The &amp;lt;code&amp;gt;nomos&amp;lt;/code&amp;gt; logger is set to &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; level and records each pipeline stage (seed selection, title tilting, drafting, validation, publication) with document identifiers and truncated titles.&lt;br /&gt;
&lt;br /&gt;
== Management commands ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;generate_decree&amp;lt;/code&amp;gt; || Run the full five-stage pipeline: fetch seed, tilt title, draft decree, validate, generate notes, and publish as a Wagtail page&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;setup_index_page&amp;lt;/code&amp;gt; || Create the &amp;lt;code&amp;gt;DecreeIndexPage&amp;lt;/code&amp;gt; as the site root (idempotent); removes the default Wagtail welcome page if present&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Deployment ==&lt;br /&gt;
&lt;br /&gt;
The planned production deployment targets &amp;lt;code&amp;gt;nomos.yusupov.cloud&amp;lt;/code&amp;gt; on a Hetzner VPS running [[Nginx]] as a reverse proxy, [[Gunicorn]] as the WSGI application server, and [[PostgreSQL]] as the production database (replacing SQLite). TLS is to be provided by [[Let&amp;#039;s Encrypt]] via Certbot. Daily generation is to be scheduled via cron calling &amp;lt;code&amp;gt;python manage.py generate_decree&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[OpenAI]]&lt;br /&gt;
* [[Django (web framework)]]&lt;br /&gt;
* [[Wagtail (CMS)]]&lt;br /&gt;
* [[Vlaamse Codex]]&lt;br /&gt;
* [[Computational creativity]]&lt;br /&gt;
* [[Procedural generation]]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{reflist}}&lt;/div&gt;</summary>
		<author><name>Mvuijlst</name></author>
	</entry>
</feed>