Code Review
SkillSecurityRun a comprehensive code review with 4 specialized reviewers (security, correctness, performance, consistency) in parallel.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Code Review skill
What this skill tells your AI
The instructions your AI receives, as published by tetherto/qvac in packages/ocr-ggml/.agent/skills/review/SKILL.md and read by ahel’s review.
Run a comprehensive code review using 4 specialized review agents: security, correctness, performance, and consistency.
Usage
/review # review current branch changes vs main
/review #1561 # review a PR by number
/review branch-name # review a specific branch vs main
/review --only security,correctness # run only specific reviewers
/review #1561 --depth max # maximum-depth pass (every reviewer on the session model)
Arguments
- No argument: review current branch changes against
main #<number>or<number>: review a GitHub PR<branch-name>: review a specific branch againstmain--only <list>: comma-separated list of reviewers to run (security, correctness, performance, consistency). Default: all 4.--depth <standard|max>: review depth.standarduses the per-reviewer default models (see Step 3).maxruns a maximum-depth pass: all reviewers on the session model — the model this session is itself running on, which is the strongest model the review is allowed to use — unlessreview.maxDepthModelpins an explicit model. Default comes fromreview.depthinpackages/ocr-ggml/.agent/config.json(falls back tostandardif absent); the flag overrides the config.
Workflow
Step 1: Determine review target
Parse $ARGUMENTS to determine the review target:
- If argument starts with
#or is a number → PR review mode - If argument is a branch name → branch review mode
- If no argument → current branch review mode
Extract --only flag if present to filter which reviewers to launch.
Extract --depth flag if present. If absent, read review.depth from packages/ocr-ggml/.agent/config.json; if the file or field is missing, use standard.
Determine the session model family — the model this session is itself running on — from the session's own model identity (Claude Code states it in context, e.g. "powered by the model named Opus 5", exact ID claude-opus-5[1m] → family opus). Map it to one of haiku, sonnet, opus, fable. If it cannot be determined, skip the clamping in Step 3 and use the table defaults as-is.
Step 2: Get the diff
PR review mode:
gh pr diff <number> --repo tetherto/qvac
gh pr view <number> --repo tetherto/qvac --json title,body,commits,headRefOid,headRefName,baseRefName
Branch review mode:
git diff main...<branch>
git log main..<branch> --oneline
git rev-parse <branch>
Current branch mode:
git diff main...HEAD
git log main..HEAD --oneline
git rev-parse HEAD
If the diff is empty, report "No changes to review" and stop.
Record the exact commit reviewed. Keep headRefOid (or the git rev-parse output) — it goes in the
report header in Step 5. Findings cite file:line as the file reads at that commit, so without the SHA
nobody can later tell a stale line number from a fixed finding.
Step 3: Launch specialized reviewers in parallel
Launch the selected review agents in parallel as sub-agents.
For each agent, set:
subagent_typeto the reviewer namemodelper the depth table below (Claude Code only — Cursor CLI inherits the parent model)promptwith enough context for the sub-agent to work independently (see template below). The prompt's "Do NOT fix code — report findings only" line is the read-only guarantee — reviewers must not modify files.
Model per reviewer and depth:
| Reviewer | --depth standard (default) | --depth max |
|---|---|---|
| security-reviewer | opus | session model |
| correctness-reviewer | opus | session model |
| performance-reviewer | sonnet | session model |
| consistency-reviewer | sonnet | session model |
- Model ladder, weakest → strongest:
haiku<sonnet<opus<fable. - The session model is a ceiling at every depth. The model passed to a reviewer is the weaker of (table value, session model family). A Sonnet session therefore runs correctness on
sonnetat standard depth, notopus; an Opus session runs a max pass entirely onopus, notfable. --depth maxraises every reviewer to the ceiling: all four run on the session model family.- Correctness gets
opusby default at standard depth: the bugs that matter most here are cross-file C++ lifetime/concurrency issues (object teardown across threads, GPU-kernel edge cases) that need deeper reasoning than diff-local pattern matching. - Security gets
opusfor the same reason. The vulnerabilities that matter in this repo are not diff-local patterns — they are multi-file trust-boundary questions: whether apull_request_targetworkflow lets fork code reach a credential, whether an approval gate binds to a mutable ref, whether a composite action three files away persists a token into a workspace that untrusted code later reads. Answering those means reading the called action, the gate implementation and the environment configuration together, and confirming the claim against the live repo rather than pattern-matching the diff. A reviewer that stops at the diff produces plausible-sounding findings on the wrong lines. review.maxDepthModelinpackages/ocr-ggml/.agent/config.jsondefaults to"session"(use the session model). Setting it to an explicit model name (fable,opus, …) pins max depth to that model and bypasses the ceiling — an escape hatch for deliberately escalating past the session model.- If the local Claude Code version rejects the resolved model name, fall back to
opus; if that is also rejected, omitmodeland let the agent definition decide. - On Cursor CLI there is no per-agent model override — reviewers inherit the parent model, which matches the ceiling rule by construction. For a maximum-depth pass, run the parent session on the strongest available model.
Agents to launch (all 4 unless --only filters):
- security-reviewer — injection, auth bypass, credential exposure, OWASP patterns
- correctness-reviewer — logic bugs, edge cases, race conditions, test coverage
- performance-reviewer — allocations, blocking calls, memory leaks, N+1
- consistency-reviewer — cross-addon pattern enforcement, architecture alignment
Prompt template — adapt [target], [diff-command], and [domain] for each reviewer:
Review the code changes on [target] in repo tetherto/qvac.
To get the diff, run: [diff-command]
Focus only on [domain] issues.
Report each finding with: severity, file path and line, description, impact, and fix recommendation.
If no issues found, report: "No [domain] issues identified."
Do NOT fix code — report findings only.
Where [diff-command] is:
- PR mode:
gh pr diff <number> --repo tetherto/qvac - Branch mode:
git diff main...<branch> - Current branch mode:
git diff main...HEAD
Step 4: Check for forbidden files
While reviewers run, do a quick check:
.npmrc,.env, or credential files must NOT be in the diff- If found, warn immediately
Step 5: Collect and present results
Collect results from all reviewers and present a unified report.
Every written report opens with this header block, immediately under the H1, before any prose. It is a required part of the output, not decoration — see the note below:
# Code Review — <target>
**PR:** [<title>](https://github.com/<owner>/<repo>/pull/<n>)
**Reviewed at:** `<owner>/<repo>@<head-sha>` · **Base:** `<base-branch>` · **Head:** `<head-branch>`
**Reviewed:** <YYYY-MM-DD> · **Depth:** <standard|max> · **Reviewers:** security, correctness, performance, consistency
For branch or current-branch mode, drop the **PR:** line and use
**Reviewed at:** \@` · Base: `main` · Head: ```.
For a report covering several PRs, repeat the block under each per-PR heading rather than once at the top — each PR has its own head SHA, and a stack's shared summary table is not a substitute for it.
Then the findings themselves:
### Security
[findings or "No issues"]
### Correctness
[findings or "No issues"]
### Performance
[findings or "No issues"]
### Consistency
[findings or "No issues"]
### Summary
- Total findings: X (Y critical, Z warnings)
- Recommendation: [ready to merge / needs fixes / needs discussion]
Step 6: Write the feedback document
Always write the report to a file — do not ask first. The chat summary is ephemeral; the file is what
/post-feedback consumes to file line-anchored PR comments, and what a human re-reads days later.
Path — repo root of the working repo (alongside the existing PR*-feedback.md docs):
| Mode | Filename |
|---|---|
| PR review | PR<number>-claude-feedback.md |
| Branch / current branch | <branch-slug>-claude-feedback.md (slashes → -, e.g. feature-QVAC-22734-claude-feedback.md) |
The claude segment is the tool that produced the review. On Cursor it is cursor instead. This is not
cosmetic: both tools review the same PRs, and a shared PR<n>-feedback.md would have one silently
overwrite the other. A plain PR<n>-feedback.md is reserved for a human-merged consolidation of both.
Re-reviewing the same PR with the same tool overwrites the same path — /post-feedback keeps its own
run state keyed on the PR, so a fresh document is not a fresh conversation.
Required shape. /post-feedback parses this document, and it refuses documents whose findings are
only table rows or only bullets. Every finding must be a heading with a ref line:
#### [SEVERITY · domain] one-line title
`path/to/file.ext:17-18`
*First whole sentence, in italics, on its own line.*
<prose body: evidence, why it is wrong, impact, then the fix>
SEVERITY∈CRITICAL·HIGH·MEDIUM·LOW·NIT.domain∈ the four reviewer names.- The ref line is the bare backticked path, on the first non-blank line after the heading.
- The italic sentence is the finding's identity —
/post-feedbackopens the posted comment with it verbatim. Nothing may sit between the ref line and that sentence. - Group findings under
## Security/## Correctness/## Performance/## Consistency. - Put non-postable material (verified-clean notes, resolved questions, corrected reviewer claims) under headings without a severity tag, so it is never offered as a comment.
Also carry over into the file, beyond the chat summary:
- The Step 5 header block verbatim, plus a Finding identity note explaining the italic-sentence rule.
- Findings deduplicated across reviewers — one entry per defect, noting cross-confirmation, not one entry per reviewer that found it.
- Any reviewer claim you disproved, under a
## Corrected reviewer claimheading. Reviewers are wrong often enough that silently dropping a bad finding loses the correction.
Verify every line number before writing it. Reviewers report anchors that do not exist — a sed -n
or grep -n against the file at the reviewed SHA costs seconds and these anchors become PR comment
positions. If you corrected any, say so in a note near the top of the document so nobody "restores" them.
Then tell the user the path in your chat reply.
Step 7: Offer to fix
After presenting the report, ask the user:
Found X issues. Want me to fix the actionable ones? (y/n)
If the user says yes:
- Fix each actionable issue directly
- Commit each fix:
fix: [description] - Re-run build/tests to verify
- Report what was fixed
Do NOT fix:
- Performance suggestions requiring architectural changes
- Consistency deviations that may be intentional
- Anything marked as "needs discussion"
Notes
- All 4 reviewers run in parallel via sub-agents for speed
- On Claude Code, set
modelper the depth table in Step 3 (opus for correctness and security, sonnet for the pattern-oriented reviewers), clamped to the session model family;--depth maxruns all four on the session model - On Cursor CLI, reviewers inherit the parent model (no model override available)
- The skill itself coordinates and synthesizes — it does not duplicate reviewer work
- Writing the feedback document (Step 6) is unconditional — it is the deliverable, not an optional extra. The chat report is a summary of it, not a substitute
- Does NOT push to remote — the user handles that
- The Step 5 header block is consumed by
/post-feedback, which files these findings as line-anchored PR comments.**Reviewed at:**gives it the commit thefile:linereferences were written against, so it can say "this document is 12 commits stale" up front instead of discovering it one rejected comment at a time;**PR:**gives it a machine-readable target instead of guessing from the filename. Do not drop either line as boilerplate — a report without them still reads fine to a human and silently degrades the tool that consumes it.
Signals
- GitHub stars
- 601
- Forks
- 111
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
review-tetherto- Source
- github.com/tetherto/qvac