con un clic
rs
Rust development. NOT for non-Rust code (use go, py, ts, tsx, or sh).
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ú
Rust development. NOT for non-Rust code (use go, py, ts, tsx, or sh).
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
Development wisdom and workflow rules. NOT for project-specific conventions (those live in CLAUDE.md, edit via wisdom).
The `BUGS.md` open-issues queue — entry format, lifecycle, pruning to diary. NOT for the record-don't-fix policy (that's CLAUDE.md Bug Triage Protocol), NOT for resolved-bug history (use /diary), NOT for feature backlog (use TODO.md/specs).
Terminal demo GIF + MP4 recordings for READMEs and social (asciinema + agg + ffmpeg). NOT for general Makefile targets (use software) or GUI screenshots (use visual).
Go development. NOT for non-Go code (use rs, py, ts, tsx, or sh).
Humanize text: strip AI-isms and add real voice. NOT for drafting new copy (use writing).
Python development. NOT for shell scripting (use sh) or non-Python code.
| name | rs |
| description | Rust development. NOT for non-Rust code (use go, py, ts, tsx, or sh). |
| when_to_use | editing .rs files or writing Rust code |
Requires software/code.md (naming, style, design) and
software/dynamic-analysis.md (test-target checkers: Miri, -Zsanitizer, loom,
cargo-fuzz, cargo-mutants, nextest). Below are Rust-specific additions.
as aliases to rename external typesuse super::, NEVER local use inside function bodies
(exception: tests/main where scoping demands it)use crate:: for absolute pathsArc, the project's main error type, common
wire/record types) gets a top-of-file single-line use so it reads bare
(Arc<str>, not std::sync::Arc<str>). A type used once or twice gets a full
inline path (std::time::Duration, std::sync::atomic::AtomicU64) instead of
a use. Pick the SAME side project-wide: if Arc is used where it's common,
use it everywhere it's common — do NOT scatter bare Arc in some files and
std::sync::Arc::... full paths in others. Reduces import churn + makes every
file read the same way.collect_tx_summaries() not tx_summaries(); nouns ok for new(), from_str()v, k, n in .map(|v| ...))n, k, i, j, x, y, z, m, g, f, h; doubled (kk, vv) for nested/plural; short descriptive (data, msg) fineo, O, I, l (look like 0 or 1)$a, $val, $ty); meaningful names for semantic roles ($state, $key)for x in xs {} over xs.for_each(|x| ...) when the closure adds no clarity.filter().map().unwrap_or() as a disguised if/else — write if/let directly.filter() filters collections; it is NOT a conditional branch.map(), .filter() ok on iterators/collections, NEVER on Option to express control flow#[repr(i16)] enum in codesrc/<module>_test.rs, imported with
#[cfg(test)] mod <module>_test; at the bottom of the source file —
NOT inline #[cfg(test)] mod tests { ... }, NOT in tests/tests/src/<module>_test.rs use crate:: paths, not super::*--test-threads=1 if global state via DashMap/RwLocktests/common/mod.rs.get_host_port_ipv4()std::panic::set_hook(Box::new(|_| std::process::exit(0)));. NEVER where the project bans process::exit — graceful-shutdown-sensitive code (e.g. trading engines that must cancel orders first) must signal the shutdown path instead.#[command]eyre + color-eyre for new projects; keep anyhow if already presentthiserror for typed errorscolor_eyre::install()? before tracing init.wrap_err("context") not .context() (avoids trait ambiguity)let _ = call_that_returns_result(). Silent drops have caused real correctness bugs. Use ?, if let Err(e) = ..., or fail loud.tracing over logEnvFilter from RUST_LOG for subscriber init#[instrument] on hot-path functions (overhead)main() wraps run() in retry loop with 5s sleepfn main() -> eyre::Result<()> {
color_eyre::install()?;
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let cli = Cli::parse();
let config = load_config(&cli.config);
loop {
match run(&config) {
Ok(()) => break Ok(()),
Err(e) => {
tracing::error!("crashed: {e:#}, restarting in 5s");
std::thread::sleep(Duration::from_secs(5));
}
}
}
}
.unwrap() in non-test code; use .expect("msg").expect() ok at startup (fail-fast) or on documented invariants; otherwise propagateResult (and the
caller has a retry/backoff/supervisor), ? the error — don't .expect(). A
socket bind, PG connect, etc. can fail TRANSIENTLY; fail-fast-panic is only for
truly unrecoverable config. "It's at startup" is not a reason to panic if
startup is re-entered (e.g. a re-entrant run_main on demote/restart)..expect("msg"): put the REASON in the message; do NOT prefix a // SAFETY:
comment (see Unsafe)..lock().unwrap_or_else(|e| e.into_inner()) to recover poisoncargo +nightly miri test on modules with unsafe blocks; NEVER ship unsafe without a // SAFETY: invariant comment// SAFETY: is RESERVED for justifying unsafe — it documents the
invariants that make an unsafe block sound, and is the audit signal a reader
greps when reviewing unsafe. NEVER put // SAFETY: on SAFE code to justify a
.expect() / panic! / fail-fast / .unwrap(). That dilutes the convention
and is wrong. For a deliberate panic, the reason goes in the .expect("…")
message or a plain // comment — // SAFETY: means "this unsafe is sound", nothing else.serde_json::from_value::<T>(value.clone()) — &Value implements Deserializer, use
T::deserialize(value) (ref, no clone):
let Ok(value) = MyType::deserialize(details) else { continue };
let Some(value) = details.get("count").and_then(|v| v.as_u64()) else { continue };
spawn(async { ... }) — name the coroutine as a function:// WRONG: tokio::spawn(async move { ... });
// RIGHT:
async fn fetch_and_process(client: Client) { ... }
tokio::spawn(fetch_and_process(client));
pub mod flat, no nested mod.rsSerialize/Deserialize on adapter-layer DTOs, not on core domain entitiescargo check fastest for error checking (no codegen)check — it does no codegen): cranelift
backend, nightly-only. Two ways:
cargo +nightly build -Zcodegen-backend --config 'profile.dev.codegen-backend="cranelift"'. NEVER put that block in
.cargo/config.toml — stable cargo then hard-errors on EVERY build.rust-toolchain.toml (components = ["rustc-codegen-cranelift-preview", ...] auto-installs it), then put [unstable] codegen-backend = true +
[profile.dev] codegen-backend = "cranelift" in .cargo/config.toml.
cargo build = cranelift, cargo build --release = LLVM (release profile
untouched). Pin a DATED nightly so a rustup update can't drift clippy/
cranelift and break CI.aws-lc-rs/aws-lc-sys +
their rustls dependents = undefined native symbols, any linker). Pin just
those to LLVM, cranelift does the rest:
--config 'profile.dev.package.aws-lc-rs.codegen-backend="llvm"' (repeat for
aws-lc-sys, rustls). ~7× faster rebuilds on codegen-heavy crates.