hermes

Rust style rules

Standing rules for Rust an assistant writes, covering ownership-first APIs, Result over panic, clippy-clean code, typed errors, async hygiene and minimal, justified unsafe.

When you write or change Rust code in this project:

Tooling

  • Code must pass cargo fmt and cargo clippy --all-targets with no warnings under the project's lint settings.
  • Never silence a lint crate-wide. Allow a specific lint on the narrowest item, with a comment explaining why.
  • Use the edition and minimum Rust version in Cargo.toml. Add a dependency only when it earns its place, with the fewest features needed.

Ownership and APIs

  • Borrow in parameters when the function does not keep the value: &str, &[T], &Path or impl AsRef<Path>. Take ownership (String, Vec<T>) when the value is stored.
  • Do not add .clone() just to satisfy the borrow checker. Restructure the code first, and when a clone is the right answer, make it visible and cheap or explain it.
  • Return owned values or iterators rather than references tied to temporary state. Use Cow when a value is only sometimes owned.
  • Model states with enums rather than booleans or sentinel values, and wrap ids and units in newtypes.
  • Implement standard traits (From, TryFrom, Display, Default, Debug) instead of ad hoc conversion methods, and mark results that must not be ignored with #[must_use].

Errors

  • Return Result for anything that can fail at runtime, and propagate with ?.
  • Do not call unwrap() in library or request-handling code. Use expect("reason this cannot fail") only for real invariants.
  • Follow the project's error approach. Where there is none, use typed error enums (for example with thiserror) in libraries and contextual errors (for example anyhow with .context(...)) in binaries.
  • Never panic across an FFI boundary or in a Drop implementation.

Unsafe

  • Avoid unsafe. If it is necessary, keep the block as small as possible, put a // SAFETY: comment on it that states the invariants that make it sound, and wrap it in a safe API.
  • Document every unsafe fn with a # Safety section, and test unsafe code under Miri where the project supports it.

Concurrency and async

  • Prefer message passing or owned data over shared mutable state. When state is shared, use Arc with a Mutex or RwLock and keep critical sections short.
  • Never hold a std::sync::Mutex guard across .await. Use the runtime's async mutex or restructure.
  • Never block inside async code. Move blocking or CPU-heavy work to spawn_blocking or a dedicated thread.

Style

  • Prefer iterator chains to index loops when they read clearly, and avoid collecting into a Vec only to iterate it again.
  • Keep items private by default, and use pub(crate) before pub.
  • Document public items with /// comments, with an example for non-trivial APIs.
  • Put unit tests in a #[cfg(test)] mod tests beside the code, and integration tests in tests/.

details

kind
Rule: standing instructions for everything the assistant does
domain
Software engineering
category
Conventions
made for
Software engineer, Backend engineer, Embedded engineer
risk
read-only
version
v1.0.0 · experimental
reviewed
2026-10-02
works in
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai

Edit on GitHubReport a problem

use in

Hodios CLI
npx @hermes-hq/hodios install rust-style-rules --target claude-code
Agent Skills
npx skills add hermes-hq/hodios-dist --skill rust-style-rules -a claude-code

Rules are always-on instructions, so they are not in the plugins: add the skill, or paste the text into CLAUDE.md.

pairs well with

All of Conventions
RuleTesting

Test-writing rules

Standing rules for tests an assistant writes, covering behaviour over implementation, no sleeps, deterministic data, mocks only at boundaries and one reason to fail per test.

test-writing-rules
RuleConventions

HTTP API design rules

Rules for HTTP APIs covering resource naming, status codes, problem+json errors, cursor pagination, idempotency keys and versioning. Load when designing or changing HTTP endpoints.

api-design-rules
RuleConventions

C# style rules

Standing rules for C# an assistant writes, covering nullable reference types, async all the way with cancellation tokens, records and pattern matching, dependency injection and xUnit tests.

csharp-style-rules
RuleConventions

Go style rules

Standing rules for Go an assistant writes, covering wrapped errors, context propagation, small consumer-side interfaces, table-driven tests and no goroutines without an owner.

go-style-rules
RuleConventions

Java style rules

Standing rules for Java an assistant writes, covering modern language features, immutability, Optional and null handling, exceptions, restrained streams, records and JUnit 5 tests.

java-style-rules
RuleConventions

Python style rules

Standing rules for Python an assistant writes, covering type hints, pathlib, logging over print, explicit exceptions, safe subprocess calls, project layout and the project's own tooling.

python-style-rules