agentleFS
MartinKChenMartinKChen/harness-claude-code/skills/pattern-engineer-rust/SKILL.md

pattern-engineer-rust

Skill0 starsChanged 5 months agoMITView on GitHub

Idiomatic Rust: edition pinned, `Cargo.lock` committed; `cargo fmt`/`clippy -D warnings`/`test`/`audit`; no `.unwrap()`/`.expect()` in prod (`?` to propagate; `thiserror` for libs, `anyhow` at edges; no `Box<dyn Error>` in lib API); no `.clone()` to dodge the borrow checker; `&str`/`&[T]` params; newtypes for ids; exhaustive `match`; serde at the boundary; no blocking in async tokio; `#![forbid(unsafe_code)]`; checked arithmetic; `try_from` over `as`. Activate on `.rs`, `Cargo.toml`.

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 0 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-rust.md in the consuming project (resolve …

    line 14
  2. Very specific:

    Commit Cargo.lock for binaries and services.

    line 24
  3. Very specific:

    Never Box<dyn Error> in a library's public API — return a concrete thiserror enum.

    line 40
  4. Very specific:

    Never .clone() solely to silence the borrow checker — restructure, borrow, or split the borrow instead.

    line 44
  5. Very specific:

    Read-only params take &str / &[T] / &T, not String / Vec<T> / owned T.

    line 45
  6. Very specific:

    Never block in an async fn: no std::thread::sleep, sync file/DB I/O, or heavy CPU on the runtime — offload to tokio::task::spawn_blocking.

    line 62
  7. Very specific:

    No truncating as casts on untrusted/runtime values — u32::try_from(x)?

    line 75
  8. Very specific:

    Keep the public surface minimal — pub(crate) by default.

    line 82
  9. Very specific:

    Test layout / coverage substance → pattern-test-coverage.

    line 87

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

pattern-engineer-rust

When to activate

Activate when writing or editing any .rs file, scaffolding a Rust crate, modifying Cargo.toml / Cargo.lock / rustfmt.toml / clippy.toml / .clippy.toml, working with tokio / serde / thiserror / anyhow / clap / axum / sqlx, or running cargo fmt / cargo clippy / cargo test / cargo audit / cargo deny. Skip for non-Rust code.

Project memory overlay

After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-rust.md in the consuming project (resolve MAIN_ROOT="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"). If present, load it as an additive overlay to the rules below; if absent, skip silently. See memory-convention for the full contract (additivity, severity floor, conflict surfacing).

Patterns

Toolchain & gate

  • Pin edition in Cargo.toml (edition = "2021" or newer); pin rust-version (MSRV) when you depend on it.
  • cargo fmt --check clean — no hand-formatting against rustfmt.
  • cargo clippy --all-targets --all-features -- -D warnings clean — warnings are errors.
  • cargo test passes (unit + integration under tests/).
  • Commit Cargo.lock for binaries and services; libraries leave it ungitignored but it is advisory.
  • cargo audit (or cargo deny check) is the dependency/advisory gate — wire it into CI.
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo audit            # or: cargo deny check

Error handling

  • No .unwrap() / .expect() on Result / Option in production paths. Tests, build scripts, examples, and benches are fine.
  • A startup-time .expect("invariant message") on config/env is acceptable when the process should die on a violated invariant — the message states the invariant.
  • Propagate with ?; don't hand-roll match that just returns the Err.
  • thiserror for typed library errors; anyhow only at application edges (main, request handlers, CLI commands).
  • Never Box<dyn Error> in a library's public API — return a concrete thiserror enum.

Ownership & borrowing

  • Never .clone() solely to silence the borrow checker — restructure, borrow, or split the borrow instead.
  • Read-only params take &str / &[T] / &T, not String / Vec<T> / owned T.
  • Cow<'_, str> (or Cow<'_, [T]>) when a value is sometimes borrowed, sometimes owned.

Types & matching

  • Newtype wrappers (struct UserId(u64);) for domain ids and units — not bare u64 / String.
  • Exhaustive match on domain enums — no catch-all _ arm that silently absorbs future variants. List variants; let new ones fail to compile.
  • Option / Result combinators (map, and_then, unwrap_or_else, ok_or, ?) over nested match where clearer.

Boundaries (serde)

  • serde derives live at the boundary only; convert into domain types at the seam — don't thread serde structs through the core.
  • #[serde(deny_unknown_fields)] when the contract is closed.
  • #[serde(rename_all = "camelCase")] (or the contract's spelling) over hand-renaming each field.

Async (tokio)

  • Never block in an async fn: no std::thread::sleep, sync file/DB I/O, or heavy CPU on the runtime — offload to tokio::task::spawn_blocking.
  • Join spawned tasks (JoinHandle), or detach deliberately with a // detached: comment saying why.
  • Timeout every outbound call (tokio::time::timeout).
  • Holding a std::sync::Mutex guard across .await is a deadlock smell — use tokio::sync::Mutex, or scope the guard so it drops before the await.

Unsafe

  • #![forbid(unsafe_code)] at the crate root of application crates.
  • Any unsafe block elsewhere carries a // SAFETY: comment proving the invariant it upholds.

Arithmetic

  • Checked / saturating arithmetic (checked_add, saturating_sub, …) on money and counters — release-mode overflow wraps silently.
  • No truncating as casts on untrusted/runtime values — u32::try_from(x)?. as is fine for compile-time-known widening.

Idiom

  • Iterator chains (.iter().filter().map().collect()) over manual index loops.
  • Implement From / TryFrom for conversions instead of ad-hoc to_x() / as_x() methods.
  • #[derive(Debug)] on public types.
  • Keep the public surface minimal — pub(crate) by default; promote to pub only when crossing the crate boundary.

Pointers to adjacent skills

  • Secrets handling, SSRF, injection, auth, crypto choice → owned by pattern-engineer-security; follow its catalogue rather than restating here.
  • Test layout / coverage substance → pattern-test-coverage.
  • HTTP route/contract wiring, healthz/readyz, env lockstep → pattern-engineer-backend-standard / pattern-engineer-api.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.