Code Standards
Rust conventions for the autoresearch codebase.
Error Handling
- Use
anyhow::Resultfor all fallible functions. - Use
thiserrorfor custom error types in library code that callers need to match on. - Use
.context("descriptive message")on every?— errors should be traceable. - Never
unwrap()in library code.unwrap()is acceptable only in tests. expect()is acceptable for provably infallible operations (e.g., regex compilation).
Serialization
- All persistent types derive
Serialize, Deserialize. - Use
#[serde(rename_all = "snake_case")]for enum variants. - Use
#[serde(tag = "phase")]for internally tagged enums (likeRunPhase). - Use
#[serde(default)]for optional fields added in later versions (forward compat). - Use
#[serde(skip_serializing_if = "Option::is_none")]to keep JSON clean.
Documentation
- Every public type and function has a
///doc comment. - Module-level
//!doc comments describe the module’s role. - Use
# Examplesin doc comments for non-obvious APIs.
Testing
- Unit tests live in
#[cfg(test)] mod testsat the bottom of each file. - Integration tests live in
tests/. - E2E fixtures live in
tests/e2e/fixtures/. - Every new CLI subcommand gets a test in
tests/cli_test.rs. - Every state transition gets a test in
tests/state_test.rs. - Target: 80%+ line coverage on
src/core/.
Style
- Run
cargo clippy -- -D warningsbefore every commit. Zero warnings. - Run
cargo fmtbefore every commit. - Run
./scripts/run_contributor_gate.shbefore opening a PR. - Run
./scripts/validate_distribution.shafter changing skill, command, reference, or agent metadata files. - Run
./scripts/run_skill_e2e.sh binary-smoke --cleanafter changing core run closeout or result-monitoring behavior. - Run
./scripts/run_skill_e2e.sh runtime-smoke --cleanafter changing runtime launch, status, or stop behavior. - Run
./scripts/run_skill_e2e.sh parallel-smoke --cleanafter changing parallel worker prepare/run/cleanup behavior. - Max line length: 100 characters (soft), 120 characters (hard).
- Prefer
matchoverif letchains for exhaustive enum handling. - Prefer
&stroverStringin function parameters when ownership isn’t needed.
Performance
- Hooks must complete in <5ms. No network calls, no heavy I/O in hook handlers.
- Use
Decimal(notf64) for all metric values — financial-grade precision. - Release builds use
opt-level = "z", LTO, strip,panic = "abort".
Naming
- Types:
PascalCase(e.g.,RunState,ResultRow) - Functions:
snake_case(e.g.,record_keep,run_verify) - CLI subcommands: lowercase single words (e.g.,
init,decide,evals) - Constants:
SCREAMING_SNAKE_CASE - Files:
snake_case.rs
Dependencies
- Minimize dependency count. Current deps are intentional:
clap— CLI parsingserde+serde_json— serializationtokio— async runtime (for exec mode)rust_decimal— precise metric valueschrono— timestampsgit2— libgit2 bindingsregex— pattern matchinganyhow+thiserror— error handlingglob— file pattern matching
- Do not add dependencies without justification in the PR description.