Перейти к содержимому

Навыки

chimera-reproduce-before-diagnosing

Диагноз — это утверждение о машине, которую вы не запускали. Сначала воспроизведите сбой одной короткой командой — особенно если диагноз пришёл от кого-то другого.

ПаттернПроисхождение: cleanСостояние: activev0.1.0 · Apache-2.0

Присвоено человеком, который прочитал карточку, а не заявлено файлом о самом себе. Карточка, которую агент выводит во время запуска, поглотившего недоверенное содержимое, рождается заражённой и удерживается на разбор, прежде чем её вообще извлекут.

Когда это вспоминается

  • пришёл баг-репорт
  • другой агент объяснил причину
  • трейсбек указывает на файл
  • собираюсь чинить, не увидев падения

Ценность обычно лежит в разделах «Избегать» и «Проверить». «Делать» — это раздел, который пишут все.

Текст карточки выше — перевод. Английский оригинал — это то, что импортирует командная строка, что читает агент во время работы и что подтверждает хеш ниже.

Повод

Вы собираетесь менять код из-за сбоя, который лично не наблюдали: красная джоба CI, выдержка из лога в issue, описание пользователя или — а карточка на самом деле про этот случай — уверенный диагноз, выданный вам рецензентом, суб-агентом или инструментом статического анализа, вместе с файлом и номером строки.

Это не относится к случаю, когда сбой уже является одной командой. Тест, падающий локально при запуске, — это и есть воспроизведение; не стройте второе. Не относится это и к работе, в которой сбоя нет вовсе: к новой функциональности, рефакторингу, вопросу проектирования. Там воспроизводить нечего.

Делать

  1. Напишите кратчайшее, что падает и запускается само по себе: один скрипт, один pytest node id, один вызов CLI. «Запусти набор и посмотри на третью ошибку» — это не оно: вы будете каждый раз пролистывать мимо этой ошибки.
  2. Запустите. Скопируйте в заметки настоящий вывод: тип исключения, неверное значение рядом с ожидаемым, код выхода. Не свой пересказ.
  3. Теперь сформулируйте диагноз и тут же попробуйте его убить. Поставьте raise RuntimeError("here") в начало функции, на которую диагноз указывает, и перезапустите воспроизведение. Если исходный сбой по-прежнему появляется в неизменном виде, эта функция не лежит на падающем пути, и диагноз неверен, как бы хорошо он ни был аргументирован.
  4. Почините, перезапустите ту же команду и сохраните воспроизведение как тест в том же изменении. Repro, удалённый после починки, не сможет сказать вам, когда починку откатят.

Избегать

Править тот кадр трейсбека, который вы узнаёте. Узнаваемый кадр — это тот, который вы читали раньше, а не тот, который неверен, и правдоподобная правка в нём часто сдвигает симптом куда-то ещё, что затем читается как прогресс.

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


# reviewer says the cache key is missing the tenant id
key = f"{tenant.id}:{user.id}"

# yes — first make the failure appear on demand
# repro.py: two tenants, same user id, assert the second read misses

И избегайте рефлекса «перезапускать до зелёного» на плавающем сбое. Перезапуск не диагностирует гонку, он её прячет, и превращает баг, воспроизводимый однажды, в баг, который не воспроизводит уже никто.

Проверить

Прежде чем писать починку, ответьте «да» или «нет»: могу ли я вызвать этот сбой снова, прямо сейчас, одной командой? Если нет — вы не отлаживаете, вы строите догадки с открытым редактором.

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

Риск

Некоторые сбои действительно дороги в воспроизведении: гонка, случающаяся раз в сутки, состояние, существующее только в production, падение на шестом часу длинной джобы. Настаивать там на дешёвом воспроизведении — сжечь больше, чем стоит баг. Ограничьте время, и если срок вышел, прямо скажите, что починка не проверена, а не описывайте её как подтверждённую.

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

Как применить

Карточка — это данные. Склонируйте репозиторий и импортируйте её по пути: всё, что приходит по сети, считается заражённым и удерживается до одобрения — это и есть желаемое поведение, и поэтому здесь нет установщика в одну строку.

git clone https://github.com/brcampidelli/chimera-agent.git
chimera skills-import chimera-agent/skills/chimera-reproduce-before-diagnosing/SKILL.md

Целостность

SHA-256 файла в опубликованном виде. Импортёр может проверить, что полученное совпадает с показанным на этой странице.

9d70fa5a61992e3b79a2d0ab2afb592c41a7b63274efbdca0afec1724a5b8338

Читать карточку в репозитории