From correctless
Reviews PRs/MRs for merge decisions: verifies scope vs issues, convention compliance from CONTRIBUTING/CI configs, contributor history, maintenance burden, and security. Invoke with /cmaintain {number}.
npx claudepluginhub joshft/correctless --plugin correctlessThis skill is limited to using the following tools:
You are the maintainer review agent. Your job is NOT to ask "is this code good?" — `/cpr-review` does that. Your job is to ask **"should I merge this?"** That's a different question. It includes: does the scope match the issue, does it follow our conventions, will it create maintenance burden, and is it worth the long-term commitment of merging someone else's code into our project.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
You are the maintainer review agent. Your job is NOT to ask "is this code good?" — /cpr-review does that. Your job is to ask "should I merge this?" That's a different question. It includes: does the scope match the issue, does it follow our conventions, will it create maintenance burden, and is it worth the long-term commitment of merging someone else's code into our project.
Invoke with: /cmaintain {PR number}
Maintainer reviews take 10-20 minutes. The user must see progress throughout.
Before starting, create a task list:
Between each step, print a 1-line status: "Standards loaded — CONTRIBUTING.md found, jest tests, conventional commits. Loading PR context..." Mark each task complete as it finishes.
Read the project's standards — this is the baseline every contribution is measured against:
CONTRIBUTING.md or CONTRIBUTING — contribution process, requirements, conventions.github/PULL_REQUEST_TEMPLATE.md, root, or .gitlab/merge_request_templates/.github/CODEOWNERS, CODEOWNERS (root), docs/CODEOWNERS. On GitLab, check root and docs/..eslintrc*, .prettierrc*, biome.json, .golangci-lint.yml, ruff.toml, rustfmt.toml, .editorconfig.github/workflows/, .gitlab-ci.yml — what checks run, what will fail.correctless/ARCHITECTURE.md if it exists — patterns, conventions, prohibitions.correctless/AGENT_CONTEXT.md if it exists — project context, common pitfallsDetect platform from git remote get-url origin:
gh pr view {number} --json title,body,files,additions,deletions,author,baseRefName,headRefNameglab mr view {number}Extract:
Closes #, Fixes #, Resolves # references)gh issue view {number} / glab issue view {number} — read the issue descriptionContributor history — calibrates review depth, not whether to review:
gh pr list --author={user} --state=merged --limit=10glab mr list --author={user} --state=merged --limit=10Fetch the diff:
gh pr diff {number}glab mr diff {number}If the remote is not GitHub or GitLab (Bitbucket, Gitea, Azure DevOps, self-hosted): neither CLI can fetch the PR. Ask the user to provide the PR diff and description manually. Proceed with all review steps using the provided content.
If both CLIs are installed but neither matches the remote: same — ask for manual input.
Compare the PR's changes against the linked issue:
Scope expansion — the most common PR problem:
Scope reduction:
Proportionality:
If no issue is linked: note this — "No issue linked. Scope cannot be verified against a requirement."
Check every changed file against the project's standards from Step 1:
Code style: Run the project's formatter on changed files. Check for diffs. "3 files have formatting issues." Specific files and lines.
Test style: Do new tests match existing test patterns? Same framework, same describe/it vs test(), same naming, same assertion library, same mock patterns? Flag deviations: "Tests use test() but the project uses describe/it pattern."
Commit format: Do commits match the project's convention? Conventional commits? Signed? DCO sign-off? Flag: "{N} commits don't follow the project's conventional commit format."
Error handling: Does new code follow the project's error patterns? Custom error types, wrapping conventions, logging patterns?
File placement: Are new files in the right directories per project structure?
Import patterns: Match existing patterns (barrel files, path aliases, ordering)?
Template compliance: Did the contributor fill in the PR template completely? Flag empty sections.
This is quality through a maintenance lens, not a code review lens. Each check below answers: "If I merge this, what am I committing to owning?"
Test coverage:
{coverage command} -- {changed files}Test quality:
New dependencies:
Code complexity:
Documentation:
This is the maintainer-specific lens that no other skill has. For each item, assess the long-term cost of merging:
Pattern divergence: Does this PR introduce patterns that don't exist elsewhere in the codebase? New error handling approach? New testing pattern? New abstraction style? Each divergence is a future maintenance cost — someone will have to decide which pattern to follow. Flag: "This introduces a {pattern} that doesn't exist elsewhere. {N} files currently use {existing pattern}."
Dependency cost: Each new dependency is a commitment to track updates, handle CVEs, and manage breaking changes. Is the dependency justified? Flag with specifics: "{package} adds {N} transitive dependencies and is last updated {date}."
API surface expansion: Does this add new public API? Every public function, endpoint, or config option is a backwards-compatibility commitment. Flag: "This adds {N} new public {functions/endpoints/config options}."
Complexity budget: Is the code understandable by someone who didn't write it? Will this be the module nobody wants to touch in 6 months? Flag: "This function is {N} lines with {M} branches — consider requesting the contributor simplify it."
Bus factor risk: Complex changes from first-time contributors are higher risk — if they don't stick around, you maintain their code. Flag for first-time contributors with complex changes: "This is a complex change from a first-time contributor. If bugs surface, the maintainer team will own the fix."
Overall burden: Rate as low / medium / high with explanation.
Quick security scan focused on "did this contribution introduce a vulnerability":
npm audit / pip audit / cargo audit / govulncheck if applicable.This is lighter than /cpr-review's full security checklist — focused on what the contribution introduced, not a full audit.
Present the review to the maintainer:
## Maintainer Review: PR #{number} — {title}
### Contributor
{username} — {first-time contributor | N previous merged PRs}
### Scope
{matches issue | expanded beyond issue (details) | partial implementation (details) | no issue linked}
### Convention Compliance
{all pass | N issues:}
- {file:line — what's wrong and what the project convention is}
### Quality
- **Tests**: {adequate coverage with edge cases | insufficient — missing {details} | no tests added}
- **Docs**: {updated | needed but missing | N/A}
- **Dependencies**: {none new | N new — for each: name, purpose, justified/questionable}
### Maintenance Burden: {low | medium | high}
{1-3 sentences explaining what merging this commits you to maintaining}
{Pattern divergences, dependency costs, API surface, complexity concerns}
### Security: {clear | N concerns}
{details if concerns found}
### Recommendation: {merge | merge with minor fixes | request changes | split PR | close}
{1-2 sentences justifying the recommendation}
### Suggested Review Comments
{Pre-written comments the maintainer can post. Each includes:}
- **File and line** (or general)
- **Comment text** (ready to copy-paste, polite and constructive)
- **Priority** (blocking vs suggestion)
For first-time contributors: comments explain the project's convention, not just flag the violation.
For regular contributors: comments are shorter, assume familiarity.
Example comment entry:
- **src/auth/middleware.ts:84** — Blocking: "This bypasses the project's error-wrapping convention. All errors from this layer should use `AppError.from(err, 'auth.middleware')` before propagating. See `src/users/service.ts:61` for the pattern."
- **General** — Suggestion: "Great test coverage on the happy path. Could you add a test for the case where the token is expired? The existing tests in `auth.test.ts` use the `expiredTokenFixture` helper."
Present to the maintainer for review before posting.
After the maintainer reviews and approves the output:
gh pr review {number} --comment --body "{review}" or gh pr comment {number} --body "{review}"glab mr note {number} --message "{review}"The maintainer can edit the review before posting. Never post without explicit approval.
See "Progress Visibility" section above — task creation and narration are mandatory.
After any subagent completes, capture total_tokens and duration_ms. Append to .correctless/artifacts/token-log-{slug}.json. If .correctless/artifacts/ doesn't exist, create it with mkdir -p .correctless/artifacts/ first.
If the file doesn't exist, create it with the first entry. /cmetrics aggregates from raw entries — no totals field needed.
If mcp.serena is true in workflow-config.json, use Serena MCP for symbol-level code analysis during contribution review:
find_symbol instead of grepping for function/type namesfind_referencing_symbols to trace callers and dependencies to assess maintenance burdenget_symbols_overview for structural overview of a modulereplace_symbol_body for precise edits (not used in this skill — maintainer review is read-only)search_for_pattern for regex searches with symbol contextFallback table — if Serena is unavailable, fall back silently to text-based equivalents:
| Serena Operation | Fallback |
|---|---|
find_symbol | Grep for function/type name |
find_referencing_symbols | Grep for symbol name across source files |
get_symbols_overview | Read directory + read index files |
replace_symbol_body | Edit tool |
search_for_pattern | Grep tool |
Graceful degradation: If a Serena tool call fails, fall back to the text-based equivalent silently. Do not abort, do not retry, do not warn the user mid-operation. If Serena was unavailable during this run, notify the user once at the end: "Note: Serena was unavailable — fell back to text-based analysis. If this persists, check that the Serena MCP server is running (uvx serena-mcp-server)." Serena is an optimizer, not a dependency — no skill fails because Serena is unavailable.
/cpr-review or /caudit. This step catches obvious issues introduced by the contribution.templates/redaction-rules.md — sanitize paths, credentials, hostnames, session IDs.