rust-doctor 0.1.18

A unified code health tool for Rust — scan, score, and fix your codebase
Documentation
/// Prompt template for the deep-audit workflow.
/// Interpolated with `directory` at runtime.
pub fn deep_audit_prompt(directory: &str) -> String {
    format!(
        r#"You are performing a comprehensive, expert-level Rust code audit on the project at '{directory}'.
This is NOT a simple lint pass — you are an elite Rust consultant performing a deep quality audit that
combines static analysis, architecture review, best-practices research, and actionable remediation.

Follow the 6 phases below sequentially. After each phase, append your findings to a running
audit document that will become the Phase 5 synthesis report.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 1 — DISCOVERY (Explore the codebase)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Before scanning, understand the project's architecture and context:

1. **Project structure**: Read `Cargo.toml` to understand:
   - Crate type (lib / bin / both), edition, MSRV
   - Dependencies and their purpose
   - Feature flags
   - Workspace structure (if any)

2. **Architecture mapping**: Explore `src/` to understand:
   - Module tree and visibility (`pub` vs `pub(crate)` discipline)
   - Entry points (`main.rs`, `lib.rs`)
   - Core domain types and traits
   - Error handling strategy (custom types? thiserror? anyhow? Box<dyn Error>?)
   - Async runtime usage (tokio, async-std, or sync-only)
   - Framework detection (axum, actix-web, rocket, tonic, etc.)

3. **Codebase metrics**: Note approximate file count, LOC, module depth.

Output: A brief architecture summary (10-15 lines) with the tech stack, patterns used, and first impressions.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 2 — STATIC ANALYSIS (rust-doctor scan)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. Use the `scan` tool on `{directory}` to get all diagnostics and the health score.
2. Use `explain_rule` on P0/P1 rules and any rule you don't recognize to understand what each finding means.
3. Categorize findings by priority:
   - **P0 Critical**: Security errors, correctness bugs, CVE advisories
   - **P1 High**: Error handling, reliability, async safety issues
   - **P2 Medium**: Performance, architecture, maintainability
   - **P3 Low**: Style, info-level suggestions

Output: Score, dimension breakdown, and findings grouped by priority with rule explanations.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 3 — DEEP CODE REVIEW (Beyond the scanner)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

rust-doctor catches specific patterns. Now go deeper — read the actual source code and look for
issues that no linter can catch. Use this expert checklist:

### Error Handling Review
- [ ] Are error types well-designed? (thiserror for libs, anyhow for bins)
- [ ] Do errors propagate context? (`?` with `.context()` / `.map_err()`)
- [ ] Are error messages lowercase, no trailing punctuation? (Rust convention)
- [ ] Does `Error::source()` return the underlying cause for error chaining?
- [ ] Are there `Box<dyn Error>` in public APIs? (should be concrete types)

### Ownership & Lifetimes
- [ ] Unnecessary `.clone()` calls — could they borrow instead?
- [ ] `String` parameters where `&str` or `impl AsRef<str>` would suffice?
- [ ] Owned types in function signatures where generics (`impl Into<T>`) give callers flexibility?
- [ ] `'static` lifetimes used where a shorter lifetime works?

### Type Design & API Quality
- [ ] Do public types derive common traits? (`Debug`, `Clone`, `PartialEq`, `Eq`, `Hash`, `Default`, `Display`)
- [ ] Are `From`/`TryFrom` implemented instead of custom conversion methods?
- [ ] Are newtypes used for type safety? (e.g., `UserId(u64)` instead of bare `u64`)
- [ ] Are builder patterns used for complex construction?
- [ ] `bool` parameters → should they be enums for clarity?
- [ ] Struct fields public when they should be private with accessors?

### Architecture & Modularity
- [ ] Is `pub` overused? Could items be `pub(crate)` or private?
- [ ] God modules/structs with too many responsibilities?
- [ ] Circular dependencies between modules?
- [ ] Is `main.rs` thin? (logic should live in `lib.rs` for testability)
- [ ] Dead code or unused imports?

### Async Correctness (if async is used)
- [ ] `std::sync::Mutex` held across `.await`? (must use `tokio::sync::Mutex`)
- [ ] `std::thread::sleep` / `std::fs::*` on async threads? (use `spawn_blocking`)
- [ ] Futures in `select!` — are they cancel-safe?
- [ ] Fire-and-forget `tokio::spawn` without tracking `JoinHandle`?
- [ ] `async fn` that never `.await`? (should be sync)
- [ ] Deadlock risk: multiple locks acquired in inconsistent order?
- [ ] Missing `Send`/`Sync` bounds on types crossing thread boundaries?

### Performance Patterns
- [ ] `Vec::new()` in loops? (preallocate with `with_capacity` or reuse with `.clear()`)
- [ ] `format!()` in hot paths? (use `write!` to existing buffer)
- [ ] `.collect()` immediately followed by `.iter()`? (remove the collect)
- [ ] Large types on the stack that should be `Box`ed?
- [ ] String concatenation in loops? (use `push_str` or `String::with_capacity`)
- [ ] Integer arithmetic that could overflow in release mode? (use `checked_*`/`saturating_*`)

### Security Hardening
- [ ] Hardcoded secrets, API keys, tokens in source?
- [ ] SQL built with `format!()` instead of parameterized queries?
- [ ] User input not validated at trust boundaries?
- [ ] `unsafe` blocks without documented safety invariants?
- [ ] Secrets in `String` (not zeroed on drop — use `secrecy` crate)?
- [ ] Custom cryptography instead of audited crates (ring, RustCrypto)?
- [ ] Sensitive data in `Debug`/`Display` impls or log macros? (redact PII/tokens)
- [ ] `Rc<RefCell<T>>` cycles without `Weak` references? (memory leaks)

### Dependency Health
- [ ] Unmaintained or abandoned dependencies?
- [ ] Excessive transitive dependency tree?
- [ ] Missing `rust-version` (MSRV) declaration?
- [ ] License compatibility issues?

### Documentation & Testing
- [ ] Public items missing rustdoc?
- [ ] Examples using `unwrap()` instead of `?`?
- [ ] Missing unit tests for core logic?
- [ ] Missing integration tests for public API?
- [ ] `#[must_use]` on functions returning `Result` or important values?
- [ ] Silently swallowed errors? (`let _ = result;`, empty match arms, `.ok()` without handling)

Output: A list of additional findings NOT caught by rust-doctor, with file:line references and severity.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 4 — BEST PRACTICES RESEARCH (Web search)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Based on the findings from Phases 2 and 3, research current Rust best practices.
Focus your searches on the specific issues found — not generic advice.

### Tool selection (adapt to your environment)

**For web research** — use whichever is available, in this priority order:
1. Exa MCP tools (`web_search_exa`, `get_code_context_exa`) — best quality for code research
2. Native `WebSearch` / `WebFetch` tools — always available as fallback

**For documentation lookup** — use whichever is available, in this priority order:
1. Context7 MCP tools (`resolve-library-id` then `query-docs`) — version-accurate, up-to-date docs
2. Native `WebFetch` on docs.rs / official docs — fallback if Context7 is not available

### What to research

1. **Framework-specific patterns**: If the project uses axum/actix/tonic, search for current
   best practices for that framework (error handling, middleware, extractors, etc.)
2. **Crate-specific guidance**: For major dependencies, look up their documentation
   (use Context7 if available, or fetch from docs.rs)
3. **Anti-pattern remediation**: For each major issue category found, search for the recommended
   Rust community approach (e.g., "Rust async error handling best practices")
4. **Performance patterns**: If performance issues were found, search for the idiomatic solution

Key reference sources to check:
- Rust API Guidelines (rust-lang.github.io/api-guidelines)
- Effective Rust (effective-rust.com)
- Rust Design Patterns (rust-unofficial.github.io/patterns)
- The Rust Performance Book (nnethercote.github.io/perf-book)
- Tokio documentation — use Context7 `query-docs` for tokio if available, else docs.rs/tokio

Output: Curated list of best practices relevant to THIS project's issues, with source URLs.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 5 — SYNTHESIS REPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Cross-reference all findings (scanner + code review + best practices) into a unified report:

### Report Structure

```
# Deep Audit Report — [project name]

## Executive Summary
- Health Score: X/100
- Critical Issues: N
- Architecture Assessment: [one-line verdict]
- Estimated Remediation Effort: [small/medium/large]

## Score Breakdown
| Dimension      | Score | Key Issues |
|----------------|-------|------------|
| Security       | X/100 | ...        |
| Reliability    | X/100 | ...        |
| Maintainability | X/100 | ...       |
| Performance    | X/100 | ...        |
| Dependencies   | X/100 | ...        |

## Findings by Priority

### P0 — Fix Immediately
For each: rule/issue, affected files, root cause, recommended fix (with code),
best practice source URL

### P1 — Fix Before Release
(same structure)

### P2 — Fix This Sprint
(same structure)

### P3 — Backlog
(same structure)

## Tech Debt Assessment
- Noise-to-signal ratio (how many findings are actionable vs. noise)
- Architecture debt (structural issues that compound over time)
- Dependency debt (outdated/unmaintained deps, license risks)

## Best Practices Gaps
Issues found by code review that rust-doctor doesn't catch yet, cross-referenced
with Rust community best practices. For each gap, include:
- What the best practice says
- How the codebase diverges
- Recommended fix with before/after code
- Source URL

## Recommendations Summary
Ordered list of the highest-impact improvements, with effort estimates.
```

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PHASE 6 — DECISION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

After presenting the full report, ask the user to choose:

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
What would you like to do next?

1. Implement all fixes — I'll work through P0→P1→P2→P3,
   fix each issue, verify with cargo check, and re-scan
   to confirm the score improved.

2. Generate a PRD — I'll create a complete Product
   Requirements Document with epics per priority level,
   user stories for each fix, acceptance criteria, and
   a status tracking JSON file.

3. Manual — You tell me which specific issues to fix
   or what to do next.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

### If Option 1 (Implement all):
1. Use task tracking to organize work items by priority (P0 first)
2. For each finding (P0 first):
   a. Read the affected file(s)
   b. Apply the fix following best practices from Phase 4
   c. Run `cargo check` to verify compilation
   d. Run `cargo clippy` to verify no new lints
3. After all fixes, re-run `scan` to verify score improvement
4. Present before/after comparison
5. Offer to commit with a conventional commit message

### If Option 2 (Generate PRD):
Create a structured PRD with:
- Epics: one per priority level (P0, P1, P2, P3)
- Stories: one per finding/rule, with:
  - Acceptance criteria (what "fixed" looks like)
  - Affected files
  - Fix guidance
  - Effort estimate
- Quality gates: re-scan must pass target score
- Status tracking JSON

### If Option 3 (Manual):
Wait for the user's instructions. Do not proceed without explicit direction.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
HARD RULES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

- ALWAYS run the `scan` tool before providing any guidance — never diagnose from memory.
- ALWAYS read the actual source code before suggesting fixes.
- ALWAYS include file:line references for every finding.
- ALWAYS verify fixes compile with `cargo check` before moving to the next.
- NEVER invent diagnostics that the scan or code review didn't find.
- NEVER apply fixes without reaching Phase 6 and getting user confirmation.
- NEVER skip Phase 3 (deep code review) — the scanner alone is insufficient for an expert audit.
- NEVER provide generic Rust advice — every recommendation must be grounded in THIS codebase.
- Show progress headers between phases so the user can follow along."#
    )
}

/// Prompt template for the health-check workflow.
/// Interpolated with `directory` at runtime.
pub fn health_check_prompt(directory: &str) -> String {
    format!(
        r#"Run a comprehensive health audit on the Rust project at '{directory}'.

## Phase 1: Scan
Use the `scan` tool to get all diagnostics and the health score.

## Phase 2: Remediation Plan
From the scan results, generate a prioritized remediation plan:
- **P0 Critical**: Security vulnerabilities, correctness bugs → fix immediately
- **P1 High**: Error handling issues, dependency problems → fix before release
- **P2 Medium**: Performance issues, architecture smells → plan for next sprint
- **P3 Low**: Style, info-level suggestions → nice-to-have

For each item, show:
1. Rule name and occurrence count
2. Affected files
3. Concrete fix action (use `explain_rule` for detailed guidance)
4. Estimated effort (trivial / small / medium / large)

## Phase 3: Confirmation
Present the full plan as a structured task list and ask:
"Do you want me to proceed with fixing these issues? I'll work through them by priority, starting with P0."

## Phase 4: Execution (if confirmed)
If the user confirms:
1. Use task tracking to organize the work by priority
2. Start with P0 items, then P1, P2, P3
3. For each item:
   - Read the affected files
   - Apply the fix following the `explain_rule` guidance
   - If unsure about the idiomatic fix, look up the relevant crate documentation:
     use Context7 MCP (`resolve-library-id` + `query-docs`) if available, else fetch from docs.rs
   - Verify the fix compiles (`cargo check`)
4. After all fixes, re-run `scan` to verify the score improved
5. Commit the changes with a conventional commit message

If the user declines or wants partial fixes, respect their choice and only fix the items they approve."#
    )
}