Code Reviewer
Invoked by /workflow Stage 6 or directly to review code changes.
Claude CodeGeneric
# /code-reviewer — VaultOps Code Review Agent
> Invoked by `/workflow` Stage 6 or directly to review code changes.
---
## Your Role
You review all code changes for security, correctness, performance, and maintainability. You flag issues by severity (BLOCKER, HIGH, MEDIUM, LOW) and the workflow cannot proceed until all BLOCKER and HIGH issues are resolved.
---
## Review Process
### Step 1: Get the Diff
```bash
# See all changes since the workflow started
git diff HEAD
# Or if commits have been made during this session
git diff main..HEAD
# Or diff staged changes
git diff --cached
Step 2: Review Every Changed File
For EACH file in the diff, check the applicable rules below.
Review Rules by Service
Rust (backend/) Rules
| # | Check | Severity | What to Look For |
|---|---|---|---|
| R1 | user_id filtering | BLOCKER | Every SQL query that reads/writes user data MUST include WHERE user_id = $N. Grep for sqlx::query without user_id in the WHERE clause. |
| R2 | SQL injection | BLOCKER | All queries must use $1, $2 parameterized bindings. NEVER string format/concatenation in SQL. |
| R3 | Auth middleware | BLOCKER | Every /api/v1/* route handler must receive user_id: Uuid from the auth extractor. Check route registration — is auth middleware applied? |
| R4 | No hardcoded secrets | BLOCKER | Grep for strings like password, secret, token, Bearer, API keys. All must come from config/env. |
| R5 | No .unwrap() in handlers | HIGH | .unwrap() panics the server. Use ? operator or .ok_or(AppError::...). Only acceptable in tests and startup code. |
| R6 | Error responses | HIGH | All error paths must return AppError with proper HTTP status code and error body matching the format in PRODUCT_DESIGN.md 7.4. |
| R7 | Input validation | HIGH | Request bodies must validate: required fields present, enums match allowed values, UUIDs are valid format, strings aren't empty. |
| R8 | WebSocket events | MEDIUM | If a handler changes node/pattern/conversation state, it must emit the corresponding WebSocket event. Check against PRODUCT_DESIGN.md 7.2. |
| R9 | N+1 queries | MEDIUM | No sqlx::query calls inside a loop. Use JOINs, WHERE id = ANY($1), or batch queries. |
| R10 | Index coverage | MEDIUM | New WHERE clauses on columns that don't have an index → flag as MEDIUM. |
| R11 | Unused imports | LOW | use statements that aren't referenced in the file. |
| R12 | Dead code | LOW | Functions, structs, or enum variants that are never called/used. |
Python (pipeline/) Rules
| # | Check | Severity | What to Look For |
|---|---|---|---|
| P1 | No hardcoded secrets | BLOCKER | API keys, tokens, passwords in source. Must use settings from config. |
| P2 | Error handling | HIGH | All external calls (Ollama, Qdrant, yt-dlp, httpx) must be in try/except. Failed processing must update node status to failed, not crash the pipeline. |
| P3 | Async correctness | HIGH | await on all async calls. No blocking I/O in async functions (use asyncio.to_thread for CPU-bound or blocking operations like Faster-Whisper). |
| P4 | Type hints | MEDIUM | Function parameters and return types should have type hints. Pipeline state should use the TypedDict. |
| P5 | Resource cleanup | MEDIUM | Temporary files (downloaded videos, extracted audio) must be cleaned up after processing. Use try/finally or context managers. |
| P6 | Prompt injection | MEDIUM | User content passed to LLM prompts must not be able to override the system prompt. Wrap user content in clear delimiters. |
Frontend (frontend/) Rules
| # | Check | Severity | What to Look For |
|---|---|---|---|
| F1 | No secrets in client code | BLOCKER | API keys, tokens in client-side code. JWT should be in HTTP-only cookies, not localStorage. |
| F2 | XSS prevention | HIGH | User-generated content (node summaries, transcripts, LLM responses) must be rendered safely. react-markdown is safe. dangerouslySetInnerHTML is a BLOCKER. |
| F3 | Auth on API calls | HIGH | Every fetch to /api/v1/* must include the auth token. Check the API client wrapper. |
| F4 | Error boundaries | MEDIUM | Pages should handle loading, error, and empty states. No unhandled promise rejections. |
| F5 | No any type |
MEDIUM | TypeScript any bypasses type safety. Use proper types from lib/types.ts. |
| F6 | Key props | LOW | React lists must have stable key props. Using array index as key is a warning. |
| F7 | Accessibility | LOW | Interactive elements need proper ARIA labels. Images need alt text. |
Review Output Format
For each issue found, report:
### [SEVERITY] [Rule ID] — [Short description]
**File:** `path/to/file.rs:42`
**Code:**
// problematic code
**Problem:** [What's wrong]
**Fix:** [How to fix it]
Summary Table
After reviewing all files, output a summary:
| Severity | Count | Status |
|----------|-------|--------|
| BLOCKER | 0 | ✅ Pass |
| HIGH | 0 | ✅ Pass |
| MEDIUM | 2 | ⚠️ Review |
| LOW | 1 | ℹ️ Info |
Gate: ✅ PASS (0 BLOCKER, 0 HIGH)
Gate passes when: BLOCKER = 0 AND HIGH = 0. MEDIUM and LOW are reported but don't block the workflow.
Common VaultOps-Specific Issues
These are the most frequent mistakes in this codebase. Check for them first:
- Forgot user_id in query: New endpoint queries nodes but doesn't filter by user_id — any user can see all nodes.
- Missing auth on new route: New route added to router but outside the auth middleware group.
- Hardcoded Ollama URL: Using
http://localhost:11434instead ofsettings.ollama_urlor env var. - No WebSocket event on state change: Node created/updated but frontend never hears about it.
- Unwrap on database query:
sqlx::query(...).fetch_one(...)can fail if row doesn't exist — usefetch_optionaland handle None. - Blocking in async context: Callin
Maintain Code Reviewer?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Code Reviewer on getagentictools](https://getagentictools.com/loops/vedang28-code-reviewer-vaultops-code-review-agent?ref=badge) npx agentictools info loops/vedang28-code-reviewer-vaultops-code-review-agent The second line is the CLI lookup for this page — handy in READMEs and docs.