PeakRDL-check
Semantic compatibility analysis and configurable quality gates for SystemRDL specifications. Detects firmware-breaking register changes, produces CI reports and provides scalable exploration of large register maps.
PeakRDL-check is local-first and complements your existing
flow around systemrdl-compiler and PeakRDL: point it at the same .rdl
sources, get an indexed, instantly searchable register map and a
reviewer-grade semantic diff that classifies interface changes by impact.
Installation
Install the command-line tool once:
pip install peakrdl-check
Available commands
Build and serve register documentation
Build a searchable index from your SystemRDL entry file, then serve the local documentation viewer:
peakrdl-check build design.rdl -o build/design
peakrdl-check serve build/design
The server prints the local URL to open. It runs until you stop it with
Ctrl+C.
Generate a diff report
Compare the old (--base) and new (--head) specifications:
peakrdl-check diff --base old.rdl --head new.rdl
The report is printed in the terminal. Add -o diff.txt to save it, or use
--format markdown, json, or sarif when another format is needed. diff
does not fail just because it finds a breaking change.
Browse a diff in the documentation viewer
Build the new register map and save a JSON diff beside it:
peakrdl-check build new.rdl -o build/review
peakrdl-check diff --base old.rdl --head new.rdl --format json -o build/review/changes.json
peakrdl-check serve build/review
Open the printed URL and select the Changes tab. The server automatically
finds changes.json in the index directory.
Run a CI gate
Use check when breaking register-interface changes should fail a CI step:
peakrdl-check check --base old.rdl --head new.rdl
The command exits with status 1 when it finds a breaking change. Add
--fail-on behavioural only if behavioural and uncertain changes should also
fail the build.
The reusable GitHub Action adds a Markdown report to the job summary, emits inline source annotations, uploads the JSON and Markdown reports as an artifact, and applies the selected failure threshold.
What a semantic diff looks like
$ peakrdl-check diff --base main/uart.rdl --head pr/uart.rdl
Semantic diff: 2 breaking, 1 documentation (policy 1.0.0)
✖ [BREAKING ] REG-ADDRESS-CHANGED uart.status
reg 'uart.status' address changed from 0x4 to 0x40.
before: 0x4 after: 0x40
at pr/uart.rdl:9
✖ [BREAKING ] ENUM-VALUE-CHANGED uart.ctrl.baud
Enum member 'B115200' in field 'baud' changed value from 0x2 to 0x4;
existing encodings break.
✎ [DOCUMENTATION] DESC-CHANGED uart.ctrl
Description wording changed on 'uart.ctrl'.
The corpus in diff-corpus/ demonstrates the other direction too: a 203-line
textual refactor (file splits, reordering, hex renumbering, typedef
extraction) that produces zero semantic changes, and a one-line parameter
edit that changes hundreds of elaborated registers. Ambiguous renames are
reported as MATCH-UNCERTAIN — the tool never silently guesses.
PeakRDL integration
To use PeakRDL-check as a registered PeakRDL subcommand, install the optional host integration:
pip install "peakrdl-check[peakrdl]"
peakrdl check pr/design.rdl --base main/design.rdl --fail-on breaking
For an editable source checkout, benchmark tooling, and the test suite, see
CONTRIBUTING.md.
An example GitHub Actions workflow is in
examples/.github/workflows/register-review.yml.
Why PeakRDL-check
- It reviews meaning, not text. A textual diff can't tell a 200-line harmless refactor from a one-line change that silently moves hundreds of registers. PeakRDL-check compares the elaborated register models and classifies every change by impact — breaking, behavioural, compatible, documentation, or uncertain — with a stable rule ID, an explanation, and before/after values. When a match is ambiguous it says so instead of guessing.
- Quality gates you control.
--fail-onpicks the severity that fails CI, and a policy JSON reclassifies any rule to match your team's rules (e.g. treat reset-value changes as release-blocking). Reports come as text, JSON, Markdown or SARIF, and a reusable GitHub Action posts job summaries and inline annotations. - It stays fast when register maps get huge. One SQLite index file instead of tens of thousands of HTML files, a virtualized viewer that only loads what you look at, second-scale incremental rebuilds after local edits, and millisecond queries — measured at 800,000 registers.
- Every number is a measurement, not a slogan. The benchmark summary
below and the full evidence dossier in PROOF.md are generated
from raw, preserved run records (
benchmarks/raw-results/, failures and all) — nothing is typed by hand, and one script reproduces the lot.
Measured performance
On an 800,000-register specification (Apple M4 Pro, medians of 3 runs each, identical fixtures — full tables and environment in PROOF.md):
| Operation | PeakRDL-check | PeakRDL-html 2.12.2 |
|---|---|---|
| Cold build (raw source → browsable) | 285 s | 1390 s (4.9× slower) |
| Output | 1 file, 338 MB | 85,216 files, 1098 MB |
| Index generation from an already-elaborated model | 10 s | n/a (regenerates everything) |
| Incremental rebuild after a one-line block edit | 33 s | n/a (full rebuild) |
| Open existing index (server ready / first page) | 105 ms / 107 ms | static files, but 51.8 MB transferred up front |
| Search p95 / exact-lookup p95 | 10.4 ms / 0.6 ms | in-browser over the fully-loaded model |
Semantic diff: 47/47 curated scenarios pass (12/12 breaking detected, 10/10 formatting-only suppressed); 240 generated mutation trials at recall 1.0, precision 1.0.
Supported input
- SystemRDL 2.0 via systemrdl-compiler 1.32.2 (parameters, arrays,
dynamic assignments, aliases,
`include/`definepreprocessing). - Not supported (yet): IP-XACT, register editing, language-server features. PeakRDL-check is a review surface, not an editor (see ADR-0009).
Architecture in one paragraph
systemrdl-compiler parses and elaborates; a thin adapter walks the
elaborated tree once (arrays kept folded) and emits a canonical model with
content-hash-deduplicated definitions and lightweight instances; that streams
into a single SQLite file with FTS5 search. A localhost stdlib server exposes
a paginated JSON API; the viewer is one static HTML+JS file with virtualized
rendering, so browser state stays proportional to what you actually look at.
The semantic diff engine compares two canonical models through separated
stages (matching → detection → versioned severity policy → explanation →
text/JSON/Markdown/SARIF). Incremental rebuilds re-elaborate only block types
from changed files and splice their subtrees into the existing index — proven
byte-equivalent to a clean rebuild. Details: docs/architecture.md.
Known limitations
- Incremental rebuilds operate at defining-file granularity.
- The register-map viewer requires a local server; static browser-only mode is not currently supported.
- Input is limited to SystemRDL 2.0. IP-XACT and register editing are outside the current scope.
See the complete limitations list.
Documentation
Architecture · Diff rules · Benchmarks and evidence · ADRs · Contributing · Security
Metadata
Release files for peakrdl-check 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| peakrdl_check-0.3.0.tar.gz | 81.7 kB | With provenance | Details for peakrdl_check-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| peakrdl_check-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for peakrdl_check-0.3.0-py3-none-any.whl |
Total release size: 156.6 kB
Release files / peakrdl_check-0.3.0.tar.gz
| Download URL | peakrdl_check-0.3.0.tar.gz |
|---|---|
| Size | 81.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
32207261ab9673fac81a7cca18425b921b1dac2b5c87832194c1b29e0efa1940
|
|
BLAKE2b-256 checksum How to use checksums |
7d33739dd129e36c91ad1cb10158fb9de5de6e203f15f4669c7b8e94db6e1785
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.
Transparency logRelease files / peakrdl_check-0.3.0-py3-none-any.whl
| Download URL | peakrdl_check-0.3.0-py3-none-any.whl |
|---|---|
| Size | 74.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
94bd1b2010f9ac6b6cfe9652396131ce50ba51cc2dac56014b150c086617b02a
|
|
BLAKE2b-256 checksum How to use checksums |
55b3ef5b0b305d66fa1780753377acc77fd67fd56dbf8b646874193549929e15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.
Transparency logSecurity for peakrdl-check 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for peakrdl_check-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.