- Rust 64.1%
- JavaScript 18.2%
- Vue 12.1%
- Shell 2.6%
- Gherkin 1.1%
- Other 1.8%
Bumps the npm-minor-patch group with 8 updates in the / directory: | Package | From | To | | --- | --- | --- | | [happy-dom](https://github.com/capricorn86/happy-dom) | `20.11.1` | `20.11.2` | | [@cucumber/gherkin](https://github.com/cucumber/gherkin) | `42.0.0` | `42.0.1` | | [@cucumber/messages](https://github.com/cucumber/messages) | `34.2.0` | `34.2.1` | | [js-yaml](https://github.com/nodeca/js-yaml) | `5.2.3` | `5.3.0` | | [marked](https://github.com/markedjs/marked) | `18.0.7` | `18.0.9` | | [vue](https://github.com/vuejs/core) | `3.5.40` | `3.5.41` | | [vue-echarts](https://github.com/ecomfe/vue-echarts) | `8.0.1` | `8.1.0` | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.2.0` | `8.2.1` | Updates `happy-dom` from 20.11.1 to 20.11.2 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.11.1...v20.11.2) Updates `@cucumber/gherkin` from 42.0.0 to 42.0.1 - [Release notes](https://github.com/cucumber/gherkin/releases) - [Changelog](https://github.com/cucumber/gherkin/blob/main/CHANGELOG.md) - [Commits](https://github.com/cucumber/gherkin/compare/v42.0.0...v42.0.1) Updates `@cucumber/messages` from 34.2.0 to 34.2.1 - [Release notes](https://github.com/cucumber/messages/releases) - [Changelog](https://github.com/cucumber/messages/blob/main/CHANGELOG.md) - [Commits](https://github.com/cucumber/messages/compare/v34.2.0...v34.2.1) Updates `js-yaml` from 5.2.3 to 5.3.0 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/5.2.3...5.3.0) Updates `marked` from 18.0.7 to 18.0.9 - [Release notes](https://github.com/markedjs/marked/releases) - [Commits](https://github.com/markedjs/marked/compare/v18.0.7...v18.0.9) Updates `vue` from 3.5.40 to 3.5.41 - [Release notes](https://github.com/vuejs/core/releases) - [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md) - [Commits](https://github.com/vuejs/core/compare/v3.5.40...v3.5.41) Updates `vue-echarts` from 8.0.1 to 8.1.0 - [Release notes](https://github.com/ecomfe/vue-echarts/releases) - [Changelog](https://github.com/ecomfe/vue-echarts/blob/main/CHANGELOG.md) - [Commits](https://github.com/ecomfe/vue-echarts/compare/v8.0.1...v8.1.0) Updates `vite` from 8.2.0 to 8.2.1 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.2.1/packages/vite) --- updated-dependencies: - dependency-name: "@cucumber/gherkin" dependency-version: 42.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: "@cucumber/messages" dependency-version: 34.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: happy-dom dependency-version: 20.11.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: js-yaml dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-minor-patch - dependency-name: marked dependency-version: 18.0.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: vite dependency-version: 8.2.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: vue dependency-version: 3.5.41 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor-patch - dependency-name: vue-echarts dependency-version: 8.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-minor-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|---|---|---|
| .claude | ||
| .github | ||
| bdd | ||
| conformance | ||
| corpus | ||
| deploy/nginx | ||
| dev | ||
| docs | ||
| frontend | ||
| frontend-lawmaking | ||
| packages | ||
| schema | ||
| script | ||
| tests/fixtures/federation | ||
| .dockerignore | ||
| .env.example | ||
| .env.sso-local.example | ||
| .gitignore | ||
| .npmrc | ||
| .pre-commit-config.yaml | ||
| .yamllint | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| corpus-registry.yaml | ||
| deny.toml | ||
| docker-compose.dev.yml | ||
| Justfile | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| REVIEW.md | ||
| rust-toolchain.toml | ||
regelrecht
Machine-readable Dutch law execution. regelrecht takes legal texts, encodes them as structured YAML, and runs them as deterministic decision logic.
What does it do
- The engine takes a regulation and a set of inputs, evaluates the decision logic, and returns a result with a full explanation trail
- Laws are tested against real-world scenarios using BDD (Gherkin) tests, many derived from legislative explanatory memoranda. The vocabulary those scenarios speak lives in
bdd/grammar.yamland every engine's step bindings are generated from it - A harvester downloads and tracks Dutch legislation from the official BWB repository
- Regulations can be edited through a web UI with live execution preview
Components
Rust packages
| Package | Description |
|---|---|
| packages/engine/ | Law execution engine (also compiles to WASM) |
| packages/law-model/ | The Rust representation of the law format, conforming to schema/ |
| packages/harvester/ | Downloads Dutch legislation from BWB |
| packages/pipeline/ | PostgreSQL job queue for law processing |
| packages/admin/ | Harvester-admin API; its dashboard UI lives in the editor |
| packages/editor-api/ | Backend API for the law editor |
| packages/corpus/ | Git integration for the regulation corpus |
| packages/auth/ | Shared OIDC/SSO authentication |
| packages/github/ | Shared GitHub REST client |
| packages/shared/ | Shared domain types across crates |
| packages/arch-extract/ | Derives the architecture model from the code (just arch-explore) |
| packages/tui/ | Terminal dashboard (Ratatui) |
Frontends and sites
| Directory | Description |
|---|---|
| frontend/ | Law editor UI (Vue 3 + Vite) |
| frontend-lawmaking/ | Law-making process visualization (Vue 3 + Vite) |
| packages/frontend-shared/ | Shared frontend primitives (auth, colour scheme, API fetch) |
| docs/ | Astro site: landing page + documentation |
Data and testing
| Directory | Description |
|---|---|
| corpus/regulation/ | A working set of regulations in machine-readable YAML, plus synthetic test_* laws |
| schema/ | Versioned JSON schema for the law format (schema/latest points at the current version) |
| bdd/ | The Gherkin vocabulary (grammar.yaml) and the engine-conformance suite |
corpus/regulation/**/scenarios/ |
Law-validation scenarios, next to the law they test |
| packages/grafana/ | Grafana monitoring dashboards (provisioning, not a crate) |
The full corpus lives elsewhere
corpus/regulation/ in this repo holds a couple of dozen laws: the ones the
tests and BDD scenarios run against, plus synthetic test_* laws for the
conformance suite. The harvested body of Dutch legislation is far too large to
carry here and lives in its own repository:
MinBZK/regelrecht-corpus — currently some 22,000 YAML files under regulation/nl.
Which branch you want depends on what you are after:
| Branch | What is on it |
|---|---|
development |
The working branch, and what corpus-registry.yaml points this repo at. Harvested laws land here first |
main |
Only moves when development is merged into it, so it lags |
enrich/* |
Output of the enrichment runs, one branch per enricher (enrich/claude, enrich/opencode) |
Short-lived prN and editor/* branches belong to preview deployments and
editor sessions; they are not meant to be read directly.
Deployed services
| Service | URL |
|---|---|
| Editor | https://editor.regelrecht.rijks.app |
| Landing page | https://regelrecht.rijks.app |
| Documentation | https://docs.regelrecht.rijks.app |
| Law-making | https://lawmaking.regelrecht.rijks.app |
| Harvester admin | https://harvester-admin.regelrecht.rijks.app |
| Grafana | https://grafana.regelrecht.rijks.app |
The pipeline API and the harvester and enrich workers deploy alongside these but have no web UI of their own.
A PR gets a preview environment once it carries the deploy:preview label; taking the label off, or closing the PR, cleans it up again.
Getting started
Prerequisites: Rust (stable) and just.
just check # everything CI runs (format, lint, build, validate, tests)
just test # every Rust test in the workspace
just test-no-docker # the same, minus the container-backed suites
just bdd # the BDD suites: law scenarios and engine conformance
just test and just check start PostgreSQL containers for the crates that
need one, so they want a Docker daemon. Without one, just test-no-docker
covers everything else. just bdd runs separately: it executes against the real
corpus and is deliberately not part of just test.
Faster builds (recommended)
Run just dev-setup once. It does three things:
- Points every worktree at one shared target dir — a new worktree reuses the already-built dependency graph instead of cold-building ~600 crates.
- Puts that target on fast local storage when the repo lives on a slow mount.
A Rust build writes tens of thousands of small files; on a 9p/NFS/SMB mount
(e.g. a WSL2 or Docker-Desktop dev container where the repo is a Windows
drive) that I/O dominates build time — often more than everything else
combined.
dev-setupdetects this and relocates the target to~/.cache/regelrecht/(local disk). This is usually the single biggest win. - Installs mold +
sccache. mold (wired intopackages/.cargo/config.toml) speeds up linking and is a hard requirement for the dev recipes;sccacheis installed but left off locally.
sccache is disabled locally because it requires CARGO_INCREMENTAL=0 and so
disables incremental compilation — which hurts the just dev edit-rebuild loop.
Enable it only for cold or flag-varying builds:
export RUSTC_WRAPPER=sccache CARGO_INCREMENTAL=0
CI uses both mold and sccache (see .github/workflows/ci.yml).
Running a dev stack
just dev # full native dev stack (admin + both frontends + grafana/prometheus)
just dev-frontend # all frontends (editor 7300, admin 7400, lawmaking 7500), no observability
just dev-frontend editor # just the editor (editor-api + editor UI + DB)
just dev-frontend admin # just the admin API + admin UI + DB
just dev-frontend lawmaking # just the lawmaking UI (no backend)
just dev-down # stop whichever of the above is running
dev-frontend with no argument starts every frontend; pass editor, admin,
or lawmaking to start just one. Either way it starts only the components those
frontends need — no grafana, prometheus, or workers. The editor runs with real
SSO against the central
Keycloak, so it needs .env.sso-local (copy .env.sso-local.example). It and
just dev are mutually exclusive (they share .dev-pids and ports) — run one at
a time.
Vite ports default to 7300/7500 (overridable via EDITOR_PORT /
LAWMAKING_PORT). When a native backend can't reach Postgres
on localhost (e.g. a WSL2/Docker-Desktop dev container, where Postgres is
published on the Docker host), point it at host.docker.internal: for the
admin / just dev paths set DB_HOST=host.docker.internal in .env; for the
editor that host comes from DATABASE_URL in .env.sso-local (the
.env.sso-local.example already uses host.docker.internal).
See the docs site for full development instructions.