Re-runnable pre-PR quality gate for the current branch. Composes two existing passes over the branch diff: a broad pr-reviewer pass (read-only review via the branch's open PR, which `pr-reviewer` requires) and a code-quality simplify pass (applies Class M mechanical refactors behind a confidence ≥ 90 % gate, reverting on failure). Run bare for the full review + simplify works; scope it with `review`, `simplify`, or the light `quick` mechanical pass. Commits each pass separately for traceabili...
Scanned 9/3/2026
Install to Claude Code
npx -y skills add mthines/agent-skills --skill polish --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Polish?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mthines-polish)More formats (shields.io, HTML) on the badges page.
---
name: polish
description: >
Re-runnable pre-PR quality gate for the current branch. Composes two existing
passes over the branch diff: a broad pr-reviewer pass (read-only review via
the branch's open PR, which `pr-reviewer` requires) and a code-quality
simplify pass
(applies Class M mechanical refactors behind a confidence ≥ 90 % gate,
reverting on failure). Run bare for the full review + simplify works; scope it
with `review`, `simplify`, or the light `quick` mechanical pass. Commits each
pass separately for traceability (`--no-commit` to skip). Use standalone any
time mid-development to clean a branch. Note that `/create-pr` delegates its
quality step to `review-loop` (the bounded convergence loop) post-draft, and
the `review-loop` skill calls only `polish simplify` — never full `polish`.
Triggers on "polish my branch", "clean this up before the PR", "review and
simplify", "tidy up", "prep my branch", "/polish".
disable-model-invocation: false
argument-hint: '[review|simplify|quick] [--no-commit] [--critical]'
license: MIT
metadata:
author: mthines
version: '2.0.0'
workflow_type: command
tags:
- code-quality
- review
- simplify
- refactor
- pre-pr
- branch-cleanup
- pr-reviewer
- orchestrator
---
# Polish — Re-runnable Branch Quality Gate
Get a branch into clean, reviewable shape **before** it goes up for review — and run it again any time you've made a lot of changes and want to tidy up.
This skill is an **orchestrator**. It does not contain quality rules of its own; it composes two existing pieces over the current branch diff:
1. The **`pr-reviewer` agent** — broad review via the branch's open PR (read-only; findings are surfaced for you to act on, applied via `implement-suggestion`). Requires an open PR — `pr-reviewer` has no PR-less mode. If no PR is open, Pass A is skipped and you are told to open a draft PR via `/create-pr` first.
2. The **`code-quality` skill in `simplify` mode** — applies Class M *mechanical* refactors one at a time behind `Skill("confidence", "code") ≥ 90 %` and a scoped fast-check, reverting any that fail. Class J (judgment) recipes stay as proposals.
`/create-pr` delegates its post-draft quality step to `review-loop` (the bounded convergence loop), which calls only `polish simplify` — never full `polish`. You can run `polish` standalone at any point for a pre-draft local check.
## Modes
Parse the **first token** of `$ARGUMENTS`. Everything else is a flag.
| Mode | Trigger | What runs |
| -------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **full** *(default)* | No mode token | `review` pass (pr-reviewer, read-only), then `simplify` pass. The "do the works" button. |
| `review` | First token `review` | `pr-reviewer` pass only — read-only review surfaced as findings for you to act on. |
| `simplify` | First token `simplify` | `code-quality` simplify pass only — apply Class M mechanical refactors. |
| `optimize` | First token `optimize` | Optimality pass only — `Skill("optimize-approach", "apply")` over the branch diff (gated approach rewrite). |
| `quick` | First token `quick` | Light mechanical pass only (comments, naming, dead code). No pr-reviewer pass, no structural refactors. |
In `full` and `review` modes the optimality lens runs **inside** the `pr-reviewer` pass (which runs `optimize-approach` in report mode at Step 2.4c). The standalone `optimize` mode above is for running only that lens without the rest of the review pass.
Flags (compose with any mode):
| Flag | Effect |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| `--no-commit` | Leave all changes in the working tree instead of committing each pass. Use mid-development to keep iterating. |
| `--critical` | Pass `--critical` through to the `pr-reviewer` agent (adversarial pre-mortem). Ignored by `simplify` / `quick`. |
| `--no-optimize` | Pass `--no-optimize` through to the `pr-reviewer` agent — skip the default-on optimality lens (Step 2.4c). Ignored by `simplify` / `quick`. |
**Order is fixed in full mode: `review` first, then `simplify`.** The review pass surfaces correctness and obvious cleanups; simplify then applies structural refactors to the already-cleaner code, so confidence gates evaluate the final shape.
## Step 0: Resolve mode and preconditions
```bash
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { echo "polish: not a git repo"; exit 1; }
BRANCH=$(git rev-parse --abbrev-ref HEAD)
git fetch origin main --quiet 2>/dev/null || git fetch origin --quiet 2>/dev/null
```
Refuse to run on the default branch — there is no branch diff to polish:
```bash
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
echo "polish: on $BRANCH — check out a feature branch first."
exit 1
fi
```
Establish the scope and whether there's anything to do:
```bash
git diff --name-only origin/main...HEAD # files changed on this branch
git diff --stat origin/main...HEAD
```
If the branch diff is empty, print `polish: no changes vs origin/main — nothing to do.` and exit.
If the branch diff is **non-code only** (docs, lockfiles, generated artefacts, asset binaries — decide from the file list, not the line count), print one line and exit: `polish: branch diff is non-code only — skipping.`
## Step 1: Working-tree check
```bash
git status --porcelain
```
- **Clean tree (empty output):** ideal. Each pass's commit contains only that pass's changes.
- **Dirty tree, committing (default):** print a one-line warning — `polish: working tree is dirty; pass commits will include your uncommitted changes. Commit or stash first to keep them separate.` — then continue.
- **Dirty tree, `--no-commit`:** no warning needed; nothing is committed.
Never stash, discard, or reset the user's uncommitted work to "clean up" the tree.
## Step 2: Run the passes
Run only the passes the resolved mode selects (see the Modes table). Each pass below is self-contained.
### Pass A — `review` (modes: full, review)
Invoke `pr-reviewer` against the branch's open PR.
`pr-reviewer` requires a PR — it always posts one visible `COMMENT` review and returns findings.
Polish does not apply those findings itself; surface them to the user.
```bash
# Resolve the current branch's PR — pr-reviewer requires one.
PR_URL=$(gh pr view --json url -q .url 2>/dev/null)
```
If no PR is open, skip Pass A and tell the user to open a draft PR first (via `/create-pr`), then re-run `polish`.
When a PR exists, dispatch the review. `pr-reviewer` is an **agent** — dispatch it via
the Task tool (`subagent_type="pr-reviewer"`), **not** `Skill()` (there is no
`pr-reviewer` skill; `Skill("pr-reviewer")` errors with `Unknown skill`):
```
Task(subagent_type="pr-reviewer", prompt="<PR-URL-or-number> [--critical if user passed it] [--no-optimize if user passed it]")
```
The `pr-reviewer` pass includes the **optimality lens** (Step 2.4c, report-only).
Pass `--no-optimize` through when the user set it on polish.
Capture from the agent's reply: the verdict and the findings list.
Surface all findings to the user — polish does not auto-apply them.
If you want findings applied, use `review-loop` (which calls `implement-suggestion` after each `pr-reviewer` pass) rather than `polish review`.
### Pass B — `simplify` (modes: full, simplify)
Invoke the code-quality skill in simplify mode against the branch diff:
```
Skill("code-quality", "simplify")
```
This runs the code-quality review pass, then **applies** Class M (mechanical) refactors one at a time — each behind `Skill("confidence", "code") ≥ 90 %` and a scoped fast-check, reverting any that fail its check. Class J (judgment) recipes are returned as proposals only.
Capture from its output: which recipes were applied (by ID, e.g. R6, R12) and which were surfaced as judgment-required proposals.
Do **not** pass `aggressive` unless the user explicitly asked for it — the default (High-impact Class M only) is the safe pre-PR setting.
### Pass D — `optimize` (mode: optimize only)
The standalone optimality pass. Invoke `optimize-approach` in apply mode against the branch diff:
```
Skill("optimize-approach", "apply")
```
This judges each approach unit against the four-axis rubric and **applies** at most one materially-better approach rewrite behind its own `apply_safe` + `confidence(code) ≥ 90 %` gate, with a scoped check and revert-on-failure. Anything not apply-safe or below the gate is surfaced as a proposal, not applied. Capture which rewrite was applied (axis + files) and which proposals were reported.
Do not run this pass in `full` mode — `full`'s reviewer pass already covers optimality via Step 2.4c, and running it twice would double the work.
### Pass C — `quick` (mode: quick only)
The light mechanical pass. Invoke code-quality in **review** mode against the branch diff, then auto-apply only the mechanical subset:
```
Skill("code-quality", "review")
```
**Auto-apply** a finding only when it meets **all three**:
- Footprint stays inside files already in the branch diff (no new files, no edits outside the diff).
- The fix is mechanical, not a judgment call: removing/rewriting a plain inline comment that explains WHAT or references the current task; renaming a local variable to a domain noun; dropping `else` after `return`/`throw`; extracting a magic number to a named constant; deleting unreachable/dead code introduced on this branch; flipping a single guard clause to an early return.
- The fix does not change behaviour observable from a test or a caller.
**Docstring / JSDoc / TSDoc / Python-docstring blocks attached to a function, method, class, type, or exported constant are a special case.** Never delete the block as noise removal — IDE hover, type strippers, and doc generators read it. Instead apply code-quality recipe **R35 step 4**: trim verbose prose to a one-sentence summary plus the structured tags (`@param`, `@returns`, `@throws`, `@deprecated`, `@since`, `@example`, `@see`, `@internal`, `@experimental`). Keep the summary line and every contract-bearing tag; drop only the restated-WHAT prose. If the block would be empty after trimming, surface it as a judgment-required finding instead of removing it. License / SPDX headers and linter pragmas (`eslint-disable-next-line`, `@ts-expect-error`, `# noqa`) are never removed.
**Surface but do NOT auto-apply** (out of scope for `quick` — that's what `simplify` is for): structural refactors, type-driven design changes, anything that expands blast radius into files outside the diff, anything where a sibling test would need updating.
## Step 3: Commit each pass that changed files
Unless `--no-commit` was passed, commit after each pass that produced changes, as its own commit, so the diff stays traceable. Skip the commit if a pass made no edits.
```bash
# After Pass A (review):
# Note: pr-reviewer is read-only — no local changes to commit from Pass A.
# Commit only if polish itself made edits (e.g. from a quick pass or simplify).
git add -u && git commit -m "chore: review pass (findings from pr-reviewer)"
# After Pass B (simplify):
git add -u && git commit -m "chore: simplify pass (mechanical refactors)"
# After Pass C (quick):
git add -u && git commit -m "chore: code-quality pass (comments, naming, dead code)"
# After Pass D (optimize):
git add -u && git commit -m "chore: optimize pass (approach rewrite)"
```
In full mode this can produce up to two commits (review, then simplify). That is intended — each pass is independently revertible.
With `--no-commit`, stage nothing; leave every change in the working tree for the user to review and commit themselves.
## Step 4: Report
Print a compact summary. Match the depth to what ran.
```
Polish (<mode>) on <branch>
Review pass (pr-reviewer):
Verdict: <PASS | FAIL | n/a (not run)>
Findings surfaced: <N findings; apply via review-loop, or "none">
Needs your judgment: <one line per blocking item, or "none">
Simplify pass:
Applied: <recipe IDs + one-line each, or "none">
Proposed (Class J, not applied): <one line each, or "none">
Quick pass: # only if mode == quick
Applied: <one line per mechanical fix, or "none">
Optimize pass: # only if mode == optimize
Applied: <axis + files of the applied approach rewrite, or "none">
Proposed (not applied): <one line each, or "none">
Commits: <SHA + message per pass, or "none (--no-commit)">
```
Surface the **findings** (review) and **Class J proposals** (simplify) prominently — these are the items the user still needs to decide on.
Do not silently drop them.
## Hard rules
- **Never weaken the codebase to look clean.** No deleting/skipping/weakening tests, no disabling lint rules or type checks, no `--no-verify`.
- **Never change public API or exported types** as a mechanical fix. That is always judgment-required — surface it.
- **Never apply a Class J (judgment) refactor automatically.** Only Class M, only behind the confidence gate. When unsure whether a fix is mechanical or judgment, treat it as judgment and surface it.
- **Approach rewrites (optimize pass) apply only behind the confidence gate, scoped to the diff's files, with revert-on-failure.** An approach rewrite touching a public API, a forbidden target, or files outside the diff is surfaced as a proposal, never auto-applied — that policy lives in the `optimize-approach` skill and polish does not override it.
- **Never write to GitHub.** Polish is local-only. PR creation and any GitHub-side review belong to `/create-pr`.
- **Never stash, reset, or discard the user's uncommitted work.**
- **One pass each per invocation. Do not loop.** If the branch still has issues after a polish run, that is a signal for the user to act on, not for the skill to grind.
## Relationship to `review-loop` and `/create-pr`
`review-loop` calls only `Skill("polish", "simplify")` — never full `polish` or `polish review`.
This is the anti-circularity guarantee: `review-loop` drives `pr-reviewer` itself each iteration;
having `polish review` re-enter `pr-reviewer` would create a dispatch cycle.
`/create-pr` delegates its post-draft quality step to `review-loop` (the bounded convergence
loop), not directly to `polish`.
`polish` is still useful standalone as a pre-draft local check.
| `review-loop` invocation | Delegates to |
| ------------------------------------ | ------------------------------- |
| `review-loop` (each iteration step C) | `Skill("polish", "simplify")` only |
| `/create-pr` flag | Post-draft quality path |
| ------------------------- | ---------------------------------------------- |
| `/create-pr` (default) | `Skill("review-loop")` (full convergence loop) |
| `/create-pr --no-review` | `Skill("polish", "simplify")` — simplify only, one pass |
| `/create-pr --no-simplify`| `pr-reviewer` agent (Task tool) one-shot only |
| `/create-pr --quick` | `Skill("polish", "quick")` on the draft diff |
| `/create-pr --no-quality` | *(quality skipped)* |
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!