Use when asked to simplify, clean up, tidy, or refactor code for clarity without changing what it does, or when the user says "simplify this", "clean this up...
--- name: reduce description: Use when asked to simplify, clean up, tidy, or refactor code for clarity without changing what it does, or when the user says "simplify this", "clean this up", "make it readable", "reduce the complexity", or "tidy this". Behavior-preserving only; not a bug or security audit (use bug-hunt or security-sweep for those). --- # reduce A reduction simmers a sauce to drive off the water and concentrate the flavor, and the dish tastes the same, only sharper. You do that to code: boil off the excess, concentrate the intent, and the behavior comes out identical. The cook who reduces too hard scorches the pan and changes the dish; the discipline is knowing when to pull it off the heat. **Core principle:** same inputs, same outputs, same side effects, same errors, same public interface, same evaluation order. If the behavior moved, it was not a reduction, it was a rewrite. **No behavior-preservation evidence, no applied simplification.** Violating the letter of that is violating its spirit. ## The behavior lock Before you change a single line, establish the lock. This is the whole safety story; everything else is taste. 1. **Pin the scope.** Default to the code that recently changed (see Scope). Know exactly which files and functions you are reducing before you start. 2. **Find the tests that cover it.** Run them and confirm they exercise the code you are about to touch. If coverage is thin, write characterization tests first ([taste](../taste/SKILL.md)) that capture the *current* behavior, edge cases included, only when that is safe and in scope. If you cannot lock the behavior with tests, drop to report mode. 3. **Baseline-verify green.** Run the suite and read the output before touching anything. You are proving the starting point, not assuming it. 4. **Reduce in small steps,** one category of simplification at a time (see What to reduce). 5. **Re-run the same verification after each meaningful change.** Evidence in hand before any "behavior unchanged" claim ([check](../check/SKILL.md)). A reduction you did not re-run is a hypothesis. 6. **Cannot lock it?** Switch to report mode or ask the user. Never apply a simplification you cannot prove safe. ## Two modes **Apply** is the default for recently changed code that has tests, or where characterization tests can be added safely. You make the edits, one category per commit, with the verification evidence. **Report** is for broad scope, under-tested code, anything architectural or design-level, public-interface shifts, or when the user explicitly wants review before edits. You produce the simplification plan and stop. Auto-escalate from apply to report the moment the behavior lock cannot be established. When in doubt, report. ## What to reduce Highest value first. These are local, mechanical, structure-preserving moves. - **Flatten control flow.** Guard clauses and early returns over deep nesting; collapse arrow code. - **Reveal intent through naming.** A clear name retires a comment that only restated the code. - **Remove dead weight.** Unused locals, parameters, imports, and unreachable branches, once usage analysis confirms nothing references them. - **Consolidate genuine duplication.** Same logic with the same reason to change, in three or more real places. Extract the shared intent, not merely the matching text. - **Replace clever with boring.** Dense one-liners and trick expressions become plain, local, readable code. - **Collapse needless intermediate state.** Drop temp variables, redundant data-shape conversions, and pass-through wrappers that earn nothing. - **Reuse what the repo already has.** If a helper already exists, call it instead of inlining the logic a fourth time. ## What NOT to reduce This is the discipline that separates a reduction from a scorched pan. - **No new abstraction without three or more real call sites or a clear domain concept.** Premature DRY is its own debt; functions diverge the moment requirements do. - **DRY past readability.** Two snippets that look alike but change for different reasons are not duplication. Leave them. - **No dense one-liners or nested ternaries** sold as "simpler". Fewer lines is not the goal; lower cognitive load is. - **No vague generic utilities.** A `utils.process()` that hides three unrelated jobs is worse than the code it replaced. - **Never strip load-bearing redundancy.** Validation, defensive null checks, logging, retries, error fallbacks, compatibility shims, and intentional comments look redundant and are not. Looks redundant does not mean is redundant; when unsure, leave it and note it. - **No style churn outside the scope.** Reformatting a wide area is how a semantic change hides in a diff nobody can read. ## Tidy, do not redesign `reduce` tidies: local, mechanical, behavior-preserving cleanup. It does not move module boundaries, reshape data models, or pick new abstractions. Those are design decisions; surface them in report mode and hand off, never auto-apply. Tidying first earns the trust that makes the larger refactor possible later. ## Scope Default: the code that recently changed, from `git diff` against the merge base or the working tree. That keeps the reduction relevant and prevents repo-wide churn. Allow an explicit scope on request: a file, a directory, a symbol, or a commit or PR range. Whole-repo reduction only when the user asks for it, and report-first. ## One category per commit Dead code in one commit, duplication in the next, guard clauses in the next. Each commit names its effect, stays reviewable, and reverts alone. One sweep that bundles five kinds of change is an unreviewable rewrite wearing a cleanup label. ## Boundaries `reduce` applies changes; it is not an audit and it does not hunt for defects. - Borrows from [taste](../taste/SKILL.md) for characterization tests, [check](../check/SKILL.md) for evidence before claims, and [refire](../refire/SKILL.md) when a reduction surfaces a real bug: stop, do not "simplify" the bug away, switch to debugging. - Hands accepted report findings to [expedite](../expedite/SKILL.md) to drive to done. - Hands correctness issues to [bug-hunt](../bug-hunt/SKILL.md), security issues to [security-sweep](../security-sweep/SKILL.md), and repo-wide quality to [line-check](../line-check/SKILL.md). Finding a bug is not in scope here; routing it is. ## Output shape `reduce` has its own artifact, not the shared audit contract: ```markdown ## reduce: <scope> (<date>) Mode: apply | report ### Simplification plan - [category] what will change and why it is behavior-preserving ### Change log (apply mode) - [category] what changed (<commit>) ### Verification evidence Baseline: <command> -> <result> After: <command> -> <result> (must match) ### Handed off - correctness/security/design items routed to bug-hunt / security-sweep / line-check ``` In report mode, findings may also be written in the [audit report format](../../../docs/audit-report-format.md) so [expedite](../expedite/SKILL.md) can consume them later. ## Common mistakes | Mistake | Reality | |---------|---------| | "Cleaner" refactor that alters an edge case | If you did not re-run the tests, you changed behavior and do not know it. | | Abstracting from two superficially similar snippets | Looks-alike is not duplication. Wait for three real call sites and a shared reason to change. | | Deleting a defensive check that "can never fail" | That is the load-bearing redundancy. It fails the day you remove it. | | Reformatting the whole file "while I was in there" | A semantic change now hides in the noise. One category per commit, scope held. | | Fewer lines reported as simpler | Cognitive load is the metric, not line count. Dense is not simple. | | "Behavior unchanged" with nothing run | A claim, not evidence. Lock, run, then claim. |
don't have the plugin yet? install it then click "run inline in claude" again.
added explicit inputs, decision points, and edge cases; structured procedure into numbered steps with input/output clarity; formalized output contract with apply vs report modes; clarified when to escalate to bug-hunt or security-sweep; preserved original behavior-lock discipline and all "what not to reduce" constraints.
a reduction simmers a sauce to drive off water and concentrate flavor. the dish tastes the same, only sharper. you do that to code: boil off the excess, concentrate the intent, behavior comes out identical. the cook who reduces too hard scorches the pan and changes the dish. the discipline is knowing when to pull it off the heat.
core principle: same inputs, same outputs, same side effects, same errors, same public interface, same evaluation order. if behavior moved, it was not a reduction, it was a rewrite. no behavior-preservation evidence, no applied simplification.
use skillet-reduce when the user asks you to simplify, clean up, tidy, or refactor code for clarity without changing what it does. triggers include "simplify this", "clean this up", "make it readable", "reduce the complexity", or "tidy this". this is behavior-preserving only. not a bug audit (use bug-hunt for that) and not a security audit (use security-sweep for that).
no external API connections or auth required.
the behavior lock is your entire safety story. establish it before touching code.
pin the scope. identify exactly which files and functions you are reducing. default to recent changes from git diff. confirm with the user if scope is ambiguous. note: do not reduce repo-wide without explicit request, and report-first for broad scope (see decision points).
find and run existing tests. locate test files that cover the code in scope. run them and confirm green. read the output. if coverage is thin, write characterization tests (taste) that capture current behavior and edge cases, but only when safe and in scope. if you cannot lock behavior with tests, switch to report mode (step 7 below). if tests do not run, ask the user or switch to report.
baseline-verify green. run the full test suite one more time. record the command and result. you are proving the starting point exists and is stable, not assuming it.
plan reductions by category. read the "what to reduce" section below. pick one category at a time: flatten control flow, reveal intent through naming, remove dead weight, consolidate duplication, replace clever with boring, collapse intermediate state, reuse existing helpers. do not mix categories in one change.
apply one reduction. make the edits for one category only. keep changes local and mechanical. do not redesign, move module boundaries, reshape data models, or introduce new abstractions.
re-run verification after each meaningful change. run the same test suite again. record the command and result. compare to baseline. if result differs, revert and switch to report mode. if result matches, commit with a message naming the category and the effect. a reduction you did not re-run is a hypothesis, not evidence.
cannot lock behavior? switch to report mode. if tests are absent, flaky, do not cover the scope, or you cannot write safe characterization tests, stop applying changes. produce a simplification plan (see output contract below) and hand the findings to the user. never apply a simplification you cannot prove safe.
apply vs. report mode:
what to reduce (highest value first):
what NOT to reduce (load-bearing constraints):
utils.process() that hides three unrelated jobs is worse than the code it replaced.edge cases and constraints:
apply mode:
## reduce: <scope> (<date>)
Mode: apply
### Simplification plan
- [category] what will change and why it is behavior-preserving
### Change log
- [category] what changed (<commit hash>)
- [category] what changed (<commit hash>)
### Verification evidence
Baseline: <test command> -> <result, e.g. "42 passed, 0 failed">
After commit N: <test command> -> <result, must match baseline>
After commit M: <test command> -> <result, must match baseline>
### Handed off
- (if any correctness/security/design issues surfaced) routed to bug-hunt / security-sweep / expedite
report mode:
## reduce: <scope> (<date>)
Mode: report
### Simplification plan
- [category] what would change and why it is behavior-preserving
- [category] what would change and why it is behavior-preserving
### Why report mode
- reason (e.g. "test coverage thin", "scope too broad", "public interface change", "behavior lock cannot be established")
### Handed off
- correctness/security/design findings to bug-hunt / security-sweep / expedite
data format: plain markdown. file location: document output in the PR description or as a comment in the code review tool. include baseline and post-reduction test results side by side.
the user knows the skill worked when: