skills/code-review/SKILL.md
Perform a code review or pull request review on a branch
npx skillsauth add alexanderguy/skills code-reviewInstall 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.
Use this skill when performing code reviews or pull request reviews.
Before reviewing, you must determine the correct base branch. Use these methods in order of reliability:
If the branch has an open pull request or merge request, use the PR's target:
# GitHub
gh pr view --json baseRefName --jq '.baseRefName' 2>/dev/null
# GitLab
glab mr view --output json 2>/dev/null | jq -r '.target_branch'
If the branch tracks a remote branch that itself branched from somewhere:
git config --get branch.<branch-name>.merge
Attempt to find a common ancestor with likely default branches:
# Check if main or master exists and find merge-base
for base in main master develop; do
if git rev-parse --verify "origin/$base" >/dev/null 2>&1; then
merge_base=$(git merge-base "origin/$base" HEAD)
echo "$base: $merge_base"
fi
done
This helps identify which branch HEAD diverged from, but does not guarantee the intent of the branch author.
If none of the above methods provide a clear answer, do not assume. Ask the user:
I cannot determine which branch this was based off. What branch should I use as the base for comparison? Common options include
main,master, ordevelop.
Proceeding with an incorrect base will cause the review to include out-of-scope changes or miss in-scope changes.
Focus only on commits that are contained within the branch being reviewed.
Use git diff <base-branch>...HEAD to determine what is in scope.
# List commits on the branch
git log --oneline <base-branch>..HEAD
# Get the full diff for review
git diff <base-branch>...HEAD
# Get diff for a specific file
git diff <base-branch>...HEAD -- <file>
If a bug, convention violation, or inconsistent naming existed in code before the branch, do not treat it as a problem in the review. This includes cases where refactored code retains a pre-existing type name, variable name, or pattern that does not match current conventions.
Only evaluate the changes introduced by the branch.
All new logic, patterns, and naming introduced by the branch should follow the project's established conventions. Pre-existing code that appears in the diff due to refactoring is exempt from this requirement.
If reviewing TypeScript code, consider loading the typescript-conventions
skill for detailed guidance on type patterns, naming, and idioms.
When delegating file review to sub-agents, provide the output of
git diff <base-branch>...HEAD -- <file> rather than the full file contents.
Sub-agents that receive full files cannot distinguish branch changes from pre-existing code and will flag out-of-scope issues.
If full files must be provided for context, explicitly instruct the sub-agent which line ranges were modified by the branch and that only those ranges are in scope.
Do not request additional test coverage for functionality provided by external libraries. Focus test coverage requests on:
Trust well-maintained libraries to do their job. If a library's behavior needs testing, that suggests reconsidering whether to use that library.
A review should help the author, not burden them. Do not raise issues that are not important to the code being reviewed. Specifically:
If something should be fixed, say so directly. If it's not worth fixing, don't bring it up.
Review comments are posted under your name to a human author. Write them as you would speak to a colleague:
Review comments and PR descriptions must describe the branch's current diff against the base, not the journey that produced it. The merged result is what ships; intermediate states, earlier review rounds, and pre-iteration code are not part of the artifact.
Re-derive the description from git diff <base>...HEAD every time. Do not trust the existing PR description — it may have been written before the branch was iterated on, and reviewers reading it now should see what is true now.
Bad: "I refactored the retry logic to use exponential backoff and removed the old fixed-delay path." Good: "The HTTP client retries transient failures with exponential backoff."
Bad (review comment): "This used to call foo() but now calls bar() — did you mean to..."
Good (review comment): "bar() is being called here without checking its return value."
Past-tense framing rots: as the branch evolves through review, descriptions of "what was changed" stop matching the diff. Present-tense framing of "what the code now does" stays correct as long as the diff is correct.
A review report may include affirmative verification claims — "tests pass," "messages are clean," "no regressions," "convention compliance verified." When a review says something is verified, the reader takes that as a checked fact. If the check was never run, the report is dishonest. The dishonesty does not surface until a human reviewer finds the issue the agent claimed did not exist.
For every affirmative claim in your review, you must be able to cite the specific check that proved it. A check is a concrete artifact: a command whose output you read, a tool invocation whose results you inspected, a file/line range you examined for a specific pattern. "I considered it" and "it looked fine to me" are not checks.
When you cannot cite a check, do one of:
lock.go:42-68" is honest; "no race conditions in the new locking code" is not.Some properties — subtle concurrency bugs, performance pathologies, security gaps — cannot be fully verified by a single check. Honest narrowing is better than a dishonest absolute: say what you looked at and what you looked for, and do not claim absence beyond that boundary.
Bad → Good:
npm test exited 0," or strike.src/api/user.ts and src/api/billing.ts; same Result<T, E> return pattern, same assert-style guards," or strike.lock.go:42-68, traced lock acquisition order; no acquire-while-holding cycles in those lines. Did not analyze interactions with pool.go or callers outside the diff.""Cite the Check" requires that affirmative claims have backing. This rule narrows it: for the checks below, the backing must be the reviewer-of-record's own eyes on raw output. The reviewer-of-record is the agent whose verdict ships — when a workflow delegates the deeper read to a subagent, the orchestrator remains the reviewer-of-record and these checks stay with them.
Their value is in catching unknown-unknowns. A delegate asked for "a punch list of findings" returns things that fit the punch-list shape; Bin 0 -> 8181 bytes on a .ts file does not look like a finding, it looks like stat noise, and gets collapsed away. Only direct inspection preserves the signal.
Reviewer-of-record must run, in-session, and read the raw output:
git diff <base>...HEAD --stat — scan for Bin markers on any file you did not expect to be binary (source code, markdown, config) and for files outside the branch's stated scope.git log --oneline <base>..HEAD — confirm the commits on the branch match the issue's scope; unexpected or off-topic commits are stop conditions.Delegating the deeper read (file-by-file behavioral review, architectural analysis, commit-message coherence) to a subagent is fine and often valuable for context isolation. Delegating the checks above is not — their value is the raw output landing in front of the reviewer-of-record's eyes.
Each commit's message is a claim about what the commit contains. Verify that
claim. For every commit on the branch, read the message, read the diff
(git show <sha>), and confirm that the two match.
If a commit contains material changes that are unrelated to its message — files touched that have nothing to do with the stated purpose, unmentioned behavioral changes, or new functionality that the message does not describe — flag it. Undescribed changes hiding inside a commit undermine the reviewability and auditability of the history.
This includes whitespace or formatting changes to code that is not otherwise being modified. Drive-by cleanup belongs in its own commit — its presence in an unrelated commit is itself a problem.
Do not require that every modified line be individually narrated in the message. The message is a summary. But if someone reading only the message would be surprised by what the diff actually contains, that is a problem worth raising.
Coherence (above) checks that each message accurately describes its diff. Style audit checks that each message conforms to the project's commit-message rules (see the style skill, which is the canonical source for the prefix-family list and other rules). The two are independent; both have to be run.
Each check below is reviewer-of-record territory (see Reviewer-of-Record Checks) — run them in-session and read the raw output yourself. Do not delegate them; a subagent asked to "verify style compliance" will return a generic "looks fine" read with no audit trail.
Subject-line audits. Most checks scan the output of:
git log <base>..HEAD --format='%s'
Scan for:
word:, [tag], or (scope) pattern. Includes Conventional Commits (feat:, fix:), component or scope prefixes (Anthropic adapter:, mm:, [X86]), ticket IDs (INTR-79:), and status tags (WIP:). Project convention is plain English sentences; any prefix is a violation regardless of how idiomatic it looks in other ecosystems.server.ts, INFERENCE.md, src/foo/bar.py). The diff lists what changed; subjects describe the change, not the file.., !, or ?.For the length limit, use a length-aware filter so the check is not eyeball-counting:
git log <base>..HEAD --format='%s' | awk 'length > 72'
Empty output is clean. Any line returned is an over-72-character subject violation.
Body audits. Most checks scan the output of:
git log <base>..HEAD --format='%b'
Scan for:
INTR-79, JIRA-1234, #456, Closes XXX-99). The commit must explain itself.For body-line length, use the same length-aware filter:
git log <base>..HEAD --format='%b' | awk 'length > 72'
Empty output is clean. Any line returned is an over-72-character body line.
Affirmative claims about these audits must cite the specific command whose output proved them — see Cite the Check.
Items marked (reviewer-of-record) must be run by the agent whose verdict ships — see Reviewer-of-Record Checks. Do not delegate them to a subagent. Unmarked items are delegable.
git log --oneline <base>..HEAD to understand the scope (reviewer-of-record)git diff <base>...HEAD --stat to see which files changed (reviewer-of-record)development
General coding conventions for clean, maintainable code. Always load this skill when writing or reviewing code in any language.
testing
Engineering philosophy and work culture principles. Load this skill when making architectural decisions or to understand the team's work principles.
tools
Implement a feature or fix based on a Linear issue
testing
Orchestrate parallel subagent task runs. Smart input resolution - provide a name, directory, yaml file, or spec file. No argument runs the latest dispatch.