Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Reviews pull requests with scope validation, requirements compliance, and line comments. Use when reviewing GitHub or GitLab PRs.
.claude/skills/athola-pr-review/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 308% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 426% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 468% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 370% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 256% | 0% |
--interactive)Review pull/merge requests with discipline: validate against original requirements, prevent scope creep, and route out-of-scope findings to issues on the detected platform.
Platform detection is automatic via leyline:git-platform. Use gh for GitHub, glab for GitLab. Check session context for git_platform:.
A PR review validates scope compliance, not code perfection.
The goal is to validate the implementation meets its stated requirements without introducing regressions. Improvements beyond the scope belong in future PRs.
review - use pensive:unified-review
review - use pensive:unified-review
Every finding must be classified:
| Category | Definition | Action | |----------|------------|--------| | BLOCKING | Bug, security issue, or regression introduced by this change | Must fix before merge | | IN-SCOPE | Issue directly related to stated requirements | Should address in this PR | | SUGGESTION | Improvement within changed code, not required | Author decides | | BACKLOG | Good idea but outside PR scope | Create GitHub issue | | IGNORE | Nitpick, style preference, or not worth tracking | Skip entirely |
BLOCKING:
IN-SCOPE:
SUGGESTION:
BACKLOG:
IGNORE:
Before looking at ANY code, understand what this PR is supposed to accomplish.
Note: Version validation (Phase 1.5) runs AFTER scope establishment but BEFORE code review. See modules/version-validation.md for details.
Search for scope artifacts in order:
bash # Spec-kit feature plans (preferred - structured implementation blueprints) find specs -name "plan.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null | head -100 # Legacy/alternative locations ls docs/plans/ 2>/dev/null # Root plan.md (may be Claude Plan Mode artifact from v2.0.51+) cat plan.md 2>/dev/null | head -100 Verification: Run the command with --help flag to verify availability.
bash find specs -name "spec.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null | head -100 cat spec.md 2>/dev/null | head -100 Verification: Run the command with --help flag to verify availability.
bash find specs -name "tasks.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null cat tasks.md 2>/dev/null Verification: Run the command with --help flag to verify availability.
bash # GitHub gh pr view <number> --json body --jq '.body' # GitLab glab mr view <number> --json description --jq '.description' Verification: Run the command with --help flag to verify availability.
bash # GitHub gh pr view <number> --json commits --jq '.commits[].messageHeadline' # GitLab glab mr view <number> --json commits Verification: Run the command with --help flag to verify availability.
Output: A clear statement of scope: > "This PR implements feature X] as specified in plan.md. The requirements are: > 1. requirement] > 2. requirement] > 3. requirement]"
If no scope artifacts exist, flag this as a process issue but continue with PR description as the baseline.
bash# GitHub gh pr diff <number> --name-only gh pr diff <number> gh pr view <number> --json additions,deletions,changedFiles,commits # GitLab glab mr diff <number> glab mr view <number>
Verification: Run the command with --help flag to verify availability.
Before detailed code review, check scope coverage:
Run version validation checks BEFORE code review.
See modules/version-validation.md for detailed validation procedures.
Quick reference:
--skip-version-check, label, or PR marker)All version mismatches are BLOCKING unless explicitly waived by maintainer.
Before diving into code, run the PR hygiene checks from modules/pr-hygiene.md:
change? Flag mixed commit types (feat, refactor, and fix), formatting commits bundled with logic, or changes spanning unrelated subsystems. Large PRs get 30% defect detection vs 75% for focused ones.
iterative AI generation without a cleanup pass? Look for redundant implementations, premature abstractions, incomplete refactors, and scope drift.
debug statements, or commented-out code that suggest the author did not read their own diff before sending?
Classify findings per modules/pr-hygiene.md severity tables.
Use pensive:unified-review on the changed files. For comment quality assessment, see modules/comment-guidelines.md.
Critical: Evaluate each finding against the scope baseline:
text**Verification:** Run the command with `--help` flag to verify availability. Finding: "Function X lacks input validation" Scope check: Is input validation mentioned in requirements? - YES → IN-SCOPE - NO, but it's a security issue → BLOCKING - NO, and it's a nice-to-have → BACKLOG
Verification: Run the command with --help flag to verify availability.
Run Skill(imbue:justify) on the PR changes to detect AI additive bias, test-logic tampering, and unnecessary complexity.
Key checks:
add/delete ratio (>5:1) that lack justification
not weakened to match broken implementations
was necessary and the change was the smallest fix
Classify justify findings using the scope framework:
| Justify Signal | Likely Classification | |---------------|----------------------| | Test logic tampered | BLOCKING | | High additive bias, no justification | IN-SCOPE | | Premature abstraction | SUGGESTION | | Compatibility shim | BACKLOG |
Include the additive bias score and Iron Law status in the Phase 6 report.
Check whether the PR touches existing design invariants. This is a judgment problem that models get wrong far too often: surface conflicts for human review rather than silently accepting or rejecting them.
Quick detection heuristic:
previously didn't interact?
existing one (two ways to do the same thing)?
bash# Check for structural pattern changes git diff --name-only HEAD...origin/master 2>/dev/null \ | rg "(interface|types|schema|model|base|core|contract)" \ || git diff --name-only HEAD...origin/master 2>/dev/null \ | grep -E "(interface|types|schema|model|base|core|contract)"
When a conflict is detected:
Do NOT resolve it. Add to the report as a special category:
| Category | Definition | Action | |----------|------------|--------| | INVARIANT | Change conflicts with an existing design decision | Escalate to human with 3-option analysis |
For each invariant conflict, present:
it was made (reference ADRs if available)
the invariant pays dividends elsewhere
inelegance; not every feature must be elegant
here's what a redesign would look like
Classification: INVARIANT findings are always BLOCKING, not because the code is wrong, but because the judgment call requires human input. Only the human reviewer can decide which of the three options is right.
Why this matters: Bad invariant decisions compound. A few wrong calls and the codebase becomes unsalvageable. This is not a context problem solvable with better documentation: it is a judgment problem that requires human wisdom.
For each BACKLOG item, create an issue on the detected platform:
bash# GitHub gh issue create \ --title "[Tech Debt] Brief description" \ --body "## Context Identified during PR #<number> review. ..." \ --label "tech-debt" # GitLab glab issue create \ --title "[Tech Debt] Brief description" \ --description "## Context Identified during MR !<number> review. ..." \ --label "tech-debt"
Verification: Run the command with --help flag to verify availability.
Ask user before creating: "I found N backlog items. Create issues? y/n/select]"
Structure the report by classification. Every BLOCKING and IN-SCOPE finding MUST include educational insights per modules/educational-insights.md: Why (the principle), Proof (link to best practice), and a Teachable Moment (generalized lesson). SUGGESTION findings include Why and optionally Proof. BACKLOG items need only a brief rationale.
markdown## PR #X: Title ### Scope Compliance **Requirements:** (from plan/spec) 1. [x] Requirement A - Implemented 2. [x] Requirement B - Implemented 3. [ ] Requirement C - **Missing** ### Blocking (1) 1. [B1] SQL injection via string concatenation - **Location**: `db/queries.py:89` - **Anchor**: `cursor.execute("SELECT * FROM t WHERE id = " + uid)` - **Issue**: User input interpolated directly into SQL - **Why**: String-interpolated SQL allows attackers to execute arbitrary queries (CWE-89). This is the #1 web application vulnerability per OWASP Top 10. - **Proof**: [OWASP SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) - **Teachable Moment**: Always use parameterized queries or an ORM. This applies everywhere user input reaches a database, cache, or search engine query. - **Fix**: Use parameterized query: `cursor.execute("SELECT * FROM t WHERE id = ?", (uid,))` ### In-Scope (1) 1. [S1] Missing validation for edge case - **Location**: `api.py:45` - **Anchor**: `def handle_request(payload):` - **Issue**: Empty input not handled per requirement - **Why**: Defensive validation at API boundaries prevents cascading failures in downstream logic. - **Proof**: [Postel's Law](https://en.wikipedia.org/wiki/Robustness_principle) - **Teachable Moment**: Validate inputs at system boundaries (API handlers, CLI args, file parsers) but trust internal function contracts. ### Suggestions (1) 1. [G1] Consider extracting helper function - **Why**: The repeated pattern on lines 30-35 and 72-77 violates DRY. Extracting it reduces future bug surface. - Author's discretion ### Backlog → GitHub Issues (3) 1. #142 - Refactor authentication module 2. #143 - Add caching layer 3. #144 - Update deprecated dependency ### Recommendation **APPROVE WITH CHANGES** Address B1 and S1 before merge.
--local)When --local [path] is passed, write the Phase 6 report to a local .md file instead of posting via API. Default path: .pr-review/pr-<number>-review.md. The file includes the review summary, test plan, and backlog items in a single document. Issue creation and PR description updates are skipped. Knowledge capture (Phase 7) still runs.
After generating the report, evaluate findings for knowledge capture into the project's review chamber.
Trigger: Automatically for findings scoring ≥60 on evaluation criteria.
bash# Capture significant findings to review-chamber # Uses memory-palace:review-chamber evaluation framework
Verification: Run the command with --help flag to verify availability.
Candidates for capture:
decisions/patterns/standards/lessons/Output: Add to report:
markdown### Knowledge Captured 📚 | Entry ID | Title | Room | |----------|-------|------| | abc123 | JWT over sessions | decisions/ | | def456 | Token refresh pattern | patterns/ | View: `/review-room list --palace <project>`
Verification: Run the command with --help flag to verify availability.
See modules/knowledge-capture.md for full workflow.
--interactive)Opt-in. Skip this phase unless the reviewer passed --interactive.
Runs the socratic loop that makes the "Don't: Merge Code You Cannot Explain" anti-pattern below executable. The reviewer opens each round by stating their understanding, asking their own question, or admitting a gap. The agent answers from the diff, then probes what the opening revealed.
Each exchange is graded pass, partial, or fail and written to gauntlet's shared progress store, tagged with one of gauntlet's seven knowledge categories. The same history steers /gauntlet challenges, so review sessions and challenge sessions compound. The selector favors untested categories first and weak ones second, so a failed probe raises that category's weight only against categories you have already answered well. Grade honestly: the weak-category bonus needs accuracy strictly below 0.5, so a lone partial earns no steer.
bashpython3 plugins/gauntlet/scripts/progress_tracker.py .gauntlet \ --developer "$(git config user.email)" --record '<answer-record-json>'
Probe results never change the merge recommendation. They add a Comprehension section to the report from Phase 6.
Full turn order, scoring table, category mapping, and the recording contract: modules/interactive-review.md.
A PR should be approved when:
it could fail (understanding check, not just "tests pass")
> "While you're here, you should also refactor X, add feature Y, and fix Z in adjacent files."
Do: Create backlog issues, keep PR focused.
> "This works but could be 5% more efficient with different approach."
Do: If it meets requirements and has no bugs, it's ready.
> "I prefer tabs over spaces."
Do: Use linters for style, reserve review for logic.
> "The file you imported from has some issues..."
Do: That's a separate PR. Create an issue if important.
> "Here's a test showing the old behavior was wrong."
Do: Write tests that break if your fix is reverted. Tests should protect against regressions in your code, not document why the change was needed. See modules/pr-hygiene.md Principle 4.
> "I also reformatted the file and fixed a typo in another module."
Do: One PR = one logical change. Formatting, refactors, and unrelated fixes belong in separate PRs. See modules/pr-hygiene.md Principle 2.
> "It works and the tests pass."
A PR where the author cannot explain how each changed section works and how it might fail is not ready to merge. This is especially true for AI-assisted code: generation speed creates the illusion of understanding.
Do: Before marking a PR ready, ask the reviewing agent to question you about the changed code: how each part works, what assumptions it makes, and what inputs would break it. Continue until you can answer without hesitation. Only merge code you own front-to-back.
This applies to self-reviews: run the same probe before requesting external review. Do not submit a PR for review that you yourself do not fully understand.
/pr-review --interactive runs this probe as a graded loop and records what you could not explain. See Phase 8 and modules/interactive-review.md.
pr-review:findings-verified)Every finding must cite a real location and a verbatim anchor. Write findings to .review/findings.json and confirm each citation resolves:
bashpython plugins/imbue/scripts/citation_verifier.py \ --findings .review/findings.json --repo-root .
Drop or label UNVERIFIED any finding the verifier fails (exit 1); only verified findings enter the report. See Skill(imbue:review-core) Step 5 and Skill(imbue:structured-output) for the schema.
/fix-pr: After review identifies issues, use this to address them/pr: To prepare a PR before reviewpensive:unified-review: For the actual code analysispensive:bug-review: For deeper bug hunting if neededscribe:slop-detector: For documentation AND commit message quality analysisscribe:doc-generator: For PR description writing guidelines (slop-free)For all changed .md files, invoke Skill(scribe:slop-detector):
--strict modeScan all PR commit messages for slop markers:
bashgh pr view <number> --json commits --jq '.commits[].messageBody' | \ grep -iE 'leverage|seamless|comprehensive|delve|robust|utilize|facilitate'
If slop found in commits: Add to SUGGESTION category with remediation guidance.
Apply scribe:slop-detector to PR body:
Location (file:line)and verbatim Anchor, and citation_verifier.py exits 0 or the unverified findings are dropped or labeled UNVERIFIED
--interactive: every hunk carrying a blocking or high-riskfinding was probed, or the reviewer ended the session
--interactive: each graded exchange appears in.gauntlet/progress/<developer>.json, and the report carries a Comprehension section whose row count matches the probes recorded
socratic probes graded and recorded to gauntlet's adaptive selector
gh api patterns for inline and summary PR comments| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 17,534 | 6,709 | -62% | 1 | 1 | 0% | 2,926 | 6,174 | +111% | 0 | 0 | — |
case-02 | fail→fail | 9,985 | 8,767 | -12% | 1 | 1 | 0% | 1,617 | 6,374 | +294% | 0 | 0 | — |
case-03 | fail→fail | 6,151 | 5,657 | -8% | 1 | 1 | 0% | 284 | 6,049 | +2030% | 0 | 0 | — |
case-04 | fail→fail | 6,274 | 27,062 | +331% | 1 | 1 | 0% | 798 | 6,806 | +753% | 0 | 0 | — |
case-05 | pass→pass | 12,418 | 12,720 | +2% | 1 | 1 | 0% | 1,877 | 7,949 | +323% | 0 | 0 | — |
case-06 | fail→fail | 4,578 | 9,313 | +103% | 1 | 1 | 0% | 616 | 6,099 | +890% | 0 | 0 | — |
case-07 | fail→pass | 9,770 | 4,579 | -53% | 1 | 1 | 0% | 1,604 | 6,551 | +308% | 0 | 0 | — |
case-08 | pass→pass | 9,126 | 4,124 | -55% | 1 | 1 | 0% | 1,457 | 6,541 | +349% | 0 | 0 | — |
case-09 | pass→pass | 12,163 | 5,723 | -53% | 1 | 1 | 0% | 1,916 | 6,732 | +251% | 0 | 0 | — |
case-10 | fail→pass | 8,743 | 6,504 | -26% | 1 | 1 | 0% | 1,309 | 6,879 | +426% | 0 | 0 | — |
case-11 | fail→pass | 7,033 | 4,775 | -32% | 1 | 1 | 0% | 1,140 | 6,478 | +468% | 0 | 0 | — |
case-12 | fail→pass | 9,256 | 5,239 | -43% | 1 | 1 | 0% | 1,391 | 6,532 | +370% | 0 | 0 | — |
case-13 | pass→pass | 11,885 | 3,284 | -72% | 1 | 1 | 0% | 1,205 | 6,271 | +420% | 0 | 0 | — |
case-14 | fail→pass | 10,479 | 2,058 | -80% | 1 | 1 | 0% | 1,711 | 6,092 | +256% | 0 | 0 | — |
case-15 | fail→fail | 4,706 | 3,049 | -35% | 1 | 1 | 0% | 693 | 6,339 | +815% | 0 | 0 | — |
case-16 | fail→pass | 11,531 | 5,138 | -55% | 1 | 1 | 0% | 1,757 | 6,687 | +281% | 0 | 0 | — |
case-17 | pass→pass | 7,537 | 3,552 | -53% | 1 | 1 | 0% | 1,178 | 6,340 | +438% | 0 | 0 | — |
case-18 | fail→pass | 7,043 | 4,020 | -43% | 1 | 1 | 0% | 1,133 | 6,403 | +465% | 0 | 0 | — |
case-19 | pass→pass | 8,994 | 4,487 | -50% | 1 | 1 | 0% | 1,324 | 6,392 | +383% | 0 | 0 | — |
case-20 | fail→pass | 7,394 | 3,920 | -47% | 1 | 1 | 0% | 1,091 | 6,388 | +486% | 0 | 0 | — |
case-21 | fail→pass | 7,338 | 3,855 | -47% | 1 | 1 | 0% | 1,122 | 6,371 | +468% | 0 | 0 | — |
case-22 | fail→pass | 12,145 | 2,261 | -81% | 1 | 1 | 0% | 1,840 | 6,069 | +230% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 18 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.