Поиск побочных поломок от изменения

Этот навык помогает выявить потенциальные проблемы, которые могут возникнуть из-за изменений в коде, и предоставляет доказательства безопасности этих изменений. Используйте его перед внесением изменений в код или при оценке рисков.

Экосистема: Универсальный

Инструкция

---
name: what-could-break
description: "Find what a change breaks outside its own diff, then prove the one fact that makes it safe by running real code. Use before any multi-file edit or an edit to a shared path."
category: development
risk: safe
source: community
source_repo: stas4000/what-could-break
source_type: community
date_added: "2026-10-08"
author: stas4000
tags: [code-review, refactoring, testing, blast-radius, verification]
tools: [claude, cursor, gemini]
license: "MIT"
license_source: "https://github.com/stas4000/what-could-break/blob/main/LICENSE"
---

# Что может сломаться

## Обзор

Перечисление вызывающих функций — это не задача. Grep справляется с этим за секунды. Этот навык находит поломки, которые grep не покажет, и предоставляет одно доказательство того, что изменение безопасно.

Запускайте его перед проектированием, а не только перед слиянием. Каждый раз, когда задача утверждает что-то о существующем коде ("X уже обрабатывает Y", "просто сделайте X публичным"), это утверждение является гипотезой, и перепись реальных потребителей определяет проектирование.

## Когда использовать

- Используйте перед любым редактированием нескольких файлов или редактированием общего пути: полезная нагрузка API, конфигурация, хранимые данные, клиент, который читают другие приложения, файл подсказки или политики.
- Используйте, когда пользователь спрашивает "что это может сломать" или "радиус поражения X".
- Используйте для небольшого изменения, которому вы не доверяете.
- Используйте, когда краткое утверждение касается существующего кода, перед тем как проектировать против этого утверждения.

## Как это работает

### Шаг 1: Не доверяйте своему собственному описанию

Анализ рисков, который звучит правильно, бесполезен: он выглядит убедительно, независимо от того, правда это или нет. Найдите один или два факта, от которых зависит всё изменение, и получите каждый из них как можно дальше по этой лестнице, если это дешево. Укажите, где это остановилось.

1. **Вы так сказали.** Ничего не стоит само по себе.
2. **Вы указали на это.** Реальный `file:line`, или собственный исходный код библиотеки на зафиксированной версии.
3. **Вы проследили это.** Вы проследили плохой случай шаг за шагом, и он не достигает.
4. **Вы запустили это.** Скрипт или тест вызывает реальный код и громко сообщает о неудаче, если вы ошибаетесь.
5. **Вы видели это вживую.** Воспроизведено в работающем приложении, сервисе или устройстве.

Четвертая ступень обычно представляет собой один небольшой скрипт, который импортирует тот же модуль, который работает в производстве, и вызывает именно ту функцию, о которой вы беспокоитесь, с теми входными данными, которые вас беспокоят.

### Шаг 2: Прочитайте изменение

Разница, символы, которые она добавляет, изменяет и удаляет, и что она теперь делает иначе, включая то, что разница не указывает. `git log -S '<symbol>'` и `git log -L :<function>:<file>` показывают, почему старая форма существует; охрана, которая выглядит бессмысленно, часто имеет коммит, объясняющий инцидент, который она остановила.

### Шаг 3: Найдите один факт, из-за которого это безопасно

Большинство изменений, выглядящих рискованными, безопасны благодаря одному факту ("это только удаляет записи кэша, которые уже истекли", "ни один клиент не читает это поле"). Если это верно, большинство рисков исчезает сразу. Если вы не можете найти один, изменение еще не понято.

### Шаг 4: Посмотрите, где останавливается grep

Ищите буквальное значение, имя поля, текст ошибки и старое поведение, а не только символ, который вы переименовали. Затем проверьте каждое из этих вручную:

- **То же правило, живущее дважды.** Второй файл конфигурации, резервный путь, который жестко кодирует старый стандарт, копия, синхронизированная в другом репозитории, константа, дублированная в миграции или тестовом наборе, значение по умолчанию для флага функции.
- **Подсказки и файлы агентов, которые повторяют правило.** Системные подсказки, файлы агентов и навыков, `AGENTS.md`, `CLAUDE.md`, рабочие инструкции. Агент подчиняется устаревшему предложению, а не вашему коду.
- **Каждый другой клиент.** Веб, iOS, Android, настольные приложения, CLI, расширения, интеграции с партнерами. Мобильные клиенты в руках пользователей остаются на старой версии в течение недель: что делает старый клиент с новой формой, а новый клиент со старым сервером?
- **Форматы передачи.** Имена и типы полей JSON, значения перечислений, null против отсутствия, форматы дат, форма пагинации, коды ошибок, полезные нагрузки вебхуков, схемы очередей, контракты GraphQL и protobuf.
- **Хранимое состояние.** Столбцы и их значения по умолчанию, строки, записанные под старой формой, записи кэша, файлы на диске, журналы только для добавления, содержимое сессий и куки, индексы поиска. Старые данные переживают развертывание.
- **Окружение и секреты.** Переменная окружения, переименованная в коде, но не в конфигурации развертывания, CI, образе или втором сервисе, который ее читает.
- **Процессы, которые перезапускаются отдельно.** Веб-сервер, рабочие процессы, задания cron, безсерверные функции, мобильное приложение, сайдкар. Во время развертывания один запускает новый код, в то время как другой запускает старый код против тех же данных. Могут ли оба сосуществовать в течение часа?
- **Время и параллелизм.** Два писателя на одной строке или ключе, повторная попытка, которая теперь срабатывает дважды, порядок, который держался только потому, что один шаг был медленным.
- **Исходный код библиотеки на зафиксированной версии.** Читайте код зависимости на версии lockfile, а не по вашей памяти о его документации.
- **Сгенерированный и поставляемый код.** Клиенты, сгенерированные из схемы, поставляемые копии, зафиксированные артефакты сборки, пакеты, ключ кэширования которых не изменился.
- **Тесты и фикстуры, которые кодируют старое поведение.** Тест, который проходит, потому что его фикстура все еще имеет старую форму, ничего не доказывает о новой.
- **Наблюдаемость.** Панели мониторинга, оповещения и парсеры журналов, соответствующие сообщению или имени метрики, которые вы изменили.

### Шаг 5: Докажите один факт

Напишите скрипт или тест, который запускает реальный код, выполните его и вставьте, что произошло. Если вы не можете его запустить, напишите "не доказано" рядом с фактом. Для широкого изменения повторите шаги 3-5 для каждого подсистемы, вместо того чтобы растягивать одно описание на всё.

## Примеры

### Пример 1: Поле, удаленное из ответа API

Один факт: ни один клиент не читает `legacy_total`. Вторая ступень — это поиск по каждому репозиторию клиента. Четвертая ступень — это скрипт, который воспроизводит реальные запросы вчерашнего дня против нового сериализатора и утверждает, что ни один ответ не уменьшает поле, которое все еще парсит хранимая сборка клиента. Отчет называет сборку iOS, которая все еще находится в руках пользователей, и очищенные веб- и админ-клиенты.

### Пример 2: "Просто сделайте этот вспомогательный метод публичным"

Краткое утверждение утверждает, что вспомогательный метод уже не имеет побочных эффектов. Рассматривайте это как гипотезу: прочитайте его, затем запустите его дважды в одном процессе и сравните состояние. Если он кэширует, утверждение неверно, и проектирование изменится до написания кода.

## Лучшие практики

- ✅ Укажите ступень, на которую достигнут каждый факт, и команду, которая это доказала.
- ✅ Перечислите очищенные риски отдельно от подтвержденных, с поиском, который вы провели.
- ✅ Укажите реальный `file:line` для каждого риска.
- ❌ Не выдумывайте вызывающую функцию, API или ключ конфигурации.
- ❌ Не отправляйте убедительное эссе вместо одного запущенного скрипта.

## Ограничения

- Риск должен иметь реальный шанс и реальную стоимость, иначе он не должен находиться в списке.
- Поиск, который ничего не нашел, все равно является ответом: запишите поиск, а не утверждайте, что риск не существует.
- Этот навык не заменяет тестирование, специфичное для окружения, или экспертную оценку.
- Держите секреты и личные данные вне отчета и вне любого оставленного скрипта.

## Примечания по безопасности и надежности

- Скрипты доказательства, которые пишет этот навык, запускают реальные производственные пути кода. Запускайте их в локальной или авторизованной тестовой среде, никогда не против производственных хранилищ данных.
- Проектировалось как только для чтения: оно проверяет разницу и выполняет проверки. Оно не изменяет состояние и не должно использоваться для применения исправлений.
Источник на GitHub