Skip to content
Back to skills

Refactor Module

ASecurity

Use when a ticket asks to restructure code without changing what it does — extract a function, split a file, rename for clarity, reduce duplication — with behaviour preserved. Invoke for "refactor X", "clean up the Y module", or "extract Z" where no behaviour change is intended.

  • 2 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 5, 2026
ai-agentsgorefactoringgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add tmj-90/gaffer --skill refactor-module --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Refactor Module?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Refactor Module
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tmj-90-refactor-module/badge)](https://www.skillsdirectory.com/skills/tmj-90-refactor-module)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: refactor-module
description: Use when a ticket asks to restructure code without changing what it does — extract a function, split a file, rename for clarity, reduce duplication — with behaviour preserved. Invoke for "refactor X", "clean up the Y module", or "extract Z" where no behaviour change is intended.
stack: []
area: refactor
---

# Refactor a module

A refactoring changes structure, not observable behaviour (Fowler). The discipline that
makes it safe is small steps with the tests green between every one of them. You wear
one hat at a time: while refactoring you add no feature and fix no bug.

## Steps

1. **Establish the safety net.** Run the suite (the `run-tests` skill) and confirm it is
   green BEFORE touching anything; record the command and summary. If the code you will
   move is thinly tested, first add characterization tests (the `add-unit-test` skill)
   that pin what it does today — including odd behaviour — through the public interface,
   not its private internals (tests coupled to internals break on every legitimate
   refactoring). Commit them separately.
2. **Read the lore.** Call `search_lore` for module boundaries, layering and naming
   conventions so the new structure fits the codebase instead of inventing a new one.
3. **Name the target and list the moves.** Write the end state in one or two sentences
   and the sequence of named refactorings that gets there: Extract Function, Inline
   Variable, Move Function, Rename, Split Phase, Replace Conditional with Polymorphism,
   Introduce Parameter Object. Each move is small enough to finish and test in minutes.
4. **Execute one move at a time.** After each move: run the fastest relevant tests (and
   typecheck if the language has one). Green → commit (`git commit -m "refactor: …"`) so
   there is a known-good point to return to. Red → undo that move
   (`git restore --staged --worktree <paths>`, and `rm` any file the move created —
   `git clean -fd` is hook-blocked) and take a smaller step. Never debug your way
   forward through a red refactoring.
5. **When a move fails because something else must change first, use the Mikado
   method.** Note the goal, try the change naively, and when it breaks, write down the
   prerequisites it revealed, then revert. Work the prerequisites leaf-first, each as its
   own green commit, then retry the goal. Keep the list in your working notes; it doubles
   as your scope check.
6. **Preserve the public interface** unless the ticket explicitly allows changing it. If
   it does, update every call site in the same change (`grep` the symbol, including
   string and dynamic references) and note the change in the evidence.
7. **Confirm equivalence.** Run the full suite, lint and build once at the end (the
   `run-tests` and `run-lint` skills). Compare the test counts with step 1: the same tests,
   plus any characterization tests you added, must pass. A test you had to edit is a
   behaviour change unless the edit only follows a rename or a move.
8. **Evidence** via the `record-evidence` skill: before and after test summaries, a
   `diff_summary` listing the moves, and any interface change (on a resume that call is
   refused: do not retry; put this, the AC → test map and the smallest-change note in
   your final message). Then the runner takes over.

## Done when

The end state from step 3 is reached, every step was green, the before/after test runs
match, and the diff contains no behaviour change: no new feature, fix, dependency, or
altered output.

## Stop and escalate when

- The Mikado prerequisites grow past what the ticket describes (for example, the change
  now touches modules or public APIs the ticket never named): stop at the last green
  commit and `request_decision` with the prerequisite list and a proposed split.
- You find a real bug. Do not fix it here — it would make "no behaviour change"
  unverifiable. Note it as a finding in the evidence for a separate ticket.
- The code cannot be put under test without changing behaviour: `request_decision`.

## Rules

- Behaviour-preserving only: green before, green after every step, same outcomes.
- No scope creep: no features, fixes, formatting sweeps or dependency bumps in a
  refactor ticket.
- Public interface stable unless the ticket says otherwise.
- The safety hook blocks `git reset --hard`; undo with `git restore` or `git revert`.
- Work on the delivery branch (the `create-branch` skill verifies); commit, never push.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.