Skip to content

Repair lint coverage, patch advisories, fix pipeline dtype corruption - #1

Open
anbeckham wants to merge 1 commit into
mainfrom
fix/ci-lint-coverage-and-mesh-dtype
Open

Repair lint coverage, patch advisories, fix pipeline dtype corruption#1
anbeckham wants to merge 1 commit into
mainfrom
fix/ci-lint-coverage-and-mesh-dtype

Conversation

@anbeckham

Copy link
Copy Markdown
Contributor

Why

Clippy ran without --all-targets, so nothing under #[cfg(test)] was ever linted. Turning it on immediately surfaced an error-level lint CI could not see. Pulling that thread led to a correctness bug in the distributed pipeline.

The dtype bug (most important part of this PR)

TensorDtype::to_u8/from_u8 mapped F16 => 0, F32 => 1. MeshPipelineHandler — the only consumer of those functions — defines 0 = F32, 1 = F16.

tag TensorDtype (before) forward_layers
0 F16 F32
1 F32 F16

So every pipeline hop swapped F16 and F32, in both directions:

  • worker.rs:169 sends dtype.to_u8() into forward_layers, which decodes it with the other table.
  • worker.rs:210 decodes the handler's returned tag with the mesh table.

A stage receiving F32 activations labelled F16 decodes them at 2 bytes per element instead of 4 — garbage activations, silently.

PipelineInitiator compounded it by hardcoding TensorDtype::F16 on the wire message while discarding the dtype the engine actually returned, and by saving checkpoints under that same wrong dtype (so recovery resumed on garbage too).

These functions are not part of the wire format — TensorDtype travels between peers as a serde enum, and to_u8/from_u8 are used in exactly two places, both at the handler boundary. Realigning them is therefore safe. The tag space is now documented on the trait, and tests assert the literal tags rather than only the round-trip, since a round-trip test passes happily while both sides are consistently wrong.

Security

Patches 5 advisories rather than ignoring them — notably RUSTSEC-2026-0185, a remote memory-exhaustion DoS in quinn-proto, the QUIC transport the mesh runs on. Also rustls-webpki (x3), crossbeam-epoch, and a rand unsoundness.

deny.toml's ignore list is rewritten. Several entries had wrong justifications: RUSTSEC-2024-0370 was labelled "bincode: crafted input DoS" but is actually proc-macro-error unmaintained; 2024-0436 was labelled "fxhash" but is paste. Every remaining entry was re-verified against the advisory DB. The two quick-xml vulnerabilities cannot be patched — self_update 0.42 pins ^0.37 and plist 1.8 (via Tauri) pins ^0.38 — so their actual exposure is documented instead.

CLI hang risk

reqwest::Client::new() applies no timeout. share_benchmark_result, documented as "best-effort, never blocks", could block forever. All 8 call sites now use a shared client with connect/request timeouts. The cloud inference client is deliberately left alone — it streams, and a blanket request timeout would truncate long generations.

Also

  • Bumps pinned actions to Node 24 runtimes ahead of the 2026-09-16 removal of Node 20 from GitHub runners.

Verification

cargo fmt --check, cargo clippy --workspace --exclude hivebear-web --all-targets -- -D warnings, 331 tests passing, cargo deny check advisories licenses clean, plus -p hivebear-inference --no-default-features as CI does.

⚠️ release.yml and mobile.yml action bumps include download-artifact v4→v8, which changes digest-mismatch from warn to error. I could not exercise a release build here — worth a workflow_dispatch run before the next tagged release.

🤖 Generated with Claude Code

…ption

CI lint coverage
  Clippy ran without --all-targets, so nothing under #[cfg(test)] was ever
  linted. Enabling it immediately surfaced an error-level lint that had been
  invisible to CI. Fixes that lint plus 3 useless_conversion warnings.

Mesh pipeline dtype corruption (correctness)
  TensorDtype::to_u8/from_u8 mapped F16=>0, F32=>1, but MeshPipelineHandler —
  the only consumer of those functions — defines 0=F32, 1=F16. Every pipeline
  hop therefore swapped F16 and F32 in both directions, so a receiving stage
  decoded F32 activations at 2 bytes per element and produced garbage.

  PipelineInitiator compounded this by hardcoding TensorDtype::F16 on the wire
  message while discarding the dtype the engine actually returned, and saved
  checkpoints under the same wrong dtype.

  These functions are not part of the wire format (TensorDtype travels as a
  serde enum), so realigning them to the handler's tag space is safe. Adds
  regression tests asserting the literal tags rather than only the round-trip,
  and documents the tag space on the trait so the two sides cannot drift again.

Security advisories
  Patches 5 real advisories rather than ignoring them, including
  RUSTSEC-2026-0185, a remote memory-exhaustion DoS in quinn-proto — the QUIC
  transport the mesh runs on. Also rustls-webpki (3), crossbeam-epoch, and a
  rand unsoundness.

  Rewrites deny.toml's ignore list: several entries carried wrong
  justifications (2024-0370 was labelled "bincode", it is proc-macro-error;
  2024-0436 was labelled "fxhash", it is paste). The two remaining
  quick-xml vulnerabilities are blocked by upstream semver pins and are
  documented with their actual exposure.

CLI hang risk
  reqwest::Client::new() applies no timeout, so any coordinator call could hang
  a command indefinitely with no output — including share_benchmark_result,
  documented as "never blocks". Routes all 8 call sites through a shared client
  with connect/request timeouts. The cloud inference client is deliberately left
  alone, since it streams.

CI runtime deprecation
  Bumps pinned actions to Node 24 runtimes ahead of the 2026-09-16 removal of
  Node 20 from GitHub runners.

Verified: fmt, clippy --all-targets, 331 tests, cargo-deny advisories+licenses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant