framework/skills/tool-usage/diagnostics/runtime-investigation/SKILL.md
Use for расследования багов по bug-report: граф вызовов + ключевые переменные → пробы → трасса → цикл гипотез.
npx skillsauth add steelmorgan/1c-agent-based-dev-framework runtime-investigationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Цель навыка — ответить на три вопроса в строгом порядке:
bug-report.expectation)Без шага 1 шаги 2-3 невозможны.
Триггер запуска: оркестратор передал bug-report.json со статусом open.
| Уровень | Инструмент | Когда |
|---|---|---|
| L0 | Чтение исходников + спеки/дизайна (code-navigation) | Всегда первым |
| L1 | event-log-analysis — ЖР через ClickHouse | Уже отработавший прогон, есть Error/Warning |
| L2 | platform-data-core § Query Execution — запросы к БД | Проверить состояние данных независимо от кода |
| L3 | agent-debug точки в коде | L0-L2 не дали ответа: факт вызова, путь if/else, значение/тип переменной |
| L4 | Перепрогон сценария/теста после вставок | После L3 — собрать наблюдения |
| L5 | gui-control + screenshot | Симптом в UI, неясно что на форме |
| L6 | syntax-checking (get_diagnostics / v8-runner syntax …) | После любого изменения кода |
| L7 | tech-log-analysis — техжурнал | ТОЛЬКО с явного согласия пользователя. Тяжёлый, медленный. Когда L0-L6 не дали ответа: блокировки, deadlock, скрытые исключения платформы, медленные SQL |
L0-L6 дебаггер использует автономно. Переход на L7 требует выйти к оркестратору с структурированным запросом:
Оркестратор переспрашивает пользователя. Без согласия — НЕ поднимать.
ФАЗА 1. Подготовка
1.1 Прочитать bug-report.json. Перевести status → in_investigation.
1.2 Воспроизвести баг детерминированно (запустить указанный тест/сценарий).
- Не воспроизводится → flaky, эскалация оркестратору.
1.3 Прочитать код вокруг точки симптома + спеку/дизайн (L0).
1.4 Построить ГРАФ ВЫЗОВОВ от точки входа сценария/теста до точки симптома (см. §4).
1.5 Выделить КЛЮЧЕВЫЕ ПЕРЕМЕННЫЕ (см. §5).
ФАЗА 2. Первая проходка (БЕЗ гипотез)
2.1 Расставить пробы H0 на каждом узле графа (префикс `AGENTDEBUG-<bug-id>-H0-NNN`):
- маркер EXECUTED
- снимок ключевых переменных (безопасная сериализация — §6)
2.2 Прогнать сценарий/тест.
2.3 Прочитать ЖР, собрать трассу: какие узлы прошли, состояние переменных.
Сохранить в task_dir/.context/debug/<bug-id>/trace-run-1.md.
2.4 Сравнить трассу с ожиданием. Локализовать первое расхождение «ожидание ≠ факт».
Если трассы достаточно, чтобы сразу определить причину → переход к Фазе 4.
ФАЗА 3. Цикл гипотез (≤ 5 итераций; +3 расширение, max 8 — см. §7)
Для гипотезы N (1..5, при расширении 6..8):
3.N.1 Сформулировать наиболее вероятную гипотезу НА ОСНОВЕ ТЕКУЩЕЙ ТРАССЫ
(не из головы). Записать в debug-report.md:
- формулировка
- evidence_from_trace (на каком факте из трассы основана)
3.N.2 Выбрать способ проверки:
(a) пробный фикс — узкое изменение в коде/тесте/сценарии,
которое легко откатить;
(b) дополнительные пробы (префикс `AGENTDEBUG-<bug-id>-H<N>-NNN`) —
новые ключевые переменные, узлы между размеченными,
состояние данных через platform-data-core § Query Execution.
3.N.3 Применить, прогнать, прочитать трассу. Сохранить trace-run-<N+1>.md.
3.N.4 Развилка:
✓ ПОДТВЕРЖДЕНА → переход к Фазе 4 (фикс по правилам)
✗ НЕ подтверждена:
- откатить пробный фикс (если был)
- снять пробы ИМЕННО ЭТОЙ гипотезы (grep H<N>); пробы H0 и
предыдущих опровергнутых гипотез ОСТАЮТСЯ
- зафиксировать в debug-report.md: что проверял, результат,
почему опровергнута
- переход к гипотезе N+1
Между итерациями допустимо вернуться к Фазе 1 и расширить граф/ключевые
переменные, добавив новые H0+ пробы (например, появились новые вызывающие
места). Это не считается отдельной гипотезой.
После 5 неподтверждённых:
- если есть конкретная следующая гипотеза с высокой уверенностью →
обратиться к оркестратору с запросом на расширение +3 (max 8 всего)
- иначе → Фаза 5 (эскалация)
ФАЗА 4. Фикс (если гипотеза подтвердилась)
4.1 Оценить масштаб по критерию «локальный vs возврат» (§8).
4.2 Локальный → применить фикс, прогнать упавший тест/сценарий + смежные.
- Должно стать зелёным
- Если не стало — это была ошибочная гипотеза, вернуться в 3.N.4 с откатом
4.3 Масштабный → возврат оркестратору с пояснением и рекомендацией
(какому агенту передать).
ФАЗА 5. Эскалация (5/8 гипотез исчерпаны или масштаб слишком большой)
5.1 Краткий структурированный отчёт оркестратору (см. §9).
5.2 Оркестратор передаёт пользователю.
ФАЗА 6. Очистка (ВСЕГДА перед завершением — успехом или эскалацией)
6.1 grep `//[AGENTDEBUG-` → ноль вхождений во ВСЕХ затронутых файлах.
6.2 Если поднимали техжурнал — восстановить исходный конфиг.
6.3 syntax-checking по затронутым модулям.
6.4 Финальный debug-report.md с итоговым статусом и обновление
bug-report.json (status: fixed_locally / returned_to_author / escalated_to_user).
Стартовая точка — место наблюдаемого симптома (упавший ассерт, исключение, неверное значение из bug-report.symptom.fail_location).
Метод: идти НАЗАД от симптома вверх по стеку:
Инструменты: code-navigation (навигация по символам), чтение модуля, поиск по Вызвать / Выполнить / обработчики событий формы / экспортные процедуры менеджера.
Результат: список узлов графа в виде:
[Тест.МойТест]
→ [Документ.РасходТовара.Объект.ОбработкаПроведения]
→ [ОбщийМодуль.РассчитатьСкидку]
→ [ОбщийМодуль.ПолучитьКатегориюКлиента] ← точка симптома
Сохранить как task_dir/.context/debug/<bug-id>/call-graph.md.
Определение: ключевая переменная — та, которая влияет на:
Если/Иначе/Пока/Для на пути к симптому), либоМетод выделения — обратный обход:
НЕ ключевые: локальные переменные, используемые только для расчёта без влияния на ветвление и не возвращаются.
Сохранить как task_dir/.context/debug/<bug-id>/instrumentation-plan.md: какие пробы куда ставит, какие ключевые переменные в каждой.
В пробах agent-debug фиксировать значения переменных. НЕ дампить целиком:
| Тип | Что НЕ логировать | Что логировать вместо |
|---|---|---|
| Документ/Справочник Объект | Весь объект | ТипЗнч, Ссылка, релевантные реквизиты по одному |
| ТаблицаЗначений | Все строки | Количество(), поля первой/проблемной строки |
| Структура | Сериализацию | Количество(), список ключей через запятую |
| Соответствие | Сериализацию | Количество(), ключ-цель если ищем конкретный |
| Объект формы | Целиком | Конкретные реквизиты формы по одному |
| Запрос | Текст полностью | Имя, ключевые параметры |
| Метаданные | Метаданные.X.<всё> | Только имя типа: Метаданные(Ссылка).Имя |
| Двоичные данные | Содержимое | Размер() |
| Пароли, токены, ПД | Никогда | Замаскировать или пропустить |
Правило главное: логируем только те поля объекта, которые код реально читает на пути к симптому (определяется по §5). Не дамп всего объекта.
Параметр-объект как ключевая переменная: если ключевая переменная — ссылка/объект, моделировать в эксперименте нужно именно тем объектом, на котором баг воспроизводится. Не подменять «похожим» из базы.
По умолчанию: 5 гипотез. После 5-й неподтверждённой — эскалация.
Расширение +3 (max 8 всего): допустимо однократно, если:
Если уверенность низкая — НЕ просить расширение, эскалировать сразу.
Качество > количество. Каждая гипотеза в debug-report.md обязана иметь evidence_from_trace — на каком факте из собранной трассы она основана. Это блокирует «гипотезы наугад».
Дебаггер чинит сам, если выполнены ВСЕ условия:
protected_paths из bug-reportВозврат оркестратору в любом из случаев:
.feature или step-library широко → Scenario-Author / Scenario-CoderПосле локального фикса — обязательная верификация:
Локальный фикс ВСЕГДА проходит ревью (Reviewer scope=debug или соответствующий типу артефакта) — иначе минует контроль качества.
debug-report.mdСохраняется в task_dir/.context/debug/<bug-id>/debug-report.md.
# Debug Report — <bug-id>
## Источник
- Bug-report: <ссылка на bug-report.json>
- Симптом: <symptom.what_ran> упал на <fail_location>
- Ожидание: <expectation.quote> (источник: <expectation.source>)
## Воспроизведение
- Команда: <symptom.command>
- Детерминизм: <yes/no>
## Граф вызовов
<ссылка на call-graph.md>
## Ключевые переменные
<ссылка на instrumentation-plan.md>
## Первая проходка (H0)
- Прогон: <ссылка на trace-run-1.md>
- Локализация расхождения: <узел графа + что не сошлось>
## Гипотезы
### H1: <формулировка>
- Evidence_from_trace: <на каком факте из трассы основана>
- Способ проверки: <фикс / доп.пробы>
- Прогон: <ссылка на trace-run-N.md>
- Результат: ПОДТВЕРЖДЕНА / ОПРОВЕРГНУТА
- Если опровергнута — почему: <...>
### H2: ...
...
## Вердикт
- Класс причины: код / данные / спека / тест/сценарий
- Корневая причина: <...>
- Затронутый слой источников правды (L1-L6): <см. source-of-truth-policy>
## Действие
- ВАРИАНТ A — Локальный фикс:
- Файл(ы): <...>
- Дифф: ≤ 30 строк
- Верификация: упавший тест зелёный, смежные тесты зелёные
- Подлежит ревью: scope=debug
- ВАРИАНТ B — Возврат оркестратору:
- Кому передать: <agent>
- Почему масштаб большой: <...>
- Рекомендация по фиксу: <...>
- ВАРИАНТ C — Эскалация:
- 5/8 гипотез не подтверждены
- Что точно установлено: <...>
- Что хотелось бы проверить, но не получилось: <...>
- Рекомендация: к кому идти (Architect / Analyst / пользователь)
## Очистка
- [x] grep `//[AGENTDEBUG-` → 0 вхождений
- [x] техжурнал восстановлен (если поднимался)
- [x] syntax-checking пройден
| Антипаттерн | Последствие |
|---|---|
| Гипотеза без evidence_from_trace | Угадывание; ресурс расследования тратится впустую |
| Не снять пробы опровергнутой гипотезы перед следующей | Шум в трассе, путаница в интерпретации |
| Оставить пробный фикс при опровергнутой гипотезе | Накопление мусора в коде |
| Дамп всего объекта в agent-debug точке | Переполнение ЖР, утечка данных |
| Подмена тестового объекта «похожим» из базы | Баг не воспроизведётся, ложный отрицательный результат |
| Поднять техжурнал без согласия пользователя | Нарушение политики; тяжёлый процесс зря |
| 10+ проб H0 без чётких ключевых переменных | Широкое наблюдение, непонятный результат → разбить на гипотезы |
| Пропустить очистку перед завершением | Маркеры AGENTDEBUG уйдут в коммит |
| Пропустить верификацию после локального фикса | Ложный «починил», на самом деле сломали смежное |
depends_on:
testing
MUST use BEFORE making a judgment about the cause of a conflict, a test failure, or an artifact dispute. Defines the end-to-end verification method L1→L6 and the classification of the first broken link.
development
MUST use AFTER a work cycle with ≥2 iterations (wrote → error → fixed → success). Provides the retrospective procedure and the format for recording practice/anti-patterns in references/learned-patterns.md or {project}/.context/learned-patterns.md.
tools
MUST use WHEN you are writing reusable knowledge into RLM (pattern / architectural decision / stable domain fact) OR reading it before a non-trivial task/solution in the domain. Provides the breakdown of native-push vs RLM-pull, tools for writing and reading RLM, H-MEM levels, and hygiene.
testing
MUST use WHEN the task is classified as simple (< 20 lines, 1 file, no new metadata objects, no architectural decisions). Provides a short cycle of 3 steps with a guard on the self path and mandatory verify.