fix(deps): crossbeam-epoch 0.9.20 for RUSTSEC-2026-0204 - #13
Open
noahgift wants to merge 3 commits into
Open
Conversation
RUSTSEC-2026-0204: invalid pointer dereference in the `fmt::Pointer` impl for `Atomic` and `Shared` when the underlying pointer is invalid. Fixed upstream in 0.9.20; this is a patch-level lockfile bump inside the existing semver range, so only Cargo.lock changes. Found by running the fleet lane-liveness dead-man's switch: whisper.apr, pepita and pzsh Nightly Bench had all been failing for exactly 23 days on this one advisory, matching its publication date. A scan then found 90 of 94 local repos carrying the vulnerable 0.9.18. Verified: `cargo audit` no longer reports RUSTSEC-2026-0204 for this repo. Other pre-existing advisories, where present, are untouched. Refs PMAT-203 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ush gate
Found while landing the RUSTSEC-2026-0204 lockfile bump (previous commit): the
local pre-push gate was already red on clippy, so that push could not land. All
three are pre-existing and unrelated to the dependency change — they are new-in-
1.95 lints that appeared with a toolchain bump, not new code.
* adapters/wos.rs: `Signal::Cont` arm collapsed into a match guard
(collapsible_if).
* metrics.rs: `duration_avg` used a `count > 0` guard around a division;
now `checked_div` (manual_checked_ops), which is also clearer about the
divide-by-zero case.
* manager.rs: five second-valued Durations trip `duration_suboptimal_units`,
which wants `Duration::from_mins`. NOT taken — that constructor stabilized in
Rust 1.87 and this crate declares `rust-version = "1.83"`, so following the
suggestion would silently raise the MSRV. Allowed at module scope with that
reason recorded inline; revisit if the declared MSRV moves past 1.87.
Verified: `cargo clippy --all-targets -- -D warnings` clean, fmt clean, and the
pre-push gate passes.
Refs PMAT-203
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e catches I verified the previous commit with `cargo clippy --all-targets`, but CI runs `cargo clippy --workspace -- -D warnings`. Different scope: --workspace reaches duende-test, which has five more `duration_suboptimal_units` sites in chaos.rs and load.rs. My local command could not have caught it — the same verify-the-effective-artifact mistake, one layer up. Allowed at crate scope with the same rationale as duende-core's manager.rs: `Duration::from_mins` stabilized in Rust 1.87 and this workspace declares rust-version 1.83, so taking clippy's suggestion would silently raise the MSRV. Verified with CI's exact commands: `cargo fmt --all -- --check` and `cargo clippy --workspace -- -D warnings` both clean. Noted, not fixed: `--workspace --all-targets` reports 59 pre-existing findings across test and bench targets. CI does not gate that surface and it is unrelated to this dependency bump. Refs PMAT-203 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Aug 28, 2026
The `gate` job added in the previous commit did what it was built to do on its first run: it went red, because two of the four CI jobs it aggregates are genuinely failing. Neither failure is caused by this branch — it touched only ci.yml. Main's last CI run was 2026-04-06 (green, e67a0d4) and nothing has run on main since. Both jobs pin rolling inputs, so both rotted unobserved for five months: Lint `dtolnay/rust-toolchain@stable` is now clippy 1.98 Security `cargo audit` fetches the advisory DB at run time Lint — two new-in-1.98 lints, both behaviour-preserving rewrites: adapters/wos.rs:312 collapsible_match → `Signal::Cont if …` guard. Non-Stopped Cont still falls through to `_ => {}`. metrics.rs:156 manual_checked_ops → `checked_div(count)` + `map_or(Duration::ZERO, …)`. count == 0 still yields ZERO; the extra relaxed load is side-effect free. Security — 2 vulnerabilities, both semver-compatible patch bumps: crossbeam-epoch 0.9.18 → 0.9.20 RUSTSEC-2026-0204 h2 0.4.13 → 0.4.19 RUSTSEC-2026-0258 The crossbeam-epoch bump is the same one PR #13 carries; #13 is the PR that has been sitting BLOCKED against a green board this whole time. Only those two packages were relocked. The 8 remaining advisories are already-allowed `unmaintained`/`unsound` warnings, untouched. Also refactors `WosAdapter::status`, which the pmat pre-commit hook rejected at Cognitive 45 > 25. Measured before touching it: the violation is entirely pre-existing and in a function this branch had no reason to edit — the hook only scans STAGED files, so `status` had never been weighed. The one-line lint fix above is what put wos.rs in the staged set. That fix on its own moved the file 126 → 125 cognitive. The 45 was nesting, not logic, so `status` splits into three helpers with the branch structure preserved exactly: query_wos_ctl_status() Ok(None) = "no answer, fall back to local state"; a non-zero wos-ctl exit is an ANSWER (Stopped), and that distinction is the one thing easy to lose here. parse_wos_ctl_status() pure str → Option<DaemonStatus> status_from_process_state() pure ProcessState → DaemonStatus wos.rs now reports no complexity violation at all. The two pure helpers are directly unit-testable, which the nested chain was not. Verified locally: `cargo fmt --all -- --check` clean, `cargo clippy --workspace -- -D warnings` clean, `cargo test --workspace` 932 passed / 0 failed — the same 932 as before the refactor. Deliberately NOT fixed: `manager.rs:94` trips `clippy::duration_suboptimal_units` on local clippy 1.97 but NOT on CI's 1.98, which reported exactly two errors. Chasing it would fix a lint the gate never asked for. That the two toolchains disagree in both directions is the real hazard of `@stable` + `-D warnings`, and is worth a follow-up pin. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Aug 28, 2026
* ci: emit the `gate` status context the org ruleset requires
The paiml org ruleset "Green Main" (id 13878864) requires exactly one
status context:
$ gh api orgs/paiml/rulesets/13878864 \
--jq '.rules[]|select(.type=="required_status_checks")
|.parameters.required_status_checks[].context'
gate
No workflow in this repo emits a check named `gate`. Measured on PR #13:
all four checks are green — Test, Lint, Coverage, Security (workflow CI)
— and the PR still reports `mergeStateStatus: BLOCKED`. Nothing a
contributor can do fixes it, because the missing check is one the repo
cannot produce. The only way through is an admin override, which the org
rules forbid, correctly. Eight repos are in this state.
A required context that no workflow emits does not raise the bar, it
closes the repo.
Fix: an aggregating `gate` job in ci.yml. Job id and `name:` are both
literally `gate` because the ruleset matches the CONTEXT, not a display
name — a friendlier name silently re-breaks merging.
The gate measures something real. It has no checks of its own; it passes
only when every existing CI job reported `success`:
needs: [test, lint, coverage, security] # if: always()
and it prints its denominator ("checked 4 of 4 expected CI jobs"). The
`EXPECTED` list is asserted against `needs` in both directions: a job in
EXPECTED but absent from needs fails as MISSING, a job in needs but not
in EXPECTED fails as UNGUARDED, and zero jobs inspected is an explicit
refusal to report a pass. So the gate cannot quietly shrink to guarding
less than it claims. `skipped` is not a pass either — only `success` is.
Falsified locally against six inputs before pushing: all-green passes;
one failure, one skip, a missing job, an empty needs, and an extra
unguarded job each fail.
`runs-on: ubuntu-latest` matches the four jobs it aggregates — not bare
`self-hosted`, which would match every self-hosted runner the org
registers including the aarch64 gx10 training node (paiml/infra#342).
Triggers are inherited from ci.yml: pull_request and push to main (this
repo's default branch).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: clear the 5 months of CI bit-rot the new `gate` surfaced
The `gate` job added in the previous commit did what it was built to do
on its first run: it went red, because two of the four CI jobs it
aggregates are genuinely failing.
Neither failure is caused by this branch — it touched only ci.yml. Main's
last CI run was 2026-04-06 (green, e67a0d4) and nothing has run on main
since. Both jobs pin rolling inputs, so both rotted unobserved for five
months:
Lint `dtolnay/rust-toolchain@stable` is now clippy 1.98
Security `cargo audit` fetches the advisory DB at run time
Lint — two new-in-1.98 lints, both behaviour-preserving rewrites:
adapters/wos.rs:312 collapsible_match → `Signal::Cont if …` guard.
Non-Stopped Cont still falls through to `_ => {}`.
metrics.rs:156 manual_checked_ops → `checked_div(count)` +
`map_or(Duration::ZERO, …)`. count == 0 still
yields ZERO; the extra relaxed load is side-effect
free.
Security — 2 vulnerabilities, both semver-compatible patch bumps:
crossbeam-epoch 0.9.18 → 0.9.20 RUSTSEC-2026-0204
h2 0.4.13 → 0.4.19 RUSTSEC-2026-0258
The crossbeam-epoch bump is the same one PR #13 carries; #13 is the PR
that has been sitting BLOCKED against a green board this whole time.
Only those two packages were relocked. The 8 remaining advisories are
already-allowed `unmaintained`/`unsound` warnings, untouched.
Also refactors `WosAdapter::status`, which the pmat pre-commit hook
rejected at Cognitive 45 > 25. Measured before touching it: the
violation is entirely pre-existing and in a function this branch had no
reason to edit — the hook only scans STAGED files, so `status` had never
been weighed. The one-line lint fix above is what put wos.rs in the
staged set. That fix on its own moved the file 126 → 125 cognitive.
The 45 was nesting, not logic, so `status` splits into three helpers
with the branch structure preserved exactly:
query_wos_ctl_status() Ok(None) = "no answer, fall back to local
state"; a non-zero wos-ctl exit is an
ANSWER (Stopped), and that distinction is
the one thing easy to lose here.
parse_wos_ctl_status() pure str → Option<DaemonStatus>
status_from_process_state() pure ProcessState → DaemonStatus
wos.rs now reports no complexity violation at all. The two pure helpers
are directly unit-testable, which the nested chain was not.
Verified locally: `cargo fmt --all -- --check` clean, `cargo clippy
--workspace -- -D warnings` clean, `cargo test --workspace` 932 passed /
0 failed — the same 932 as before the refactor.
Deliberately NOT fixed: `manager.rs:94` trips
`clippy::duration_suboptimal_units` on local clippy 1.97 but NOT on CI's
1.98, which reported exactly two errors. Chasing it would fix a lint the
gate never asked for. That the two toolchains disagree in both
directions is the real hazard of `@stable` + `-D warnings`, and is worth
a follow-up pin.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(lint): restore the deliberate `unused_async` allows under clippy 1.98
Third and last layer of the same bit-rot. `cargo clippy` stops at the
first crate that fails, so each fix only revealed the next crate:
run 1 duende-core collapsible_match, manual_checked_ops
run 2 duende-test unused_async_trait_impl ×2
now duende-observe unused_async_trait_impl ×2
All four remaining sites are the same defect, and it is not a code
defect. Each already carried a deliberate, commented
`#[allow(clippy::unused_async)]` — the `async` is intended API surface
("Will be async when actually spawning chaos threads"). clippy 1.98
split that case out into `clippy::unused_async_trait_impl`, so the
existing allows stopped covering their own documented intent.
Fix is to allow the new name, NOT to change the signatures. Clippy's own
suggestion — rewrite `pub async fn start(&mut self) -> Result<()>` as
`pub fn start(&mut self) -> impl Future<Output = Result<()>>` — would
churn public API in four places to silence a lint the authors had
already considered and rejected.
`#[allow(unknown_lints)]` accompanies it because the new name does not
exist before clippy 1.98, where `-D warnings` turns an unknown lint into
a hard error. Measured, not assumed: the first attempt used
`#[cfg_attr(clippy, allow(...))]` and clippy rejected THAT two ways at
once —
error: no need to put clippy lints behind a `clippy` cfg
error: unknown lint: `clippy::unused_async_trait_impl`
so the file now builds clean on both 1.97 and 1.98.
Verified with CI's exact toolchain, installed locally to stop guessing
at it (`rustup toolchain install 1.98.0`), running CI's exact commands:
cargo +1.98.0 fmt --all -- --check clean
cargo +1.98.0 clippy --workspace -- -D warnings clean, whole workspace
cargo +1.98.0 test --workspace 932 passed / 0 failed
cargo clippy (1.97) --workspace still clean
That last line is the portability check: this repo pins
`dtolnay/rust-toolchain@stable`, so the lint set moves under it without
a commit. 1.97 and 1.98 disagree in BOTH directions here — 1.97 alone
flags `manager.rs:94` (`duration_suboptimal_units`), 1.98 alone flags
these four. Pinning the toolchain is the real fix and is worth a
follow-up; this commit just gets the gate honest and green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RUSTSEC-2026-0204
crossbeam-epoch0.9.18 → 0.9.20. Invalid pointer dereference in thefmt::Pointerimpl forAtomic/Shared. Patch-level lockfile bump. Found via the fleet lane-liveness sweep; 90 of 94 local repos carried the vulnerable version. PMAT-203.Second commit: three pre-existing clippy errors
The lockfile push could not land because the pre-push gate was already red on clippy. All three are new-in-1.95 lints that appeared with a toolchain bump — pre-existing, unrelated to the dependency change:
adapters/wos.rs—Signal::Contarm collapsed into a match guard (collapsible_if)metrics.rs—duration_avghad acount > 0guard around a division; nowchecked_div(manual_checked_ops), which is also clearer about the divide-by-zero casemanager.rs— five second-valuedDurations tripduration_suboptimal_units, which wantsDuration::from_mins. Not taken: that constructor stabilized in Rust 1.87 and this crate declaresrust-version = "1.83", so following the suggestion would silently raise the MSRV. Allowed at module scope with the reason recorded inline; revisit if the declared MSRV moves past 1.87.Verification
cargo clippy --all-targets -- -D warningsclean, fmt clean, pre-push gate passes, andcargo auditno longer reports 0204.🤖 Generated with Claude Code