con un clic
ds-rust-review
Review Rust code for safety metrics, error handling, and idiomatic Rust.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Review Rust code for safety metrics, error handling, and idiomatic Rust.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
Design a target architecture for a new system — module boundaries, dependency rules, seams, and build order — from its requirements. Reports a blueprint; changes nothing.
Analyze an existing codebase's architecture and produce a sequenced refactoring plan — assess module boundaries, dependency structure, and layering, then lay out ordered, risk-tagged steps. Language-agnostic. Reports a plan; changes nothing.
Turn a goal or another command's output into an ordered task roadmap.
Find the root cause of a failure with the scientific method — reproduce, isolate, fix, then prove it.
Interview the user relentlessly about a plan or design until reaching shared understanding.
Run an extremely strict maintainability + single-source-of-truth review of code changes — abstraction quality, file sprawl, spaghetti-condition growth, and duplicate/competing implementations. Reports findings by default; `--fix` applies the mechanical, unambiguous ones — structural/code-judo restructurings rest on judgment and stay reported.
| name | ds-rust-review |
| description | Review Rust code for safety metrics, error handling, and idiomatic Rust. |
| disable-model-invocation | true |
Applies to: Rust stable, edition 2024. Systems programming, CLI tools, services.
Scan the invocation for the --no-tiger, --fix, and --full flags. Treat every other argument as review scope (files or directories); if no scope is given, review the changed files on the current branch.
--no-tiger present → skip the Tiger Style section; run the remaining sections only.--no-tiger absent → run all sections (default).--fix → after reporting, apply only the violations whose fix is mechanical and unambiguous (a rename to the idiom, a missing error check the review is certain about). Anything that changes logic or rests on an unverified assumption — especially security and correctness findings — stays report-only. After applying, re-run any build/test/lint check already in the loop and revert any fix that breaks it — or that touched more than the intended mechanical edit. End with a summary of what was applied and what was left.--full → review the entire codebase instead of just the branch's changes. Explicit positional scope still wins; --full only replaces the no-scope default.The whole-crate metric commands below are baseline context. Anchor findings to the code in scope — don't report pre-existing unwrap/panic counts outside the change as if the change introduced them.
# Safety surface metrics
cargo geiger 2>/dev/null # count unsafe blocks across crate graph
cargo geiger --output-format json # machine-readable
# Lints — must pass clean
cargo clippy -- -D warnings
# Security audit
cargo audit
# Unused dependencies
cargo +nightly udeps --all-targets 2>/dev/null
# Warnings in clean build
cargo clean && cargo build 2>&1 | grep -E "^warning"
# Count unsafe/panic/unwrap manually
grep -rn "unsafe " src/
grep -rn "\.unwrap()" src/
grep -rn "\.expect(" src/
grep -rn "panic!(" src/
grep -rn "todo!()" src/
grep -rn "unimplemented!()" src/
Run these commands, report counts, then do manual review below.
Report these numbers at the top of the review:
unsafe blocks: <N> (cargo geiger or manual grep)
unwrap() calls: <N>
expect() calls: <N>
panic!() calls: <N>
todo!()/unimpl!(): <N>
clippy warnings: <N>
audit findings: <N>
Each non-zero number introduced or touched by the change requires justification. Pre-existing counts outside the scope are context, not findings.
Use the checklist as a lens, not a scorecard: reason about the actual change, report real violations anchored to file:line, and flag issues even when they aren't listed. Don't manufacture findings to fill a category.
Skip this section entirely if --no-tiger was passed. Otherwise it is mandatory.
assert! / debug_assert!let _ = or .ok() on a meaningful operationunsafe block has a // SAFETY: comment explaining the invariant relied uponextern blocks are declared unsafe extern, and no_mangle/link_section/export_name use the #[unsafe(...)] wrapper.unwrap() in library code (crates without main.rs).expect("msg") has a descriptive message that identifies WHAT failed and WHY it should notpanic!() on recoverable errors (bad input, missing file, network failure)panic!() acceptable only for: violated invariants, programmer errors, OOM in systems contextthiserror with typed enum variantsanyhow with .context("operation description")? operator used consistently — no manual match Err(e) => return Err(e.into())Result-returning functions have their error handled at call sites — no implicit .ok() discard on meaningful operations.clone() — check if a reference sufficesArc<Mutex<T>> where single-threaded RefCell<T> or owned data worksMutex lock scope is minimal — no lock held across await pointsBox<dyn Error> in library public API — use typed errorsasync fn (no std::thread::sleep, std::fs::read)tokio::task::spawn_blockingSend when used with multi-thread Tokio runtimeselect! arms handle cancellation correctlyif let / while let over .unwrap() on Optionsmatches!() macro for pattern matching in boolean context#[repr(C)]/FFI types — don't flag ordering on ordinary repr(Rust) structs (the compiler reorders them)#[derive] used where applicable (Debug, Clone, PartialEq)Display that just re-emits the Debug output — if Display adds nothing over {:?}, drop itasync || …, stable since 1.85) instead of || async { … } where a closure must return a futureimpl Trait return types capture every in-scope generic lifetime — narrow with + use<...> where the wider capture is unwantedIdiom-level checks only — for a ranked, costed optimization plan, use /ds-perf-plan.
String::with_capacity(n) / Vec::with_capacity(n) where size is knownHashMap::get + HashMap::insert — use entry() APIsqlx, diesel)Command::new / shell execution with unsanitized user inputunsafe block has a dedicated test#[should_panic] tests for intentional panicscargo fuzz or bolero)features flags used to minimize compiled surface area[dev-dependencies], not [dependencies]cargo audit clean (no known CVEs)Header (always emit):
unsafe: <N> | unwrap: <N> | expect: <N> | panic: <N> | clippy: <N>
Findings:
<file>:<line>: <severity>: <problem>. <fix>.
Severity: critical (soundness/CVE), major (reliability/correctness), minor (idiom/style).
Skip findings with no actionable fix. Do not report clippy items already caught by cargo clippy -- -D warnings.