André Ataíde
July 17, 2026

Wardex v2.4.1: Code Health Audit Wrap-Up and Sealed Release

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.


Context

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.


Phase 1 — Security Hardening

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.


Phase 2 — Test Coverage

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.


Phase 3 — Refactor

Twenty-four files changed in the structural cleanup:

ChangeDetail
Typed model.DecisionNew 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 removalDeprecated exitcodes.Tampered alias removed (superseded by the StoreInconsistent / Tampered split since v2.1.2).
Tool relocationcmd/gen-sbom/ moved to tools/gen-sbom/ to separate build-time tooling from the CLI command tree.
RBAC extractionDuplicated profile/RBAC logic extracted into config.ApplyProfile; both main.go and evaluate_helpers.go now use the shared implementation.
Exhaustive switchesAll Decision switches made exhaustive to satisfy the exhaustive linter — zero issues.

Documentation

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.


Sealed Release

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.


Upgrade

go install github.com/had-nu/wardex/v2@latest

Checksums, SBOMs, and the chain-seal manifest are available in the GitHub Release.