As the RegelRecht project grows, we need a structured way to document design decisions and architectural choices. Important decisions about law execution, article resolution, URI handling, and system architecture should be documented with their rationale for future reference.
Without a formal process, design decisions live in:
We need a lightweight but structured approach to capture these decisions.
We adopt an RFC (Request for Comments) process where significant design decisions are documented as markdown files in docs/src/content/rfcs/.
RFC metadata goes in the YAML frontmatter, not in a bold-labelled preamble.
The site renders status and implementation as tags and date / authors /
depends_on as a header line; the body starts at the first ## Context.
Claim the number on the default branch the day you open the pull request, by
adding a placeholder with status: Reserved (see below). Until an RFC merges,
its number is invisible to everyone else, and the sequence on the site reads as
if the gap were free. That is not hypothetical: RFC-025 and RFC-036 were each
claimed twice by authors who could not have known, and one of those collisions
cost a colleague a merge conflict on a file they thought they were creating.
A number is taken when a pull request claims it, not when that pull request merges.
status is the RFC’s place in the decision lifecycle, not whether code exists:
Reserved is the one status that is not a place in the decision lifecycle. It
carries no design, so it sets no implementation field, and it names the pull
request holding the number in reserved_by.
What makes a file a placeholder is reserved_by, not the status word. The
content schema keys on it: a file carrying it states no implementation and
must be Reserved or Rejected, while every other RFC states one. A
Reserved file without a reserved_by link is a build error too, because a
reservation nobody can trace back to a branch blocks a number forever.
When the pull request merges, it replaces the placeholder with the real RFC.
When it is closed unmerged, the placeholder stays and becomes Rejected: the
number is spent either way.
An RFC whose decision has been acted on is Accepted even if the code is only partially built. A built-and-merged RFC is not a Draft; “Draft” means the design itself is unsettled.
Whether the decision is built is tracked separately from status, in the
implementation field, so the lifecycle status stays clean:
Every RFC sets implementation. Stating it explicitly (rather than leaving a
fully-built RFC blank) keeps an absent tag from reading as “unknown” next to
the RFCs that do carry one. The two fields are orthogonal: an Accepted RFC can
be Partially implemented, and code can land ahead of acceptance (a Proposed RFC
that is already Implemented).
When in doubt, ask: “Would someone maintaining this code in 6 months benefit from understanding why we made this decision?”
We accept these tradeoffs because the benefits of documented decisions outweigh the cost of the process.
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