skills/code-review-and-quality/SKILL.md
Use when reviewing a pull request or code change before merge. Use for the five-axis evaluation (correctness, readability, architecture, security, performance), exposure × impact severity classification, AC coverage verification, and the `## Automated review` comment. Use in both human and CI mode — the methodology is identical; only the inputs and agent invocation differ.
npx skillsauth add paulund/skills code-review-and-qualityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Single reasoning pass that produces (a) a ## Automated review comment with findings and AC coverage, (b) a risk-low/risk-medium/risk-high label that decides whether humans must review, and (c) a reviewed label transition in CI mode.
Run the five steps in order. Skip none.
Read enough surrounding code to answer: what system does this diff touch and what role does it play? Read the file the diff modifies, plus its public callers, plus the test file. Do not skim — the diff hunks alone don't reveal intent.
For each changed file, evaluate:
Axis 1 — Correctness. Wrong logic, wrong type, off-by-one, dropped error handling. Broken invariants, unhandled edge cases. All acceptance criteria visibly addressed.
Axis 2 — Readability. Dead code, redundant branches, premature abstraction. Unhelpful comments vs. missing why-comments. Naming clarity — does the name reveal intent? Match the diff against the smell baseline below.
Axis 3 — Architecture. Module boundaries — are they justified? Deletion test applies. AHA violations — abstracted before the third occurrence. Single-adapter seams with unnecessary interfaces.
Axis 4 — Security. Apply the four data-flow questions from references/security-data-flow.md — sources, sinks, trust boundaries, secret handling.
Axis 5 — Performance. N+1 queries, sync work in hot paths. Unnecessary allocations, unbounded loops. Bundle impact for new UI imports.
A fixed set of Fowler code smells (Refactoring, ch. 3) the Readability axis always carries, on top of whatever the repo documents. Binding rules:
Each smell reads what it is → how to fix; match it against the diff:
switch/if-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.a.b().c().d() navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.For each candidate finding, write the trace: entry → action → service → sink. Read the full path, not just the diff hunk. A missing try/catch that the caller already provides is not a finding. A console.log of an unredacted value is.
For each Closes #N, run gh issue view <N> --json body and extract the ACs verbatim. For each AC:
See references/intent-check.md for the full process.
Replace a flat 4-level table with two axes. See references/severity-classification.md.
/api/v1/posts is high exposure.| | Impact: Severe | Impact: Significant | Impact: Moderate | Impact: Minor | | -------------------- | -------------- | ------------------- | ---------------- | ------------- | | Exposure: High | critical | high | medium | low | | Exposure: Medium | high | high | medium | low | | Exposure: Low | medium | medium | low | low | | Exposure: None | low | low | drop | drop |
Drop findings that are neither reachable nor significant.
Every reported finding must include: file:line + trace (entry → sink) + concrete failure or exploit path. Findings that don't meet this bar get dropped. No exceptions.
This is the discipline that kills checklist-mimicry. If you can't write the trace, you don't have a finding.
Smell-finding carve-out. Smell findings cite file:line + smell name + quoted code; the data-flow trace is not required. The severity cap and judgement-call framing are what make this safe.
Compute the PR's risk-low/risk-medium/risk-high label. Three dimensions, summed into one band. See references/categorization.md.
Take the highest floor; apply reversibility and invariant adjustments. Output the level with a one-sentence justification.
Labels and merge semantics:
risk-low — agent-only review. Comment + label. No human review required.risk-medium — comment + label. Human reviews the agent's flagged concerns, then merges.risk-high — comment + label. Full human review of the diff is mandatory.Always this exact structure — ## Automated review, ### Findings, ### Acceptance criteria coverage (omit if no linked issues), ### Security, ### Risk. No findings → fill with None. / All criteria addressed. / No security-relevant changes.. See references/comment-template.md.
## Automated review
### Findings
- [severity | file:line | trace → impact] — fixed in commit <sha>
### Acceptance criteria coverage
- [criterion verbatim] — covered by `<test-file>:<test-name>`
- [criterion verbatim] — **NOT COVERED** — see #N
### Security
- [severity | file:line | trace → impact] — fixed in commit <sha>
- (No security-relevant changes.)
### Risk
<low|medium|high> — <one-sentence justification>
Fix every finding by editing code in this run. Commit grouped by concern:
git add <files>
git commit -m "Address review: <one-line summary>"
# For security: git commit -m "Security review: <one-line summary>"
All findings — Critical, High, Medium, and Low — must be fixed in the same run. Do not file separate GitHub issues for any severity.
| Rationalization | Reality | |---|---| | "I'll fix the style issues later" | They never get fixed. File issues or fix now. | | "It's not my code, I shouldn't rewrite it" | You're reviewing the change, not the author. Flag problems in the diff. | | "The tests pass, so it must be correct" | Tests only prove what they assert. Missing test coverage is a finding. | | "This is an edge case, no one will hit it" | Edge cases in production are crashes. Fix them. | | "I'm not 80% confident this is exploitable" | If you can't write a trace, drop it. Don't file a hedge. | | "I'll let the security audit catch it" | Trace data flow now. Security findings are the highest-impact and easiest to miss. | | "I can't write a trace for this smell, so I'll skip it" | Smell findings don't need a trace — cite file:line + smell name + quote. |
## Automated review comment posted on the PR| File | When to load |
| --- | --- |
| references/categorization.md | When computing the risk label |
| references/severity-classification.md | When classifying a finding's severity |
| references/intent-check.md | When verifying AC coverage from the linked issue |
| references/security-data-flow.md | When security findings are possible |
| references/comment-template.md | When composing the ## Automated review comment |
gh — never rely on the PR description alone.Closes #N.## Automated review comment on every run — even with zero findings.risk-<level> label and transition reviewing → reviewed in CI mode.references/security-data-flow.md handles these with proper exploit-path analysis).development
Use when implementing any logic, fixing any bug, or changing any behaviour. Use when you need to prove code works, when a bug report arrives, or when modifying existing functionality. Do NOT use for config changes, data migrations, or dependency updates.
development
Use when starting a new feature, when requirements are unclear, when asked to write code without a clear spec, or before any non-trivial implementation. Do NOT use for trivial bug fixes or one-line changes.
development
Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters. Detects the stack from dependency files, fetches official documentation, implements following documented patterns, and cites sources for every framework-specific decision.
development
Use when preparing to ship a feature, release, or deployment. Use before merging to main, creating a release, or deploying to production. Do NOT use for CI-only changes or internal refactors that don't reach production.