| name | rust-workspace-engineering |
| description | eddy Rust workspace conventions, Nix toolchain use, error handling, env parsing, tests, and docs coupling. |
Rust Workspace Engineering
Toolchain
Run Rust workspace devtooling through just recipes. Nix remains supported for provisioning the pinned Rust toolchain. Prefer focused checks during RGR and just ci for the aggregate routine gate.
Rust test recipes must use cargo nextest; do not run cargo test directly unless a documented nextest-incompatible case requires it.
Modify Rust package dependencies with Cargo package-manager commands such as cargo add, cargo remove, or cargo update. Do not hand-edit dependency entries, versions, or feature lists in Cargo.toml. Generated Cargo.lock updates from Cargo commands are acceptable.
Code Conventions
- Rust lint policy lives in
Cargo.toml and should keep the exact lints from
stable Clippy quality groups at forbid, not merely deny. Do not configure
clippy::all as a group-level forbid; keep the generated exact member list
in [lints.clippy] so third-party macro allow attributes cannot produce
forbidden_lint_groups warnings that bypass -D warnings. Keep
clippy::cargo enabled; do not enable experimental clippy::nursery,
subjective clippy::pedantic, or the contradictory clippy::restriction
group as groups.
build.rs runs scripts/sync-clippy-lints.mjs --check during Cargo builds.
If the pinned toolchain changes the clippy::all membership, run
just sync-clippy-lints and commit the resulting Cargo.toml update.
- Exact
clippy::restriction lints may be opted into at forbid when they
support quality, test diagnostics, or LLM-friendly maintainability. Do not
use the restriction group wholesale.
- The only allowed project-wide downgrade from
forbid to deny is for an
exact lint when a third-party macro emits an allow for that exact lint. If
this carve-out is needed, downgrade only the exact lint being allowed by the
macro, never a containing group, and document the reason next to the lint
setting.
- No
unwrap() or expect() outside #[cfg(test)].
- Use
?, anyhow::Context, or explicit error variants.
- Use
read_non_empty_env(name) and parse_env::<T>(name) in ar-gateway/src/main.rs.
- Cap provider error bodies with
ar_llm::cap_for_error or equivalent helpers.
- Keep crate boundaries aligned with
AGENTS.md and docs/CRATES.md.
Tests
Pure helpers get adjacent unit tests. For a Rust module foo.rs, place unit tests in a same-directory sidecar file foo_test.rs and load it from foo.rs with #[cfg(test)] plus #[path = "foo_test.rs"] mod tests;. HTTP integrations use wiremock. LLM behavior uses CannedProvider or ScriptedProvider fakes.
User-Facing Changes
Use conventional commit titles for user-facing or operator-facing behavior; the release PR generates changelog notes from conventional commits.