7.5 KiB
7.5 KiB
AGENTS.md - Agentic Coding Guidelines
Guidelines for AI agents and autonomous developers operating in this repository.
Build/Test/Lint Commands
Quick Commands
# Format Rust code
just fmt
cargo +nightly fmt --all
# Lint Rust code
cargo clippy --all-targets -- -D warnings
# Run all tests for a single crate
cd platform && cargo test --all-features
# Run a single test
cargo test <test_name> -- --nocapture
# Run a single test in a specific crate
cd platform && cargo test --package <crate_name> <test_name>
# Build everything
just build-all
# Quick development build
just dev-build
# Run CI checks locally
just ci-full # All checks: lint, fmt, test, audit
just ci-fmt # Format checking
just ci-lint-rust # Clippy linting
just ci-test # Run all tests
Development Workflow
# Incremental development build
just build-incremental
# Validate changes before commit
just validate-all
# Check build system health
just build-check
# Run tests with coverage
just ci-test-coverage
Code Style Guidelines
Rust (Primary Language)
Imports
- Organization: Use
group_imports = "StdExternalCrate"(stdlib → external → crate) - Style:
usestatements grouped and reordered automatically by rustfmt - Nightly features: Enabled via
unstable_features = truein.rustfmt.toml - Public exports: Re-export via
pub usefor ergonomic APIs (seeplatform-config/src/lib.rs)
Formatting & Line Length
- Max line width: 100 characters
- Tab style: Spaces (4 per indentation)
- Newline style: Unix (LF)
- Chain width: 60 characters before wrapping
- Function parameters: Use tall layout (
fn_params_layout = "Tall") - Match arms: Trailing commas disabled; match block structure preserved
- Comments: Wrapped at 80 chars; normalized; doc attributes normalized
Types & Naming
- Naming convention:
snake_casefor functions/variables,PascalCasefor types/traits - Type complexity: Limit to 500 (threshold:
.clippy.toml) - Cognitive complexity: Limit to 25 (threshold:
.clippy.toml) - Nesting depth: Max 5 levels (threshold:
.clippy.toml) - Generic types: Use single-char names only in narrow scopes; prefer descriptive names
Error Handling
- Pattern: Use
thiserrororanyhowfor result types; define customResult<T> - Custom errors: Enum-based with
#[from]derives (seeprovctl-core/src/error.rs) - No panics: Avoid
panic!(),unwrap(),todo!(),unimplemented!() - Error variants: Include context (operation, resource, reason) in error kinds
- String errors: Use structured enum variants, not bare strings
- Result type: Always return
Result<T>from fallible functions; definetype Result<T> = std::result::Result<T, Error>
Documentation
- Module docs: Always include
//!at crate/module start with purpose and features - Examples: Include
# Examplessections (useignorefor untested code) - Feature docs: List capabilities, not obvious implementation details
- Code comments: Only for "why", not "what" (code should be self-documenting)
Traits & Impl Blocks
- Trait organization: Group related impls together; separate concerns
- Method order: Public API first, then private helpers
- Default implementations: Use trait defaults to reduce boilerplate
- Associated types: Prefer over generic parameters when type is determined by implementor
Nushell Scripts
Follows Nushell guidelines in .claude/guidelines/nushell/. Key points:
- Structured data pipelines preferred
- Error handling with
?operator - Type annotations on function parameters
- Module organization with clear public/private boundaries
- Avoid shell anti-patterns; prefer Nushell idioms
TOML Configuration
- Format checking:
taplo format --check - Lint:
taplo lint - Workspace: All Rust projects use workspace Cargo.toml
Architecture & Organization
Workspace Structure
platform/
├── Cargo.toml (workspace root with [workspace.dependencies])
├── crates/
│ ├── platform-config/ (shared config loading)
│ ├── service-clients/ (inter-service communication)
│ ├── ai-service/ (AI integration)
│ ├── orchestrator/ (workflow orchestration)
│ └── ...
└── prov-ecosystem/
└── crates/ (ecosystem services)
Module Organization
- Public modules: Exported via
pub useinlib.rs - Private modules: Implementation details not in public API
- Error modules: Standalone
error.rswith custom error types - Hierarchy: Clear parent-child relationships; avoid circular dependencies
Configuration Management
- Formats: Nickel (NCL) or TOML; auto-converted to JSON internally
- Loading hierarchy: Environment variables → File-based → Defaults
- Trait pattern: Implement
ConfigLoaderfor service configs - Validation: Services validate configs on load via
ConfigValidator
Clippy & Linting Rules
Required Settings
- Lint level:
-D warnings(deny all warnings) - Clippy thresholds (
.clippy.toml):- Cognitive complexity: 25
- Type complexity: 500
- Nesting depth: 5
- Single-char bindings: 4 allowed
Pre-commit Hooks
- Rust format:
cargo +nightly fmt --all -- --check(blocks commit if fails) - Clippy:
cargo clippy --all-targets -- -D warnings(blocks commit if fails) - Note: Tests run in CI only; blocked on pre-push to prevent dev friction
Git & Commit Workflow
Forbidden
- ❌ Force push (
--force) - ❌ Hard reset/rebase without authorization
- ❌ Branch creation outside established workflow
Format Commands
cargo +nightly fmt --all # Format all projects
cargo fmt --package <crate> # Format single crate
git diff --check # Verify no trailing whitespace
Testing Strategy
Test Organization
- Unit tests: In same file,
#[cfg(test)]modules - Integration tests: Separate
tests/directories - Coverage: Run via
cargo llvm-cov --all-features - CI: All tests run with
--all-featuresflag
Test Patterns
- Use descriptive names:
test_error_handling_on_missing_config - Isolate state; use fixtures/builders for setup
- Assert both success and error cases
- Document non-obvious test scenarios
Key Tools & Dependencies
Core Stack
- Async runtime:
tokio(full features) - Serialization:
serde+serde_json - Error handling:
thiserror,anyhow - Logging:
tracing+tracing-subscriber - Web:
axum,tower-http - CLI:
clap(derive macros) - Database:
sqlx,surrealdb
Build & Dev Tools
- Formatter:
cargo +nightly fmt - Linter:
cargo clippy - Test coverage:
cargo-llvm-cov - TOML formatter:
taplo - Task runner:
just(justfiles) - Shell: Nushell for scripts
Implementation Checklist
Before coding:
- ✅ Check
.rustfmt.tomlfor formatting rules - ✅ Verify error handling: custom enum, no panics
- ✅ Add doc comments with examples
- ✅ Organize imports per stdlib → external → crate
- ✅ Test single function:
cargo test <name> -- --nocapture - ✅ Run clippy:
cargo clippy --all-targets -- -D warnings - ✅ Format:
cargo +nightly fmt --all
References
- Workspace:
platform/Cargo.toml - Rustfmt config:
.rustfmt.toml - Clippy config:
.clippy.toml - Pre-commit:
.pre-commit-config.yaml - CI recipes:
justfiles/ci.just - Nushell guidelines:
.claude/guidelines/nushell/