221 lines
7.5 KiB
Markdown
221 lines
7.5 KiB
Markdown
|
|
# AGENTS.md - Agentic Coding Guidelines
|
||
|
|
|
||
|
|
Guidelines for AI agents and autonomous developers operating in this repository.
|
||
|
|
|
||
|
|
## Build/Test/Lint Commands
|
||
|
|
|
||
|
|
### Quick Commands
|
||
|
|
```bash
|
||
|
|
# 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
|
||
|
|
```bash
|
||
|
|
# 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**: `use` statements grouped and reordered automatically by rustfmt
|
||
|
|
- **Nightly features**: Enabled via `unstable_features = true` in `.rustfmt.toml`
|
||
|
|
- **Public exports**: Re-export via `pub use` for ergonomic APIs (see `platform-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_case` for functions/variables, `PascalCase` for 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 `thiserror` or `anyhow` for result types; define custom `Result<T>`
|
||
|
|
- **Custom errors**: Enum-based with `#[from]` derives (see `provctl-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; define `type Result<T> = std::result::Result<T, Error>`
|
||
|
|
|
||
|
|
#### Documentation
|
||
|
|
- **Module docs**: Always include `//!` at crate/module start with purpose and features
|
||
|
|
- **Examples**: Include `# Examples` sections (use `ignore` for 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 use` in `lib.rs`
|
||
|
|
- **Private modules**: Implementation details not in public API
|
||
|
|
- **Error modules**: Standalone `error.rs` with 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 `ConfigLoader` for 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
|
||
|
|
```bash
|
||
|
|
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-features` flag
|
||
|
|
|
||
|
|
### 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:
|
||
|
|
1. ✅ Check `.rustfmt.toml` for formatting rules
|
||
|
|
2. ✅ Verify error handling: custom enum, no panics
|
||
|
|
3. ✅ Add doc comments with examples
|
||
|
|
4. ✅ Organize imports per stdlib → external → crate
|
||
|
|
5. ✅ Test single function: `cargo test <name> -- --nocapture`
|
||
|
|
6. ✅ Run clippy: `cargo clippy --all-targets -- -D warnings`
|
||
|
|
7. ✅ 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/`
|