How RegelRecht records what a law is supposed to do: Gherkin scenarios over a fixed vocabulary, executed by the engine that executes the law.
A machine-executable law is a claim: run this text against these facts and you get this outcome. A scenario is where the claim gets checked.
The form is Gherkin, executed by cucumber-rs. That looks like a testing decision and mostly is not one. A scenario is the only artifact in this repository that a legal expert and a programmer can both sign off on without either of them learning the other’s tools. It states facts and an outcome, and says nothing whatever about how the outcome is computed.
Facts come in under Given, one question is asked under When, and every Then is an assertion that holds or does not.
Read from corpus/regulation/nl/wet/wet_op_de_zorgtoeslag/scenarios/eligibility.feature when this page was built, so it is the scenario CI runs and not a copy of it. The runner below executes what you make of it: the engine is compiled to WebAssembly and runs in this browser, on your machine.
The interesting move is the last line. hoogte_zorgtoeslag is asserted in eurocent, to the cent, on an income above the threshold where the allowance tapers off. Raise it by one and the step turns red. Nothing about the law changed; the claim about it did.
bdd/grammar.yaml is the single source of truth for what a step may say. The bindings are generated from it: Rust through packages/engine/build.rs, the JavaScript the editor and this page run through bdd/codegen/gen-js.mjs. Never hand-edit a generated file. Change the grammar and run just bdd-codegen.
A step that is not in the grammar does not exist. That is a stronger guarantee than it sounds. A scenario cannot express a condition the engine has no operation for, so an expectation that quietly outruns what the format can say gets rejected at the door rather than six months later. And no engine can invent a phrasing of its own: an implementation that speaks the language speaks all of it, or fails the conformance suite.
Steps are grouped in tiers. The core tier is what a law-validation scenario uses, and every engine has to support it:
Given the calculation date is "…"set_calculation_dateset_calculation_dateGiven law "…" is loadedload_lawload_lawGiven parameter "…" is "…"set_parameter_stringset_parameter_stringGiven parameter "…" is …set_parameter_numberset_parameter_numberGiven the following parameters:set_parameters_tableset_parameters_tableGiven the following "…" data with key "…":set_data_sourceset_data_sourceGiven the following "…" data with key "…" for law "…":set_data_source_for_lawset_data_source_for_lawGiven parameter "…" is the collection:set_parameter_collectionset_parameter_collectionWhen I evaluate "…" of "…"evaluateevaluateThen the execution succeedsassert_succeedsassert_succeedsThen the execution failsassert_failsassert_failsThen the execution fails with "…"assert_fails_withassert_fails_withThen output "…" is trueassert_boolean_trueassert_boolean_trueThen output "…" is falseassert_boolean_falseassert_boolean_falseThen output "…" equals …assert_equals_numberassert_equals_numberThen output "…" equals "…"assert_equals_stringassert_equals_stringThen output "…" is absentassert_nullassert_nullThen output "…" is unknownassert_unknownassert_unknownThen output "…" is unknown for lack of "…"assert_unknown_forassert_unknown_forThen output "…" contains "…"assert_containsassert_containsThree smaller tiers sit beside it. provenance asks where an output came from (execution provenance), untranslatable covers execution over a law with a marking on it, and notes covers resolving a stand-off annotation against an article (RFC-005). They exist because those features need proving, not because a law-validation scenario needs them.
Writing a scenario down is the easy half. Knowing what the answer ought to be is the rest of it.
Where we can, we take it from the legislature. Dutch bills come with a Memorie van Toelichting, and the parliamentary papers around them work examples out in full, down to the household and the amount. That arithmetic is the lawmaker’s own reading of the rule, and it is published under a date you can cite. Turning it into a scenario costs almost nothing and buys a check that nobody on this project authored.
The zorgtoeslag scenario above is one of those. Its expected amount comes from a worked example in the answers to parliamentary questions, quoted in corpus/annotations/wet_op_de_zorgtoeslag/annotations.yaml with a link to the document it came from. When the scenario and the memorandum disagree, one of two things is true, and both are worth knowing.
Where the legislature worked nothing out, the expected value is somebody’s judgement and the scenario says so in a comment above it. A few in the corpus record a disagreement rather than a check: the scenario asserts what the law ought to produce, carries a @wip tag, and is skipped until the model catches up.
The same language, two buckets, and the difference decides who fixes a failure.
Law validation sits next to the laws, in corpus/regulation/**/scenarios/*.feature, and runs against the real corpus. A failure here means a law moved or a scenario went stale. Which of the two it is, is a human’s call, so CI does not block on this bucket.
Engine conformance sits in bdd/conformance/*.feature and proves an engine speaks the whole language, against synthetic test_* laws rather than real ones. A failure is unambiguous: the engine is wrong. CI blocks on it.
REGULATION_PATH points the law-validation bucket at a corpus, so the same scenarios run over a different set of laws. just bdd-demo aims it at corpus/demo/regulation, the laws migrated from the proof of concept with their synthetic persona data. The engine and its harness know nothing demo-specific.
Testing covers the rest of the test suite and how the BDD run fits into it. For what an execution trace shows once a scenario has run, see Traceability.
An exploration into transparent, executable legislation, and one of the three projects in the starting selection of the Nederlandse Digitale Dienst.
GitHub repository
How it works
Stay informed
Roadmap (Dutch)
Documentation
Research
Nederlandse Digitale Dienst
Ministry of Economic Affairs and Climate Policy