# DEVELOP.md — Development Rules & Tracking ## Quick Start ```bash # Prerequisites rustup show # Rust 1.80+ cargo install cargo-watch # Run locally cargo run -- --config config/default.toml # Run with auto-reload cargo watch -x run # Run tests cargo test # Lint cargo clippy -- -D warnings cargo fmt --check ``` ## Development Rules ### Code Quality 1. **No warnings.** All code must compile with zero warnings. CI treats warnings as errors (`-D warnings`). 2. **Format before commit.** Run `cargo fmt` — CI checks formatting. 3. **Clippy clean.** Run `cargo clippy -- -D warnings` — CI checks lints. 4. **Tests required.** Every new module/function must have unit tests. Public API changes require integration tests. 5. **Doc comments.** All public items (`pub fn`, `pub struct`, `pub enum`) must have `///` doc comments. ### Git Workflow 1. **Branch naming**: `/` - `feat/dns-cache`, `fix/ttl-overflow`, `docs/readme`, `chore/ci-update` 2. **Commit messages**: Conventional Commits format - `feat: add DNS response cache` - `fix: handle truncated UDP responses` - `docs: update plan.md` 3. **PR required.** All changes go through a pull request. No direct pushes to `main`. 4. **Squash merge.** PRs are squash-merged into `main`. 5. **CI must pass.** Lint, test, and build must succeed before merge. ### Architecture Rules 1. **No panics in production code.** Use `Result` everywhere. `unwrap()` only in tests. 2. **Structured errors.** Define error types per module using `thiserror`. Use `anyhow` only in `main.rs`. 3. **Async everywhere.** All I/O is async (Tokio). No blocking calls in async context. 4. **Config-driven.** No hardcoded values. All tunables come from config file or env vars. 5. **Dependency injection.** Accept traits, not concrete types. Makes testing easy. ### Testing Rules 1. **Unit tests** in the same file (`#[cfg(test)] mod tests { ... }`). 2. **Integration tests** in `tests/` directory. 3. **Test naming**: `test___` — e.g., `test_cache_expired_entry_returns_miss`. 4. **No external dependencies in unit tests.** Mock upstream resolvers. 5. **Integration tests** may spin up the full server on a random port. ### Security Rules 1. **No secrets in code.** Use env vars or config files (gitignored). 2. **Validate all input.** DNS queries from the network are untrusted — validate lengths, offsets, labels. 3. **Timeouts on all upstream calls.** Never hang indefinitely. 4. **Rate limiting.** Protect against abuse from a single IP. 5. **Dependency audit.** Run `cargo audit` in CI. ### Commit Checklist Before pushing, verify: - [ ] `cargo fmt --check` passes - [ ] `cargo clippy -- -D warnings` passes - [ ] `cargo test` passes - [ ] New code has tests - [ ] Public items have doc comments - [ ] No `unwrap()` outside of tests - [ ] Config values are externalized (not hardcoded) ## Milestone Tracking See [docs/plan.md](docs/plan.md) for the full project plan and milestone checklist. | Milestone | Status | |-----------|--------| | M1 — Core Forwarding | ✅ Done | | M2 — Multiple Upstreams & Config | ✅ Done | | M3 — Caching | 🔲 Not started | | M4 — Observability | 🔲 Not started | | M5 — Blocking & Filtering | 🔲 Not started | | M6 — Production Hardening | 🔲 Not started | ## Useful Commands ```bash # Build release binary cargo build --release # Run with specific log level RUST_LOG=debug cargo run # Generate and open docs cargo doc --open # Dependency audit cargo install cargo-audit cargo audit # Watch tests cargo watch -x test ```