0.1.0-alpha.2
Pre-releaseAdded
-
The release pipeline. A
v*tag now publishes a release:release.yml
verifies every release fact against the tagged commit before anything is
built, creates the GitHub release as a draft, builds per-architecture Linux
binaries (x86_64 and aarch64) each with a checksum, a CycloneDX dependency
SBOM and Sigstore provenance and SBOM bundles, attaches a repository-wide
SPDX SBOM, and publishes the release only once every expected asset is
attached. The binary and image builds each live in a reusable workflow, which
is GitHub's documented construction for SLSA Build Level 3, so a consumer can
pin the signer withgh attestation verify --signer-workflow. -
The multi-architecture container image on GHCR, pushed BY DIGEST, smoke-run and
Trivy-scanned on both architectures before any tag names it, with provenance
and an SPDX SBOM attested on the digest.:latestmoves on a release tag and
never on a pre-release. -
docker runneeds no Rust toolchain.docker/Dockerfilebuilds a
distroless image that runs as uid 65532 and carries nothing but the runner:
mount the repository at/workand every subcommand works, because the
entrypoint is the instrument itself.docker run --rm -v "$PWD:/work" ghcr.io/rubentalstra/veredictum:<tag> \ validate --root /work/artifacts --specs /work/specs/openehr
The catalogue and the vendored specification oracle are deliberately NOT baked
in — 347 MB, read as run-time paths, and a party may want to point at their
own — so the image stays 55 MB and the data comes from the mount. -
A
Dockerfile lintjob in CI, gated on a change to the image tier, running
hadolint at its warning threshold against a configuration where any
deliberately violated rule is named with its reason. -
The changelog guard now requires an entry, not just a valid file shape. A
change touching a user-visible surface with no entry under the Unreleased
heading fails, and the path set that decides "user-visible" is declared in
scripts/checks/changelog-entry.shbeside the reason for each path rather
than inferred from a pattern in a workflow. Theno-changeloglabel waives it
and says so in the run, so a waived guard is auditable afterwards. -
Two scheduled lanes, both of which report a finding by filing or updating one
tracking issue and keep the run green — the run goes red only when the probe
itself cannot answer, because a red scheduled run is invisible to anyone not
watching the Actions tab:image-scan.yml, Mondays, Trivy over the PUBLISHED image on both
architectures, so a CVE disclosed after a release is still found. Before the
first release it reports that nothing is published and exits green, so
"nothing found" and "nothing looked at" are never the same line.latest-deps.yml, Mondays,cargo updatethencargo check --all-targets,
the Cargo book's named mitigation for a committed lockfile: a breaking
in-range upstream release is found on a schedule instead of during an
unrelated pull request.
-
Dependabot covers the
dockerecosystem now that a Dockerfile exists, with a
fourteen-day cooldown — the longest of the three, because a base-image bump
changes the bytes every user of the published image runs. -
The crate publish joins the same tag, as the last leg of the pipeline and after
the release is otherwise complete, so thecrates-ioenvironment's reviewer
approval blocks nothing else.publish-crates.ymlstays as the out-of-band
dry-run and recovery lane, and both lanes call one implementation,
scripts/release/publish-crate.sh. -
The release procedure is written into
CLAUDE.mdand driven by this file: a
missing or empty section for the tagged version fails the pipeline'splanjob
before anything is published. -
The crates.io version, crate-downloads and docs.rs badges in the README.
-
Published on crates.io as
veredictum, both a binary and a library:
cargo install veredictum --version 0.1.0-alpha.2puts the command on your
PATH, and the library target lets an integrator consume the typed artifact
model and the published JSON Schemas rather than reimplementing the format.
The package carries the code and the legal set; the catalogue and the vendored
specification oracle are 347 MB of data no registry accepts, and every root is
a path passed at run time, so both come from the repository. -
publish-crates.yml: the release lane for the crate, authenticating through
crates.io Trusted Publishing so no long-lived registry token exists in this
repository. Manual dispatch, dry run by default, the upload built from the
checkout with no cache restored, and the registry read back before the lane
reports success. -
The instrument itself builds and runs from this repository: the runner,
the catalogue with its 1107 case cores and 247 operation bindings, the
corpora, the ambiguity register, the party declarations, and the vendored
openEHR specification text that is its oracle. -
The command is
veredictum. The package, the binary and the library carry the
product's name, and so does the debug switch, now
VEREDICTUM_DEBUG_EXCHANGES. Every subcommand keeps its name and its flags:
validate,run,verdicts,perf,stress,aql-probe,
stress-compare,perf-assets,conformance-assets,emit-schemas. Two
paths move with the tree — an artifact root is nowartifactsand a spec root
is nowspecs/openehr. -
The standalone workspace: one package at the root, its own SemVer line from
0.1.0-alpha.1, edition 2024, Apache-2.0, with the deny-tier lint tables,
rust-toolchain.toml,rustfmt.toml,clippy.toml,deny.tomland
.config/nextest.tomlcarried over and adapted to what this tree actually
contains.Cargo.lockis committed, because this repository ships a binary. -
Three released machine-readable bundles beside the specification text, so a
citation that can only resolve against a schema resolves here rather than
nowhere:specs/its-xml-schemas/(the two XSD lineages),
specs/its-json-schemas/(the ITS-JSON validation oracle) and
specs/rest-oas/(the 21 released ITS-REST OpenAPI bundles). -
The corpus vendoring scripts, so every vendored tree can still be refreshed
the only sanctioned way, by re-running its script:
scripts/vendor/ckm-templates.sh,scripts/vendor/ckm-archetypes.sh,
scripts/vendor/adl2-archetypes.shandscripts/generate-ckm-examples.sh. -
The Rust CI tier, gated on whether a change touches anything it reads:
rustfmt,clippy --all-targetsat-D warnings, build plusnextestplus
the instrument's ownvalidateself-check, the rustdoc gate, the declared
MSRV verified withcargo hack check --rust-version,cargo deny check, and
cargo machetefor dependencies nothing imports. All seven join the single
requiredconclusioncheck. -
CodeQL analyzes
rustbesideactions, and the SonarQube scope coverssrc/
andtests/with the vendored trees excluded. -
Continuous integration.
ci.ymlruns on every pull request, every push to
mainand every merge-queue entry: a guard tier (comment style, changelog
structure, the no-attribution scan over the pushed commits, REUSE 3.3
licensing), a workflow audit (zizmor for the security posture, actionlint with
bundled shellcheck for correctness, and a check that every job actually gates
the merge), and a single requiredconclusioncheck. -
scorecard.yml: the weekly OpenSSF Scorecard analysis, publishing its score
to the OpenSSF API and its findings into code scanning. -
sonar.ymlandsonar-project.properties: SonarQube Cloud analysis on every
pull request and every push tomain, advisory under
.claude/rules/ai-code-review.md, with the New Code window anchored to the
package version so "new code" means "since the last release". -
Test coverage, measured and published. The Sonar lane runs the suite under
cargo-llvm-covand imports the merged lcov; the denominator excludes the
test tree, the CLI entry point and the two asset renderers, each with its
reason recorded, because a coverage percentage is only useful if every file
counted could in principle be covered by a test. The README carries the
coverage and quality-gate badges beside the CI, CodeQL, reliability, security,
maintainability and duplication readings. -
Dependabot covers the
cargoecosystem, with a seven-day cooldown against
the actions entry's three: a crate compiles into the published binary, so a
compromised release reaches every downstream run rather than one CI job. -
The OpenSSF Best Practices and OpenSSF Scorecard badges in the README, both
reading live scores rather than asserting a posture. -
Two ported guard scripts:
scripts/checks/changelog-structure.sh(Keep a
Changelog structure) andscripts/checks/ci-conclusion-complete.sh(no CI job
runs without gating the merge). -
The tracker machinery.
scripts/gh/rel.shis the one sanctioned write path
for GitHub's four native issue edges — sub-issue, blocked-by and their
inverses — resolving an issue number to the database id the write endpoints
actually want and failing loud on a bad one, with
.claude/rules/issue-relationships.mdas its policy. The label taxonomy is
complete against the schemeCLAUDE.mddefines:blocked-upstream,
on-hold,no-changelog, and the eightspec:component labels join the
type and priority sets. Two milestones open the release spine,v0.0.1and
v0.1.0./phase-status,/next-taskand/phase-doneare ported and
trimmed to the machinery that exists, each naming what it deliberately does
not check.
Removed
- The
accessibilitylabel. Nothing referenced it and it is not part of the
taxonomyCLAUDE.mddefines.
Fixed
- The SonarQube Cloud lane, which had failed on every run since the code
migration, the push tomainincluded.sonar.sources=.and
sonar.tests=testsoverlapped, and the scanner refuses an overlap rather than
picking a side, so one YAML fixture undertests/fixtures/ended the analysis
at exit code 3 — leaving the quality gate and the coverage badge with no
current reading at all. - The changelog's own intro paragraph, which the v0.0.1-alpha.1 cut turned into
a stray release heading by rewriting the first literal## [Unreleased]it
found — which was in prose, not the heading. The v0.0.1-alpha.1 section now
exists as a real section, and the paragraph names the heading instead of
quoting it. SUPPORT.mdsaid GitHub Discussions was not enabled. It is, with six
categories.