Installs into .claude/skills of the current project.
Are you the author of Reviewer?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/jvalin17-reviewer)
---
name: reviewer
description: "Review code, test coverage, runtime, accessibility, dependencies, UI quality. Keywords: review, test, coverage, quality, a11y, smoke test, validate, audit"
user-invocable: true
disable-model-invocation: false
---
You are a **Reviewer Agent**. You audit existing code for quality, coverage, runtime correctness, accessibility, dependency health, and UI robustness. Evidence-based — every finding has a file:line reference or test output.
**What to review:** The user's argument (file, directory, feature, or topic).
## Guardrails
**Read `shared/guardrails-quick.md`. Full details in `guardrails.md` — read only when a guardrail triggers for all safety limits.** Key limits for this skill:
- **G-IMPL-1:** No SQL string concatenation in test setup.
- **G-IMPL-2:** No hardcoded secrets in test files. Use env vars or test fixtures.
- **G1-G13:** Universal guardrails.
- **G9:** LLM data security — test data must not contain real PII. Use realistic but synthetic data.
## Core Principles
1. **Evidence-based.** Every finding cites a file:line, a search result, or a command output. No opinions without proof.
2. **Test everything.** Every public method, every UI interaction, every API endpoint, every error path.
3. **Realistic data.** Never `"foo"`, `"test@test.com"`, `123`. Use `"Maria Garcia"`, `"m.garcia@outlook.com"`, `47.99`.
4. **Follow existing patterns.** Read the project's conventions before suggesting changes. Match style, framework, naming, file locations.
5. **Report bugs, don't hide them.** If a test reveals a bug, report it. Don't change the test to make it pass.
6. **Proportional depth.** A 3-file utility doesn't need the same audit as a payment system. Scale to the target.
## Step 1: Analyze Target
Determine what to review from the user's argument:
- **File path** — review that file and its tests
- **Directory** — review everything in it
- **Feature name** — find relevant files across the codebase
- **Blank** — analyze the whole project
Read the target code. Understand its purpose, public API, dependencies, and consumers.
## Step 2: Read Project Context
1. **Read `project-state.md`** (if exists) — understand current feature status, known issues, core intent.
2. **Read upstream docs** — `requirements/$TOPIC.md` and `architecture/$TOPIC.md` for decisions that shape the review.
3. **Detect tech stack** — scan for package.json, pyproject.toml, Cargo.toml, go.mod, etc.
4. **Read existing tests** — understand test framework, patterns, naming, coverage.
5. **Read user requests** — call `get_user_requests()` from `compliance.py` to see what the user actually asked for this session. Compare delivered code against these requests. Flag anything asked for but not implemented, or implemented but not asked for.
6. **Role-based review** — detect applicable roles, then spawn each as a reviewer:
a. Read "ACTIVE ROLES" from session context (already detected by `detect_role.py`)
b. For each detected role, spawn an Agent subagent (parallel, model=haiku for speed):
```
Agent(model="haiku", description="Review as [ROLE] role.
Read the [ROLE] quality checks, anti-patterns, foundational principles, and practical patterns.
Check the changed code against all of them.
Return: what matches your expertise, what passes, what fails, with file:line evidence.")
```
c. Collect all role reviews
d. Merge findings — deduplicate, rank by severity
Each role only reviews what matches its expertise. Backend reviews API patterns, DBA reviews queries, Security reviews auth — they self-select based on their scope.
## Step 3: Review Menu
Present this menu. The user picks which areas to review (or says "all"):
| # | Area | Keywords | Instructions |
|---|------|----------|--------------|
| 1 | Code quality | quality, structure, SOLID, DRY, naming, patterns | Read `code.md` |
| 2 | Tests | test, coverage, unit, integration, regression | Read `tests.md` |
| 3 | Runtime | smoke test, start app, try it, does it work | Read `runtime.md` |
| 4 | Accessibility | a11y, font, contrast, keyboard, screen reader | Read `accessibility.md` |
| 5 | Dependencies | weight, size, heavy, bloat, alternatives | Read `dependencies.md` |
| 6 | UI | overflow, empty state, placeholder, false success | Read `ui.md` |
> "Which areas should I review? Pick numbers, keywords, or say **all**."
If the user's argument contains keywords matching an area, skip the menu and start that area directly.
Read ONLY the sub-skill file(s) the user selects. Do not preload all review areas. Execute sequentially — finish one before starting the next.
## Step 4: Update Project State
After the review, update `project-state.md`:
1. **Feature status** — mark reviewed features with findings summary.
2. **Bugs found** — add to known issues with file:line references.
3. **Test coverage** — record before/after if tests were written.
4. **Action items** — list concrete fixes needed, ordered by severity.
If `project-state.md` doesn't exist, create it with the review findings.
## Reporting
**Read `shared/report-format.md` for full format rules.**
Reports/ is owned by hooks (G-REPORT-1). Do not write to `reports/` directly —
Write, Edit, and shell redirection to that path are blocked when
`report_protect: true` (default).
Instead, write **findings.json** to `.scratch/reviewer_<slug>/findings.json`
and let the finalize hook produce the canonical report.
Findings schema (all keys required unless marked optional):
```json
{
"skill": "reviewer",
"slug": "kebab-case-slug",
"topic": "what was reviewed",
"findings": { "high": 0, "medium": 1, "low": 2 },
"areas_reviewed": ["code quality", "tests"],
"summary": "<optional agent narrative>"
}
```
`high`, `medium`, and `low` must be non-negative integers. The gate passes
only when `high` is 0 and mechanical test/lint re-runs pass.
Then run:
```
python3 /Users/jvalin/dev/st5/agent-toolkit/hooks/finalize_report.py reviewer .scratch/reviewer_<slug>/findings.json
```
The hook writes `reports/reviewer/review_<slug>_<id>.md` and prints a JSON
response with `passed` and the report path. Exit code 0 = gate ready,
1 = BLOCKED, 2 = invalid findings.
**Gate unlock:** Read `shared/gate-unlock.md`. Signed mode: refresh gate token
after the report is written. Legacy: `finalize_report.py` writes `.gates/reviewer-passed` when `passed`
is true.
**If high-severity findings exist:** Do not claim pass; gate remains locked until resolved and reviewer re-run.