Point it at a running openEHR CDR and it tells you, with citations, which parts of the specification that server actually implements.
It executes a machine-readable catalogue of 1103 spec-cited test cases against
the server's own wire, records every exchange, and computes verdicts as pure
functions over what it recorded. Functional conformance, measured performance and
step-load stress come from one tool. The released openEHR specifications are the
only authority it accepts: every expectation in the catalogue names the section
it comes from, so it can be refuted by a better reading of the specification and
by nothing else. The case and binding counts quoted on this page come from the
line veredictum validate prints over artifacts/, which step 1 below runs.
Why an independent instrument
A server vendor's own test suite cannot answer the question a hospital is asking. The suite and the server are written by the same people against the same reading of the specification, and when the two disagree it is usually the suite that gets adjusted.
Veredictum is built so that cannot happen here. The vendored specification text is the oracle and is never a suspect. When a run goes red the failure is attributed before anything is changed, to exactly one of three suspects, by comparing what the specification requires against what the catalogue expects against what the server did:
| Suspect | Fix path |
|---|---|
| The server under test violates the specification | a defect report to that CDR, carrying the reproduced exchange and the citation |
| The instrument misdrove the case or misjudged the response | fix the runner. Those rows were inconclusive, never failures |
| The catalogue expectation is wrong against the specification | fix the artifact, with a new cited source for the corrected expectation |
The instrument is a first-class suspect on every red row, ahead of the server. The first live triage attributed 7 of 7 diagnosed defects to the runner and none to the server under test. An instrument that presumes itself correct is worth nothing to the people who are supposed to rely on its verdicts.
Run it
Work from a clone. The published crate carries the code, and the catalogue and
the vendored specification oracle are 347 MB of data that no registry accepts —
so veredictum reads both as paths you pass it, and the repository is where
they live.
# 1. Check the catalogue itself. Zero findings is the only passing result.
# 2. Declare your deployment: copy an example and edit the endpoints, the
# credential variable names and the postures your server actually serves.
# 3. Drive the catalogue against your running server.
# 4. Compute the verdicts and render the submission documents.
cargo run -- --help lists every subcommand, perf, stress and aql-probe
among them. The toolchain pins itself from rust-toolchain.toml; the only extra
tool is cargo-nextest, and only if you intend to run the test suite.
Without a Rust toolchain
The container image carries the runner, so a clone plus Docker is enough. Mount
the repository at /work and the arguments are the ordinary subcommands — the
entrypoint is the instrument itself:
The catalogue and the vendored specification oracle are not baked in: they are 347 MB, the runner reads every root as a path passed at run time, and a party may legitimately want to point at their own. The image is the runner, and the data comes from the mount.
Prebuilt binaries for x86_64 and aarch64 Linux are attached to each
release, each with a
sha256sum, a CycloneDX dependency SBOM and a Sigstore bundle:
With cargo
The binary is on crates.io, which is the path to take if you want the command on
your PATH and intend to point it at a catalogue you already have:
The library target is published with it, so an integrator can consume the typed artifact model and the published JSON Schemas directly rather than reimplementing the format.
What is in the box
| 1103 case cores | artifacts/schedule/ — one small isolated case per behaviour, so a red row names one defect. Grouped by chapter: EHR, composition, content, contribution, directory, query, definition, demographic, admin, messaging, security, SMART, simplified formats, system. schedule/performance/ holds the four measured-workload journey definitions, which are their own family and are not case cores |
| 247 operation bindings | artifacts/bindings/ — a case says what the operation IS, in the Service Model's own vocabulary; a binding says how it reaches the wire. A case core carries no status code, header or media type |
| The vocabularies | artifacts/vocab/ — the capability matrix, the wire surface the coverage gate enumerates, the outcome and selector grammars, and the journey catalogue the measured workload decomposes through |
| The corpora | artifacts/corpus/ — payload fixtures with their adjudicated verdicts, plus breadth packs vendored verbatim from upstream libraries. Every invalid shape is kept as a negative case, so a lenient server fails it |
| The ambiguity register | artifacts/registers/ambiguities.yaml — where the specification is silent or contradicts itself, with a typed disposition. Never a private resolution |
| The published schemas | schemas/ — JSON Schema for every artifact family, emitted and drift-tested, so an integrator can author against the format |
| The oracle | specs/openehr/ — the released specification text, vendored verbatim, plus the released XSD, JSON Schema and OpenAPI bundles a citation resolves against |
Coverage is a mandate
A green run over a thin catalogue proves nothing, so coverage is machine-checked
rather than asserted. The surface-coverage gate enumerates the wire surface
from the released sources alone — the Service Model's platform interfaces crossed
with their ITS-REST branches — and fails on any operation, status-code branch,
header rule, negotiation variant or error family that has neither a covering case
nor a cited exception. A behaviour the specification defines and the catalogue
misses is a gap to close or an honest boundary in the register.
Cases are added. They are never removed to make a run go green.
Verdicts are computed, never asserted
A verdict is a pure function of the party's statement, the recorded results, the catalogue and the capability matrix. Performance works the same way: a class verdict is re-derived from the HDR histograms embedded in the record, so the stored summary is tamper-checked rather than trusted, and latency is measured from the planned arrival instant under open-loop offered load, which is what stops coordinated omission from hiding a stall.
Origin of the name
Veredictum is medieval Latin for "truly spoken", vere dictum, and it is the word that became the English verdict. That is what this instrument produces: it runs the catalogue against a running CDR and speaks a verdict about what it observed. The seal above is the mark of that verdict.
Architecture
ARCHITECTURE.md is the design record, and it is where the
reasoning lives rather than a summary of it: the testable surface and the
case-core field definitions, the per-operation wire bindings, the outcome
taxonomy and the ambiguity register, the assertion vocabulary, how a verdict is
computed, and the population-anchored performance-class model — the POC / S / L /
R volumetric floors derived from OECD, Eurostat and NHS statistics, with the
hospital-simulation journey decomposition behind the measured runs. It also
carries the evidence base for why the instrument exists in this shape: the state
of the official CNF component, how other standards run conformance, and the
ISO/IEC 9646 and CASCO vocabulary the scheme is built in.
Contributing
CONTRIBUTING.md has the gates and the review bar.
CLAUDE.md is the working discipline the project holds itself to,
including the attribution law above. Security reports go through
SECURITY.md, and questions through SUPPORT.md.
If you maintain a CDR and want it graded, open an issue. A defect this instrument finds in your server arrives with the exchange and the citation, and a defect you find in this instrument is a first-class bug here.
License
Apache-2.0. Attribution travels with every copy and derivative through the
license and the NOTICE file, as its section 4 requires. The vendored
specification text and clinical models keep their upstream terms, recorded per
tree in PROVENANCE.md and declared machine-readably in REUSE.toml.