| name | quickapps-code-review |
| description | Use before creating a PR or claiming a change is ready (or on explicit user invocation). Self-reviews the current diff against the patterns this team's reviewers consistently flag. |
| allowed-tools | Read Grep Glob LSP Bash(git diff:*) Bash(git log:*) Bash(git show:*) Bash(git status:*) Bash(git rev-parse:*) Bash(date:*) Bash(gh pr view:*) Bash(gh pr diff:*) Bash(gh pr list:*) Write(docs/reviews/*) Bash(mkdir -p docs/reviews) |
| argument-hint | [pr|uncommitted] |
| arguments | scope |
| model | opus |
| effort | xhigh |
| context | fork |
| agent | general-purpose |
quickapps-code-review
Self-review the current diff against the recurring feedback this team's reviewers actually leave. Catches it before they do.
When to use
- Before
gh pr create
- After finishing a feature or fix, before claiming "done"
- When the user explicitly asks for a "review", "self-review", or "pre-submit check"
Arguments
scope = $scope (one of pr | uncommitted; if empty, default to pr):
pr — review only committed changes on the current branch vs development. Use exactly:
git diff development...HEAD
Do not run plain git diff (no revision range), git diff --staged, or include git status output. Uncommitted/unstaged files are out of scope.
uncommitted — review only working-tree + staged changes (not yet committed). Use exactly:
git diff HEAD
Do not include committed changes from the branch.
If the resolved diff is empty (or whitespace-only), report "nothing to review" and stop — do not write a review file.
How to run
- Resolve the diff using only the command listed for
$scope above. If $scope is empty, treat it as pr. Never mix scopes in one run.
- For every new or renamed function, method, or class in the diff: verify call sites with
findReferences / Grep (production + tests). Flag zero production callers unless the symbol is explicitly test-only.
- Walk the checklist below per file changed. For each hit, report: file:line, the rule, and a concrete suggested fix.
- Group findings as Blocking (would get a "change requested") vs Nit (would get a
nit: tag). Render each finding as a markdown checkbox (- [ ]) so they can be ticked off as they are addressed.
- End with a short verdict: ship / fix-then-ship / split.
- Save the review to
docs/reviews/<branch>__<YYYYMMDD-HHMM>.md:
<branch>: current branch from git rev-parse --abbrev-ref HEAD, with / replaced by -. Keep prefixes (feat-, fix-, chore-) as-is.
<YYYYMMDD-HHMM>: short local datetime from date +%Y%m%d-%H%M.
- Create
docs/reviews/ if missing, then write the file (both pre-approved).
- Surface the review in the chat too — don't rely on the file alone.
When verifying field existence (§9) or whether an identifier still exists after a rename (§6, §8), prefer LSP (hover, goToDefinition, findReferences) over re-reading files. This skill is read-only; navigation tools are too.
Do NOT auto-apply fixes unless the user asks — surface them first.
The checklist
The single most common review comment is some form of "why is this here?" — apply that lens to every new file, field, parameter, import, and comment.
1. Necessity — "why is this here?"
This is the single most frequently left comment — most often phrased "is it used?" / "where is it used?" / "clean up". Trace every new symbol to a real consumer before submitting.
2. PR scope
3. Module boundaries / imports
4. DI / Injector
5. Settings
6. Naming & consistency
7. Design doc fidelity
8. Schema / cache regeneration
9. Typing & attribute access
10. Decomposition
11. Logging
12. Security — forwarded headers
13. Subclass / protocol contracts
14. Multi-instance protocol state
15. Pipelines that mix user and admin sources
16. Preview feature consistency
17. Exception handling
Red flags — stop and reconsider
If you find yourself thinking any of these while reviewing your own change, treat it as a blocker:
| Thought | Reaction |
|---|
| "This bit isn't strictly needed but might be useful later" | Delete it — a reviewer will ask "why is this here?" |
| "This method/var might get used eventually" | If nothing calls it now, delete it — "is it used?" is the #1 comment. |
"I'll wrap except Exception around it to be safe" | You may be swallowing a specific error a caller relies on. Catch narrowly. |
"I'll put this helper in common/ for now" | If one module uses it, it lives in that module. |
| "I'll just sneak this rename in" | No. Separate PR. |
"It's just one os.getenv" | Move to BaseSettings. |
| "I'll update the design doc in a follow-up" | Do it in this PR. |
| "common/ importing from agent/ is fine for now" | It is not. Fix the direction. |
| "The cached tool-call responses still work" | If you renamed a tool, regenerate caches. |
"Any is fine here" | Use the concrete type. |
"Optional None default makes tests easier" | Injector always provides it in prod — require the type. |
| "I'll add a helper now in case we need it later" | Grep for callers first — dead code gets "is it used anywhere?" |
| "Special-case preview strip in the validator" | Extend nullify_preview_fields / shared preview machinery instead. |
| "PR description is close enough" | Every bullet must match the diff after any revert/split. |
Output format
The file saved to docs/reviews/ and the in-chat summary share this layout:
# Code review — <branch> ($scope)
_Generated: <YYYY-MM-DD HH:MM>_
## Blocking
- [ ] `path/to/file.py:42` — §<N> <rule name>: <what's wrong>. Suggested: <fix>.
- [ ] ...
## Nits
- [ ] `path/to/file.py:88` — §<N> <rule name>: <what's wrong>. Suggested: <fix>.
## Scope / structure
- [ ] split-PR concerns, missing schema regen, design-doc updates, etc.
## Verdict
<ship | fix-then-ship | split>
Every finding is a checkbox — the author ticks them off as fixes land.
Maintenance
This checklist drifts as conventions evolve. At the start of every review run, check freshness:
git log -1 --since='7 days ago' --format=%h -- .claude/skills/quickapps-code-review/SKILL.md
- Non-empty output → fresh. Skip; don't load
references/REFRESHING.md.
- Empty output → stale. Tell the user "the review checklist hasn't been refreshed in over a week; refresh recommended" and offer to run it. Load references/REFRESHING.md only if the user agrees.
Refresh is always separate from the review run — never block reviewing on a stale checklist.