CtrlK
BlogDocsLog inGet started
Tessl Logo

polish

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".

68

Quality

86%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

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.

ModeTriggerWhat runs
full (default)No mode tokenreview pass (pr-reviewer, read-only), then simplify pass. The "do the works" button.
reviewFirst token reviewpr-reviewer pass only — read-only review surfaced as findings for you to act on.
simplifyFirst token simplifycode-quality simplify pass only — apply Class M mechanical refactors.
optimizeFirst token optimizeOptimality pass only — Skill("optimize-approach", "apply") over the branch diff (gated approach rewrite).
quickFirst token quickLight 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):

FlagEffect
--no-commitLeave all changes in the working tree instead of committing each pass. Use mid-development to keep iterating.
--criticalPass --critical through to the pr-reviewer agent (adversarial pre-mortem). Ignored by simplify / quick.
--no-optimizePass --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

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:

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:

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

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.

# 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.

# 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 invocationDelegates to
review-loop (each iteration step C)Skill("polish", "simplify") only
/create-pr flagPost-draft quality path
/create-pr (default)Skill("review-loop") (full convergence loop)
/create-pr --no-reviewSkill("polish", "simplify") — simplify only, one pass
/create-pr --no-simplifypr-reviewer agent (Task tool) one-shot only
/create-pr --quickSkill("polish", "quick") on the draft diff
/create-pr --no-quality(quality skipped)
Repository
mthines/agent-skills
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.