---
name: build-review-md
description: |
  Use this skill when the user wants to create or set up a REVIEW.md configuration file for their repository. Trigger for ANY of these: (1) user says "create REVIEW.md", "set up REVIEW.md", or "configure review rules", (2) code-gauntlet Phase 2d detects no REVIEW.md and suggests creating one, (3) user wants to customize what the code-gauntlet skill focuses on or ignores, (4) user asks "how do I configure the reviewer" or "how do I set review rules". Do NOT trigger for: reviewing code (use code-gauntlet), explaining what REVIEW.md does in the abstract, or editing an already-complete REVIEW.md the user is satisfied with. This skill NEVER loads into the main code-gauntlet context — it is a standalone configuration wizard.
---

# REVIEW.md Builder

Guided wizard that creates a REVIEW.md configuration tailored to the repo's actual languages, frameworks, and priorities. Produces a root REVIEW.md and subdirectory configs only when the multi-stack test justifies them.

**This skill produces configuration files, not code review.** Do not run review agents or analyze code for bugs. Stay in configuration mode until exit.

---

## Step 1: Detect

Scan the repository to understand what you are configuring. Do this silently — do not ask the user to describe their stack.

**Languages** — scan file extensions:

- `.ts`, `.tsx` → TypeScript/React
- `.js`, `.jsx` → JavaScript
- `.py` → Python
- `.go` → Go
- `.rs` → Rust
- `.cs` → C#/.NET
- `.java` → Java
- `.rb` → Ruby
- `.php` → PHP

**Frameworks and runtimes** — check for manifest files:

- `package.json` → Node/JS/TS ecosystem; read `dependencies` and `devDependencies` for React, Next.js, Vue, Express, NestJS, RTK Query, Zod, Vitest, Jest
- `requirements.txt` / `pyproject.toml` / `setup.py` → Python; check for Django, FastAPI, SQLAlchemy, pytest
- `Cargo.toml` → Rust; check for tokio, axum, sqlx
- `go.mod` → Go; check for gin, echo, gorm
- `pom.xml` / `build.gradle` → Java/Kotlin; check for Spring Boot, Hibernate
- `*.csproj` / `*.sln` → .NET; check for ASP.NET Core, EF Core, xUnit, NUnit
- `Gemfile` → Ruby on Rails

**Multi-stack / mono-repo detection** — a repo is multi-stack when it contains multiple package manifest files in different subdirectories (e.g., `frontend/package.json` AND `backend/*.csproj`). Record the subdirectory paths.

**Existing REVIEW.md** — check whether a root REVIEW.md already exists. If it does, announce what you found and ask:

```
AskUserQuestion(
  questions: [{
    question: "A REVIEW.md already exists at the repo root. What would you like to do?",
    header: "REVIEW.md",
    multiSelect: false,
    options: [
      { label: "Extend it (Recommended)", description: "Add rules to what's already there, keeping existing settings" },
      { label: "Start fresh", description: "Replace it with a newly generated REVIEW.md" },
      { label: "Cancel", description: "Keep the existing file unchanged and exit" }
    ]
  }]
)
```

If "Cancel", exit immediately with the message: "Your existing REVIEW.md is unchanged."

---

## Step 2: Ask priorities

Announce your detection findings in one sentence (e.g., "I found a TypeScript/React frontend and a .NET backend in separate directories."), then ask:

```
AskUserQuestion(
  questions: [{
    question: "What matters most for this review configuration?",
    header: "Priorities",
    multiSelect: false,
    options: [
      { label: "All of the above (Recommended)", description: "Security, correctness, quality, performance, tests, and conventions" },
      { label: "Security & Correctness", description: "Secrets, auth gaps, bugs, async errors, type misuse" },
      { label: "Code Quality & Performance", description: "Complexity, duplication, naming, N+1 queries, resource leaks" },
      { label: "Tests & Conventions", description: "Missing tests, commit messages, PR size, naming patterns" }
    ]
  }]
)
```

Record the selected priorities. Security and Correctness always produce **prescriptive rules** ("MUST", "NEVER", "CRITICAL") because violations are always wrong. Code quality, performance, test coverage, and conventions produce **directional rules** ("prefer", "consider", "flag when") that allow judgment.

---

## Step 3: Generate root REVIEW.md

Generate a root REVIEW.md with 8–10 rules drawn from the detected stack and selected priorities. Rules must be specific and verifiable — see guidance below.

**Rule writing standards** (derived from research on LLM instruction-following):

- Prescriptive rules for security and correctness: state the requirement, then state why in one sentence. Example: "CRITICAL: Never commit secrets or API keys in source files. Use environment variables or secret managers — exposure in git history is permanent."
- Directional rules for quality and conventions: state the preference, then the escape hatch or rationale. Example: "Prefer composition over inheritance. Deep hierarchies make behavior unpredictable — flag more than 2 levels unless there is an explicit abstraction reason."
- One-liners are acceptable only when the rule is truly unambiguous. Two-sentence rules with rationale outperform one-liners for anything contextual.
- CRITICAL label is reserved for security and correctness violations that are always wrong. Use it for at most 3–4 rules per file — overuse destroys emphasis.
- Do not write rules that duplicate what linters catch deterministically (formatting, indentation, import sorting).

**Do not pin a threshold the user didn't ask for.** The pipeline's built-in defaults (non-security
confidence **55**, security confidence **70**, severity **low** — everything shown) apply automatically
whenever a key is absent from REVIEW.md's config block; writing an explicit number here — even a
"conservative starting point" — silently overrides that default the moment the wizard runs, for every
user, without them choosing it. A `## Confidence Threshold` / `## Severity Threshold` markdown heading is
never parsed at all (`references/review-md-spec.md` in the code-gauntlet skill → Format) — the only
mechanism that works is the fenced config block, with the four snake_case keys inside it. Emit the block
with the threshold keys commented out as digit-free examples:

```yaml
# code-gauntlet
# confidence_threshold: <0-100>
#   Built-in default when omitted: 55 for non-security dimensions, 70 for security.
# severity_threshold: <critical|high|medium|low>
#   Built-in default when omitted: low (show everything).
```

If Step 2 surfaced an explicit user preference for a starting threshold, uncomment the relevant key and
write that value instead of leaving the example commented out — but never substitute a number the user
didn't state.

**Do not emit a `## Model Tier` section.** Nothing reads it (issue #153): the model policy is fixed to the
single benchmarked configuration, and the only remaining pin is the fail-loud `CODE_GAUNTLET_MODEL_TIER`
env knob. Emitting the heading advertises a knob that does not exist.

**Rule sections** — organize by selected priorities:

- Security (always first, if selected)
- Correctness / language-specific bugs
- Architecture and design (if code quality selected)
- Performance (if selected)
- Tests (if selected)
- Conventions (always last, if selected)

**Do not generate a `## Skip` section.** There is no REVIEW.md mechanism that excludes files from
review by glob pattern — a `## Skip` heading is inert prose, never parsed (`references/review-md-spec.md`
→ "Rules and other prose"). Generating one implies a working feature that does not exist.

**Output** — write the file to `REVIEW.md` at the repo root. Announce: "Root REVIEW.md written with [N] rules."

---

## Step 4: Generate subdirectory REVIEW.md(s)

Apply the multi-stack decision test: for each technology-specific rule you want to add, ask: **"Would this rule generate false positives when applied to the other stack?"**

Subdirectory rules are advisory prose shared with every context-reading agent (summarize, discovery, validate; the file location is provenance); only thresholds and ignore patterns are enforced for that subtree.

If yes → the rule belongs in a subdirectory REVIEW.md.
If no → the rule belongs in the root REVIEW.md.

**Only create subdirectory configs when the answer is "yes" for at least 3 rules.** A single technology-specific rule does not justify a new file — add it to root with a path qualifier in the rule text: "For files in `backend/`: prefer event-sourced state transitions over direct entity mutation."

**When creating subdirectory configs:**

- Emit `## Rules` and, if needed, a config block — no `## Model Tier` and no `## Skip` (see Step 3)
- Do not repeat rules that are already in root
- Do not contradict root rules — extend them. If root says "prefer immutable types," the subdirectory rule should add the escape hatch, not contradict
- Subdirectory configs should have 5–8 rules each; stop at the second directory level

**Common subdirectory rules by stack:**

*TypeScript/React frontend:*

- TypeScript strict mode enforcement (no `any`, no `@ts-ignore` without comment)
- React hooks rules (no conditional hooks, useEffect cleanup, dependency arrays)
- RTK Query cache invalidation (invalidatesTags on mutations)
- Zod schema validation at API boundaries (.safeParse() not type assertions)

*.NET/C# backend:*

- Async/await patterns (no .Result/.Wait(), async void except event handlers, CancellationToken)
- EF Core patterns (N+1 detection, AsNoTracking for reads, scoped DbContext)
- DI lifetime correctness (no scoped in singleton)

*Python:*

- Type hints required on public functions
- SQLAlchemy session management (no session reuse across requests)
- Async correctness (no blocking calls in async functions)

*Go:*

- Error wrapping with context (errors.Wrap, not bare return err)
- Context propagation (first argument, no context.Background() in handlers)
- Goroutine leak prevention (always close channels, cancel contexts)

**Output** — write each subdirectory REVIEW.md. Announce each file written and the rule count.

---

## Step 5: Exit

After all files are written, output a brief summary:

```
REVIEW.md created. Start your review — the config will be picked up automatically.

Files written:
  REVIEW.md — [N] rules (built-in thresholds: 55 confidence / 70 for security, low severity)
  [subdir]/REVIEW.md — [N] rules  (if applicable)

The built-in thresholds show everything above 55 confidence (70 for security
findings) at any severity. After a few reviews, tune them in REVIEW.md's config block if needed:
- If false positives accumulate, uncomment and raise `confidence_threshold`
- If low-severity noise drowns out what matters, uncomment and set `severity_threshold` to medium or high
- Run `code-gauntlet` on any open PR to see results immediately
```

Do not offer to run a review or explain the review process. The user can trigger code-gauntlet separately.

---

## Critical Rules

1. **No code review.** This skill configures — it does not analyze code for bugs, security issues, or quality problems.
2. **Prescriptive for non-negotiables, directional for preferences.** Never write a CRITICAL rule for a style preference, never write a directional rule for a security requirement.
3. **15–25 rules total across all files.** Exceeding this degrades LLM instruction-following. Prefer 8–10 in root, 5–8 per subdirectory.
4. **Do not create subdirectory configs without the decision test.** Technology-specific rules that pass the false-positive test belong in root with a path qualifier.
5. **Never pin an unrequested threshold.** Leave `confidence_threshold` / `severity_threshold` commented out in the generated config block unless the user explicitly asked for a specific value — the pipeline's built-in defaults (55 non-security / 70 security confidence, low severity) already apply when the keys are absent.
6. **Never generate a `## Skip` section.** It is never parsed — generating one implies a feature that does not exist.
7. **Never emit a `## Model Tier` section.** Nothing reads it (issue #153) — emitting it advertises a knob that does not exist.
