mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-06 13:27:43 +00:00
b5e565c0ce
* docs: update security advisory lessons * chore(agents): add Rust code quality rules and skill Add rules derived from full-project code review (48 findings across 7 dimensions) to prevent recurring issues in agent-generated code. AGENTS.md changes: - crates/AGENTS.md: error type design, concurrency, recursion safety, type casting, test quality rules - root AGENTS.md: serde safety, naming conventions - crates/ecstore/AGENTS.md: allocation discipline, lock ordering, recursion safety, dead code policy - crates/notify/AGENTS.md: lock ordering for runtime_view/facade Skill changes: - code-change-verification: add Rust-specific checks (unwrap, as cast, clone, lock order, recursion, error types, test assertions) - security-advisory-lessons: add serde deserialization safety pattern - NEW rust-code-quality: automated scan + manual review checklist
2.4 KiB
2.4 KiB
Rust Code Quality Checklist
Use this as a quick pre-merge checklist for every Rust code change.
Critical (P0 — block merge)
| Check | Command |
|---|---|
No unwrap() in request/storage hot path |
rg '\.unwrap\(\)' <files> | grep -v test |
No as truncation on user input |
rg ' as (u32|usize|i32)' <files> |
| Lock order consistent across call sites | Manual: trace all lock acquisitions |
| Recursive functions have depth limit | Manual: check for max_depth or iterative pattern |
No panic!/unwrap_or_else(panic!) in production |
rg 'panic!|unwrap_or_else.*panic' <files> | grep -v test |
High (P1 — must fix)
| Check | Command |
|---|---|
No Result<_, String> in public API |
rg 'Result<.*String>' <files> | grep -v test |
No Box<dyn Error> in public trait |
rg 'Box<dyn.*Error' <files> | grep -v test |
No unnecessary .clone() in hot path |
Manual: check loops and per-request paths |
Error::source() implemented when inner error stored |
Manual: check impl Error |
No eprintln!/println! in production |
rg 'println!|eprintln!' <files> | grep -v test |
Medium (P2 — should fix)
| Check | Command |
|---|---|
| Tests have assertions | Manual: check for assert in test functions |
HashMap/Vec use with_capacity when size known |
Manual: check ::new() in loops |
No #![allow(dead_code)] at crate root |
rg 'allow.dead_code' <files> | grep 'lib.rs' |
Serde structs from untrusted input have deny_unknown_fields |
Manual: check #[derive(Deserialize)] |
Low (P3 — nice to fix)
| Check | Command |
|---|---|
| No camelCase statics | rg 'static ref [a-z]' <files> |
Arc::ptr_eq instead of as_ptr + ptr::eq |
rg 'as_ptr|ptr::eq' <files> |
| Public functions have doc comments | rg 'pub fn' <files> | grep -v '///' |
Quick One-Liner
# Run all automated checks on changed files
CHANGED=$(git diff --name-only HEAD~1 -- '*.rs' | grep -v test | grep -v bench)
echo "=== unwrap/expect ===" && rg -c '\.unwrap\(\)|\.expect\(' $CHANGED 2>/dev/null
echo "=== as casts ===" && rg -c ' as (u8|u16|u32|u64|usize|i8|i16|i32|i64|isize)\b' $CHANGED 2>/dev/null
echo "=== String errors ===" && rg -c 'Result<.*String>' $CHANGED 2>/dev/null
echo "=== println ===" && rg -c 'println!|eprintln!' $CHANGED 2>/dev/null
echo "=== Ordering::Relaxed ===" && rg -c 'Ordering::Relaxed' $CHANGED 2>/dev/null