mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
d1db9a10cd
Agent-instruction and architecture docs had drifted from the code: - CLAUDE.md: slim to commands + pointers; fix wrong claim that `make pre-commit` is the full pre-PR gate (that is `make pre-pr`); drop stale pre-#3929 file paths and merged bug narratives - AGENTS.md: drop dead `rust-refactor-helper` skill rule and the hand-maintained (already stale) scoped-AGENTS index; link architecture docs from Sources of Truth - .github/AGENTS.md: replace the outdated copied CI command matrix with a pointer to ci.yml - crates/AGENTS.md: merge duplicated Testing sections - ARCHITECTURE.md: resolve the utils->config contradiction (edges are removed), mark volatile counts as snapshots, fix a bad path - docs/architecture: add README router; move one-shot plans/trackers (rebalance-decommission phases, migration-progress ledger, PR template) to docs/superpowers/plans with archive headers; fix stale source paths in kept inventories (core/sets.rs, core/pools.rs, store/mod.rs, startup_* split from #3671) - docs/operations/tier-ilm-debugging.md: extracted tier debugging playbook with corrected paths - scripts/check_doc_paths.sh: new guard failing pre-commit/pre-pr when instruction/architecture docs reference nonexistent file paths - .claude/skills: add tier-debug and arch-checks repo skills; .gitignore now keeps .claude/skills and docs/operations committable Verification: ./scripts/check_doc_paths.sh, ./scripts/check_architecture_migration_rules.sh (both pass) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Crates Instructions
Applies to all paths under crates/.
Library Design
- Treat crate code as reusable library code by default.
- Prefer
thiserrorfor library-facing error types. - Do not use
unwrap(),expect(), or panic-driven control flow outside tests.
Error Type Design
- Public API functions must return a typed error enum (preferably
thiserror-derived), neverResult<_, String>. - Do not use
Box<dyn Error>orBox<dyn Error + Send + Sync>in public trait methods or struct methods. Define a concrete error type with specific variants. - When implementing
std::error::Error, always overridefn source()if you store an inner error. Breaking the error chain makes debugging impossible. - Internal helpers that return
Result<_, String>and are immediately wrapped via.map_err(Error::other)should return the actual error type directly.
Concurrency
- Document lock acquisition order when a module uses multiple locks. Never acquire the same set of locks in different orders across code paths.
- Never hold a
tokio::sync::RwLock/Mutexwrite guard across.awaitpoints unless the critical section is unavoidably async and the hold time is bounded. - Prefer
compare_exchangeloops over load-then-store for concurrent counters (peak values, adaptive heuristics). - When resetting multi-field atomic statistics, use a version/sequence counter or accept that concurrent readers may see partial snapshots; document the tradeoff.
std::sync::Mutexis acceptable in async context only when held for a brief, non-await-containing critical section. If in doubt, usetokio::sync::Mutex.
Recursion Safety
- Recursive tree/graph traversals must have a depth limit (e.g.,
max_depthcounter) or use an iterative approach with an explicitVecstack. - This applies to cache trees, directory walks, and any user-influenced hierarchy.
- A corrupted or malicious input must not be able to overflow the thread stack.
Type Casting
- Never use
asfor numeric conversions that may truncate or overflow. Usetry_into()with explicit error handling, or clamp withvalue.max(0) as usizewhen the domain is bounded. f64 as usizesaturates but is fragile; clamp to[0, usize::MAX as f64]first.- Treat every
ascast in a PR review as a potential bug; require justification.
Testing
- Keep unit tests close to the module they test.
- Keep integration tests under each crate's
tests/directory. - Add regression tests for bug fixes and behavior changes.
- Every test function must contain at least one
assert!/assert_eq!/assert_matches!. A test that only calls code without asserting is not a test. - In tests, prefer
.expect("context: what was being tested")over bare.unwrap(). A test failure should tell you which operation failed and with what input.
Async and Performance
- Keep async paths non-blocking.
- Move CPU-heavy operations out of async hot paths with
tokio::task::spawn_blockingwhen appropriate.