Сессия, выкатившая баг, и ретро, сказавшее «гладко»
Claude Code выкатил баг нумерации в реальном репозитории, а четыре одобренные правки сделали так, что он больше не уедет в релиз. Сессия писала кредит-ноты для небольшого API выставления счетов, набор тестов вернул зелёный результат, а проверка, которую мы потом прогнали вручную, показала, что отклонённый запрос сжёг номер счёта. Затем мы запустили ретро на этой сессии, по одной одобрили правки и снова выполнили ту же задачу: результат был чистым.
Ретро это разбор, который команда проводит после инцидента; здесь он запускается на собственном логе сессии Claude Code. Наше первое ретро началось словами 'This session was smooth', и ни одна из его находок не была этим багом. Лечение состоит из семи шагов по порядку: установить, выполнить задачу, запустить ретро и сказать, что сломалось, привязать каждого кандидата к моменту, одобрить каждого выжившего в его носитель, закоммитить и проверить, повторить задачу.
Что такое ретро и установка /retro
/retro это скилл Matt Pocock, который разбирает сессию программирования, а не ваш код. Он читает лог сессии, то есть файл, где Claude Code хранит каждый промпт и каждый вызов инструмента, и ищет кандидатов в семи категориях, например проверку, которая могла бы поймать ошибку. Он показывает их по степени важности и, по его докам, только предлагает: ничего не меняется, пока вы не выберете кандидата.
Установка это первый шаг: в своём репозитории обновите официальный маркетплейс, затем установите пакет скиллов на уровне проекта, чтобы он жил только в этом репозитории. Наш маркетплейс был привязан к старому релизу без ретро, поэтому сначала пришлось обновить его. В новой сессии введите слэш, и команда retro появится в списке.
Одно ограничение: облачная сессия не может читать логи на вашей машине, поэтому запускайте ретро там, где шла сессия.
Запусти задачу и дай ей закончить: наша сессия выкатила баг
Второй шаг вы и так делаете каждый день: введите свою настоящую задачу в обычной сессии, дайте ей закончить и не закрывайте сессию, ведь именно её прочитает ретро.
Мы взяли небольшой API выставления счетов на Node и TypeScript со своим набором тестов, без файла инструкций, без пайплайна и без коммит-хука. Задача была короткой, как вы бы и сами её набрали: добавить кредит-ноты к оплаченным счетам с последовательной нумерацией и дать возможность аннулировать оплаченный счёт, начислив кредитом остаток.
Сессия написала роут, миграцию и собственные тесты и прогнала набор перед остановкой. Затем мы выполнили проверку, которую сделала бы финансовая служба вручную, скрытый тест, написанный заранее, и одно требование не прошло.
| Сигнал | Результат |
|---|---|
| Набор тестов | 42 теста пройдены |
| Проверка типов | чисто |
| Скрытая финансовая проверка | провалена: получен более поздний номер кредит-ноты, чем ожидалось |
Причина: хендлер берёт следующий номер из счётчика до того, как проверит запрос, а счётчик сохраняется в момент чтения. Слишком большая кредит-нота отклоняется, и это правильно, но номер всё равно потерян, и это неправильно. Сессия скопировала этот порядок из существующего роута выписки счетов, который теряет номера счетов точно так же.
Мы запускали задачу дважды, и другой прогон вышел чистым, так что обычная сессия делает это лишь иногда.
Запусти /retro, затем скажи, что сломалось
Третий шаг: введите команду ретро в той же сессии, а потом запустите её снова, дописав после неё провал. Наше первое ретро начиналось так: 'This session was smooth'.
Оно выстроило по рангу несколько пунктов, и ни один из них не был багом: отсутствующая защита, правило миграций, которое никто не проверяет, и ничего, что мог бы применять ревьюер. Ретро читает лог сессии, а сессия так и не узнала, что провалилась.
Поэтому вы говорите ему сами: запустите команду ещё раз, передав провал как аргумент, то есть текст после команды. В нашем говорилось, что финансовая служба проверила сборку, что слишком большая кредит-нота была отклонена, что следующая корректная нота вышла с опозданием по номеру и что ретро ничего не должно чинить.
На этот раз оно нашло причину в собственном коде: сначала берёт номер, потом проверяет, и сообщило, что скопировало этот порядок из существующего хендлера выписки. Дальше появились новые кандидаты: тест, который оно написало, прогонял сбойную последовательность, но проверял только коды статусов, функция счётчика, которая выглядит чистой, а на деле нет, и соглашение, которое никто не записал.
Всё, что вы обнаружили после сессии, впишите в аргумент, иначе ретро будет проверять сессию, которая, по его мнению, прошла нормально.
Привяжи каждого кандидата к моменту до одобрения
Четвёртый шаг скилл сам не делает: попросите ретро процитировать момент транскрипта за каждым кандидатом и отбросьте всех, кого оно не может показать.
Доки объясняют, почему ранжированного списка недостаточно: когда работа закончена, модель забывает трудности сессии и придумывает общие советы. Поэтому отбрасывайте любого кандидата, которого нельзя привязать к конкретному моменту: достаточно одного предложения с просьбой процитировать транскрипт для каждого.
На первом ретро ответ был прямым: у большинства кандидатов не было опоры в транскрипте. Оно оставило отсутствующую защиту, потому что его собственный листинг папки с хуками ничего не вывел, и отбросило проверку миграций как гипотетическую.
На втором ретро, которое уже знало про баг, трассировка оставила четырёх кандидатов и отбросила одного.
| Кандидат | После трассировки |
|---|---|
| Тест, который оно написало (принято, отклонено, принято, номер не проверен) | оставлен, уверенно |
| Функция счётчика без предупреждения | оставлена, уверенно |
| Неписаное соглашение | оставлено, слабее |
| Отсутствующая защита | оставлена, хотя оно сказало, что защита этот баг не поймала бы |
| Последний кандидат | отброшен: он считал один и тот же момент дважды |
В открытом issue в репозитории скилла отмечено, что за большинством запусков ретро следует просьба пользователя предоставить доказательства. Кандидат с трассировкой всё равно остаётся моделью, читающей собственный лог, так что строка «слабее» это суждение, и вы решаете, кого переносить дальше.
Одобри каждого выжившего в его носитель
Пятый шаг: здесь цикл окупается. Одобряйте выжившего по одному, каждого в его носитель, то есть в место, где будет жить правило. Скилл даёт вам лестницу. Механическое нарушение получает детерминированную проверку, и точка: правило в линтере, коммит-хук или задача в пайплайне. Решение на усмотрение идёт в файл стандартов кода, который читает ревьюер. Файл инструкций используется, по словам доков, «incredibly sparingly», для указателей на другие файлы.
Мы одобрили четыре изменения:
- Отсутствующая защита стала отслеживаемым коммит-хуком, который запускает проверку типов и тесты и блокирует коммит, если что-то из этого падает. Harness отказался сделать файл исполняемым, поэтому мы выполнили эту команду сами.
- Тест стал одним тестом на
vitest, фиксирующим правило: кредит-нота принята, кредит-нота отклонена, и следующая корректная должна получить следующий номер. Он упал при первом запуске, в этом и смысл: он поймал баг, который выкатила сессия. - Решение на усмотрение стало одной строкой в новом
CODING_STANDARDS.md: брать порядковый номер только после прохождения всех проверок, чтобы отклонённый запрос не оставлял пропусков в последовательности. - Пробел в навигации стал одним комментарием над функцией счётчика: она сохраняет счётчик сразу, поэтому номер тратится, даже если вызывающий код потом упадёт, так что вызывайте её только после проверки.
Итого изменено четыре файла и ноль строк в CLAUDE.md, потому что оба ретро отказались его писать. Первое сказало, что указатель в управляющем файле будет стоить контекста в каждом ходе и устареет, второе посоветовало оставить это комментарием к функции. Доки это подтверждают: Claude воспринимает такие файлы как контекст, а не как принудительную конфигурацию, а чтобы заблокировать действие, нужен хук.
Два ограничения: хук защищает только коммиты, а комментарий, по словам самого ретро, это ставка на следующего вызывающего, а не доказанное исправление.
Замкни цикл: хук блокирует коммит, аудит, коммит, повтор
Шестой шаг это коммит, а последний это повторный запуск той же задачи, где и выясняется, держится ли цикл.
Когда мы добавили одобренные файлы в индекс и сделали коммит, хук сработал первым и отклонил его. Проверка типов прошла, затем новый тест нумерации упал: он получил более поздний номер, чем ожидал. Хук проверяет файлы в том виде, в каком они лежат на диске, а на диске всё ещё был код с багом.
Поэтому вернитесь в сессию и попросите только исправление: брать номер после прохождения проверок, прогнать проверки, не коммитить. Затем закоммитьте снова, хук проходит зелёным, и вы получаете два коммита: изменения ретро, затем фича с её исправлением. Само ретро ничего не коммитило, о чём слово в слово говорит открытый issue в репозитории, так что коммитите вы.
Далее запустите /doctor prompt-audit, собственную проверку Claude Code на устаревшие строки в файлах инструкций. Здесь ловушка: без пути он проверяет ваши глобальные файлы, а не репозиторий. С путём он назвал новый файл стандартов чистым и отметил, что старый роут выписки нарушает правило: это баг в коде, а не проблема промпта.
Последний шаг: свежая сессия с той же задачей. Наша перед написанием кода прочла файл стандартов кода, readme, хук и красный тест нумерации, а затем написала в своём итоге, что номер берётся только после прохождения всех этих проверок, поэтому отклонённый запрос не оставляет пропуска в последовательности.
| Первая сессия | Свежая сессия после цикла | |
|---|---|---|
| Пройдено тестов | 42 | зелёный результат |
| Скрытая финансовая проверка | провалена | 5 из 5 |
| Номера после отклонённого запроса | сожжены, пропуск | без пропусков |
Одна честная оговорка: эта свежая сессия получила урок в виде красного теста и строки стандартов, так что это прогон после цикла, а не бенчмарк.
Вердикт: когда запускать ретро, когда нет, и одно правило
Ретро читает сессию, поэтому то, чего сессия не видела, вы записываете в аргумент. Именно об это вы и споткнётесь.
Запускайте ретро после сессии, которая пошла не так, до того как вы её очистите, или на логе старой сессии. Не запускайте его на автопилоте и не подключайте к хуку: автор скилла говорит это своими словами, вам не нужно это автоматизировать. Доки добавляют ограничение: оно не проверяет те проверки, которые предложило в прошлом месяце, поэтому подчищать их вам всё равно придётся самим.
Правило, которое стоит запомнить, это предложение из самих доков: относитесь к файлу инструкций как к коду, пересматривайте его, когда что-то идёт не так, регулярно чистите и проверяйте изменения, наблюдая, действительно ли меняется поведение Claude. Цикл не делает агента правым, он лишь позволяет быстрее поймать ту же неправоту, а проверки, которые вы добавляете, это код, который теперь вам поддерживать.
В бесплатном паке к этому видео есть чек-лист ретро со всеми шагами, вопросом для трассировки и носителями, а также скрипт коммит-хука и тест нумерации из нашего прогона, так что вы можете начать с нашей основы.
AIDive