De verrijker vroeg over vier ronden tien keer om een datumbewerking. Zes
verschillende namen: YEAR, MONTH, DAY_OF_MONTH, START_OF_MONTH, een
periodetype, en een “kalendermaand volgende op”. Ze komen neer op twee functies.
Die achterstand was af te lezen uit het corpus zelf. Een markering met
resolution: operation is de bewering dat een bewerking ontbreekt, en sinds
RFC-031 noemt resolved_by verplicht wat die bewering zou oplossen. Groepeer de
markeringen op dat veld en de gevraagde bewerkingen staan op een rij, met hun
frequentie erbij. Zonder dat veld waren dit tien losse aantekeningen in tien
bestanden gebleven.
De vraag eronder gaat over tellen. Vier gevraagde namen zijn twee functies op
drie kalendereenheden, en de taal heeft al een plek waar een kalendereenheid
staat: het veld in van DATE_DIFF uit RFC-021.
De motor kende vijf datumbewerkingen en ze zijn alle vijf anders
geparameteriseerd. DATE bouwt een datum uit year, month en day, waar de
eenheid de veldnaam is. DATE_ADD telt op met dezelfde vorm. DATE_DIFF neemt
de eenheid als waarde in in. AGE en DAY_OF_WEEK dragen hun eenheid in hun
naam.
Die spreiding is een spoor. AGE is DATE_DIFF ... in: years met een eigen
naam, geschreven voordat DATE_DIFF bestond; RFC-021 zegt dat zelf. DAY_OF_WEEK is het spoor van één wet die ooit een weekdag nodig had. Dat
DAY_OF_WEEK bestaat en DAY_OF_MONTH niet, is dus geen gat in een ontwerp.
Vier namen erbij verlengen dat spoor met vier.
Twee bewerkingen erbij, en niet vier.
YEAR, MONTH, DAY_OF_MONTH en START_OF_MONTH komen er niet als aparte
namen. DAY_OF_WEEK blijft staan zoals hij is.
De regel eronder: een parameter is toegestaan wanneer hij loopt over een
gesloten dimensie die al elders in de taal staat. Een vrij mode-veld is dat
niet, en daarom viel het in RFC-024 af. Een kalendereenheid is het wel.
Voor DATE_PART is die dimensie exact het argumentenlijstje van DATE.
DATE_PART is de inverse van DATE en leest terug wat DATE opbouwt. Daarmee
is beantwoord waarom in: month bestaat terwijl geen enkele wettekst erom
vraagt: een nieuwe bewerking heeft een wettekst nodig, een nieuwe eenheidswaarde
binnen een dimensie die de taal al volledig kent niet. De inverse van een
bestaande bewerking is compleet of hij is willekeurig.
Diezelfde regel houdt de weekdag erbuiten. Een weekdag hoort niet bij de
jaar-maand-dagontleding, valt dus buiten de dimensie, en zou een grondtekst
nodig hebben. Vraagt een volgende wettekst opnieuw om een weekdag, dan is de zet
weekday aan DATE_PART toevoegen en DAY_OF_WEEK degraderen tot
compat-alias via het mechanisme dat de motor daarvoor al heeft. Geen enkele wet
in het corpus gebruikt DAY_OF_WEEK, alleen een conformance-fixture, dus die
degradatie kost later niets.
Voor START_OF is de dimensie krapper. day is de identiteit, en week vraagt
een conventie (ISO-maandag) die geen wettekst oplegt. END_OF is de spiegel van
START_OF en komt er niet in, omdat alle gevonden wetteksten naar beneden
afkappen en geen enkele naar boven.
Vier van de vijf wetteksten die om deze bewerkingen vroegen, lopen uit op dezelfde twee regels: de eerste dag van de kalendermaand volgende op de maand waarin iets gebeurt. Die figuur krijgt één schrijfwijze en die staat vast.
Afkappen gaat vóór optellen. In die volgorde is de uitkomst exact voor elke
invoerdatum, inclusief de eerste van de maand en inclusief 31 januari, want de
afgekapte datum is dag 1 en die bestaat in elke maand. De dagklem van DATE_ADD
(31 januari plus een maand is 28 februari) komt er dus nooit aan te pas. De
omgekeerde volgorde geeft toevallig hetzelfde antwoord, maar redeneert via die
klem, en dat is een controle die een reviewer elke keer opnieuw moet doen.
Waar de wet vraagt of iets ná de eerste dag van de maand gebeurde, staat er een
dagnummer: GREATER_THAN(DATE_PART($d, in: day), 1). Een wijziging óp de eerste
telt in die maand zelf mee, en dat is de enige casus die deze vraag hardop
stelt. De schrijfwijze EQUALS($d, START_OF($d, in: month)) levert hetzelfde op
en leest als een puzzel.
DATE_PART vervalt die
invoer, en daarmee een hele klasse inconsistente invoer: een berekeningsjaar
dat niet bij de peildatum hoort.DATE_DIFF telt en schrijft days|months|years;
DATE_PART en START_OF selecteren en schrijven year|month|day. Dit is de
zwakste plek van het voorstel: een agent die kopieert schrijft ooit
in: months bij START_OF. Het schema vangt dat met een enum, en de motor
noemt de fout bij naam in plaats van hem stil te accepteren. Eén
meervoudsvorm voor beide betekenissen was het alternatief, en in: years voor
“het jaartal” leest verkeerd genoeg om die prijs niet te betalen.in: month
maakt die fout schrijfbaar. De schemabeschrijving waarschuwt ervoor; geen van
de tien verzoeken had hem nodig.AGE blijft ongemoeid. Hij is DATE_DIFF ... in: years met een eigen naam en
een eigen grondslag (BW art. 1:2), en hem nu opruimen raakt wetten in het
corpus.Alternatief 1: vier losse namen (YEAR, MONTH, DAY_OF_MONTH,
START_OF_MONTH)
Afgewezen. Het vermoeden achter deze route is dat weinig geparameteriseerde
bewerkingen moeilijker fout te gebruiken zijn. Voor extractie klopt dat niet.
De fout die een agent hier maakt is semantisch: maanden van verschillende jaren
vergelijken, rekenen op een dagnummer. MONTH als eigen naam maakt die fout
even waarschijnlijk als in: month. De parameterisatie wint op vindbaarheid.
Alternatief 2: alleen DATE_PART, en START_OF weglaten
START_OF is volledig afleidbaar uit DATE_PART en het bestaande DATE:
lees het jaar, lees de maand, zet day: 1. Onder een zuinige lezing is één
nieuwe bewerking dus genoeg. RFC-024 sluit die lezing af: dit is een rekenketen
die een afkapping benadert, negen regels lang, met de afkapping verstopt in de
literal day: 1, en RFC-024 verwierp zulke ketens uitdrukkelijk. Een afkapping
krijgt een naam. De negenregelige schrijfwijze hoort in de reverse-validatie
als aan te merken omweg, naast de afrondingsketens die RFC-012 al noemt.
Het tweede gevolg van RFC-024 zit in wat START_OF niet mag worden. Geen
eigenschap van een datumtype, geen stille normalisatie op de grens van een
bewerking, geen impliciet gedrag van type: date. De afkapping staat in de
wet-YAML op de plek waar de wet hem voorschrijft, en nergens anders. Dat is
dezelfde reden waarom RFC-024 het afronden weghaalde bij de eenheidscoercie van
RFC-015.
Alternatief 3: een periodetype
De verrijker vroeg om een type voor “de periode dat het bevel ten uitvoer wordt
gelegd”, omdat dat in de wettekst één zelfstandig naamwoord is. Afgewezen. Een
periode is een paar <naam>_begindatum en <naam>_einddatum, met een lege
einddatum voor een lopende periode. Een echt periodetype zou vergelijking,
bevatting, rekenkunde, schema, type_spec en taint-propagatie nodig hebben voor
een begrip dat met twee datums al volledig werkt. De “voor zover”-clausule maakt
dat zichtbaar: het eerste wat zo’n type zou moeten kunnen is zijn begin
verschuiven, en dat is DATE_ADD op de begindatum.
Alternatief 4: in mag een variabele zijn
DATE_DIFF staat een $variabele toe als eenheid en het schema noemt die
mogelijkheid naast de enum. DATE_PART en START_OF doen dat niet. Geen
wettekst laat het te lezen datumdeel zelf uit een berekening volgen, en een
harde enum is de plek waar de fout van een agent goedkoop wordt gevangen.
DATE_PART levert een Int, START_OF een string in canonieke YYYY-MM-DD
vorm, zodat de uitkomst zowel onder EQUALS als onder de ordening klopt
(RFC-021).value genest staan en zijn niet geldig op actieniveau,
net als de andere datumbewerkingen.in als een gewone string. Het schema is daarin strenger dan
het model, en de motor noemt een onbekende waarde bij naam
(START_OF 'in' must be one of 'year', 'month', got 'months'). De
conformance-suite meet dat verschil als bekende afwijking in plaats van het te
verzwijgen.bdd/grammar.yaml heeft geen nieuwe stappen nodig. De grammatica gaat over
invoer, uitvoering en assertie, en niet over bewerkingen: output "x" equals {n} dekt DATE_PART en output "x" equals "2026-03-01" dekt START_OF.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