From 749921b70129fe7088f7ea7609c9d96c1b3e40b9 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Wed, 12 Aug 2026 00:34:55 +0200 Subject: [PATCH 1/3] fix(ci): un-vacuum the mutants-core gate; dedupe the v0.33.0 changelog section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two findings from the v0.33.0 pre-tag clean-room audit. Neither blocks the tag (the first is nightly + continue-on-error, the second is cosmetic), but the first is the exact defect class this release exists to remove, so it should not outlive the release that introduced it. 1. mutants-core was made UNCONDITIONALLY VACUOUS by my own REQ-288 follow-up. The empty-diff short-circuit (`if [ ! -s pr.diff ]; then exit 0`) belongs to mutants-cli, which computes pr.diff. My patch applied it to every matching check step, and mutants-core has no step that writes pr.diff — so the guard always fired and the job never evaluated outcomes.json or missed.txt for rivet-core. The in-file claim that "honest numbers surface without blocking" was false as written. Guard removed from mutants-core; mutants-cli keeps it (correct there). Root cause worth naming: a str.replace without a count. The fix for a vacuous gate introduced a vacuous gate one job over. 2. The [0.33.0] changelog section carried two `### Fixed` subheads and documented REQ-290 twice (my summary plus #776's fuller entry). Collapsed to one section, keeping the detailed entry. A duplicated section in a release about honest reporting is worth fixing before the tag, not after. yamllint clean; docs check 0 violations. Refs: REQ-288 --- .github/workflows/ci.yml | 4 ---- CHANGELOG.md | 6 ------ 2 files changed, 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0fecf7e..64666e5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -857,10 +857,6 @@ jobs: # `continue-on-error: true`, so honest numbers surface without blocking. run: | REPORT=mutants-out/mutants.out - if [ ! -s pr.diff ]; then - echo "no Rust changes in this diff — nothing to mutate, nothing to check" - exit 0 - fi if [ ! -f "$REPORT/outcomes.json" ]; then echo "::error::no $REPORT/outcomes.json — cargo-mutants crashed or its layout changed; not reporting a pass over missing evidence" ls -R mutants-out 2>/dev/null || echo "(no mutants-out/ at all)" diff --git a/CHANGELOG.md b/CHANGELOG.md index 10dafa02..581a9ae7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,11 +29,6 @@ ran, reported green, and could not go red. Ported from spar's gate audit (`/` and `fuzz/`); the root check passed while `fuzz/` carried real drift in 5 tracked files. The gate now derives the workspace list so a new nested workspace cannot silently escape it. -- **The anti-rot check ran in no workflow** (REQ-290, #770) — - `rivet check verification-evidence` exists precisely to catch artifacts citing - tests that no longer exist, and nothing invoked it. Now wired into the - Traceability job, and its zero-steps case no longer prints a checkmark over an - empty scan. - **Changed-areas filter was under-scoped and failed open** (REQ-291, #771) — a `rust=false` verdict skips Clippy/Test/MSRV/Semver/Miri/Proptest, and on GitHub a *skipped* required context is indistinguishable from a passed one. Embedded @@ -47,7 +42,6 @@ ran, reported green, and could not go red. Ported from spar's gate audit commit broke it. Externals are now emitted before locals. A failed external load also no longer degrades silently to "no externals". -### Fixed - **`rivet check verification-evidence` is now wired into CI + no longer scores an empty scan as a pass** (REQ-290, #770) — the anti-rot check for stale `cargo test ` names (REQ-236, hardened again in REQ-280 for nextest From 57a3da261a4c340a2e1b15598b467cf21398fea1 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 18 Aug 2026 20:59:20 +0200 Subject: [PATCH 2/3] docs(changelog): correct the REQ-290 claim + state the known limitations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v0.33.0 entry headlined REQ-290 as "no longer scores an empty scan as a pass". Confirmed against the main binary, that overclaims: an empty scan now renders as an honest warning with empty_scan true in JSON, but it still exits 0, so CI still scores it a pass. What changed is the rendering, not the verdict. On this repo the check examines 0 steps. Also records the two defects reported after the release branch was cut and confirmed against main (#807) — the discarded --manifest-path value hiding nested workspaces, and satisfiability by an empty stub test — including the order they must be fixed in. Confirmed with the main binary that docs check fails loudly (exit 1 on a deliberate violation, exit 0 clean), so this file is gated for real. --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 581a9ae7..7a20d187 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,8 +42,8 @@ ran, reported green, and could not go red. Ported from spar's gate audit commit broke it. Externals are now emitted before locals. A failed external load also no longer degrades silently to "no externals". -- **`rivet check verification-evidence` is now wired into CI + no longer scores - an empty scan as a pass** (REQ-290, #770) — the anti-rot check for stale +- **`rivet check verification-evidence` is now wired into CI + reports an empty + scan honestly** (REQ-290, #770) — the anti-rot check for stale `cargo test ` names (REQ-236, hardened again in REQ-280 for nextest filtersets) BUILT the tool that catches spar#388's failure shape, but no workflow ran it, so the protection was opt-in-by-memory. Two fixes: (1) the @@ -56,6 +56,18 @@ ran, reported green, and could not go red. Ported from spar's gate audit nothing was verified` with `empty_scan: true` in JSON output so a machine can tell the vacuous case from a genuine pass. + **Known limitations — stated plainly, because this release is about gates that + prove less than they appear.** (a) An empty scan still **exits 0**, so CI + scores it a pass; what changed is the rendering and the JSON, not the verdict. + On rivet's own repo the check currently examines **0 steps**, so this gate + protects downstream projects, not this one. (b) Post-release, two further + defects were reported and confirmed (#807): the check is blind to tests in + nested independent workspaces because a step's `--manifest-path` value is + parsed and then discarded rather than widening the scan root (false failures), + and it verifies only that a *name* exists somewhere scanned — so an empty stub + `#[test] fn the_name() {}` satisfies it (false pass). Both are tracked in + #807 for the next release, and must be fixed in that order. + ## [0.32.0] - 2026-08-05 Weak-green hardening + mutation reliability + security. This release began as a From a75147ece6422dda3981269f30acd0b4036bcbf1 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 18 Aug 2026 21:11:47 +0200 Subject: [PATCH 3/3] build(deps): bump h2 0.4.13 -> 0.4.16 (fixes RUSTSEC-2026-0258) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Advisory published 2026-08-17, after this release branch was cut, which turned the Security Audit gate red during the pre-tag check. Unbounded empty DATA frames; h2 reaches rivet through axum and hyper, so it sits in the live request path of `rivet serve` rather than being dev-only. Applied as a surgical 2-line lockfile edit. A plain `cargo update -p h2` on this machine also re-pointed five Windows-only crates from windows-sys 0.61.2 to the 0.52.0 already in the tree — semver-valid resolver churn, but unrelated to the advisory and not something to smuggle into a security fix. Patching only the h2 version and checksum keeps the diff to what the advisory requires. Confirmed with `cargo build --locked` (exit 0, lock untouched by the build), the full serve integration suite (52 passed), and `cargo audit` with CI's exact ignore set (exit 0, was exit 1). --- CHANGELOG.md | 10 ++++++++++ Cargo.lock | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a20d187..471b48a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,16 @@ ran, reported green, and could not go red. Ported from spar's gate audit `#[test] fn the_name() {}` satisfies it (false pass). Both are tracked in #807 for the next release, and must be fixed in that order. +### Security + +- **`h2` 0.4.13 → 0.4.16** (RUSTSEC-2026-0258, *unbounded empty DATA frames*). + The advisory was published 2026-08-17, after this release branch was cut, and + turned the Security Audit gate red during the pre-tag check. `h2` reaches + rivet through `axum` → `hyper`, so it is in the live request path of `rivet + serve` — not a dev-only dependency. Lockfile-only change: the `h2` entry moves + and nothing else does, `cargo build --locked` is clean, and `cargo audit` with + CI's ignore set exits 0. + ## [0.32.0] - 2026-08-05 Weak-green hardening + mutation reliability + security. This release began as a diff --git a/Cargo.lock b/Cargo.lock index efd7a89c..1d21c0f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1473,9 +1473,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" dependencies = [ "atomic-waker", "bytes",