RFC-026 beantwoordt welke knopen meedoen en waar de sluiting ophoudt. Deze RFC beantwoordt in welke volgorde je ze aandoet en wat een venster is. Die tweede vraag heeft een eigen meting en een eigen faalvorm, en RFC-026 draagt hem niet zonder uit elkaar te vallen. De afhankelijkheid loopt één kant op: zonder de afbakening van RFC-026 heeft een volgorde geen begin.
Een verrijkingsrun verwerkt vandaag een venster: de volgende N entries in documentvolgorde, geteld vanaf een cursor. N is een constante uit een omgevingsvariabele. De snede die daaruit volgt heeft niets te maken met wat de wet doet; hij loopt dwars door de afhankelijkheden heen.
Het gevolg is meetbaar. Artikel 1 wordt bezocht terwijl artikel 5 nog geen model heeft. Een binding van 1 naar een output van 5 is daar niet te leggen, want die output bestaat op dat moment niet. Alleen het laatste venster ziet alles wat ervoor staat. Een deel van wat na afloop op de poorten blijft staan is daarom een te vroege meting en geen fout.
In het bouwplan is een venster een verzameling artikelen waarvan niets van iets anders in diezelfde verzameling afhangt. De omvang volgt uit de wet en niet uit een constante.
De lagen komen uit één deterministische scan. De artikeltekst noemt de andere
artikelen woordelijk (“bedoeld in artikel 8”) en de oogst draagt daarnaast een
references-blok met het BWB-nummer erbij. De scan leest beide, condenseert de
graaf op sterk samenhangende componenten en verdeelt die componenten over lagen.
Een knoop is (wet, artikel) en niet artikel: de wetsgrens komt uit de bron en
is geen aanname van de code.
Dezelfde scan levert het tweede product: welke entry welke waarde produceert. Dat is de index die de afrondende pass nodig heeft. De volgorde en de te sluiten bindingen komen dus uit één scan, want twee scans lopen uiteen.
Een consument die vóór zijn producent draait kan alleen raden hoe de waarde gaat heten. Draait de producent eerst, dan ziet de consument de output mét de naam die de producent er werkelijk aan gaf, en is de binding echt. Draaien ze in de verkeerde volgorde, dan verzinnen twee vensters onafhankelijk een naam voor hetzelfde begrip. Die twee namen komen nooit meer bij elkaar: een afrondende pass verbindt wat overeenkomt, en twee verschillende woorden voor één begrip komen niet overeen. Zo’n gat is stil, en een openstaande bevinding is dat niet; niemand vindt het terug.
De volgorde is daarmee een correctheidseigenschap, en dat is ook de reden dat gelijktijdigheid binnen een laag veilig is en tussen lagen niet.
Een deel van onze markeringen is geen inhoudelijk oordeel. Het doelwit bestond nog niet toen we keken.
Het staat in de lopende run zwart op wit. Artikel 2 van de Wet op de zorgtoeslag
draagt een open term standaardpremie, gedelegeerd aan Onze Minister, terwijl
artikel 4 inmiddels een output met diezelfde naam levert. Toen artikel 2 werd
geschreven had artikel 4 geen model, dus was er niets om aan te binden en werd de
waarde als open term genoteerd. Die markering zegt iets over het moment van kijken
en niet over de wet.
Deze klasse verdwijnt door de goede volgorde en niet door iets slimmers. Wat er na de goede volgorde nog van overblijft, gaat naar de afrondende pass.
Wetten en artikelen verwijzen over en weer, dus er is niet altijd een topologische volgorde. RFC-026 stelt dat vast tussen wetten en kiest daar een sluitings-poort in plaats van een volgorde. Binnen één wet geldt hetzelfde in het klein: de Awir heeft één sterk samenhangende component van negen hoofdartikelen (2, 3, 7, 8, 9, 13, 14, 16 en 38).
Een groep die niet te ordenen is, wordt één laag. Dat is een venster dat je hebt afgeleid in plaats van geraden, en het is het eerlijke antwoord op de cyclusvraag: binnen zo’n component bestaat geen volgorde die producenten vooraan zet, dus daar blijft de afrondende pass nodig.
Vijf onafhankelijke artikelen in één laag kun je door één agent laten doen of door vijf agents tegelijk. Dat is een afweging en geen ontwerpkeuze, dus het is een instelling met standaard één tegelijk.
Het cijfer dat de afweging draagt: venster 3 van de lopende run kostte $5,92 bij vier aanroepen, waarvan 5,3 miljoen tokens cache-read. Dat zijn de skills, het schema en de contextbrief die elke beurt opnieuw meegaan. Die vaste last per sessie is de post die je vermenigvuldigt als je fijner snijdt: negen artikelen in negen sessies in plaats van twee betaalt hem vier tot vijf keer vaker. Preciezer, en mogelijk duurder.
Tokens zijn vandaag de schaarste omdat dit op een persoonlijk account draait. Bij vierduizend wetten is de wandklok de schaarste, en een keten die alleen sequentieel kan schaalt daar niet mee.
Twee agents die tegelijk in dezelfde YAML schrijven is een meting waarvan niemand kan zeggen wie wat schreef; ronde 3 verloor daar vier runs aan. Elke agent werkt daarom in een eigen kopie van de checkout, en de samenvoeging is per entry. De samenvoeging weigert in plaats van te raden: een venster dat een entry aanraakte die niet aan hem was toegewezen laat de run falen met dat entrynummer in de melding.
Gemeten op het corpus van ronde 4: de Awir met 329 entries en de Wet op de zorgtoeslag met 35, beide volledig verrijkt. Daarin staan 57 intra-wet bindingen die vooruit wijzen, waarbij de consument vóór de producent in het document staat. Dat is de klasse die een venster niet kan leggen.
Een volgorde uit de verwijzingsgraaf lost die niet op. Een topologische orde over de hoofdartikelen, cycli gecondenseerd en gelijkspel op documentvolgorde, bracht die 57 op 69. Documentvolgorde is al een goede bouwvolgorde, want de wetgever zet definities en algemene bepalingen vooraan. De verwijzingsgraaf draait dat juist om: “in afwijking van artikel 8” laat een later artikel naar een eerder wijzen zonder dat er een waarde overgaat, en zulke kanten wegen in een topologische orde even zwaar als de kanten die er wel toe doen.
De vensterrand lost hem wel op. 48 van de 57 zitten binnen één hoofdartikel: een aanhef die bindt aan zijn eigen leden of onderdelen. Geen enkele herordening van artikelen raakt die. Een vensterrand die een hoofdartikel niet doorknipt haalt ze allemaal binnen één venster; bij de venstermaat die vandaag draait daalt het aantal bindingen dat buiten zijn venster valt van 46 naar 8.
Van die acht hebben er vijf een invoernaam die woordelijk gelijk is aan de outputnaam. Dat is het mechanische deel. De andere drie noemen hetzelfde begrip met andere woorden en zijn de enige gevallen waar een agent nodig is.
Het bouwplan als volgorde levert op dit materiaal dus niets op en de laag als vensterrand het meeste. Dat berust op twee wetten. De volgordemodus blijft daarom bestaan en staat uit, zodat de claim op ander materiaal opnieuw te meten is.
Wat er na de vensterrand overblijft, sluit een pass over de hele wet, na het laatste venster. Hij verbindt alleen wat inmiddels bestaat.
Het deterministische deel schrijft de worker zelf: een invoer zonder source
waarvan de naam woordelijk gelijk is aan een output die een andere entry van
dezelfde wet levert, met de parameters van die entry aangeleverd uit wat de
consument zelf heeft. Bij enige twijfel gebeurt er niets. Twee entries die
dezelfde output leveren, een parameter die de consument niet kan aanleveren, een
open term die nu ook als output bestaat: dat gaat als aanwijzing naar een agent
met een smalle opdracht die vooral zegt wat hij niet mag. Niets herinterpreteren,
geen artikel opnieuw modelleren, geen markering bijzetten of weghalen die over de
inhoud gaat.
De pass draait over een wet die al door alle poorten is gegaan, dus alles wat hij toevoegt is achteruitgang. Daarom meet hij zichzelf na, en beide helften doen dat: twee tellingen vóór en na de schrijfactie, de schemafouten en de deterministische bevindingen. De meting beslist, niet wat de pass van plan was.
De twee helften hebben een andere drempel omdat ze een andere opdracht hebben.
Het deterministische deel moet iets verbeteren en niets verslechteren: staan beide
tellingen na afloop gelijk, dan gaat de tekst terug. Gelijk is geen bewijs van
niets: één bevinding die verdwijnt naast één die ontstaat telt ook gelijk, en op
een aantal is een verzameling niet af te lezen. Dat de schemafouten meetellen is
geen ruimhartigheid maar de plek waar dit deel zijn werk aflevert — een invoer
zonder source is een schemafout en geen bevinding, dus een gelegde binding
repareert het schema terwijl het bevindingenaantal stilstaat. Gemeten op de
bevindingen alleen zou de pass zijn eigen enige effect weigeren.
Het agent-deel wordt afgerekend op “niets slechter”. Of een aanwijzing goed beantwoord is, valt uit geen van beide tellingen af te lezen: een correct beantwoorde aanwijzing hoeft geen bevinding weg te nemen. Loopt een telling op of wordt het bestand onleesbaar, dan gaat de tekst terug naar wat er vóór de agent stond. Dat deel is de laatste schrijver van de run, dus wat het laat staan is wat gecommit wordt, en de harde schemapoort draait er daarom achter en niet ervóór.
De cursor telt vandaag lineair door het document en garandeert daarmee terminatie in een vast aantal runs. Beide veranderingen laten die garantie staan.
De vensterrand die een hoofdartikel heel houdt schuift de rechterrand alleen
vooruit, nooit terug. Elke geslaagde run verzet de cursor met ten minste N
entries of bereikt het einde, dus de grens van ceil(entries / N) runs blijft
gelden.
In de laagmodus telt de cursor lagen in plaats van entries. Elke geslaagde run
verhoogt hem met één en het aantal lagen ligt vast, dus de wandeling eindigt in
ten hoogste lagen runs. De twee tellingen betekenen niet hetzelfde, dus staat de
modus naast de cursor in de sidecar: verandert de modus, dan begint de wandeling
opnieuw, net zoals bij een gewijzigd pad.
Een bouwplan kan ook door meerdere wetten wandelen. De Wet op de zorgtoeslag
bindt aan drie entries van de Awir: berekeningsjaar in 2.1.b,
toetsingsinkomen in 2.1.i en rendementsgrondslag_zonder_vrijstelling in 7.5.
Loopt het plan over die grens, dan worden die drie eerst verrijkt en pas daarna
het artikel van de zorgtoeslag dat ze leest. De binding is dan echt en geen
markering met een adres erbij. Dat vraagt een index over het hele corpus en het raakt de afbakening uit
RFC-026: welke wetten doen mee, waar stopt de sluiting, wat is een bekend gat.
Die veralgemenisering staat als issue MinBZK/regelrecht#1088 en wordt hier niet
opnieuw uitgeschreven. De datastructuur is er wel op gebouwd: een knoop is
(wet, artikel), en een kruisverwijzing wordt al gelezen en bewaard.
De vaste last per sessie valt half weg als de contextbrief per artikel krimpt tot alleen wat dát artikel aanhaalt. Of dat opweegt tegen het vaker betalen van die last bij fijner snijden, is te meten en niet te beredeneren. Dat staat open tot er een run is waarin de wandklok telt.
An exploration by Bureau Architectuur of the Dutch Ministry of Economic Affairs and Climate Policy into the possibilities of transparent, executable legislation.
GitHub repository
How it works
Stay informed
Roadmap (Dutch)
Documentation
Research
Bureau Architectuur
Ministry of Economic Affairs and Climate Policy