Use when you need to scope refactors safely, preserve behavior, avoid unrelated churn, and verify changed surfaces.
How this skill is triggered — by the user, by Claude, or both
Slash command
/skillry-core-operations:05-refactor-safetyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Enforce a disciplined process for structural code changes: lock in existing behavior with tests before touching anything, shrink the diff to only what is necessary, keep each step independently verifiable, and maintain a clear rollback path. This prevents the three most common refactor failures — silent behavior regressions, test-suite gaps masked by green CI, and scope creep that tangles unrel...
Enforce a disciplined process for structural code changes: lock in existing behavior with tests before touching anything, shrink the diff to only what is necessary, keep each step independently verifiable, and maintain a clear rollback path. This prevents the three most common refactor failures — silent behavior regressions, test-suite gaps masked by green CI, and scope creep that tangles unrelated concerns into one unreviewable PR. The defining rule: a refactor must not change observable behavior, so the test result before and after must be identical.
git grep -n "functionName\|ClassName" -- '*.ts' or the IDE "Find usages". List them; you will verify each one after the change.npm test -- --testPathPattern=affected or pytest tests/affected). Do not advance until it is green. If a test fails, revert that single step and diagnose in isolation.require/import), docs, config files, __mocks__, fixtures, and CI workflow YAML. Stale names there cause confusing runtime failures that the compiler never catches.git diff --stat, read every changed file, and revert anything outside the scoped module (or split it into a separate PR).Refactor in place when behavior must be preserved exactly and tests can prove it. Choose a rewrite (behind a flag, old path kept until the new one is proven) when the existing code has no tests, depends on a discontinued library, or its control flow cannot be reasoned about. The tell: if you cannot write a characterization test because you cannot predict the current output, you do not understand the code well enough to refactor it safely — rewrite against a spec instead.
| Tier | Example | Required safety net |
|---|---|---|
| Low | rename a local var, extract a private helper | unit test for the enclosing unit |
| Medium | rename an exported function used in one package | characterization tests + all call sites verified |
| High | change a shared interface or base class | characterization tests + integration tests + staged rollout |
| Critical | migrate ORM, auth, or money-handling code | full suite + feature flag + old path retained one release |
git diff --stat reviewed; no unrelated files appear.# 1. Baseline: record pass/fail and coverage for the target before changes
npm test -- --watch=false
npx jest --coverage --collectCoverageFrom='src/auth/**' 2>/dev/null | tail -20
# Python equivalent:
pytest --cov=src/auth --cov-report=term-missing -q | tail -20
# 2. Map all call sites (static)
git grep -n "calcPrice\|PriceCalculator" -- '*.ts' '*.tsx'
git grep -l "calcPrice" | wc -l # blast-radius count
# 3. Catch dynamic / non-obvious consumers a compiler will miss
rg -n "calcPrice" --type-add 'cfg:*.{json,yaml,yml,md}' -tcfg
rg -n "require\(.*calcPrice|import\(.*calcPrice" src/
rg -n "calcPrice" __mocks__/ test/fixtures/ .github/workflows/
# 4. Per-step verification (run after EACH atomic commit)
npm test -- --testPathPattern=auth
tsc --noEmit && npx eslint src/auth
# 5. Confirm no unrelated churn before opening the PR
git diff --stat
git diff --name-only | grep -v '^src/auth/' || echo "scope clean"
# Language-specific call-site + dead-code detection
# TypeScript: find unused exports before deleting a symbol
npx ts-prune | rg "calcPrice"
# Python: find references and dead code
git grep -n "calc_price" -- '*.py'
vulture src/ --min-confidence 80 | rg "calc_price"
# Go: who imports the package, and is the symbol used
go list -deps ./... | rg pricing
staticcheck ./... 2>/dev/null | rg "U1000" # unused code
# Worked example: a rename split into atomic, individually-green commits
git mv src/pricing/calcPrice.ts src/pricing/priceCalculator.ts # step A: move only
npm test -- --testPathPattern=pricing && git commit -am "move: rename file"
# step B: rename the symbol, update imports, no logic change
rg -l "calcPrice" src/ | xargs sed -i '' 's/calcPrice/priceCalculator/g'
npm test -- --testPathPattern=pricing && git commit -am "rename: calcPrice -> priceCalculator"
# step C (separate PR): only now change behavior, with a new failing test first
git diff --stat # confirm step B touched only renames, zero logic lines
# Bisect a regression introduced by a refactor (atomic commits make this work)
git bisect start
git bisect bad # current HEAD is broken
git bisect good <pre-refactor-sha> # last known-good commit
# git checks out midpoints; at each step run the scoped test and mark it:
npm test -- --testPathPattern=pricing && git bisect good || git bisect bad
git bisect reset # when the first bad commit is found
# Verify the suite outcome is byte-identical before vs after (behavior preserved)
git stash && npm test -- --watch=false 2>&1 | tee /tmp/before.txt
git stash pop && npm test -- --watch=false 2>&1 | tee /tmp/after.txt
diff <(grep -E 'Tests:|passing|failing' /tmp/before.txt) \
<(grep -E 'Tests:|passing|failing' /tmp/after.txt) && echo "behavior preserved"
# Confirm coverage did not drop on the touched module
npx jest --coverage --collectCoverageFrom='src/pricing/**' 2>/dev/null | rg "pricing|All files"
git blame, and breaks git bisect. Resist all of it.git mv src/auth.ts src/authentication.ts with logic edits makes bisect useless — you cannot tell whether the move or the logic introduced the regression.require(path.join(__dirname, moduleName)) is invisible to static grep. Search the string form separately.any casts and loose JS interop hide type mismatches that only fail at runtime. Run integration tests, not only unit tests.Report must include:
npx claudepluginhub fluxonlab/skillry --plugin skillry-core-operationsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.