# Style Guide
This project is "typechecker-first": prefer designs the compiler can validate statically.
## Safety
- **Unsafe is forbidden by default.**
- Add `#![forbid(unsafe_code)]` at crate roots unless explicitly waived for a specific, reviewed reason.
- If unsafe is ever approved, it must be:
- isolated behind a safe API boundary
- documented with invariants
- covered by tests
## Rust edition
- Use **Rust 2024 edition** defaults for new code (unless a compelling reason exists).
## Module layout
- Do **not** use `mod.rs` in new code. Use the Rust 2018+ "non-mod-rs" module layout:
- `foo.rs` with submodules in `foo/…`
## Error handling (no panics)
- Do not use `unwrap()` / `expect()` in production code.
- In tests, they may be acceptable when they improve readability and failure messages.
- Prefer typed errors and `Result`.
- Prefer fallible conversions: `TryFrom` / `TryInto` over `as` casts when failure is possible.
## API design
- Prefer small, well-typed domain types ("newtypes") over primitives with comments.
- Keep implementation details private by default (`pub` is opt-in).
- Prefer explicit constructors over public fields unless the type is a plain data carrier.
## Mutability & interior mutability
- Prefer straightforward ownership + borrowing.
- Avoid `Cell` / `RefCell` unless you have a measured need and a clear invariant.
## Mutability gating rule (repeat)
- If interior mutability is necessary, do not do it (fail your task), then
- Ask your coordinator to explicitly authorize another subtask with interior mutability, with your justification.
## Formatting & linting
- Rustfmt is mandatory.
- Clippy is mandatory; treat warnings as errors in CI/local workflows.
- Avoid adding dependencies unless justified by the bead/task.
## Refactor gating rule (repeat)
If your implementation is blocked by a large refactor that you are not cleared to do:
- do not do it
- fail your task and ask the Coordinator to create/assign a bead for the refactor first