| name | review |
|---|---|
| description | Exhaustive, evidence-driven code review of the current branch's pull request. Surfaces every actionable issue (correctness, reliability, performance, maintainability, and architecture), walks the findings one at a time to collect a decision on each, then implements the chosen fixes with regression tests where a harness exists. Requires an open PR on the current branch. Use when the user asks to review, audit, or critique a PR. |
| user_invocable | true |
| disable-model-invocation | true |
| argument | Optional additional context for the review (focus areas, concerns, background). Does not change scope — the review always covers the current branch's PR. |
Perform an exhaustive, evidence-driven code review of the pull request for the current branch. Find all concrete issues worth acting on, from critical bugs through nits, inconsistencies, maintainability problems, and architectural concerns, then walk the user through findings one at a time, collecting a decision on each before moving to the next. Only after every finding has a decision do you implement the chosen fixes in a single batch.
Each PR has a persistent review ledger at memory/pr_reviews/<pr-number>.md in the current repo root. This file is the source of truth for findings, decisions, and fix outcomes across review sessions. Create memory/pr_reviews/ if it does not exist. Ledger files are intentional review history — commit them when a session produces meaningful decisions or fixes; do not gitignore them.
- After resolving the PR number in Step 1, read
memory/pr_reviews/<pr-number>.mdif it exists. - Load all prior findings, decisions, and statuses into working memory before reviewing or presenting anything. For ledger entries with
status: fixed,skipped, orwithdrawn, remember the id and outcome only — do not re-triage their text unless reopening. - Do not re-present findings whose status is already
fixed,skipped, orwithdrawnunless fresh code review shows the issue is still present — in that case, add a new finding (new id) or set the existing one tostatus: reopenedwith an updated note. - Continue finding ids from the ledger (
F1,F2, …). Never reuse or renumber ids. - Update the ledger after each decision (Step 5) and after each implemented fix (Step 6). Keep it on disk at the end; never delete it.
- Resume shortcut: If any finding has
status: decidedand none arependingorreopened, skip Step 5 and go straight to the Step 5 recap → user confirmation → Step 6.
Use this structure (YAML frontmatter + markdown sections):
---
pr: 275
title: PR title from gh pr view
branch: feature/foo
base: main
repo: owner/repo
---
# PR Review #275
2 Critical, 5 Warning, 2 Nit | 6 fixed, 4 skipped, 2 pending | last session 2026-05-30
## Sessions
### 2026-05-30T14:00:00-07:00
Context: optional user argument for this session. Brief note on what happened this session.
## Findings
### F1: Short title
- **severity:** Critical | Warning | Nit
- **architecture:** true | false
- **confidence:** high | medium | low
- **location:** path/to/file.swift:42 (or area for cross-cutting issues)
- **description:** what is wrong
- **evidence:** short quote or pointer
- **impact:** user-visible or maintenance impact
- **recommendation:** preferred fix
- **alternatives:** optional; up to two
- **test_plan:** optional regression test to add/update
- **decision:** empty until decided; then the chosen action (e.g. apply recommendation, alternative, skip)
- **decision_notes:** why the user chose it; freeform notes from the session
- **status:** pending | reopened | decided | fixed | skipped | withdrawn
- **fixed_at:** ISO timestamp when fix landed; omit if not fixed
- **fix_summary:** what changed to resolve it; omit if not fixed
- **source_thread_id:** optional `PRRT_…` from `queries.sh threads` when this finding was surfaced from an open inline review thread; omit otherwise
- **source_review_id:** optional `PRR_…` from `queries.sh reviews` when the finding came from a top-level review body; omit otherwise
- **source_comment_id:** optional issue-comment id from `queries.sh comments` when the finding came from a PR conversation comment; omit otherwiseKeep YAML frontmatter to static PR metadata only (pr, title, branch, base, repo). Log sessions in ## Sessions (newest first). Update the rolling summary line under the title after each session — format: <severity counts> | <status counts> | last session <date>. Add new findings under ## Findings. Update fields in place as decisions and fixes happen.
PR review feedback is read-only context by default — the same role as prior ledger entries. Use it to understand what has already been raised, addressed, or closed on the PR. Do not reply to, resolve, or minimize on GitHub except in the narrow case documented in Close handled PR feedback below.
Intake path: run each subcommand with --all (paginate with --after when truncation says so):
~/.agents/scripts/queries.sh truncation
~/.agents/scripts/queries.sh threads --all
~/.agents/scripts/queries.sh reviews --all
~/.agents/scripts/queries.sh comments --all--all includes resolved threads and minimized review bodies / issue comments — treat these like ledger entries with fixed/skipped/withdrawn status: load them for dedupe and history, do not re-raise unless current code regressed.
Do not use broad PR comment sources that bypass the script: gh pr view --comments, unfiltered GraphQL, or full conversation dumps.
How to use feedback:
isResolved: true/isMinimized: true— already handled on GitHub; remember the concern and outcome, skip re-raising unless the code regressed.- Open (
isResolved: false, not minimized) — verify against current code. If already fixed in the branch, skip silently. If you disagree with the comment after verification, skip silently — do not re-raise, argue, or add a counter-finding. If still valid and your own analysis agrees, you may add a new ledger finding when not already tracked; recordsource_thread_id(orsource_review_id/source_comment_idwhen the feedback is not an inline thread). - Do not adopt review comments as a todo list; the review must stand on its own reading of the code. Surfacing a thread-linked finding in Step 5 is not adopting the whole PR comment queue — only findings you present and the user accepts may be closed on GitHub later.
The review scope is always the current branch's PR. Do not interpret the user's argument as scope — it is supplemental context only (focus areas, concerns, background, or questions to keep in mind while reviewing).
- Confirm the current branch with
git branch --show-current. - Resolve the PR with
gh pr view --json number,title,baseRefName,headRefName,url,isDraft,mergeable,reviewDecision,statusCheckRollup(no branch argument — uses the current branch). If no PR exists, stop and tell the user this skill only works on branches with an open PR. Record the PR number, title, base branch, and repo from this output. Note draft status, merge conflicts, failing checks, and other blockers before deep review. - Load the review ledger from
memory/pr_reviews/<pr-number>.mdif it exists; otherwise create a new ledger file with frontmatter for this PR, a rolling summary line, an empty## Sessionssection, and an empty## Findingssection. - Get the diff with
gh pr diff(and read the changed files for context). If the hosted diff is noisy, use the local base diff such asorigin/<base>...HEAD, where<base>comes from the PR metadata. - Read any free-form argument the user passed as additional review context — not as a scope selector.
Before judging code, understand the project:
- Read project instructions and conventions such as
AGENTS.md,README, and top-level config files. - Check repository state with commands like
git status --short,git branch --show-current, and the PR diff/log (gh pr view,gh pr diff, or the local base diff). - Read the changed files with surrounding context, not just the patch.
- Note the PR title, description, and any linked issues for intent and contract expectations.
- PR feedback (context only) — see PR feedback as context. Run
truncationfirst; thenthreads --all,reviews --all, andcomments --all(paginate each with--afterwhen its*HasMoreis true). Read only enough to dedupe; do not write to GitHub during intake. - Identify the test framework and the smallest useful test commands for the affected areas. When fixes are likely, run those tests once to confirm a green baseline before relying on them for the test-driven fixes in Step 6.
- Apply any supplemental context from the user's argument (e.g., "pay extra attention to auth" or "we're worried about race conditions") while keeping the review scope limited to the PR diff and its related call sites.
- Cross-check the ledger: note which findings are still
pending,reopened, ordecidedbut not yet fixed. Ignore ledger entries alreadyfixed,skipped, orwithdrawnunless the code regressed.
Prioritize production code.
- Use tests only as context: how behavior is supposed to work, or whether production code is untested — do not nitpick test style, helpers, mocks, or coverage mechanics.
- Findings whose primary location is test-only should be rare. Report them only when the test documents incorrect expected behavior, hides a production defect, or asserts something false about the product.
- When production code and tests both change, review the production change first; mention test gaps only if they block confidence in a production finding.
Look for both targeted defects and broader design issues.
Targeted review categories (short cues, not exhaustive checklists):
- Correctness: logic errors, bad state transitions, invalid assumptions, missing edge cases, wrong API usage, data/persistence corruption, broken migrations.
- Concurrency and async: races, deadlocks, actor/thread isolation, TOCTOU, cancellation leaks, lock ordering, unsafe shared state.
- Reliability and error handling: swallowed errors, missing validation, weak retry/accounting, bad fallbacks, missing observability for important failures.
- Performance and scalability: N+1 queries, redundant expensive work, poor data structures, unbounded memory or task growth, hot-path regressions.
- Compatibility and integration: platform/version mismatches, API or schema contract drift, feature-flag mistakes, environment-specific failures.
- Dependencies, build, and release: unsafe dependency or lockfile changes, build/packaging/signing risks, missing rollout or rollback.
- Coupling and maintainability: implicit ordering, stringly-typed interfaces, duplicated logic, unclear boundaries, over-complex control flow.
- API ergonomics and foot-guns: misleading names, surprising defaults, easy-to-misuse patterns, hidden ordering requirements, weak invariants.
- Tests and tooling: missing production coverage for changed behavior, or CI/build risks that affect shipped code — not test-file style, helpers, mocks, or coverage mechanics for their own sake.
- User experience and accessibility: confusing flows, broken empty/loading/error states, focus/keyboard issues, accessibility or localization regressions.
- Documentation and contract consistency: stale comments or docs, misleading PR descriptions, tests or docs that encode a different contract than the code.
- Cleanup: dead code, unused imports, inconsistent naming, unreachable branches.
Architectural observations:
- Missing or blurred boundaries between layers.
- Modules that own too many responsibilities or live in the wrong place.
- Repeated patterns that should become a shared abstraction.
- Data paths, state models, or workflow contracts that will become painful as the codebase grows.
- Strategic simplifications that reduce risk without broad churn.
Examine changed production behavior through its call sites, data flow, and tests (tests as context only). If a suspected issue is only theoretical, verify user reachability and realistic timing before presenting it as a finding.
Collect all new findings before presenting them. Skip issues already recorded in the ledger with a final status unless the code still exhibits the problem.
Do not duplicate context you already have: Skip raising a finding when the issue is already tracked in the ledger (fixed/skipped/withdrawn unless reopened) or when PR feedback (open or already resolved/minimized on GitHub) describes the same concern and current code already addresses it. PR comments are not action items.
Give each finding a severity, ranked by real impact:
- Critical: data loss, crash, severe correctness regression, broken production path.
- Warning: likely user-visible bug, race, reliability gap, significant performance issue, brittle contract.
- Nit: naming, small cleanup, local duplication, minor maintainability issue.
Independently, tag a finding Architecture/Design when it concerns boundaries, responsibilities, shared abstractions, or data/workflow contracts rather than a single localized defect. This tag is orthogonal to severity — a design issue can be anything from Critical to Nit — so order findings by real impact and never demote one just because it is architectural.
Each finding must include:
- Severity, the Architecture/Design tag when it applies, a short title, and confidence (
high,medium, orlow) when the issue is plausible but not certain (common for concurrency, performance, and reachability arguments). - Exact file paths and line numbers for localized issues; for architectural or cross-cutting findings, cite the relevant files, ranges, or module paths instead.
- A clear description of the broken behavior or design problem.
- Evidence from the code, with short snippets only when useful.
- The user-visible or maintenance impact.
- A recommended fix and, when there are real tradeoffs, up to two alternatives.
- A test plan when the recommended action changes behavior worth testing and a usable test harness exists: name the red-green regression test to add or update. Keep this in the finding body, not crammed into a choice label.
Be complete but honest: include every concrete new issue in the PR — bugs, inconsistencies, inefficiencies, duplication, brittle contracts, foot-guns, maintainability problems, architectural drift, missing tests, and useful cleanup — and rank them truthfully by severity rather than filtering them out. Deprioritize or omit findings that live only in test/fixture/CI files unless they indicate a production bug or a false contract about product behavior. Do not pad the review with speculative or low-value comments, and if an earlier suspected issue turns out to be false, set status: withdrawn in the ledger. If the PR contains no new actionable issues and no pending ledger items need decisions, say so plainly and stop; never invent findings to fill the review.
Write new findings to the review ledger (memory/pr_reviews/<pr-number>.md) with status: pending and empty decision fields. Also include any ledger findings still pending, reopened, or decided (not yet fixed/skipped) in the queue for Step 5.
This step is strictly about collecting decisions, not implementing them. Do not edit code, write tests, or run fixes during Step 5. Implementation happens in Step 6, after every finding has a decision.
Present only findings whose status is pending or reopened. Always walk them one at a time, highest impact first. Never dump the full list for batch triage, and never collapse nits into a group — one finding at a time is the only mode, no matter how many findings there are.
For each finding awaiting a decision, in order:
- Show the finding in a short message: id and number (
F2 — Finding 2 of 5), severity, confidence when nothigh, and the Architecture/Design tag if it applies, title, file path and line number (or area), the issue and its user-visible or maintenance impact, and your recommendation with a one-sentence reason. When the finding has asource_thread_id(or other source id), say so explicitly (e.g. "Matches open reviewer thread onpath:line"). If the recommended action warrants a regression test, describe that test here in the finding body. - Ask the user to choose what to do with this finding. Use the richest interactive prompting mechanism available — if your environment supports buttoned multiple-choice prompts, use them; otherwise present a short numbered list inline and ask the user to reply with a number or a freeform answer. Whichever surface you use, keep the option labels short and always include:
- The recommended action as the first option, clearly marked
(Recommended). - Up to two additional concrete alternatives when real tradeoffs exist.
- A
Skipoption so the user can decline this finding. - Make clear that the user can also respond freeform (override the options, ask for more detail, or stop).
- The recommended action as the first option, clearly marked
- Record the user's decision in the ledger: set
decision,decision_notes, andstatus: decided(orstatus: skippedif they skip). Do not start fixing yet. - Move on to the next finding and repeat.
If the user challenges a finding, re-check the relevant code before asking for a decision — don't defend stale analysis. If the challenge holds, set status: withdrawn with decision_notes explaining why the finding was wrong; do not ask the user to skip a finding you no longer believe. If the finding still holds, update evidence and re-ask. If the user asks for more detail, expand inline before re-asking. If the user says stop, abandon the remaining findings and skip to Step 6 with whatever has been decided so far.
Before moving to Step 6, present a short recap of the decisions collected — one line per finding (F2: <title> → <chosen action>), grouped by "Will fix" vs "Skipped". Ask for a final confirmation to proceed with implementation. Only after the user confirms, move to Step 6.
Now implement every fix the user chose, working from the ledger. Apply accepted Architecture/Design changes first when they would subsume or reshape smaller fixes; otherwise work highest impact first (Critical → Warning → Nit). Keep each change focused on its finding; do not bundle unrelated cleanup.
For any selected fix that changes runtime behavior, data contracts, user-visible behavior, persistence, API semantics, or other logic worth testing, use red-green TDD wherever a usable test harness exists or can reasonably be created. This includes bug fixes, correctness issues, crashes, race conditions, data integrity problems, and any requested non-defect change whose new behavior should be pinned down:
- Write or update a regression test before editing production code.
- Run the smallest test scope that includes the regression test.
- Confirm the test fails for the right reason: the failure must reproduce the reviewed defect, not a typo, missing import, setup error, or unrelated failure.
- Record the relevant failure output so the fix can be verified against it.
- Only after the red test is confirmed, edit the production code.
- Re-run the regression test and confirm it passes.
- Run the broader relevant test suite, formatter, linter, or type checker for the changed area.
Where a usable harness exists, do not skip the failing-first step for defects. If no harness exists or red-green is genuinely impractical for a given fix, note that explicitly and proceed rather than blocking the fix on impossible tests. If a test that should fail cannot be made to fail for the right reason, stop and explain the blocker before writing production code.
Documentation, naming, and mechanical cleanup do not need failing-first tests unless they expose behavior.
After implementing each fix, update the ledger: set status: fixed, fixed_at, and fix_summary. For skipped findings, ensure status: skipped and decision_notes capture why. Briefly note in chat which finding it resolved so the user can track progress against the recap. When all selected fixes are done, update the ledger rolling summary, then Close handled PR feedback for any fixed findings that qualify, and proceed to Step 7.
Close the loop on GitHub only for feedback this session explicitly tied to a ledger finding, presented in Step 5, accepted by the user, and fixed in Step 6. This is the only write path for PR comments in this skill. Mechanics, IDs, and minimize rules: ~/.agents/scripts/queries.sh closing-guide.
All must be true:
- The finding has
source_thread_id,source_review_id, orsource_comment_idrecorded at intake (ids fromqueries.shwith--allduring Step 2). - You presented it in Step 5 and the user chose to fix it (not Skip / withdrawn).
- The fix is on the branch (
status: fixedin the ledger) — push first if the reply should reference commits on the remote. - The source author is
jubishoporcoderabbitai(same allowlist asqueries.sh). Ignore all other authors.
Do not close when you skipped the finding, disagreed with the comment, fixed without Step 5 acceptance, or invented the finding without a recorded source id.
At the start of Step 6 (or when first linking a finding to a thread), record every source id you may close later. Only close ids on this checklist — not threads or summaries that appeared after your push.
queries.sh check-writes— if it fails, note in the close-out that GitHub feedback was left open; do not use the user's token.- For each qualifying
source_thread_id: write the reply body to a file, thenqueries.sh thread-reply --thread … --body-file …, thenqueries.sh thread-resolve --thread …. - For qualifying
source_review_id/source_comment_idfromcoderabbitaionly:queries.sh minimize --subject …perclosing-guide. queries.sh open-count(paginate with--afterwhenthreadsHasMoreis true).
Leave a jubishop thread open when the fix needs owner follow-up or the thread is ambiguous.
- Fixed — one line per finding: id, title, what changed, tests touched; note any linked
source_thread_idclosed on GitHub (or skipped because bot token was missing). - Skipped / withdrawn — declined or withdrawn findings; no re-litigation.
- GitHub feedback — which checklist thread ids were replied to and resolved; which
coderabbitaisummaries were minimized, if any; anything left open intentionally. - Validation — what tests, linters, formatters, or type checks ran and what did not run or failed.
- Next steps — suggest a commit message if fixes were made; commit only if the user asks; otherwise confirm the review session is complete. Commit the ledger file when it contains meaningful decisions or fixes from this session.
- PR-only. This skill does not review staged changes, unstaged changes, arbitrary commits, file paths, or the whole repo. If there is no PR on the current branch, stop immediately.
- The user's argument is supplemental context only — never use it to narrow or widen scope beyond the PR.
- The review ledger at
memory/pr_reviews/<pr-number>.mdpersists across sessions; read it at the start and update it throughout. Treat ledger files as intentional review history — commit them when meaningful. - PR comments are context by default. Load feedback via
~/.agents/scripts/queries.shwith--all; do not write to GitHub during intake. Disagreement with an open comment → skip silently. The only write path is Close handled PR feedback after Step 5 acceptance and a Step 6 fix for a finding with a recorded source id. - Respect dirty worktrees. Do not revert or overwrite unrelated user changes.
- Read enough surrounding code to avoid patch-only false positives.
- Prefer the project's existing patterns and test style.
- Keep remediation options concrete and scoped.
- Surface uncertainty clearly when evidence is incomplete.