Safe Refactoring with Tests

VerifiedCaution

Restructures code while preserving behavior exactly, establishing a passing test baseline first, then making incremental steps that each keep the suite green.

Sby Skills Guide Bot
DevelopmentIntermediate
9/19/2026
Claude Code
#refactoring#regression-testing#test-baseline#code-structure#behavior-preservation

Recommended for

Automated summary

This skill governs refactoring by first requiring a green test suite, then making incremental moves that each leave the codebase working.

Strengths

  • Mandates a passing test baseline before any edit, and stops if the suite is already red
  • Breaks the refactor into small steps, each verified by running the tests
  • Greps for callers and interface dependencies before moving or renaming anything
  • Provides a structured diagnostic path when a test breaks mid-refactor

Limitations

  • Assumes a project with identifiable test commands; without tests, writing them becomes a prerequisite
  • Deliberately refuses to fix a bug and restructure in the same step, which makes the process longer
  • The name references FastAPI but the instructions are generic, with no framework-specific guidance
When to use it

Use it when reorganizing existing code (extracting, moving, renaming) without altering its observable behavior.

When not to use it

Avoid it for adding features, fixing bugs, or refactoring code that has no baseline tests to protect it.

Security analysis

Caution
Quality score93/100

No destructive commands, credential access, network exfiltration, obfuscated payloads, or safety-disabling instructions are present. The skill uses Bash/Edit/Write only for normal test-driven refactoring, so the risk is limited to executing project tests and modifying files.

Findings
  • •Uses Bash to run the project test suite and git diff, which executes repository-defined commands/code.
  • •Uses Edit/Write to modify source files; appropriate for refactoring but still changes the working tree.
How this analysis is made

Examples

Split a large module
Refactor src/api/users.py into smaller modules — it's doing routing, validation, and database access all in one file. Behavior must stay exactly the same.
Extract logic into a helper
Extract the order-validation logic out of app/services/orders.py into its own helper function, without changing what it returns or how it handles errors.
Relocate a package
Move the payment module from app/utils/payments to app/billing/payments and update every caller, keeping all tests green at each step.

name: fastapi-refactor description: Use when the user wants to restructure code while preserving behavior exactly. Establishes a passing test baseline first, then makes incremental moves that each leave the suite green. Refuses to change behavior and structure in the same step. Also known as klaussy-refactor. allowed-tools: Read Grep Glob Bash Edit Write

Refactor the code the user described. The goal is to change structure while preserving behavior exactly. Do NOT change what the code does — only how it's organized.


Phase 1: Establish the Safety Net

Before changing any code, confirm you have tests that cover the current behavior.

  1. Read CLAUDE.md for project structure, test commands, and conventions.
  2. Read any .claude/rules/*.md whose paths: glob matches the area being refactored — they encode the conventions the moved code must continue to obey.
  3. Run the existing test suite. Record the results — every test must pass before you start. If tests are failing already, stop and report that. Do not refactor code that doesn't have a passing baseline.
  4. Assess coverage of the code you plan to change. Read the existing tests for the modules involved. If a function you're restructuring has no tests:
    • Write tests for its current behavior first.
    • Run them to confirm they pass.
    • These are your regression guardrails — they prove the refactor didn't break anything.

Phase 2: Understand the Current Code

Read the code you're refactoring in full. The three checks below are independent — issue them as a single batch of parallel tool calls, not sequentially:

  1. What it does — the inputs, outputs, side effects, and edge cases. Read the file(s) in full.
  2. Who calls it — grep for callers across the whole repo. Every caller is a contract you must preserve.
  3. What depends on its interface — function signatures, return types, exceptions thrown, event emissions. Grep for type/import references too. These are the things you cannot change without updating all consumers.

Phase 3: Plan the Refactor

Design the target structure before editing.

  1. Describe the structural change — what moves where, what gets renamed, what gets split or merged.
  2. List what must NOT change — public interfaces, return values, side effects, error behavior. Be explicit.
  3. Plan incremental steps. Break the refactor into the smallest possible moves that each leave the code in a working state. Never change behavior and structure in the same step. For example:
    • Step 1: Extract a function (tests still pass).
    • Step 2: Move the function to a new module (tests still pass).
    • Step 3: Update callers to use the new location (tests still pass).

Phase 4: Refactor

Execute your plan. After EACH incremental step:

  1. Run the test suite. If anything fails, your last change broke something. Fix it before moving on — do not accumulate breakage across steps.
  2. Re-read the code to verify it looks correct.

When a test fails mid-refactor

Don't immediately edit the test or roll back the step. Diagnose:

  1. Did you miss a caller? Re-grep for the symbol you moved or renamed across the whole repo (not just the immediate file). Update every match in this same step.
  2. Did you change a signature unintentionally? Compare the new signature to the old one — argument order, default values, return type. Even a "trivial" rename of a kwarg breaks callers using keyword args.
  3. Did you introduce a subtle behavior change? Re-read the moved code line-by-line against the original. Refactors break in tiny ways: a list comprehension that no longer preserves order, an early-return that now runs cleanup, a class attribute that became an instance attribute.

Only after the test is green again move on to the next step.

Rules

  • Never change behavior and structure in the same step. If you need to fix a bug you found, do it in a separate commit.
  • Preserve all public interfaces unless the explicit goal is to change them. If you change a function signature, update every caller in the same step.
  • Don't "improve" things outside the refactor scope. No drive-by style fixes, no adding types to unrelated code, no renaming things you aren't restructuring.
  • Match existing conventions. If moving code to a new file, follow the naming and structure patterns already in the codebase.
  • Don't add narrating comments. Restructuring is not an excuse to annotate. When you delete or move code, delete its now-stale comments too; keep only short comments that explain a non-obvious WHY, and never leave commented-out code behind.

Phase 5: Verify

  1. Run the full test suite one final time. Every test that passed before must pass now. No exceptions.
  2. Check your diff. Run git diff and verify:
    • No behavioral changes snuck in.
    • No unrelated files were modified.
    • No debug code or commented-out code remains.
  3. Verify callers. Re-grep for callers of anything you moved or renamed. Confirm every reference was updated.

When NOT to use

  • The user wants to add new behavior, not rearrange existing code — use implement.
  • There's no passing test baseline AND the user can't accept "write tests first" — refactor without tests is just hope; flag the missing baseline and stop.
  • The user wants to fix a known bug as part of the refactor — split: bug fix in one commit (debug skill), refactor in another. Mixing them hides regressions.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/safe-refactoring-with-tests-mu7w4g46' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/safe-refactoring-with-tests-mu7w4g46/download' --output '.skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md.part' && mv '.skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md.part' '.skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Tools declared by the author (check availability in your agent): Read Grep Glob Bash Edit Write

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md' && test -s '.skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/fastapi-refactor' && cp -R '.skill-downloads/safe-refactoring-with-tests-mu7w4g46' '.claude/skills/fastapi-refactor'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/safe-refactoring-with-tests-mu7w4g46'

openskills read 'safe-refactoring-with-tests-mu7w4g46'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/safe-refactoring-with-tests-mu7w4g46/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills