RFC-000: RFC Process

AcceptedImplemented

Context

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:

  • Pull request discussions (hard to discover)
  • Code comments (fragmented)
  • Institutional memory (lost when team members change)

We need a lightweight but structured approach to capture these decisions.

Decision

We adopt an RFC (Request for Comments) process where significant design decisions are documented as markdown files in docs/src/content/rfcs/.

RFC Template

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.

--- title: "RFC-NNN: Title" status: Proposed # Draft | Proposed | Accepted | Rejected | Superseded implementation: Not implemented # Implemented | Partially implemented | Not implemented date: YYYY-MM-DD authors: - Name depends_on: # optional; omit if none - RFC-NNN (Short description) # short_title: Sidebar Label # optional; defaults to the title --- ## Context Why is this decision necessary? What problem does it solve? ## Decision What was decided? ## Why Benefits, tradeoffs, alternatives

Numbering Convention

  • RFC-000 is reserved for this process document
  • Subsequent RFCs are numbered sequentially: RFC-001, RFC-002, etc.
  • Once a number is assigned, it is never reused (even for rejected RFCs)

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 Values

status is the RFC’s place in the decision lifecycle, not whether code exists:

  • Draft: Work in progress, not yet ready for discussion
  • Proposed: Under discussion, not yet decided
  • Accepted: Decision is made and should be followed
  • Rejected: Proposal was considered but not accepted
  • Superseded: Replaced by a newer RFC (reference the new RFC)
  • Reserved: Not an RFC yet — a placeholder holding a number that an open pull request has claimed

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.

Implementation Status

Whether the decision is built is tracked separately from status, in the implementation field, so the lifecycle status stays clean:

  • Implemented: the decision is fully realised in code
  • Partially implemented: the core exists; the RFC describes more that is absent
  • Not implemented: design only, no code yet

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 to Write an RFC

Write an RFC for:

  • Law representation formats: Changes to YAML schema, article structure, machine_readable sections
  • Execution engine architecture: Changes to how the engine processes articles, resolves URIs, handles parameters
  • Integration patterns: How components interact (engine ↔ regulation files, API designs)
  • Cross-cutting design patterns: Decisions that affect multiple parts of the system

Skip RFC for:

  • Bug fixes: Unless they require architectural changes
  • Individual law implementations: Adding new YAML files following existing patterns
  • Routine implementation work: Following established patterns
  • Temporary workarounds: Meant to be replaced soon

When in doubt, ask: “Would someone maintaining this code in 6 months benefit from understanding why we made this decision?”

Why

Benefits

  • Future contributors understand why decisions were made
  • Writing forces clear problem articulation
  • Decisions don’t live only in people’s heads
  • RFCs evolve alongside code in version control
  • One place to find architectural decisions

Tradeoffs

  • Adds process overhead for major decisions
  • Requires discipline to maintain
  • Can become outdated if not updated

We accept these tradeoffs because the benefits of documented decisions outweigh the cost of the process.

Alternatives Considered

  1. Code comments only: Hard to discover, fragmented across codebase
  2. Wiki/Confluence: Separate from code, unclear version control
  3. GitHub Issues: Good for discussions, but not structured for long-term documentation
  4. ADRs (Architecture Decision Records): Very similar to RFCs; we chose “RFC” terminology as it’s more familiar in open source

References

RegelRecht

An exploration into transparent, executable legislation, and one of the three projects in the starting selection of the Nederlandse Digitale Dienst.

Links

GitHub repository
How it works
Stay informed
Roadmap (Dutch)
Documentation
Research

Contact

regelrecht@minbzk.nl

Part of

Nederlandse Digitale Dienst
Ministry of Economic Affairs and Climate Policy