From rails-agent-skills
Refactors code structure without changing behavior: extracts service objects from fat controllers/models, splits large classes, renames abstractions, reduces duplication via characterization tests, small steps, and per-step verification.
npx claudepluginhub igmarin/rails-agent-skills --plugin rails-agent-skillsThis skill uses the workspace's default tool permissions.
Use this skill when the task is to change structure without changing intended behavior.
Refactors code to improve structure, readability, and maintainability while preserving behavior. Guides test-driven cycle, checklists, and patterns like extract function.
Refactors code to improve structure, reduce duplication, and apply SRP/DRY principles without changing behavior. Use for incremental code quality enhancements with test verification.
Applies named refactoring patterns to fix code smells like Feature Envy or long methods, preserving behavior via test-verified small changes. Use for refactor requests, technical debt, or legacy cleanup.
Share bugs, ideas, or general feedback.
Use this skill when the task is to change structure without changing intended behavior.
Core principle: Small, reversible steps over large rewrites. Separate design improvement from behavior change.
| Step | Action | Verification |
|---|---|---|
| 1 | Define stable behavior | Written statement of what must not change |
| 2 | Add characterization tests | Tests pass on current code |
| 3 | Choose smallest safe slice | One boundary at a time |
| 4 | Rename, move, or extract | Tests still pass |
| 5 | Remove compatibility shims | Tests still pass, new path proven |
NO REFACTORING WITHOUT CHARACTERIZATION TESTS FIRST.
NEVER mix behavior changes with structural refactors in the same step.
ONE boundary per refactoring step — never extract two abstractions in the same step.
VERIFY tests pass after EVERY step — not just at the end.
If a public interface changes, document the compatibility shim and its removal condition.
EXTREMELY-IMPORTANT: Run verification after every refactoring step.
AFTER each step:
1. Run the full test suite
2. Read the output — check exit code, count failures
3. If tests fail: STOP, undo the step, investigate
4. If tests pass: proceed to next step
5. ONLY claim completion with evidence from the last test run —
report the last line of output (e.g. "5 examples, 0 failures")
Report test run output at EACH step — not only at the end. At least two separate evidence entries at different sequence points are required.
Forbidden claims:
Write this before touching any production file. This is not optional — no refactoring step begins until this test exists and passes on the current (un-refactored) code.
# spec/requests/orders_spec.rb (or service/model spec — mirror the file being refactored)
# frozen_string_literal: true
RSpec.describe "Orders#create current behavior", type: :request do
describe "POST /orders" do
let(:valid_params) { { order: { product_id: 1, quantity: 2 } } }
it "creates order and enqueues warehouse notification" do
expect { post orders_path, params: valid_params }
.to change(Order, :count).by(1)
expect(NotifyWarehouseJob).to have_been_enqueued
end
end
end
Run it: bundle exec rspec spec/requests/orders_spec.rb — it must pass on the current code before any refactoring begins. If it fails, stop and fix the test or the existing code first.
The default tiny slice when extracting controller orchestration:
Before (controller does orchestration):
def create
order = OrderCreator.new(params).call
NotifyWarehouseJob.perform_later(order.id)
redirect_to order_path(order)
end
After (same behavior, extraction only):
def create
order = Orders::CreateOrder.call(params: params)
redirect_to order_path(order)
end
Use support files for detailed guidance and examples:
When asked to refactor:
| Skill | When to chain |
|---|---|
| rspec-best-practices | For additional spec structure and shared examples after characterization tests are written |
| rails-architecture-review | When refactor reveals structural problems (details) |
| rails-code-review | For reviewing the refactored code (details) |
| ruby-service-objects | When extracting logic into service objects (details) |