بنقرة واحدة
review-pr
// Walk through a structured PR review workflow. Use this skill when reviewing a pull request, triaging PRs, or starting a code review.
// Walk through a structured PR review workflow. Use this skill when reviewing a pull request, triaging PRs, or starting a code review.
Characterize a slow / stuck course-update worker on dashboard.wikiedu.org or outreachdashboard.wmflabs.org. Use this skill when asked to investigate why a course update is taking unusually long, hung, or running for many hours, or to estimate the scale-of-work of an in-flight update. Pure HTTP recon against public APIs — never SSH into prod.
Prepare a pull request description for the current branch following the WikiEduDashboard PR template. Use this skill when asked to prepare a PR, draft a PR description, or get a branch ready to open as a pull request.
Stage and commit changes with a well-formed commit message following the WikiEduDashboard format. Use this skill when asked to commit, make a commit, or create a commit.
Write browser-based Capybara feature specs for WikiEduDashboard controllers and views. Use this skill when asked to improve test coverage, write feature specs, add browser tests, or cover a controller with specs.
| name | review-pr |
| description | Walk through a structured PR review workflow. Use this skill when reviewing a pull request, triaging PRs, or starting a code review. |
A structured workflow for reviewing pull requests. Claude surfaces information and runs commands; the reviewer makes all judgments.
Invoke as /review-pr (to list open PRs) or /review-pr 6797 (specific PR).
If a PR number was given as $ARGUMENTS, use it. Otherwise:
gh pr list --state open --json number,title,author,createdAt,additions,deletions,changedFiles --template '{{range .}}#{{.number}} {{.title}} ({{.author.login}}, +{{.additions}}/−{{.deletions}}, {{.changedFiles}} files, {{timeago .createdAt}}){{"\n"}}{{end}}'
Ask the reviewer which PR to review.
Once a PR is selected, gather orientation in parallel:
PR metadata and description:
gh pr view <number> --json title,author,body,labels,createdAt,headRefName,baseRefName,statusCheckRollup
CI status — summarize pass/fail/pending from statusCheckRollup.
Changed files overview:
gh pr diff <number> --name-only
Diff size (use diffstat or pipe through wc; gh pr diff
does not support --stat):
gh pr diff <number> | diffstat
Present a concise orientation summary: what the PR does (from the description), who wrote it, CI status, and scope (files/lines changed).
After gathering orientation, check for existing reviews from us:
gh api repos/WikiEducationFoundation/WikiEduDashboard/pulls/<number>/reviews \
--jq '[.[] | select(.user.login == "ragesoss")] | sort_by(.submitted_at) | last | {state, submitted_at: .submitted_at, commit_id: .commit_id}'
Also fetch our prior review comments and PR comments:
gh api repos/WikiEducationFoundation/WikiEduDashboard/pulls/<number>/comments \
--jq '[.[] | select(.user.login == "ragesoss")] | .[].body'
gh pr view <number> --json comments --jq '.comments[] | select(.author.login == "ragesoss") | .body'
If a prior review exists, compare the review's commit_id against the
current HEAD of the PR branch. If there are new commits after the
reviewed commit, this is a re-review. Switch to the re-review
workflow (below) instead of Phases 2–5.
If there is no prior review from us, proceed to Phase 2 as normal.
The goal is to catch issues worth flagging early, before investing in a deep review. Check each of the following and report findings clearly.
[WIP]? If so, note it — may not be ready for review.statusCheckRollup or link.)Check whether the author has earlier related PRs (closed or open) with review comments from the reviewer:
gh pr list --author <login> --state closed --limit 10 --json number,title,additions
If a large or related prior PR exists, fetch its review comments with
gh api repos/.../pulls/<number>/comments and summarize any feedback
that is still relevant to the current PR.
Present triage findings as a checklist. Ask the reviewer:
Any of these worth sending quick feedback on before continuing, or should we proceed to the full review?
If the reviewer wants to send early feedback, help them draft a comment (see "Posting review comments" below for tone/attribution rules), then stop or continue as directed.
Check out the PR to a local review branch:
gh pr checkout <number> --branch review/<number>
If there are local uncommitted changes, stash or warn before proceeding.
Merge current master into the review branch so that testing happens against the latest code, not just the PR's base:
git merge master --no-edit
If there are merge conflicts, report them to the reviewer.
If the PR adds or changes JS dependencies (package.json changed),
run yarn install. Always run yarn build and confirm it succeeds
without errors — a broken build is itself a review finding. If the
build fails, report the errors before continuing.
Before writing any new specs, run existing specs that cover the same area as the PR. This establishes whether the PR introduces regressions in previously-passing tests.
Identify affected spec files by mapping changed files to their specs:
app/controllers/foo_controller.rb → spec/controllers/foo_controller_spec.rbapp/presenters/foo_presenter.rb → spec/presenters/foo_presenter_spec.rbapp/views/foo/bar.html.haml → spec/features/*foo* or spec/features/*bar*app/services/foo.rb → spec/services/foo_spec.rbAlso include any spec the PR itself modifies. Run them all:
bundle exec rspec <affected_spec_files>
Compare results to master if any fail — check out master, run the same specs, and report whether failures are pre-existing or PR-introduced. PR-introduced failures are review findings with the same weight as bugs found in code review.
For PRs with user-facing changes, write exploratory feature specs that exercise the new functionality. Exploratory specs serve three purposes: verifying the feature works, giving the reviewer a visual demo, and — when code-reading has surfaced a suspected behavior change — converting that reasoned finding into reproducible fact. A spec that exercises the contrasting cases (before/after, affected/unaffected) turns an argument about code paths into a demonstration the author can rerun. When a spec serves this third purpose, consider including it in the review comment (or linking to it) so the finding is harder to dismiss. (The reviewer can skip the exploratory spec entirely if the PR is trivial, but the default is to write one.)
spec/features/<descriptive>_spec.rb)
with focused examples covering the key user flows and edge cases.
Seed with production-realistic data shapes, not minimal or
arbitrary values: a spec that passes against integer seeds like
1000 can hide a bug that only fires against the comma-formatted
strings production actually stores. This matters most when the PR
touches input types, validation, serialization, or display
formatting. Sources for realistic shapes: existing factories and
fixtures, db/seeds.rb, other specs that exercise the same model,
or — if none of those is conclusive — ask the reviewer.bin/feature-spec spec/features/<file>_spec.rb
HEADED=1 bin/feature-spec spec/features/<file>_spec.rb
The exploratory spec can also be shared with the PR author if useful.
For purely backend PRs, write unit specs instead of feature specs if the PR's own spec coverage is thin. The same three purposes apply, especially the third — a contrasting-cases unit spec is just as useful for pinning down a suspected behavior change. For configuration-only or trivial changes, skip to Phase 5.
Run linters on the checked-out branch:
# Ruby files changed in the PR
bundle exec rubocop <changed .rb files>
# JS/JSX files changed in the PR
yarn eslint <changed .js/.jsx files>
If the PR diff includes any file in db/migrate/, work through this
checklist explicitly before continuing the rest of the review. Reach a
clear verdict on in-deployment viability before moving on; if anything
is unknown (DB version, table size, etc.), ask the reviewer rather than
glossing over it.
add_column, nullable + literal default is
the textbook safe form.update_all, each,
or find_each over rows? Inline backfills hold the migration open
and block writes; large tables need batched backfills run separately.ALGORITHM=INSTANT
or INPLACE. INSTANT ADD COLUMN (MariaDB 10.3+, MySQL 8.0.12+) makes
nullable+default column adds metadata-only; without it the same
migration can rewrite the table. Check both Wiki Ed Dashboard
(production stage) and Peony (peony stage) — they're independent
hosts and may run different MariaDB versions. SELECT VERSION(); on
each is the cheap check.course_wiki_timeslices, revisions,
course_user_wiki_timeslices, article_course_timeslices) need a
fast-path algorithm or out-of-band execution.State a verdict — "safe to ship inside a normal deploy" or specifics about what to do differently — before continuing.
Walk through the diff one logical group at a time. For each group of related changes:
gh pr diff <number> or read the changed files).After presenting each group, pause for the reviewer's questions or comments before continuing.
By this point, the Phase 3 baseline specs and Phase 4 exploratory specs have already run. This phase covers additional testing beyond that baseline.
Run the PR's own specs. If the PR includes spec files that weren't already run in the Phase 3 baseline, run them now:
bundle exec rspec <pr_spec_files>
Offer additional testing options:
bundle exec rspec (takes a while). Recommended
for PRs that touch shared code (helpers, presenters, base classes).Report all test results clearly. If there are failures, determine whether they're PR-introduced or pre-existing (by comparing to master) and report accordingly.
This phase applies to both first-time reviews and re-reviews.
Review the entire PR diff (not just the delta, for re-reviews) and produce a structured assessment of how thoroughly the changeset is tested and where risk remains. This is for the reviewer's benefit, not for posting.
For each area of the PR, classify into three buckets:
Well-tested — code paths exercised by the PR's own specs or the existing test suite. Note which specs cover which functionality.
Exploratory-only — covered by specs written during review but not by the PR's own specs. These paths will lose coverage if the exploratory specs aren't adopted by the author.
Untested — no spec coverage at all. For each untested area, assess:
Present this to the reviewer and ask whether any higher-risk untested areas warrant writing additional specs or flagging to the author before approving.
Present a checklist covering each of these. Mark each as pass, fail, or not applicable. Failed items aren't necessarily blocking — the reviewer decides — but all must be explicitly assessed.
yarn build completes without errorsSummarize the review status:
If the reviewer wants to leave a review, help draft it (see below), then submit via:
gh pr review <number> --approve --body "..."
gh pr review <number> --request-changes --body "..."
gh pr review <number> --comment --body "..."
After a --request-changes review, convert the PR to draft so it
leaves the review queue until the author pushes fixes:
gh pr ready <number> --undo
Do not do this for --comment or --approve reviews. When the
author marks the PR ready for review again, that's the signal to
re-review.
Clean up: delete any temporary exploratory spec files, then switch back to the previous branch:
git checkout master
When Phase 1 detects a prior review with new commits since, use this workflow instead of Phases 2–5. Phase 7 (Wrap up) still applies afterward.
Identify what changed since the last review:
# Commits since the reviewed commit
gh api repos/WikiEducationFoundation/WikiEduDashboard/pulls/<number>/commits \
--jq '[.[] | {sha: .sha[0:10], message: .commit.message | split("\n")[0], date: .commit.author.date}]'
Note which commits are new (after the prior review's submitted_at).
Fetch the diff scoped to just the new changes:
git diff <reviewed_commit_sha>..HEAD
Present the reviewer with: how many new commits, what they claim to address (from commit messages), and the size of the delta.
Parse the prior review comments and PR comments into a list of specific issues raised. For each issue:
Present findings as a table:
| Issue | Status | Notes |
|---|---|---|
joins should be left_joins | Resolved | Fixed in abc1234 |
| Inline JS should be extracted | Partial | Extracted to file but inline blocks remain |
| ... | ... | ... |
Ask the reviewer if the assessments look right before continuing.
Walk through the new-commits diff (from Step 1) looking for issues introduced by the fixes themselves. Common patterns:
Apply the same review lens as Phase 5 (security, performance, side effects, etc.) but scoped to the delta only. Don't re-review code that was already covered in the original review and hasn't changed.
Check out the PR branch (or update the existing checkout):
gh pr checkout <number> --branch review/<number>
git merge master --no-edit
If package.json changed in the new commits, run yarn install.
Always run yarn build and confirm it succeeds without errors.
Run existing specs for affected areas (same as Phase 3 baseline). Map changed files to their corresponding spec files and run them. Compare failures to master to distinguish PR-introduced regressions from pre-existing issues.
Rerun the PR's own specs. If the PR includes spec files, run them:
bundle exec rspec <spec files from the PR>
Report pass/fail. Failures here may indicate regressions introduced by the fix commits.
Rerun exploratory specs. If exploratory specs were written during the original review, rerun them to see if previously-failing examples now pass — these are a direct check on the claimed fixes. If some still fail, those are unresolved issues; add them to the table from Step 2. If the new commits introduced functionality not covered by the existing specs, offer to extend them.
Assess and fill test coverage gaps. Check whether the new commits added or changed logic that lacks spec coverage. In particular:
If significant coverage gaps exist — whether from the original PR or introduced by the fix commits — write specs to fill them, following the same approach as Phase 4 (exploratory specs). These serve the review: they verify the fixes work, expose regressions, and give the reviewer confidence in the code. Specs that the author should adopt can be shared in the follow-up comment.
If no exploratory specs exist from the original review and the PR includes no spec files, this is a significant gap. Write specs that cover the core functionality before proceeding — don't move on without being able to verify the code works.
Compose a follow-up comment structured as:
Follow the same tone and attribution rules as "Posting review comments" below. After drafting, show it to the reviewer for approval before posting.
After posting, proceed to Phase 7 (Wrap up). Phase 6 (Testing) is usually unnecessary since Step 4 already covers spec runs, but offer it if the reviewer wants broader testing (e.g., full suite, manual testing).
All review comments and PR feedback posted via this skill must follow these rules:
How to use feedback: At the start of a review, include a note about how we intend AI-driven review feedback to be used — not to be automatically trusted or blindly acted upon, but good to read, understand and use or ignore based on the developer's own judgment.
Approval required: Never post a review or comment without first
showing the full draft to the reviewer and receiving explicit approval.
Always wait for confirmation before running gh pr review or
gh pr comment.
Tone: Impersonal and direct. No first-person ("I found..."). No chatbot pleasantries ("Nice work!", "Great PR!"). Use passive voice or refer to "the code", "the session", "Claude Code" where needed. Frame findings as observations that warrant verification, not as authoritative conclusions — AI analysis is provisional and may be wrong.
Attribution: Every posted comment must end with an italicized attribution line that honestly characterizes the human involvement. Include: how much wall-clock time the reviewer spent, roughly how many interactions they had with Claude Code, what they actually reviewed vs. what they approved without deep verification, and — if local verification happened — what specifically was verified ("ran X locally", "reproduced Y via a new spec", "checked production state"). The goal is to let the PR author calibrate how much weight to give the feedback; named verifications calibrate more sharply than time and interaction counts alone. Examples:
Drafted in a Claude Code session (~30 min, ~15 interactions).
Sage directed the triage and code review phases, verified the
joins bug independently, and reviewed the full comment before
posting. Other findings were spot-checked but not all individually
verified.
Drafted in a Claude Code session (~5 min, 3 interactions). Sage approved posting after a quick read-through but did not independently verify the findings.
If the comment includes AI-generated code (such as an exploratory spec), say so explicitly and note whether the reviewer ran or reviewed that code.
Link: After posting any review or comment, fetch and display the URL so the reviewer can click through:
gh api repos/WikiEducationFoundation/WikiEduDashboard/pulls/<number>/reviews --jq '.[-1].html_url'