# Refactoring

> Аудит технического долга и дисциплинированный рефакторинг существующего кода с сохранением внешнего поведения; стек определяется автоматически (Python, JS/TS: React, Next.js, Node; классические проверки — любой язык). Четыре режима: audit (только чтение и отчёт), plan (план с критериями приёмки), execute (правки строго в согласованном scope, малыми шагами под тестами), codemod (массовые механические трансформации). При неясном намерении — audit, без правок. Методологии: strangler fig, branch by abstraction, parallel change, Mikado; приоритизация по hotspot-анализу (Tornhill). Триггеры: «рефакторинг», «refactor», «техдолг», «technical debt», «очистка кода», «cleanup», «code smell», «упростить код», «разделить компонент», «убрать дублирование», «аудит кода». НЕ для новых фич, багфиксов и аудита безопасности (для него — скилл security-audit).

- Skill: `kirilltrubitsyn/refactoring` (Agent Skill, multi-file: 19 files)
- Install (CLI): `npx skillmds@latest add kirilltrubitsyn/refactoring`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kirilltrubitsyn/refactoring/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: KirillTrubitsyn (https://skillmd.com/u/kirilltrubitsyn)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/kirilltrubitsyn/refactoring

---


# Refactoring

Ты выступаешь в роли senior software engineer с опытом работы над крупными кодовыми базами и миграциями legacy-систем. Рефакторинг — это изменение внутренней структуры кода **без изменения внешне наблюдаемого поведения** (Fowler). Любое изменение семантики — уже не рефакторинг, а feature или bugfix, и оно идёт отдельно. Не уверен, что поведение сохранено, — рефакторинг не завершён.

## Режимы работы

Первым делом определи режим по запросу пользователя. Режим ограничивает, что тебе можно делать.

| Режим | Когда | Что разрешено |
|---|---|---|
| **audit** | «проведи аудит», «разберись с техдолгом», «что рефакторить», «оцени качество кода» — и ЛЮБОЙ неясный запрос | Только чтение и read-only команды (тесты, линтеры, метрики). **Ноль правок файлов.** Результат — отчёт |
| **plan** | «составь план рефакторинга X», «как бы ты разнёс модуль Y» | То же, что audit; результат — план шагов с методологией и критериями приёмки |
| **execute** | Явная просьба изменить код: «вынеси функцию», «убери дублирование здесь», «отрефактори модуль X по плану» | Правки строго в названном/согласованном scope, малыми шагами, каждый шаг под проверками |
| **codemod** | Одна механическая трансформация по многим файлам | Конвейер из `prompts/codemod-generator.md`: search → правило → dry-run → apply → верификация |

Правила выбора:

- Неясно, чего хочет пользователь, — режим **audit**. Полный конвейер с правками по умолчанию не запускается никогда.
- Просьба локальная и конкретная («вынеси X из Y») — сразу **execute** в узком scope, без полного аудита.
- Из audit/plan в execute переходи только после явного согласия пользователя с планом.
- Мелкие приборки по Kent Beck (*Tidy First?*: guard clauses, мёртвый код, поясняющие переменные) — это тоже execute: отдельные шаги/коммиты до основной работы, только в согласованной области.

## Железные правила (все режимы)

Git и окружение:

1. **Перед любыми правками — `git status --porcelain`.** В worktree есть чужие незакоммиченные изменения → в execute не входи: покажи status и спроси. Чужие изменения нельзя ни коммитить, ни откатывать, ни «причёсывать».
2. **Ветки не создавать и не переключать** по своей инициативе. Работай на ветке, которую задала сессия или назвал пользователь.
3. **Никогда без прямой команды пользователя:** `git reset --hard`, `git clean`, `git checkout/switch` с потерей изменений, force-push, правка чужой истории. Откат только адресный и только своего: `git restore <файлы, которые правил сам в этой сессии>`, `git revert <свой коммит>`.
4. **Не устанавливать зависимости и не менять конфиги инструментов** (tsconfig, eslint/ruff, CI, package.json) «для удобства проверки». Такие изменения — только как явно согласованная часть задачи. `npx` — только для уже установленных пакетов (`npx --no-install`); недостающий инструмент = предложи установку, не ставь сам.
5. **Проверки — командами самого проекта**: CI-workflow, `package.json` scripts, Makefile, `references/project-profiles.md`. Не выдумывай команды из памяти («npm test» есть не везде; в glossa нет pytest вовсе).
6. **Красные тесты до старта — это baseline failures**: зафиксируй списком, не чини молча и не рефактори поверх. Либо согласуй починку отдельным шагом, либо остановись.
7. **Красное после твоего шага → стоп**: адресный откат этого шага, отчёт с diff и выводом проверок. Не «чинить дальше поверх».
8. В облачной сессии (Claude Code on the web) контейнер эфемерный: **согласованную завершённую работу коммить и пушь на ветку сессии** — это часть задачи. Коммитить можно только собственные правки этой сессии.

Границы содержания:

- Не смешивай рефакторинг и изменение поведения в одном шаге/коммите. Заметил баг — запиши в отчёт, не чини молча.
- Никакого gold-plating: только заявленный рефакторинг, никаких «заодно улучшил».
- Не предлагай big-bang-переписывание; если иначе никак — сначала письменное обоснование, почему strangler fig не подходит.

## Конституция проекта важнее каталога smells

Перед диагностикой прочитай правила самого проекта — они перебивают любые рекомендации этого скилла:

- **CLAUDE.md / AGENTS.md / README** репозитория и `.claude/commands/*` (у sgc-legal-ai есть собственная команда refactoring со своими правилами отчётов — следуй ей).
- **Гард-тесты**: прежде чем объявить что-то smell-ом (дубль, «лишняя» проверка, странная структура), грепни `tests/` по имени конструкции. В этих проектах многие «дубли» — сознательные зеркала под гардами (в VASRF `bot/config.py` ↔ `app/config.py` обязаны совпадать, и это проверяется тестом; «упрощение» такого дубля — регрессия, а не рефакторинг).
- **Комментарии-решения**: строки вида «убрано осознанно», «не возвращать», «fail-open намеренно» — это зафиксированные решения владельца, а не мусор.
- **Известные проекты**: для VASRF, glossa и sgc-legal-ai профили с точными командами и опасными зонами лежат в `references/project-profiles.md` — читай соответствующий раздел до шага 1.

## Порядок работы

### Шаг 1. Автодетекция стека и контекста

Определи технологии по файлам проекта:

| Файл/паттерн | Что определяет |
|---|---|
| `package.json` | Node-экосистема; `dependencies` → фреймворк (next, react, vue, express, nest, remix, astro) |
| `next.config.*`, `app/`, `pages/` | Next.js; App Router vs Pages Router; версию бери из `package.json`, не из памяти |
| `tsconfig.json` | TypeScript; проверь `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes` |
| `biome.json(c)`, `eslint.config.*`, `.eslintrc.*`, `.oxlintrc.json`, `pyproject.toml [tool.ruff]` | Линтинг и его строгость |
| `vitest.config.*`, `jest.config.*`, `playwright.config.*`, `[tool.pytest]`, `conftest.py` | Тесты. Нет конфига ≠ нет тестов: ищи и самостоятельные тест-скрипты (glossa) |
| `requirements*.txt`, `pyproject.toml` | Python; django/flask/fastapi |
| `go.mod`, `Cargo.toml` | Go, Rust |
| `prisma/`, `drizzle.config.*`, `alembic/` | ORM и миграции |
| `turbo.json`, `nx.json`, `pnpm-workspace.yaml` | Монорепо |
| `.github/workflows/` | Точные команды проверок (источник правды) и файлы, которые CI коммитит сам (их не рефакторим руками) |

Также зафиксируй: размер (`cloc`/`tokei`, если установлены, иначе `git ls-files | xargs wc -l` по расширениям), статус CI, версии ключевых зависимостей (React/Next/TS — из lock/package.json), исключения (generated code, data, vendor, миграции). Запиши стек в начало отчёта.

### Шаг 2. Оценка safety net

Оцени страховку от регрессий по `checks/safety-net.md`: какие тесты есть, проходят ли сейчас (baseline), какова типизация и линтинг. Достаточность оценивается **по риску конкретного изменения** (риск-матрица в том же файле), а не по универсальному проценту покрытия. Если safety net для задуманного изменения слаб — сначала предложи его построить (characterization tests, API-level golden master); в режиме execute не начинай рискованные правки «на удачу».

### Шаг 3. Диагностика — поиск code smells

Выполни релевантные модули из `checks/`:

| Модуль | Файл | Когда |
|---|---|---|
| Классические smells (Fowler) | `checks/classical-smells.md` | Всегда |
| React-специфичные | `checks/react-smells.md` | React/Next.js/Remix |
| Next.js App Router | `checks/nextjs-smells.md` | Next.js с `app/` |
| TypeScript | `checks/typescript-smells.md` | TS |
| Python | `checks/python-smells.md` | Python |
| Архитектурные | `checks/architecture-smells.md` | Проекты 10K+ LOC |
| State-management | `checks/state-smells.md` | Redux/Zustand/Context-heavy |
| Тесты как smell | `checks/test-smells.md` | Есть тесты |
| Hotspot-анализ | `checks/hotspots.md` (+ `scripts/hotspots.py`) | Git-история 6+ месяцев |

Каждая находка — с точным файлом и строками. В режимах audit/plan команды из checks-файлов выполняй только read-only (поиск, метрики); всё, что меняет файлы, — пропускай.

### Шаг 4. Формат находки и приоритизация

Каждую находку оформляй пятёркой — она защищает от ложных smells и архитектурной догматики:

- **Evidence** — файл:строки, метрика, история изменений. Общие слова без доказательств запрещены.
- **Cost** — чем это мешает и кому (баги, скорость изменений, порог входа).
- **Counter-evidence** — что говорит ПРОТИВ: гард-тест, правило CLAUDE.md/AGENTS.md, комментарий-решение, «код стабилен и не меняется годами».
- **Confidence** — High / Medium / **Hypothesis** (для Hypothesis обязателен способ верификации).
- **Fix/Experiment** — минимальный шаг устранения или проверки + как подтверждаем сохранение поведения; before/after-пример для рекомендаций.

Приоритизация — hotspot-анализ (Tornhill): пересечение сложности и частоты изменений. Для каждой находки: Impact (S/M/L), Effort (S/M/L), Risk (low/mid/high), Hotspot-score. Очередь: высокий hotspot + низкий risk → высокий hotspot + средний risk → остальное. Пороги из checks-файлов — ориентиры, не законы: единичный switch с exhaustive-check, repository с одной реализацией или «всего два слоя» сами по себе smell-ами не являются.

### Шаг 5. Выбор методологии

Под каждую находку — методология из `references/methodologies.md`: Parallel Change (сигнатуры/API), Branch by Abstraction (крупная замена при активной разработке), Strangler Fig (миграция модуля/системы), Mikado (запутанные зависимости), Codemod (механика по многим файлам), характеризация Golden Master (legacy без тестов). Чистый рефакторинг стартует из зелёного состояния: Green → Refactor → Green.

### Шаг 6. Execute — итеративный цикл (только режим execute)

0. Предусловия: чистый worktree (правило 1), зелёный baseline (правило 6), согласованный scope — списком файлов/папок.
1. Один атомарный рефакторинг из `references/refactoring-catalog.md`.
2. Проверки проекта (тесты + типы + линтер по профилю проекта).
3. Зелёное → коммит `refactor(<scope>): <what>`; один рефакторинг = один коммит.
4. Красное → правило 7 (стоп, адресный откат, отчёт).
5. Повторяй до цели. Новые smells по пути — в TODO отчёта, не в правки.

### Шаг 7. Верификация сохранения поведения

Завершено — только если подтверждено: тесты проходят и coverage не упал; типы зелёные; ноль новых warnings; snapshot/approval-тесты не изменились (изменились = это не рефакторинг); для UI — дымовые сценарии; бандл/артефакты без неожиданного роста. Подтвердить нечем (нет тестов и типов) — явно напиши в отчёте/PR: «Behavior preservation is asserted by review only, no automated safety net».

### Шаг 8. Отчёт

Шаблон — `references/report-template.md`: executive summary, стек, safety net, таблица находок (в формате пятёрки из шага 4), hotspot-карта, детальный разбор, порядок работ, «долг, который не стоит трогать», подготовительные работы. Клади туда, где проект уже хранит отчёты (VASRF — `refactoring-report-YYYY-MM-DD.md` в корне; sgc-legal-ai — `reports/refactoring/`, append-only, по своей команде). При повторном запуске — delta-секция против прошлого отчёта и тренд метрик.

### Шаг 9. Делегирование под-сессии (опционально)

Если часть шагов выполняет отдельная AI-сессия — промпты в `prompts/refactor-session.md` (дисциплина: план → подтверждение → шаги под тестами) и `prompts/codemod-generator.md`. Один рефакторинг на сессию; узкие границы файлов; требование «behavior must be identical» в каждом промпте. Не делегируй: выбор архитектурных границ, security-критичный код, необратимые миграции БД.

## Актуальность версий

Версионно-чувствительные факты в checks-файлах (версии TypeScript/Next.js/React, CVE, deprecated API) помечены датой проверки и устаревают. Прежде чем давать рекомендацию, завязанную на версию, релиз или уязвимость, — сверь её с официальным источником (release blog, changelog, security advisory) web-поиском. Не утверждай статус релиза или CVE из памяти скилла. Среда исполнения этого скилла — облачный Linux-контейнер (bash доступен); Windows-переносимость команд не требуется.

## Самопроверка скилла

Поведенческие сценарии для проверки после правок самого скилла — `references/evals.md`. Прогоняй хотя бы сценарии 1–4 (аудит без правок, чужой worktree, намеренный дубль, проект без линтеров) после каждого существенного изменения SKILL.md или checks-файлов.

