Three audit phases — security, tests, refactor — land in a single maintenance release. The release itself is anchored via the 3CP provenance flow introduced in v2.4.0.
A compliance tool is only as trustworthy as its own codebase. v2.4.1 closes a three-phase internal code health audit of the Wardex tree: security hardening, test coverage, and structural refactoring. None of these change user-facing behavior; all of them raise the confidence bar for every release that follows.
Ten files were hardened: panic paths replaced with safe returns, os.Exit replaced with a mockable exitFunc, KnownFields(true) enforced on all YAML decoding, MaxBytesReader bounding untrusted reads, gRPC TLS enforced, and test fixtures made overridable.
Twenty-five new tests were added across internal/cpl, pkg/epss, and cmd/provenance, bringing coverage of the provenance and canonicalization paths to a verifiable level. All tests pass under -race.
Twenty-four files changed in the structural cleanup:
| Change | Detail |
|---|---|
Typed model.Decision | New DecisionAllow / DecisionBlock / DecisionWarn constants replace raw "allow"/"block"/"warn" string comparisons across pkg/releasegate, pkg/statestore, pkg/report, cmd/evaluate, cmd/art14, cmd/aggregate, pkg/accept, and main.go. |
| Dead code removal | Deprecated exitcodes.Tampered alias removed (superseded by the StoreInconsistent / Tampered split since v2.1.2). |
| Tool relocation | cmd/gen-sbom/ moved to tools/gen-sbom/ to separate build-time tooling from the CLI command tree. |
| RBAC extraction | Duplicated profile/RBAC logic extracted into config.ApplyProfile; both main.go and evaluate_helpers.go now use the shared implementation. |
| Exhaustive switches | All Decision switches made exhaustive to satisfy the exhaustive linter — zero issues. |
The heuristic scoring formula was removed from both README.md (PT) and README-en.md (EN). The formula was documentation-only and never consumed by the scorer — its presence invited readers to reverse-engineer a function that the engine does not use.
As with v2.4.0, the release artifacts are anchored via the 3CP provenance flow. The chain-seal-v2.4.1.json manifest records a SHA-256 chain hash over the five release artifacts, submitted to the embedded Gleipnir anchor:
$ wardex provenance seal --dir ./dist --label "release-v2.4.1" -o chain-seal-v2.4.1.json
Chain seal written to: chain-seal-v2.4.1.json
Total files: 5
Chain hash: 65aac744766e960460235fcccbba61034182b5223c47d75b6e0be2a3114f2509
Anchored: release-v2.4.1 (block ~0)
The CI release workflow was also corrected to reference the relocated tools/gen-sbom/ path (it had not been updated during the Phase 3 move), so the native SBOM step now succeeds on tagged builds.
A maintenance release is still a release. v2.4.1 is the first Wardex version whose own pipeline was caught and fixed mid-release — the gen-sbom relocation in Phase 3 had left two workflow files pointing at the old path. The re-pushed tag triggers a clean, fully-sealed build.
go install github.com/had-nu/wardex/v2@latest
Checksums, SBOMs, and the chain-seal manifest are available in the GitHub Release.