rs-guard 1.0.0

AI-powered code review CLI for GitHub PRs
Documentation
# rs-guard — Agent Guide

> Current state of the `rs-guard` repository for AI coding agents.

---

## Project Overview

**rs-guard** is a Rust-based AI code review CLI tool. It fetches Pull Request diffs from GitHub, sends them to an LLM provider for review, parses a structured verdict from the response, and submits the review state (`APPROVE`, `REQUEST_CHANGES`, or `COMMENT`) back to GitHub — all in a single execution.

**Current Status:** Phases 1–6 are complete. The crate is published on crates.io and registered on crates.ai.

- **Repository:** `git@github.com:nebulaideas/rs-guard.git`
- **Current Branch:** `main`
- **License:** MIT License (Copyright 2026 Nebula Ideas)
- **Language:** Rust (edition 2021, toolchain 1.82+)
- **Crate:** [rs-guard on crates.io]https://crates.io/crates/rs-guard | [docs.rs]https://docs.rs/rs-guard

---

## Technology Stack

| Layer           | Technology                                        |
| --------------- | ------------------------------------------------- |
| Language        | Rust (edition 2021, toolchain 1.82+)              |
| Build Tool      | Cargo (single crate)                              |
| Async Runtime   | Tokio                                             |
| HTTP Client     | reqwest (rustls-tls)                              |
| CLI Framework   | clap (derive macros)                              |
| Serialization   | serde, serde_json, toml                           |
| Error Handling  | thiserror, anyhow                                 |
| Terminal Output | colored                                           |
| Testing         | Built-in test framework + wiremock (HTTP mocking) |
| URL Validation  | url crate                                         |
| Secrets         | env vars + redact module                          |
| Hashing         | sha2 + hex (cache keys)                           |

### Implemented LLM Providers

| Provider             | Status     | Default Model        |
| -------------------- | ---------- | -------------------- |
| DeepSeek             | ✅ Phase 1 | `deepseek-v4-flash`  |
| Kimi (Moonshot AI)   | ✅ Phase 2 | `kimi-k2.5`          |
| Qwen (Alibaba Cloud) | ✅ Phase 2 | `qwen-plus`          |
| OpenRouter           | ✅ Phase 2 | `openai/gpt-4o-mini` |
| OpenAI               | ✅ Phase 2 | `gpt-4o-mini`        |

---

## Repository Structure

```text
rs-guard/
├── src/                           # Single crate source (16 modules)
│   ├── main.rs                    # CLI entry point (thin)
│   ├── lib.rs                     # Library root
│   ├── pipeline.rs                # Orchestration + PipelineResult
│   ├── cache.rs                   # LLM response caching (SHA-256 keyed)
│   ├── cli.rs                     # Clap argument parsing
│   ├── config.rs                  # Env vars + .reviewer.toml parsing
│   ├── diff.rs                    # PR diff fetching + local diff + chunking
│   ├── error.rs                   # RsGuardError enum
│   ├── github.rs                  # GitHub API review submission
│   ├── http.rs                    # HTTP utilities + URL validation
│   ├── llm/                       # LLM provider modules
│   │   ├── mod.rs                 # LlmProvider trait + types
│   │   ├── deepseek.rs            # DeepSeek provider
│   │   ├── kimi.rs                # Kimi provider
│   │   ├── qwen.rs                # Qwen provider
│   │   ├── openrouter.rs          # OpenRouter provider
│   │   ├── openai.rs              # OpenAI provider
│   │   ├── factory.rs             # Provider factory
│   │   └── providers.rs           # Centralized provider metadata
│   ├── output.rs                  # Terminal output + artifact + metrics writing
│   ├── redact.rs                  # Secret redaction
│   ├── retry.rs                   # Retry logic + circuit breaker
│   └── verdict.rs                 # Verdict parsing + review state
├── benches/
│   └── verdict.rs                 # Criterion benchmarks (5 scenarios)
├── tests/
│   ├── test_data/                 # Sample diffs + LLM responses
│   ├── config_tests.rs            # 21 config tests
│   ├── diff_tests.rs              # 12 diff tests (wiremock + inline)
│   ├── github_tests.rs            # 13 github tests (wiremock)
│   ├── integration_tests.rs       # 5 full pipeline tests (wiremock)
│   ├── provider_tests.rs          # 14 provider tests (wiremock)
│   └── verdict_tests.rs           # 15 verdict tests
├── examples/
│   ├── github-actions-workflow/   # Sample CI workflows
│   └── local-review/              # Pre-commit hook examples
├── docs/
│   ├── MVP_IMPLEMENTATION_PLAN.md # Implementation roadmap
│   ├── ARCHITECTURE.md            # System design + Mermaid diagrams
│   ├── USAGE.md                   # Full CLI reference + troubleshooting
│   ├── API.md                     # Module API docs + custom provider guide
│   ├── PROVIDERS.md               # Per-provider setup guide
│   ├── CONFIGURATION.md           # .reviewer.toml reference
│   └── LOCAL_MODE.md              # Pre-commit hook setup
├── .github/workflows/
│   ├── ci.yml                     # CI pipeline (format, lint, test, deny, audit, bench)
│   ├── docs-deploy.yml            # GitHub Pages docs deployment
│   ├── release.yml                # Release pipeline
│   └── ai-review.yml              # Sample AI review workflow
├── Cargo.toml / Cargo.lock
├── deny.toml                      # cargo-deny config
├── .rustfmt.toml                  # Formatting config
├── .gitignore
├── README.md
├── CHANGELOG.md
└── LICENSE                        # MIT
```

---

## Key Architecture Decisions

| Decision                 | Choice                                                                                     |
| ------------------------ | ------------------------------------------------------------------------------------------ |
| Crate structure          | Single crate (workspace deferred until library demand emerges)                             |
| Provider dispatch        | `Box<dyn LlmProvider>` trait objects (refactored from enum dispatch in Phase 1)            |
| Exit signal              | `PipelineResult` enum (Success / ReviewBlocked) — not `process::exit()` in library code    |
| SSRF protection          | URL allowlist per provider in CI mode; loopback allowed in local mode                      |
| Print functions          | Accept `impl Write` for testability                                                        |
| `Config::empty()`        | Test-only constructor for integration tests                                                |
| `#![deny(missing_docs)]` | Enforced at crate level                                                                    |
| Cache keying             | SHA-256 over (diff \| prompt \| provider \| model \| temperature) — all parameters matter  |
| Cache timestamps         | Stored in file content (line 1), not mtime — reliable across clock changes and file copies |
| Cache size limit         | 100 MB default with LRU cleanup — prevents unbounded disk usage                            |
| Circuit breaker          | Simple Closed/Open only (no half-open), opt-in, default disabled                           |
| Cost calculation         | Integer cents, not floating point — avoids precision issues                                |
| Diff chunking            | `Cow<str>` return — zero allocation when no truncation needed                              |

---

## Build and Test Commands

```bash
# Build
cargo build

# Full test suite (~252 tests)
cargo test

# Lint (zero warnings required)
cargo clippy --all-targets --all-features -- -D warnings

# Format check
cargo fmt --all -- --check

# Documentation
cargo doc --no-deps --open

# Benchmarks
cargo bench --bench verdict -- --quick

# Security audits
cargo deny check
cargo install cargo-audit --locked  # one-time setup
cargo audit
```

---

## Test Coverage

| Module        | Test Count                        | Type               |
| ------------- | --------------------------------- | ------------------ |
| `verdict.rs`  | 22 (7 inline + 15 integration)    | Unit + Integration |
| `config.rs`   | 21                                | Integration        |
| `github.rs`   | 13                                | Inline (wiremock)  |
| `output.rs`   | 6                                 | Inline             |
| `cache.rs`    | 19                                | Inline             |
| `retry.rs`    | 17 (6 retry + 11 circuit breaker) | Inline             |
| `provider*`   | 19 (5 inline + 14 integration)    | Unit + Integration |
| `diff.rs`     | 26 (21 inline + 5 integration)    | Unit + Integration |
| `redact.rs`   | 8                                 | Inline             |
| `pipeline.rs` | 5                                 | Integration        |
| `http.rs`     | 16                                | Inline             |
| `cli.rs`      | 3                                 | Inline             |
| **Total**     | **~252**                          |                    |

---

## Phase 3 Status — ✅ Complete

### Pre-requisite Cleanup (Phase 0)

| Task                                                | Status                                    |
| --------------------------------------------------- | ----------------------------------------- |
| P0.1 — Remove `process::exit` from `run_pipeline()` | ✅ Done                                   |
| P0.2 — `github.rs` test suite (13 tests)            | ✅ Done                                   |
| P0.3 — `output.rs` `impl Write` refactor + tests    | ✅ Done                                   |
| P0.4 — `#![deny(missing_docs)]`                     | ✅ Done                                   |
| P0.5 — Update AGENTS.md                             | ✅ Done (this file)                       |
| P0.6 — DRY diff-fetch error handling                | ❌ Deferred (behaviors differ per source) |
| P0.7 — Shared HTTP client builder                   | ✅ Done                                   |
| P0.8 — `tests/test_data/` directory                 | ✅ Done                                   |
| P0.9 — Full pipeline integration test (5 scenarios) | ✅ Done                                   |

### Advanced Features

| Task                                                         | Status                                                                     |
| ------------------------------------------------------------ | -------------------------------------------------------------------------- |
| 3.1 — Response caching (`src/cache.rs`, `.rs-guard/cache/`)  | ✅ Done — 13 inline tests, SHA-256 keyed, TTL+size limit, atomic writes    |
| 3.2 — Metrics export (`rs-guard-metrics.json`)               | ✅ Done — `ReviewMetrics` struct, `write_metrics()`, per-run JSON artifact |
| 3.3 — Error recovery (exp backoff + circuit breaker)         | ✅ Done — `with_retry`, `CircuitBreaker`, 20 inline tests, thread-safe     |
| 3.4 — Diff chunking (50/50 head/tail, `Cow<str>`)            | ✅ Done — integrated in pipeline, warning shown in both CI and local modes |
| 3.5 — Enhanced CI pipeline (deny, audit, bench, docs-deploy) | ✅ Done — `ci.yml` + `docs-deploy.yml`, `benches/verdict.rs`               |

---

## Phase 4 Status — ✅ Complete

### Documentation Polish

| Task                                                      | Status  |
| --------------------------------------------------------- | ------- |
| 4.1 — Update AGENTS.md                                    | ✅ Done |
| 4.2 — Update CHANGELOG.md (0.1.0–0.3.0 + [Unreleased])    | ✅ Done |
| 4.3 — README.md rewrite (keep logo, add Phase 3 features) | ✅ Done |
| 4.4 — `docs/ARCHITECTURE.md` (Mermaid diagrams)           | ✅ Done |
| 4.5 — `docs/USAGE.md` (full CLI + troubleshooting)        | ✅ Done |
| 4.6 — `docs/API.md` (module API + custom provider guide)  | ✅ Done |
| 4.7 — Update `docs/MVP_IMPLEMENTATION_PLAN.md`            | ✅ Done |

---

## Phase 5 Status — ✅ Complete

### Library Extraction Readiness

| Task                                                        | Status                         |
| ----------------------------------------------------------- | ------------------------------ |
| 5.1 — All public APIs documented (`#![deny(missing_docs)]`) | ✅ Done                        |
| 5.2 — Test coverage >= 85% (~170 tests)                     | ✅ Done                        |
| 5.3 — Benchmark suite for verdict parsing                   | ✅ Done — `benches/verdict.rs` |
| 5.4 — Workspace deferred (single crate remains)             | ✅ Done                        |

---

## Phase 6 Status — ✅ Complete

### crates.io Publishing & crates.ai Registration

| Task                                                               | Status                                                                   |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| 6.1 — Prerequisites verification (tests, clippy, fmt, deny, audit) | ✅ Done                                                                  |
| 6.2 — `Cargo.toml` metadata finalized                              | ✅ Done — version 0.6.0, all fields complete                             |
| 6.3 — `README.md` with `cargo install` instructions                | ✅ Done                                                                  |
| 6.4 — `CHANGELOG.md` with Phase 6 entry                            | ✅ Done                                                                  |
| 6.5 — Publish to crates.io                                         | ✅ Done — [crates.io/crates/rs-guard]https://crates.io/crates/rs-guard |
| 6.6 — Register on crates.ai                                        | ✅ Done — [crates.ai/crates/rs-guard]https://crates.ai/crates/rs-guard |
| 6.7 — Post-publish verification                                    | ✅ Done                                                                  |

---

## Notes for Agents

- **Source code exists** — all ~4,200 lines across 16 modules.
- **~252 tests** pass with `wiremock`, `serial_test`, and `tempfile` infrastructure.
- **The implementation plan** (`docs/MVP_IMPLEMENTATION_PLAN.md`) is authoritative but section "Phase 0: Pre-requisite Cleanup" was added during Phase 3 implementation.
- **`Config::empty()`** is a `#[doc(hidden)]` constructor for tests — not for production use.
- **New modules** added since the original plan: `pipeline.rs`, `http.rs`, `redact.rs`, `cache.rs`, `llm/providers.rs`.
- **Decision Log** in Appendix F of the plan tracks all architectural decisions.
- **Cache directory** (`.rs-guard/cache/`) is auto-gitignored on first use — do not commit it.
- **`--no-cache` flag** bypasses the LLM response cache for a fresh API call.

---

## Step 8: crates.io Publishing & crates.ai Registration (Pending User Approval)

The following steps require your explicit approval and API credentials. Do not proceed until you are ready.

### 8.1 — Prerequisites Verification (Run Locally)

Before publishing, verify all checks pass:

```bash
# All tests must pass
cargo test

# Zero clippy warnings
cargo clippy --all-targets --all-features -- -D warnings

# Formatting clean
cargo fmt --all -- --check

# License + security clean
cargo deny check --config deny.toml

# No known vulnerabilities
cargo install cargo-audit --locked  # one-time setup
cargo audit
```

### 8.2 — Dry Run Publishing

Verify the crate is ready for publishing:

```bash
cargo publish --dry-run
```

If any issues are found, fix them before proceeding.

### 8.3 — Publish to crates.io

**Requires your crates.io API key.** Obtain it from <https://crates.io/settings/tokens>.

```bash
# Login once (API key stored locally)
cargo login

# Publish the crate
cargo publish
```

After publishing:

- Verify the crate appears at <https://crates.io/crates/rs-guard>
- Verify docs.rs auto-generates documentation at <https://docs.rs/rs-guard>

### 8.4 — Register on crates.ai

**Manual web-based process:**

1. Visit <https://crates.ai> and sign in with GitHub OAuth
2. Submit the repository URL: `https://github.com/nebulaideas/rs-guard`
3. Add project metadata:
   - **Description:** "AI-powered code review CLI for GitHub PRs. Multi-provider LLM support with in-memory verdict parsing."
   - **Tags:** `ai`, `code-review`, `github`, `llm`, `cli`, `devops`, `ci-cd`
   - **Screenshot/GIF:** Terminal output showing colored review summary
4. Link documentation:
   - README (primary)
   - docs.rs (auto-generated)
   - GitHub Pages docs site (when deployed)

### 8.5 — Post-Publish Verification

After publication, verify from a clean environment:

```bash
# Test cargo install
cargo install rs-guard --force
rs-guard --version

# Verify docs.rs
# Visit: https://docs.rs/rs-guard/latest/rs-guard/

# Verify crates.ai listing
# Visit: https://crates.ai/crates/rs-guard (after registration)
```

### 8.6 — Update AGENTS.md After Publication

Once published, update the Phase 6 status table in this file:

| Task                            | Status                                                                   |
| ------------------------------- | ------------------------------------------------------------------------ |
| 6.5 — Publish to crates.io      | ✅ Done — [crates.io/crates/rs-guard]https://crates.io/crates/rs-guard |
| 6.6 — Register on crates.ai     | ✅ Done — [crates.ai/crates/rs-guard]https://crates.ai/crates/rs-guard |
| 6.7 — Post-publish verification | ✅ Done                                                                  |

---