Analyze a PR from any repository and extract quality signals — description, reviews, scope, tests, CI, guidelines, outcome
Scanned 9/2/2026
Install to Claude Code
npx -y skills add kookr-ai/kookr --skill oss-pr-critic --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Oss Pr Critic?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kookr-ai-oss-pr-critic)More formats (shields.io, HTML) on the badges page.
---
name: oss-pr-critic
description: Analyze a PR from any repository and extract quality signals — description, reviews, scope, tests, CI, guidelines, outcome
keywords: oss, pr, critic, review, analysis, signals, quality, open source, contribution
related: [oss-pr-plan, oss-pr-state, oss-pr-threshold, oss-pr-distill]
---
# OSS PR Critic
Deep-read a PR from any repository and extract structured quality signals. Generalized version of `codex-pr-critic`.
## When to Use
Invoked for each PR in the batch selected by `oss-pr-plan`.
## Non-Negotiable Rules
| # | Rule | Violation Example | Correct Pattern |
|---|------|-------------------|-----------------|
| 1 | Read the full PR body, not just title | Scoring based on title alone | `gh pr view -R {repo} {number} --json body,title,reviews,comments` |
| 2 | Read ALL review comments | Only reading the first review | Fetch reviews AND review comments (inline) |
| 3 | Distinguish review types | Treating all comments as equal | Separate: approval, changes_requested, comment-only, inline nit |
| 4 | Note the outcome | Ignoring whether PR was merged or abandoned | merged_at != null means merged; otherwise rejected/abandoned |
| 5 | Don't editorialize prematurely | Writing "this is a bad PR" | Record signals objectively; patterns emerge during distillation |
| 6 | Load recon report for repo conventions | Judging without knowing repo rules | `cat ~/.claude/{repoSlug}-recon/recon-report.md` if it exists |
## Parameters
- **repoFullName**: `owner/repo`
- **repoSlug**: URL-safe slug
## Data Collection Per PR
```bash
REPO="{{repoFullName}}"
# PR metadata
gh pr view -R ${REPO} {number} --json number,title,body,state,mergedAt,closedAt,author,additions,deletions,changedFiles,labels,createdAt,baseRefName,headRefName
# Reviews (approval/rejection decisions)
gh api "repos/${REPO}/pulls/{number}/reviews" --jq '.[] | {user: .user.login, state: .state, body: (.body[:300])}'
# Review comments (inline code comments)
gh api "repos/${REPO}/pulls/{number}/comments?per_page=100" --jq '.[] | {user: .user.login, body: (.body[:300]), path: .path, created_at: .created_at}'
# PR comments (general discussion)
gh api "repos/${REPO}/issues/{number}/comments?per_page=50" --jq '.[] | {user: .user.login, body: (.body[:300]), created_at: .created_at}'
```
## Signal Extraction Framework
### 1. Description Quality
- Does it follow the repo's PR template (from recon report)?
- Does it reference an issue?
- Is the motivation clear?
- Are implementation choices explained?
### 2. Review Dynamics
- How many review rounds before merge/close?
- Were changes requested? How many times?
- Feedback categories: **Blocking**, **Suggestion**, **Nit**, **Question**, **Praise**
- Did the author respond constructively?
### 3. Scope & Size
- Lines added/deleted, files changed
- Focused (single concern) or sprawling?
- Smaller, focused PRs (<300 lines) typically get reviewed faster
### 4. Test Coverage
- Tests included?
- Edge cases or just happy path?
- Tests mentioned in PR description?
### 5. Commit Discipline
- Atomic commits or single squash?
- Conventional commit messages?
- Does each commit compile?
### 6. CI Compliance
- CI pass on first push?
- Lint/format issues?
### 7. Contribution Guidelines Adherence
- CLA signed (if required per recon)?
- Issue linked (if required)?
- PR template filled out?
- Respects stated priorities?
### 8. Outcome Classification
| Outcome | Meaning | Learning Value |
|---------|---------|----------------|
| **Merged quickly** (<3 days, <2 rounds) | Well-executed | What "good" looks like |
| **Merged after discussion** (>3 days or >2 rounds) | Complex but accepted | How to navigate feedback |
| **Closed by author** | Author gave up | What discourages contributors |
| **Closed by maintainer** | Didn't meet standards | What maintainers reject |
| **Stale-closed** | Auto-closed | Process friction signals |
## Output Format
```markdown
### PR #{number}: {title}
- **Author**: {login} | **Outcome**: {merged/closed/stale} | **Duration**: {days}
- **Size**: +{additions}/-{deletions} across {files} files
- **Reviews**: {count} rounds, {approved/changes_requested/comment}
- **Description**: {good/adequate/poor/missing} — {specific note}
- **Tests**: {included/missing/partial} — {specific note}
- **Issue link**: {yes/no} — {issue number if yes}
- **CI**: {passed-first/failed-then-fixed/never-passed}
- **Guidelines adherence**: {good/partial/poor} — {specific note}
- **Key signals**:
- {signal 1}
- {signal 2}
- **Lesson**: {one-sentence takeaway}
```
## Deeper Analysis for Rejections
Rejected PRs (closed by maintainer, closed by author, stale-closed) contain the most lessons. They deserve **disproportionately more investigation** than merged PRs. For every non-merged PR, add these steps beyond the standard 8 dimensions:
1. **Fetch competing/superseding PRs.** If the close reason references another PR, fetch its metadata. Compare scope, description quality, and changeset size side by side. The contrast is the lesson.
2. **Trace the full comment timeline.** Quote each step: reviewer closes → author responds → community weighs in. The escalation arc (or graceful acceptance) is itself a signal.
3. **Extract technical rebuttals.** If community members debunked the PR's claims, include the specific technical reasoning (not just "community disagreed").
4. **Include CI failure details.** Don't write "CI failed twice" — include the actual error messages from rust-log-analyzer or equivalent bots. The error type (syntax error vs. test failure vs. infra flake) matters.
5. **Diagnose the root failure mode.** Was it scope (too big), overlap (duplicate work), quality (untested), framing (oversold), or fit (wrong repo/area)? Name it explicitly.
## Edge Cases
- **Very large PRs** (>1000 lines): Focus on review dynamics, not code details
- **Bot PRs**: Should have been filtered by plan phase; skip if encountered
- **Maintainer PRs**: Note different review expectations (often self-merged or 1 approval)
- **First-time contributors**: Note extra guidance/friction signals
- **Reverted PRs**: High-value signal — what went wrong post-merge?
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!