Semantic compatibility analysis and configurable quality gates for SystemRDL specifications
Project description
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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file peakrdl_check-0.3.0.tar.gz.
File metadata
- Download URL: peakrdl_check-0.3.0.tar.gz
- Upload date:
- Size: 81.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32207261ab9673fac81a7cca18425b921b1dac2b5c87832194c1b29e0efa1940
|
|
| MD5 |
749c9f197c5165ec1b71145ced3bc57d
|
|
| BLAKE2b-256 |
7d33739dd129e36c91ad1cb10158fb9de5de6e203f15f4669c7b8e94db6e1785
|
Provenance
The following attestation bundles were made for peakrdl_check-0.3.0.tar.gz:
Publisher:
release.yml on chrismcdev/PeakRDL-check
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peakrdl_check-0.3.0.tar.gz -
Subject digest:
32207261ab9673fac81a7cca18425b921b1dac2b5c87832194c1b29e0efa1940 - Sigstore transparency entry: 2192469209
- Sigstore integration time:
-
Permalink:
chrismcdev/PeakRDL-check@47d6ce7fb7401941863f86b93382b64ac81744de -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chrismcdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47d6ce7fb7401941863f86b93382b64ac81744de -
Trigger Event:
push
-
Statement type:
File details
Details for the file peakrdl_check-0.3.0-py3-none-any.whl.
File metadata
- Download URL: peakrdl_check-0.3.0-py3-none-any.whl
- Upload date:
- Size: 74.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94bd1b2010f9ac6b6cfe9652396131ce50ba51cc2dac56014b150c086617b02a
|
|
| MD5 |
281f667cec3691eff4c455509cc5cba8
|
|
| BLAKE2b-256 |
55b3ef5b0b305d66fa1780753377acc77fd67fd56dbf8b646874193549929e15
|
Provenance
The following attestation bundles were made for peakrdl_check-0.3.0-py3-none-any.whl:
Publisher:
release.yml on chrismcdev/PeakRDL-check
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peakrdl_check-0.3.0-py3-none-any.whl -
Subject digest:
94bd1b2010f9ac6b6cfe9652396131ce50ba51cc2dac56014b150c086617b02a - Sigstore transparency entry: 2192469214
- Sigstore integration time:
-
Permalink:
chrismcdev/PeakRDL-check@47d6ce7fb7401941863f86b93382b64ac81744de -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chrismcdev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47d6ce7fb7401941863f86b93382b64ac81744de -
Trigger Event:
push
-
Statement type: