.agents/skills/rust-code-quality/SKILL.md
Use this skill on every Rust code change to enforce quality rules that cargo clippy does not catch.
.rs files.Run these on every changed .rs file (excluding test modules):
# 1. unwrap/expect in production code
rg -n '\.unwrap\(\)|\.expect\(' <changed-files> | grep -v '#\[cfg(test)\]' | grep -v 'test' | grep -v 'bench'
# 2. Silent type truncation via `as` cast
rg -n ' as (u8|u16|u32|u64|usize|i8|i16|i32|i64|isize)\b' <changed-files>
# 3. String as error type
rg -n 'Result<.*String>' <changed-files> | grep -v test
# 4. Box<dyn Error> in public APIs
rg -n 'Box<dyn.*Error' <changed-files> | grep -v test
# 5. println/eprintln in production
rg -n 'println!\|eprintln!' <changed-files> | grep -v test
# 6. Ordering::Relaxed usage (verify each is intentional)
rg -n 'Ordering::Relaxed' <changed-files>
# 7. Default substituted for a possibly-required value (judge each: is the value optional by domain?)
rg -n 'unwrap_or_default\(\)|unwrap_or\(' <changed-files>
For every Rust code change, verify:
unwrap() or expect() in production code without justification commentResult<_, String> in public API signaturesBox<dyn Error> in public trait/struct methodsError::source() is overridden when inner error is storedas truncation (negative→unsigned, large→small)try_into() or explicit clamping used for numeric conversionsf64 as usize without prior clampingtokio::sync lock guard (read or write) held across .await without bounded hold time — long-lived read guards wedge writers (#4195)compare_exchange loops, not load-then-storestd::sync::Mutex in async context is held only briefly, never across .await.clone() on structs with >5 heap-allocated fields in hot pathsHashMap::with_capacity() / Vec::with_capacity() used when size is knownArc rather than cloned&str or Cow<str> instead of Stringassert!.expect("context") not bare .unwrap()println!/eprintln! in production code (use tracing)#[serde(deny_unknown_fields)]#[serde(default)] not used on security-critical fields without validation#![allow(dead_code)] at crate rootcrates/utils, crates/common, the touched crate) or plain std/tokio behavior no wrapper refines; reused helpers match the call site's semantics (normalization, error type, backoff, durability gating)SAFETY, unwrap justification — are not narration)unwrap() in request hot path, silent truncation on user input, lock ordering violation, recursion without depth limitResult<_, String> in public API, unnecessary clone in hot path, Box<dyn Error> in trait method, unwrap_or_default() on a domain-required value (metadata, quorum, version id)assert! in test, println! in production, missing with_capacity, new helper duplicating an existing workspace utility, defensive branch with no nameable trigger (corrupt or stale persisted/peer data is always a nameable trigger for boundary-crossing values), near-duplicate test, redundant error re-wrappingas_ptr() vs Arc::ptr_eq, narrating comment## Rust Code Quality Report
### Automated Scan
- unwrap/expect in production: N found
- as casts: N found
- String errors: N found
- println/eprintln: N found
### Findings
- [P1] `path:line` — description
- Fix: ...
- Validation: ...
### Verdict
PASS / BLOCKED (list blocking findings)