Skip to content
Back to skills

Vibe Review

ASecurity

Evidence-based code review skill — mandatory gate after every phase completes. Triggers on "review:" prefix, "review the code", "code review", "audit the codebase", "check code quality", "review phase N", "is the code ready", "quality check". Mandatory gate: Phase N cannot proceed to Phase N+1 until review passes with 0 P0 and 0 P1. Final phase review blocks deploy on the same bar (0 P0, 0 P1). Acts as Senior Engineer, Architect, and Code Quality Auditor. Gracefully handles missing ARCHITECTU...

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
developmenttypescriptpythonrustgobashreactnodeexpresstestingcode-review

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 24, 2026

npx -y skills add aakashdhar/vibe-skill --skill vibe-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Vibe Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Vibe Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aakashdhar-vibe-review/badge)](https://www.skillsdirectory.com/skills/aakashdhar-vibe-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: vibe-review
description: >
  Evidence-based code review skill — mandatory gate after every phase completes.
  Triggers on "review:" prefix, "review the code", "code review", "audit the codebase",
  "check code quality", "review phase N", "is the code ready", "quality check".
  Mandatory gate: Phase N cannot proceed to Phase N+1 until review passes with 0 P0 and 0 P1.
  Final phase review blocks deploy on the same bar (0 P0, 0 P1).
  Acts as Senior Engineer, Architect, and Code Quality Auditor.
  Gracefully handles missing ARCHITECTURE.md — reviews against PLAN.md patterns instead.
  Automated checks adapt to project stack (not npm-only).
  Every finding backed by file path and line number. No vague feedback.
---

# Vibe Review Skill

Mandatory quality gate after every phase.
Acts as **Senior Engineer, Architect, and Code Quality Auditor**.
Evidence-based. Every finding backed by file path and line number.

**Never writes feature or source code.** Review is read-only on the codebase; the only
files it writes are its own artifacts — the report in `vibe/reviews/`, `backlog.md`, the
gate lines and RFX tasks in `vibe/TASKS.md`, and `vibe/.gates.json`.

**Never fix what you find — not even a one-line P1.** Every P0/P1 becomes an `RFX-NNN`
task under the phase's gate line, and the gate is recorded with the counts you found
(so it is `open`). The fix happens in the build's fix loop (vibe-mode
`AUTONOMOUS_EXECUTION_BLOCK.md`), and a fresh review then decides whether the gate
passes. Fixing inside the review and marking the gate passed skips the evidence the
gate exists to produce: the fix is never reviewed by anyone but its author.

---

## The O'Reilly principle this enforces

Issues caught at Phase 1: cheap — fix once, never propagates.
Issues caught at Phase 3: expensive — retrofit across every feature.
Issues caught at deploy: very expensive — production risk.

Without a review gate, bad patterns from Phase 1 get copied into every feature.
Architecture drifts silently. Duplication builds. Quality degrades.

---

## The reviewer's stance — falsify, don't bless

A review is not a request for approval. Do not ask "is this code good?" — that
question is answered "yes" by default and finds nothing. Ask the opposite, of
every change under review:

> **"Prove this is unsafe, incorrect, or unnecessarily complex."**

You are trying to *break* the change, not confirm it. For each significant unit,
actively attempt to construct:

- **An input that makes it wrong** — an edge case, empty/null, boundary, unicode,
  concurrency, an unexpected ordering — that produces a wrong result or a crash.
- **A failure it does not handle** — the network call that times out, the promise
  that rejects, the file that is missing, the permission that is denied.
- **A simpler version that does the same job** — if you can write it in fewer
  moving parts, the current form is unnecessarily complex (a real P2/P1).
- **A security hole** — untrusted input reaching a sink, a secret in scope, a
  missing authz check, an injection path.

A finding is only worth reporting if you can state the concrete scenario that
triggers it (inputs/state → wrong output/crash). "This looks fragile" is not a
finding; "with an empty `items` array this throws at line 42" is. This falsifying
stance is what a *second-opinion* reviewer must adopt above all — its value is in
disagreeing with the first pass, not echoing it.

If, after genuinely trying, you cannot break a unit, say so plainly and move on —
an honest "I could not find a way to make this fail" is a real result. Do not
manufacture findings to look thorough.

---

## When this skill runs

**Mandatory — phase gates:**
```
Phase 1 complete → review: phase 1 → gate passed? → Phase 2 begins
Phase 2 complete → review: phase 2 → gate passed? → Phase 3 begins
Final phase      → review: final  → gate passed? → deploy unlocked
```

**On demand:**
```
review: phase 2 invoice management
review: audit the Supabase integration
review: full codebase before new team member
```

**Gate rules:**
- **P0 AND P1 → block progression.** Both must be zero for a phase gate to pass; fix
  them (rework tasks) before the next phase begins. A P1 is never deferred past the
  phase that introduced it — "0 open P0/P1" is the bar at *every* phase gate, not only
  the final one.
- P2 / P3 → logged to backlog.md, carried to the final cleanup pass (do not block).
- Final phase: 0 P0 AND 0 P1 (same bar, plus P2/P3 addressed or explicitly accepted).
- Gate passes **only** at 0 open P0 and 0 open P1 → next phase begins.

---

## Documents this skill reads

Read in this order. Note if any are missing.

1. `vibe/ARCHITECTURE.md` — primary reference for drift detection
2. `vibe/CODEBASE.md` — exact file paths as-built
3. `vibe/SPEC.md` — acceptance criteria to verify against
4. `vibe/DECISIONS.md` — past spec/scope decisions, context for why things are as they are
5. `vibe/IMPLEMENTATION_LOG.md` *(if exists)* — implementation decisions (why-this-approach / why-this-library); the "why" behind the code
6. `vibe/PLAN.md` — phase scope, what was meant to be built
7. `vibe/TASKS.md` — what tasks completed this phase
8. `vibe/reviews/` — all previous review files for carryover tracking
9. `BRIEF.md` *(if exists)* — original intent and core value
10. `CLAUDE.md` — boundaries and conventions

**If vibe/ARCHITECTURE.md does not exist:**
> Flag this as a finding in the report: "ARCHITECTURE.md not found — no explicit architecture
> decisions documented. Pattern compliance reviewed against PLAN.md and CODEBASE.md instead."
> Use PLAN.md folder structure, tech stack, and conventions as the reference baseline.
> Recommend running `architect:` to formalise decisions. This is a P1 finding.

---

## Step 0A — Concept boundary pre-screening (graph-assisted)

**Check for dependency graph before reading any source files:**
```bash
ls vibe/graph/CONCEPT_GRAPH.json 2>/dev/null && echo "GRAPH EXISTS" || echo "NO GRAPH"
```

**If graph exists — run boundary pre-screening:**

Read `vibe/graph/DEPENDENCY_GRAPH.json` and check for cross-concept imports
that violate ARCHITECTURE.md patterns:

```python
import json

dep_g = json.load(open('vibe/graph/DEPENDENCY_GRAPH.json'))
arch_violations = []

for file_path, node in dep_g.items():
    file_concept = node.get('concept', 'foundation')
    for imported in node.get('imports', []):
        imported_node = dep_g.get(imported, {})
        imported_concept = imported_node.get('concept', 'foundation')

        if file_concept != imported_concept and imported_concept != 'foundation':
            # Frontend component importing backend/agent directly → DIP violation
            if node.get('type') == 'component' and imported_node.get('type') in ['agent', 'service', 'model']:
                arch_violations.append({'file': file_path, 'imports': imported,
                    'issue': 'Frontend directly imports backend — DIP violation', 'severity': 'P1'})
            # Agent calling another agent directly (bypasses orchestrator)
            elif node.get('type') == 'agent' and imported_node.get('type') == 'agent':
                if 'base_agent' not in imported:
                    arch_violations.append({'file': file_path, 'imports': imported,
                        'issue': 'Agent directly imports agent — bypasses orchestrator', 'severity': 'P1'})

for v in arch_violations:
    print(f"{v['severity']}: {v['file']} → {v['imports']} ({v['issue']})")
```

**Flagged files** → deep review (read source, check thoroughly)
**Clean files** → standard review (check naming, size, test coverage only)

This pre-screening surfaces most P1 architectural findings before reading
a single source file. On a clean codebase: 0 violations, shallower reads.
On a drifting codebase: violations surface immediately, guide where to look.

**If no graph exists — proceed with standard full read:**
No pre-screening available. Read all files in the phase as normal.

---

## Step 0 — Run automated checks first

> **Prefer first-party review tools when available.** If the session has the
> `/code-review` and/or `/security-review` commands, run them here — they are
> deeper and produce structured findings. Fold their output into this review's
> P0-P3 findings (map their severities onto ours) rather than re-deriving
> everything by hand. The stack commands below still run (tests/lint/typecheck/
> audit are ground truth); the manual Steps 3-8 then focus on what the tools
> don't cover (architecture drift vs ARCHITECTURE.md, spec alignment). Treat the
> hand-rolled grep checks as the fallback when those tools aren't available.

Run these before reading any code. Adapt to the project stack from CODEBASE.md section 2.

**Node / npm projects:**
```bash
npm test              # Failures are P0
npx eslint . --quiet  # Errors are P0, warnings are P2
npx tsc --noEmit      # TypeScript errors are P0
npm audit             # High/critical = P0, moderate = P1
```

**Python projects:**
```bash
pytest                # Failures are P0
ruff check .          # Errors are P0
mypy .                # Type errors are P0
pip-audit             # Critical vulnerabilities are P0
```

**Flutter / Dart projects:**
```bash
flutter test          # Failures are P0
flutter analyze       # Errors are P0
dart pub audit        # Critical vulnerabilities are P0
```

**No test runner configured:**
Flag as P1: "No automated test runner configured. Tests exist but cannot be run automatically."

Include full tool output in the review report.
If a check fails with P0-level findings: document output, do not stop — continue full review.
Machines verify first, agent verifies second.

---

## Step 1 — Establish review scope

**Scoping rule:** If this phase modified more than 30 files, review feature by feature.
Generate a sub-report per feature, then synthesise into one phase report.
Do not attempt to review 30+ files in a single pass — quality degrades.

**Review focus by phase:**

Phase 1 — Foundation integrity:
Is this a solid base? Patterns, abstractions, folder structure, TypeScript setup, shared utilities.

Phase 2+ — Incremental delta + integration:
What this phase added + does it integrate cleanly? Cross-phase consistency. Emerging duplication.

Final phase — Full production readiness:
Everything. Performance, security, accessibility, error handling, bundle size. Strictest gate.

---

## Step 2 — Carryover check

Read all `vibe/reviews/phase-N-review.md` files. Read `vibe/reviews/backlog.md`.

**If no previous reviews exist** (this is Phase 1):
State: "No previous reviews — this is the first review. No carryover to check."
Skip carryover section in the report.

**If previous reviews exist:**
For each previously logged issue, check current state:
```
✅ P1-001 — [Issue] — RESOLVED
⚠️ P1-002 — [Issue] — STILL PRESENT — escalating to P0 (appeared in 2+ reviews)
❌ P1-003 — [Issue] — NOT ADDRESSED — remains P1
```

Escalation rule: unresolved P0 from previous phase → highest priority.
P1 appearing unresolved across 2+ phase reviews → escalate to P0.
P2 appearing unresolved across 3+ phase reviews → escalate to P1.

---

## Step 3 — Architecture drift detection

> 🧠 **Effort:** drift detection and the SOLID/security judgment in Steps 3-7 are
> the highest-value reasoning in a review — run the review at high/xhigh effort
> with adaptive thinking. For the final-gate review, consider claude-opus-5.

**Most important section. Check ARCHITECTURE.md (or PLAN.md if no ARCHITECTURE.md) first.**

For each documented decision, check the actual code.

Drift format:
```
🔴 ARCHITECTURE DRIFT — [Section violated]
   Decision: "[exact quote from ARCHITECTURE.md or PLAN.md]"
   Found: [file path] line [N]
          [exact violation]
   Decision origin: [architect: session / D-ID / PLAN.md]
   Impact: [what breaks or degrades]
   Fix: [specific action]
```

Check:
- Folder structure — all new files in correct folder?
- Naming conventions — files, components, hooks, utilities match exactly?
- State management — correct layer for each type of state?
- Data fetching — all calls going through the abstraction layer?
- Component patterns — functional, one per file, props typed?
- TypeScript — strict mode, no any, all params typed?
- Error handling — following the documented strategy?
- Testing — co-located files, names describe behaviour?

Any violation = P0. Architecture drift that propagates is expensive.

**Undocumented significant decisions (P2).** While reading the code, watch for choices that
clearly cleared the "meaningful" bar — a new library/dependency added, a non-obvious pattern,
a data-model or API-shape decision, or a deliberate deviation from ARCHITECTURE.md — that are
**not** recorded in `vibe/IMPLEMENTATION_LOG.md` (nor DECISIONS.md/ARCHITECTURE.md). Flag each
as a P2 finding: name the choice, the file, and why it warranted a log entry. This keeps the
"why" from silently rotting out of the record. Do not flag routine implementation — only
decisions that a future reader would need the reason for. (If IMPLEMENTATION_LOG.md is absent
entirely on a project past Phase 1, that itself is one P2 finding, not one per decision.)

---

## Step 4 — SOLID principles review

Read each source file created or modified this phase. Every violation cites file path and line.

**SRP:** Each component/hook/service has one reason to change.
- >500 lines → P1. >1000 lines → P0 CRITICAL.
- Component handling both UI AND business logic → extract hook.

**OCP:** New features added without modifying existing working code?
- Conditional chains replacing polymorphism? Flag.

**LSP:** Components/functions behave consistently across implementations?
- Hook return shapes consistent — all returning `{ data, loading, error }`?

**ISP:** Props interfaces not forcing unused props?
- Props interface >10 props (especially optional) → P1.

**DIP:** High-level components depend on abstractions, not concrete implementations?
- Direct DB client import in component → P0 CRITICAL
- Direct localStorage in component → P1

---

## Step 5 — Platform-specific review

Read `references/PLATFORM_CHECKS.md`. Apply the section matching this project's stack
(from CODEBASE.md section 2).

Platforms covered: React Web · React Native · Node/Express · Supabase · Security (universal)

---

## Step 6 — Code quality analysis

**Component size audit:** Log every component exceeding thresholds.
**Duplication analysis:** Patterns repeated across 3+ files → extract.
**TypeScript quality:** Count `any` usages — each is P0.
**Test quality:** Names describe behaviour, not implementation. AAA structure present.

---

**Performance-tagged findings (handoff to vibe-perf):** when a finding is a
performance concern (N+1 queries, unbounded lists, missing memoisation, oversized
bundles, sequential calls that could parallelise), tag it `category: performance`
in the report's structured findings and note it. This is what `vibe-perf` Entry B
triggers on — after review, if any `performance` P1/P2 findings exist, suggest
running `perf:` to audit and fix them properly. Do not attempt deep perf fixes
inside review.

---

## Step 7 — Security review

**Universal — all projects, all phases:**
```bash
# Include npm audit / pip-audit output from Step 0
```
- [ ] Hardcoded secrets, tokens, API keys → P0 CRITICAL
- [ ] `.env` in `.gitignore` → P0 if missing
- [ ] User input rendered without sanitisation (XSS) → P0
- [ ] Auth checks before protected content → P0 if missing
- [ ] Sensitive data not logged → P1
- [ ] Input validation at API boundary → P1 if missing
- [ ] Dependency vulnerabilities: high/critical = P0, moderate = P1

**Final phase review only (additional checks):**
- [ ] CORS not configured as `*` in production → P1
- [ ] Security headers (Helmet or equivalent) → P1
- [ ] Rate limiting on public endpoints → P1
- [ ] HTTPS enforced in production config
- [ ] Content Security Policy (CSP) headers set
- [ ] Session management correct
- [ ] Zero high/critical dependency vulnerabilities (must be zero before deploy)

---

## Step 8 — Testing review

- Tests present for all business logic? (missing → P1)
- Test names describe behaviour? (implementation names → P2)
- AAA structure? (missing → P2)
- Edge cases and error states covered for critical paths? (missing → P1)
- Coverage estimate >70% on business logic? (below → P1)

**Runtime evidence, not assertion (for UI / runnable changes).** Code review reads
the source; it does not prove the thing runs. Where the change touches something
observable — a screen, an endpoint, a CLI path — confirm it against the running
software, not just the diff: boot it, exercise the primary flow, and check for
console/stderr errors. A screen that renders blank, a route that 500s, or a
console error is a P0/P1 with the observed symptom as its evidence — "opened
/checkout, button click throws `undefined is not a function` in console" beats any
amount of reading. If you cannot run it in this environment, say the check was not
performed rather than implying the code was verified.

---

## Step 9 — Generate the review report

Read `references/REVIEW_REPORT.md` for the full template.

Save to `vibe/reviews/phase-[N]-review.md`.

**Quality score formula:**
- Start at 10.0
- Subtract 1.0 per P0 finding
- Subtract 0.5 per P1 finding
- Subtract 0.2 per P2 finding
- Subtract 0.1 per P3 finding
- Subtract 0.5 additional per architecture drift violation

**Evidence standard — non-negotiable:**
Every P0 and P1 must have file path + line number + specific actionable recommendation.
"Some components are too complex" — rejected, no file path.
If a finding cannot be backed by evidence — it does not go in the report.

**The machine-readable findings block is MANDATORY, not optional.** Every report must
contain the ` ```json ` structured-findings block from `references/REVIEW_REPORT.md`
(one object per finding: `id`, `severity`, `file`, `line`, `issue`, `fix`) — a prose
summary or a markdown table alone is not enough. Tooling (the gate, the panel's
findings/fix UI) parses that block; without it the findings are invisible and can't be
fixed, and the gate can't count them. A human-readable table may accompany it, never
replace it.

---

## Step 10 — Update vibe/TASKS.md

Edit the gate line **in place** under its own heading (`## Phase [N] gate`, or
`## Final gate` for `review: final`). Never add a second gate section. If the heading is
missing (older or retrofit file), add it at the end of that phase's block. See the
update rules in vibe-new-app `references/TASKS_MD.md`.

**P0 or P1 issues found — mark blocked and insert fix tasks under the gate line:**
```
## Phase [N] gate
🔴 review: phase [N] — blocked [date] · [N] P0 + [M] P1 open
   [ ] RFX-001 · [P0/P1 fix — plain English]
                 File: [path] · Issue: [one line]
   → Full report: vibe/reviews/phase-[N]-review.md
```

**Zero P0 and zero P1 — mark passed:**
```
## Phase [N] gate
✅ review: phase [N] — passed [date] · 0 P0, 0 P1 (P2/P3 to backlog)
```

On a re-review, replace the 🔴 line with the new result and leave completed `[x]`
RFX tasks beneath it as history.

---

## Step 11 — Update vibe/reviews/backlog.md

Add all P1/P2/P3 findings. Use the format in `references/REVIEW_REPORT.md`.

---

## Step 11.5 — Record the gate state (enforcement)

Read `references/GATES.md`. Write the outcome to `vibe/.gates.json` so phase
advancement and the deploy gate can *check* this review rather than trust memory —
this is what makes the gate hold in manual mode. Merge into the existing file; never
drop other phases' entries.

```bash
# Set these from the review you just completed:
#   PHASE = the phase reviewed ("1", "2", … or "final")
#   P0 / P1 = the P0 / P1 finding counts from this review
PHASE="[phase]"; P0=[p0 count]; P1=[p1 count]
python3 - "$PHASE" "$P0" "$P1" << 'PY'
import json, sys, pathlib, datetime
phase, p0, p1 = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
p = pathlib.Path("vibe/.gates.json")
g = json.loads(p.read_text()) if p.exists() and p.read_text().strip() else {"phases": {}}
g.setdefault("phases", {})
# One bar at every gate (phase and final): passed only at 0 P0 AND 0 P1.
status = "passed" if (p0 == 0 and p1 == 0) else "open"
entry = {"review": status, "p0": p0, "p1": p1,
         "date": datetime.date.today().isoformat(),
         "report": f"vibe/reviews/phase-{phase}-review.md"}
if phase == "final":
    g["final"] = entry
else:
    g["phases"][phase] = entry
p.write_text(json.dumps(g, indent=2) + "\n")
print(f"gate recorded: phase {phase} → {status} (P0={p0}, P1={p1})")
PY
```

If P0 > 0 **or** P1 > 0, the phase gate is **open** — the generated CLAUDE.md's
advancement rule blocks the next phase from starting until a re-review passes.

---

## Step 12 — Update vibe/ARCHITECTURE.md (if gaps found)

If review reveals a pattern being used that isn't documented:
- Add to the relevant section with `> 📝 [date] · Added during phase-[N] review`
- Log in DECISIONS.md if it changes something previously decided

---

## Step 13 — Signal done and generate hooks

**Read execution mode:**
```bash
grep "VIBE_MODE" CLAUDE.md 2>/dev/null | cut -d= -f2 | tr -d ' '
```

**Standard output (both modes):**
```
## Phase [N] Review Complete

📊 Score: [X/10] — Grade [A-F]
🏗️  Architecture drift: [N issues / none]
🔴 P0 issues: [N — fix tasks in TASKS.md / none]
🔶 P1 issues: [N — fix tasks in TASKS.md / none]
📋 Report: vibe/reviews/phase-[N]-review.md
```

**If `manual` or not set — standard gate message:**
```
Gate decision:
[✅ PASS — Phase [N+1] may begin. Say "next" to continue.]
[🔴 BLOCKED — complete RFX tasks in TASKS.md first, then say "next".]
```

**If `autonomous` — structured signal for calling skill:**

On PASS (0 P0 and 0 P1):
```
REVIEW_RESULT: PASS
P0: 0 | P1: 0 | P2: [N]
AUTONOMOUS: Phase [N] gate passed.
```
Return control to the calling skill. It decides what happens next (see
vibe-mode's AUTONOMOUS_EXECUTION_BLOCK — by default the phase ends here).

On FAIL (any P0 or P1):
```
REVIEW_RESULT: FAIL
P0: [N] | P1: [N] | P2: [N]
AUTONOMOUS: PAUSED — [N] P0 + [M] P1 issue(s) block the gate.

[List each P0/P1 with file path, line, and specific fix]

Fix the above, then say "resume" to continue autonomous execution.
```
Return this signal to the calling skill — do not wait here. The autonomous execution
block (vibe-mode `references/AUTONOMOUS_EXECUTION_BLOCK.md`) owns what happens next: it
runs the RFX fix tasks and re-runs this review, up to 2 cycles, and records a stop in
`vibe/.run_state.json` if the gate still won't clear. When review is run on its own
(not from that block), print the list above and stop; on "resume", re-run this review.

---

## Step 14 — Generate .claude/settings.json hooks (Phase 1 review only)

After the very first phase review (Phase 1), check if `.claude/settings.json`
has a PostToolUse lint hook. If not — offer to add it. (In autonomous mode, don't ask
and don't change `.claude/settings.json`: note "lint hook not installed — offer on the
next interactive review" in the review report and move on. Editing the agent's own
settings is a decision for a person.)

> "Phase 1 review complete. One quick setup: adding a lint+typecheck hook
> will catch TypeScript errors and ESLint violations as soon as they're
> introduced rather than at the next phase gate. Want me to add it? (y/n)"

If yes — **merge** the hook into `.claude/settings.json` (never overwrite it).
`.claude/settings.json` may already hold `permissions`, `env`, or other hooks
(e.g. a `PreToolUse` hook written by `vibe-doctor`). A `cat > … <<EOF` overwrite
would wipe all of that. Read-merge-write instead, and no-op if an equivalent
lint hook is already present:

```bash
# Pick the lint command for the stack (see per-stack variants below):
LINT_CMD='npm run lint --silent 2>&1 | tail -10 || true'

mkdir -p .claude
python3 - "$LINT_CMD" << 'PY'
import json, sys, pathlib
lint_cmd = sys.argv[1]
p = pathlib.Path(".claude/settings.json")
cfg = {}
if p.exists() and p.read_text().strip():
    try:
        cfg = json.loads(p.read_text())          # preserve existing config
    except json.JSONDecodeError:
        print("settings.json is not valid JSON — leaving it untouched"); sys.exit(0)
hooks = cfg.setdefault("hooks", {})
post = hooks.setdefault("PostToolUse", [])
# Skip if any PostToolUse hook already runs a lint/typecheck command.
already = any(
    "lint" in h.get("command", "") or "tsc" in h.get("command", "") or "ruff" in h.get("command", "")
    for entry in post for h in entry.get("hooks", [])
)
if not already:
    post.append({"matcher": "Edit|Write",
                 "hooks": [{"type": "command", "command": lint_cmd}]})
    p.write_text(json.dumps(cfg, indent=2) + "\n")
    print("Lint hook merged into .claude/settings.json")
else:
    print("A lint/typecheck PostToolUse hook already exists — no change")
PY
```

Set `LINT_CMD` per stack — Python: `ruff check . 2>&1 | tail -10 || true`;
TypeScript with typecheck: `npm run lint --silent 2>&1 | tail -5; npx tsc --noEmit 2>&1 | tail -5 || true`.

> Prefer the `update-config` skill if it is available in the session — it owns
> `settings.json` edits and merges hooks safely. Use the inline merge above only
> as a fallback.

Tell the user:
> "Hook added to .claude/settings.json. From now on, lint runs automatically
> after every file edit. ESLint errors surface immediately — no more discovering
> them at phase gate review."

If the merge reported that a lint/typecheck hook already exists — skip silently.
If the user says no — skip and note they can add it manually later.

---

## Always-flag anti-patterns

**P0 — Critical:**
1. Direct DB client import in component (DIP violation)
2. Component >1000 lines (SRP violation CRITICAL)
3. `any` type anywhere (TypeScript violation)
4. Hardcoded secrets/tokens/API keys (security CRITICAL)
5. Auth check missing on protected route/endpoint (security CRITICAL)
6. Architecture drift from ARCHITECTURE.md (or PLAN.md if no ARCHITECTURE.md)
7. npm/pip audit high/critical vulnerability
8. TypeScript compilation errors
9. All tests failing (if test runner exists)

**P1 — Fix before deploy:**
9. Component >500 lines (SRP violation)
10. Direct storage/localStorage without abstraction (DIP)
11. Missing error boundaries on data-fetching components
12. Hooks managing multiple unrelated concerns
13. Props interface >10 props (ISP violation)
14. console.log in production code
15. Test names describing implementation not behaviour
16. Missing tests for business logic
17. ARCHITECTURE.md not present (recommend running architect:)

---

## Pre-submission checklist

- [ ] Automated checks run — output included in report
- [ ] Every P0 and P1 has file path and line number
- [ ] Drift checked against ARCHITECTURE.md (or PLAN.md if missing) — not generic rules
- [ ] Carryover from previous reviews addressed (or stated as first review)
- [ ] Quality score calculated using the formula — not estimated
- [ ] Strengths acknowledged with file references
- [ ] RFX tasks in TASKS.md for all P0 issues
- [ ] P1/P2/P3 logged to vibe/reviews/backlog.md
- [ ] Gate decision stated clearly
- [ ] No section TBD or skipped
- [ ] Report saved to vibe/reviews/phase-[N]-review.md

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.