stemedb/.claude/guides/coding-guidelines.md
jml 9bfa626203 docs: reorganize documentation structure for clarity
Major documentation restructure to improve discoverability and reduce duplication.

## Changes

**Deleted (Archived/Consolidated)**:
- Removed duplicate getting started guides
- Archived outdated planning documents
- Consolidated corpus and configuration docs
- Removed obsolete vision/spec files (superseded by vision.md)
- Cleaned up scrapyard and old PDFs

**New Structure**:
- docs/about/ - Project overview and introduction
- docs/guides/ - User guides (moved from root)
- docs/specs/ - Technical specifications
- docs/sdk/ - SDK documentation (Go)
- docs/references/ - API references
- docs/archive/ - Archived historical docs
- applications/aphoria/docs/advanced/ - Advanced topics
- applications/aphoria/docs/reference/ - CLI reference
- applications/aphoria/docs/archive/ - Archived aphoria docs

**Updated**:
- README.md - New root README with clear navigation
- CONTRIBUTING.md - Contribution guidelines
- CLAUDE.md - Updated paths to new structure
- roadmap.md - Added recent completions

## Files Changed
- 57 files changed
- 1,977 insertions(+)
- 961 deletions(-)

**Net change**: +1,016 lines (added CONTRIBUTING.md, README.md, reorganized content)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 07:33:40 +00:00

145 lines
3.5 KiB
Markdown

# Rust Coding Guidelines
## Core Stack
| Component | Required | Forbidden |
|-----------|----------|-----------|
| Error handling | `thiserror` (lib), `anyhow` (bin) | `.unwrap()`, `.expect()`, `panic!` |
| Serialization | `rkyv` (zero-copy) | `serde_json` for hot paths |
| Hashing | `blake3` | `sha256`, `md5` |
| KV Store | `sled` (MVP), trait-abstracted | Direct `rocksdb` coupling |
| Async | `tokio` (if needed) | `async-std` |
| Logging | `tracing` | `log`, `println!` |
| Testing | `proptest`, `rstest` | Mocking core types |
## Error Handling
```rust
// Library errors: use thiserror
#[derive(Debug, thiserror::Error)]
pub enum StemeError {
#[error("assertion not found: {0}")]
NotFound(Hash),
#[error("invalid signature for agent {agent}")]
InvalidSignature { agent: AgentId },
#[error("storage error: {0}")]
Storage(#[from] sled::Error),
}
// Always add context
fn load_assertion(hash: &Hash) -> Result<Assertion, StemeError> {
let bytes = self.store
.get(hash)
.context("failed to read from store")?
.ok_or(StemeError::NotFound(*hash))?;
// ...
}
```
## Type Safety
Use newtypes for domain IDs:
```rust
// Good: Strong types
pub struct EntityId(pub String);
pub struct RelationId(pub String);
pub struct Hash(pub [u8; 32]);
pub struct AgentId(pub [u8; 32]);
// Bad: Stringly-typed
fn query(subject: String, predicate: String) -> ...
```
## Formatting
- Use underscores in numbers: `1_000_000` not `1000000`
- Use inline interpolation: `println!("{hash:?}")` not `println!("{:?}", hash)`
- Max line length: 100 characters
- Run `cargo fmt` before commit
## Testing
```rust
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
// Property test for critical invariants
proptest! {
#[test]
fn assertion_round_trips(bytes in prop::collection::vec(any::<u8>(), 0..1000)) {
let assertion = /* create from bytes */;
let serialized = rkyv::to_bytes(&assertion)?;
let deserialized = rkyv::from_bytes(&serialized)?;
assert_eq!(assertion, deserialized);
}
}
// Descriptive test names
#[test]
fn test_lens_consensus_returns_highest_vote_count() {
// Arrange
let assertions = vec![/* ... */];
// Act
let result = ConsensusLens.resolve(&assertions, &ctx);
// Assert
assert_eq!(result.value, expected);
}
}
```
## Module Structure
```
crates/stemedb-core/
src/
lib.rs # Public API, re-exports
assertion.rs # Assertion struct
types.rs # EntityId, RelationId, Hash, etc.
store.rs # Storage trait
error.rs # StemeError
tests/
integration.rs # Cross-module tests
```
## Documentation
```rust
/// Resolves conflicting assertions using weighted voting.
///
/// # Arguments
/// * `candidates` - All assertions matching the query
/// * `context` - Query context including agent reputations
///
/// # Returns
/// The assertion with highest weighted support, or None if empty.
///
/// # Example
/// ```
/// let lens = ConsensusLens::default();
/// let result = lens.resolve(&assertions, &ctx);
/// ```
pub fn resolve(&self, candidates: &[Assertion], context: &QueryContext) -> Option<Assertion> {
// ...
}
```
## Clippy
Must pass with zero warnings:
```bash
cargo clippy --workspace -- -D warnings
```
Common fixes:
- `needless_return`: Remove explicit `return` when implicit works
- `redundant_clone`: Check if clone is actually needed
- `missing_docs`: Add doc comments to public items