agentleFS
mik2winmik2win/foureyes/skills/refactor/SKILL.md

refactor

Skill2 starsChanged 3 months agoMITView on GitHub

Clean up and improve already-written code — simplification, reuse/DRY extraction, efficiency, language modernization, and architecture/layer hygiene. QUALITY-ONLY: this skill does NOT hunt for correctness bugs — use /code-review for that. It applies edits then verifies via format + test. TRIGGER when: the user wants to tidy, simplify, modernize, de-duplicate, or make changed code more reusable or efficient. DO NOT TRIGGER when: the user wants to hunt correctness/security/crash bugs (use /code-review), scan the WHOLE codebase for rot/ball-of-mud hotspots (use /arch-health), or design a module's interface from scratch (use /codebase-design).

196 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use ascii-diagram, debug-fix and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • SethGammonSkill

    ascii-diagram

    Generate perfectly aligned ASCII diagrams — architecture, flow, sequence, box-and-arrow. Uses a programmatic character-grid approach so alignment is guaranteed by math, not token prediction. Includes post-render verification.

    Also in 4 projects that use this

  • zebbernSkill

    debug-fix

    Find and fix a bug or issue — from any source (GitHub issue, error message, user report, or observed behavior)

    Also in 4 projects that use this

  • parcadeiSkill

    agent-context-isolation

    Agent Context Isolation

    Also in 3 projects that use this

  • parcadeiSkill

    agentica-infrastructure

    Reference guide for Agentica multi-agent infrastructure APIs

    Also in 3 projects that use this

  • +8 more from parcadei

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. 0 are common, 6 are distinctive, and 8 are very specific to this project.

  • 0

    Common

    Most of the 169 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read these before touching any code.

    line 29
  2. Very specific:

    If PROJECT.md is missing or still TEMPLATE, fall back to the root CLAUDE.md (always in context) when it carries the commands/architecture …

    line 40
  3. Very specific:

    Read every target file in full before judging it.

    line 59
  4. Distinctive:

    AFTER are applied; the rest go to Output § Deferred.

    line 70
  5. Distinctive:

    Before a stand-in object replaces a repeated null check, say what the absence means — "there is none" and "there is one but unknown" differ.

    line 122
  6. Very specific:

    Delete unused imports/symbols, unreachable branches, commented-out code, and stale TODO/FIXME/legacy/back-compat shims (MVP-stage projects …

    line 126
  7. Distinctive:

    Stay pure: if a change could alter behavior, is ambiguous, or needs a judgment call (e.g.

    line 160
  8. Distinctive:

    STOP and ask the user instead of guessing.

    line 162
  9. Very specific:

    Format: run the format command from PROJECT.md.

    line 163
  10. Very specific:

    Test: run the test command from PROJECT.md (scope to affected tests when the project supports it).

    line 165
  11. Very specific:

    If test is n/a (no suite at all), say so and lean harder on staying pure — recommend /test before any non-trivial refactor, since nothing …

    line 168
  12. Very specific:

    If the unit will not instantiate in a harness at all, read skills/refactor/LEGACY.md and follow it instead of widening this pass.

    line 170
  13. Distinctive:

    Confirm destructive removals: Don't silently delete exported symbols or back-compat shims callers may rely on.

    line 200
  14. Very specific:

    Verify, never publish: Run format + test; never git add/commit — suggest the command, the user runs it.

    line 204

“Common” is measured: kept by at least 6 in 10 of the 169 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Refactor

Improve the quality of changed code WITHOUT changing its behavior. Pure refactor: same inputs produce the same outputs. This skill APPLIES the cleanups, then runs the project's format and test commands to confirm nothing broke. It does NOT look for bugs — for correctness/security/crash analysis run /code-review.


Phase 0 — Load profile

Read these before touching any code. They define every project fact this skill needs:

  1. .claude/PROJECT.md — Commands (format, lint, test), Architecture (layers, boundaries, composition root), and any project-specific conventions.
  2. .claude/rules/_generic/* — stack-agnostic rules (code quality, comments, naming). If CONTEXT.md exists, align names toward its ubiquitous language (a rename to the canonical term is behaviour-preserving and in scope).
  3. Stack rule packs in .claude/rules/* whose paths (front-matter glob) match the target files. These carry the language- and framework-specific modernization and anti-pattern checks — do not hardcode any here; defer to them.

If PROJECT.md is missing or still TEMPLATE, fall back to the root CLAUDE.md (always in context) when it carries the commands/architecture above — proceed on it, noting you're running without a kit profile. Only if neither has those facts, tell the user to run /bootstrap first, then stop.


Phase 1 — Resolve target

$ARGUMENTS selects what to refactor:

  • file path — that file.
  • directory — all source files under it.
  • staged — git diff --cached --name-only files.
  • range (e.g. main..HEAD) — git diff --name-only <range> files.
  • plan/card file — the files it scopes; the log goes back into it (see Persist to the artifact).
  • (empty, default) — changed files: git diff --name-only plus git diff --cached --name-only. If none, ask the user what to refactor.

Read every target file in full before judging it. Match each file against the rule packs' paths so you apply the right stack-specific checks per file.


Phase 2 — Refactor dimensions

Apply these in order. Each is QUALITY-only; never alter observable behavior. Give every candidate a verdict before it can become an edit: FIRST — it makes the change you are about to make cheaper; AFTER — that change is done and this area is due again soon; LATER — real, no payoff attached to today's work; NEVER — this behaviour is not changing again. Only FIRST and AFTER are applied; the rest go to Output § Deferred. A first-of-its-kind mess is never LATER.

D1 — Language modernization (per installed rules)

Apply the modern-idiom and anti-pattern checks defined in the matched stack rule packs (control flow, data containers, I/O, exception/error handling, etc.). Do not invent idioms — use only what the installed rules prescribe for this stack.

D2 — Architecture & layer hygiene (per PROJECT.md)

  • Boundaries: imports point inward only; no sibling-to-sibling coupling; cross-boundary wiring lives in the composition root named in PROJECT.md.
  • SRP: each unit has one reason to change. If describing it needs "and" → split. First answer aloud whether a second use site exists and whether an alternative implementation does; neither → the split buys an interface and no depth, so leave it and say why.
  • Layer purity: domain/business logic stays free of I/O, rendering, and framework calls per the layering in PROJECT.md; orchestration and presentation stay in their layers.
  • Boundary conversion: external/raw responses are mapped to domain types at the adapter edge, not passed raw into inner layers.
  • Irremovable dependencies: one you cannot remove is exposed in a single place, not buried — construction lifted into the constructor or one lazy accessor, a fragile external call wrapped.

D3 — Function quality (per code-quality rule)

  • Size: a limit passed is a look, not a cut — extract only at a seam where meaning and mechanics part ways and the split test holds (the piece reads without its caller, the caller without opening the piece); otherwise keep the function long and say why. Outputs include side effects: list the mutations before choosing the cut. Extract into the SAME unit first with an awkward name; moving it elsewhere is a separate step, and a branch moves with its condition.
  • Naming: names state intent; rename the unclear.
  • Parameters: 0–2 ideal; 3 acceptable; 4+ → group into a parameter object, and replacing two or more fields still pays. A flag is any argument every caller passes as a literal and the body branches on — enums and strings too, not a computed value; split the function. For an Extract Class cut, remove one member and note what became nonsense: that list, not the count, is it.
  • Guard clauses: flatten nesting with an early return only when one leg is the unusual case AND nothing runs after the block — an audit call or a log after the if makes the flattening a behaviour change (Phase 3 rule 2 applies: confirm first).
  • Command/Query separation: a unit either does something or returns something. The test is observable side effects — caching, memoisation and lazy initialisation pass it and are not violations; do not flag them.
  • Conditionals: one that picks which object handles a case is fine; one that inspects a value and supplies behaviour on its behalf means a type is missing (a switch on the receiver's class, a respond_to? chain, an attribute named type/kind). Report what is missing, not "simplify".

D4 — Duplication extraction (DRY)

Same logic, computation, or construction in 2+ places → extract to one shared unit at the lowest layer both callers reach, per the architecture in PROJECT.md. Extract only what changes for the same reason: identical bodies encoding two rules are coincidence, and two cases do not show the axis of variation — name it, or wait for the third. Derive the abstraction, do not invent it: take the two most alike cases, remove the single smallest difference, run the suite, repeat. Gates — what does the merged version simplify (removing duplication is not itself a reason); which error can it no longer raise loudly; does it read harder than the copies, and then stop. Judge by result: one place to edit per behaviour, and a wrong abstraction gets dearer with every caller. An abstraction already proved wrong is undone by procedure: inline it back into EVERY caller, delete in each what its arguments show it never runs, then re-extract with all cases visible. Before a stand-in object replaces a repeated null check, say what the absence means — "there is none" and "there is one but unknown" differ; a site still asking "is this real?" guards instead.

D5 — Dead-code removal

Delete unused imports/symbols, unreachable branches, commented-out code, and stale TODO/FIXME/legacy/back-compat shims (MVP-stage projects keep no re-export stubs). Replace magic numbers with named constants. Delete comments that merely narrate the code; keep only non-obvious WHY. Confirm before deleting anything that could be a public/exported symbol or a back-compat shim callers may rely on — never remove user-visible behaviour silently (Phase 3 rule 2 applies). Before deleting an override or a field that may shadow a base one, text-search the tree for a base definition of the same name: found → the deletion is a behaviour change, not cleanup, and a green build proves nothing. When the complaint is "I can't follow this", subtract before explaining and comment only what survives removal.

D6 — Stack-specific dimensions

Apply every additional check defined in the installed stack rule packs matched in Phase 0 (framework patterns, data/ORM patterns, concurrency, domain invariants, etc.). These are the source of truth for stack specifics — reference them generically, never duplicate them.


Phase 3 — Apply & verify

  1. Confirm before writing. Phases 1–2 produce a proposed cleanup list; this phase is the first that touches files. Show the list — file, what changes, why — and get the user's go before the first Edit. A refactor is a multi-site, judgment-bearing edit whose diff the user is expected to review as a whole, so the gate is "apply these N?", not a per-edit prompt. Skip it only when the user's own request already named the exact change ("rename X to Y here").
  2. Apply the cleanups with Edit, smallest safe steps first, running the tests after each step, never once at the end and never from a red bar. A step that reddens the suite and is not obvious in seconds is reverted to the last green and redone smaller — never debugged forward; a reverted step is a result, not a failure. The red reads exactly two ways: behaviour changed (revert), or the test asserted an interaction the refactor dissolved (fix the test, say so). Merge two units by making them textually identical first, one micro-change at a time; replace a stored value by running new beside old and asserting they agree at every read before deleting the old. Name each move before making it and its mirror after; name its abort condition first (docs/decision-craft.md §1). Replacing working code wholesale runs as the reversible sequence in skills/tdd/refactoring.md §Changing structure safely.
  3. Stay pure: if a change could alter behavior, is ambiguous, or needs a judgment call (e.g. removing code that might be used by reflection, changing a public signature), STOP and ask the user instead of guessing. Defer rather than risk semantics.
  4. Format: run the format command from PROJECT.md. If format is n/a (no formatter), skip and note it in the output.
  5. Test: run the test command from PROJECT.md (scope to affected tests when the project supports it). If tests fail, the refactor changed behavior — revert the offending edit and report it. If a risky refactor lacks coverage, suggest /test first. If test is n/a (no suite at all), say so and lean harder on staying pure — recommend /test before any non-trivial refactor, since nothing else pins behavior. If the unit will not instantiate in a harness at all, read skills/refactor/LEGACY.md and follow it instead of widening this pass.

For large or multi-file targets, fan out reading/analysis with the Agent tool, then apply edits yourself so changes stay coordinated.


Output

Report concisely:

  • Changes by dimension — what was cleaned up under each of D1–D6 (one line each).
  • Files touched — absolute paths.
  • Verification — format result and test result (pass/fail + summary).
  • Deferred — anything skipped as risky/ambiguous or verdicted LATER/NEVER, with the reason.
  • Price — what the pass cost as well as bought: more indirection, a worse metric, debts left. More complex than the problem it removed → revert; an invisible concept made visible still wins.

Persist to the artifact

(Mandatory when $ARGUMENTS or the session brief names a plan, card or spec file.) Follow ../implement/reference/work-log.md. Keep a ledger on disk from the first phase and record deviations the moment they are decided. Before the final reply, append ## Refactor Log — <date> — <verdict> to that file; its ### Result is the changes by dimension, each candidate's verdict (FIRST / AFTER / LATER / NEVER) with applied / left, and the price line. Anything you could not observe yourself goes under Re-check later, with its command and today's baseline: a post-deploy log grep, a soak count, a UI gesture. The chat output is a copy of the log, never the only record. No planning artifact → skip this section.


Hard rules

  • Behaviour-preserving only. Same inputs → same outputs. If a change could alter observable behaviour or is ambiguous, STOP and ask — defer rather than guess.
  • Never hunt bugs here. Correctness/security/crash analysis is /code-review's job.
  • Confirm destructive removals. Don't silently delete exported symbols or back-compat shims callers may rely on.
  • Never trade structure for a guessed cost. A cleanup that "looks slower" still ships — finish it, then take the doubt to /perf with a baseline, not to a watered-down move.
  • Verify, never publish. Run format + test; never git add/commit — suggest the command, the user runs it.

Cross-reference

  • /code-review — finds correctness, security, and crash bugs. This skill does NOT; run it for bug hunting. The split mirrors the built-in taxonomy (/code-review = bugs, built-in /simplify = quality-only): this skill is the kit's PROJECT.md-aware counterpart of /simplify. When both passes run on the same diff, quality findings belong HERE and correctness findings there — never report the same issue from both.
  • /test — add coverage BEFORE attempting a risky refactor so behavior is pinned.
  • /perf — where a suspected performance cost goes, after the structure is clean.
  • /arch-health — scans the WHOLE codebase for shallow modules & ball-of-mud hotspots and routes the one you pick here; this skill cleans the current diff on demand.
  • /codebase-design — the deep-module vocabulary D2's architecture hygiene draws on when a boundary needs redesigning, not just tidying.
  • /clean-mvp — whole-codebase cruft sweep (dead code, unused files, legacy shims); this skill's D5 removes dead code only within the current target.
  • /distill — mines the whole repo's implicit conventions into project rules; this skill then applies those installed rules to the target diff (D1/D6 read them).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.