Skill v1.0.1
LLM-judged scan90/100+1 new
version: "1.0.1" name: runtime-investigation description: "Use for расследования багов по bug-report: граф вызовов + ключевые переменные → пробы → трасса → цикл гипотез."
Runtime Investigation — расследование багов в рантайме
1. Когда применять
Цель навыка — ответить на три вопроса в строгом порядке:
- Что фактически происходит? Вызывается ли процедура? С какими аргументами? Какие значения переменных? Какой путь по if/else? Что вернул запрос?
- Совпадает ли это с ожиданием? (из спеки/дизайна/ассерта теста —
bug-report.expectation) - Где источник расхождения?
- Код неверен — поведение не соответствует требованию
- Код верен, данные не те — контракт нарушен на стороне вызывающего/подготовки данных
- Код соответствует спеке, спека неверна/неполна
- Тест/сценарий проверяет не то
Без шага 1 шаги 2-3 невозможны.
Триггер запуска: оркестратор передал bug-report.json со статусом open.
2. Иерархия инструментов (от дешёвого к дорогому)
| Уровень | Инструмент | Когда | |
|---|---|---|---|
| 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 требует выйти к оркестратору с структурированным запросом:
- Какую гипотезу нельзя проверить через L0-L6 и почему
- Какие события техжурнала нужны (EXCP / DBMSSQL / TLOCK / TDEADLOCK / TTIMEOUT / CALL)
- Ориентировочное время сбора
Оркестратор переспрашивает пользователя. Без согласия — НЕ поднимать.
3. Полный алгоритм
ФАЗА 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).
4. Построение графа вызовов
Стартовая точка — место наблюдаемого симптома (упавший ассерт, исключение, неверное значение из bug-report.symptom.fail_location).
Метод: идти НАЗАД от симптома вверх по стеку:
- Какая процедура его вызвала?
- Кто вызвал её?
- … до точки входа сценария/теста.
Инструменты: code-navigation (навигация по символам), чтение модуля, поиск по Вызвать / Выполнить / обработчики событий формы / экспортные процедуры менеджера.
Результат: список узлов графа в виде:
[Тест.МойТест]→ [Документ.РасходТовара.Объект.ОбработкаПроведения]→ [ОбщийМодуль.РассчитатьСкидку]→ [ОбщийМодуль.ПолучитьКатегориюКлиента] ← точка симптома
Сохранить как task_dir/.context/debug/<bug-id>/call-graph.md.
5. Выделение ключевых переменных
Определение: ключевая переменная — та, которая влияет на:
- Условие исполнения проблемной точки (входит в
Если/Иначе/Пока/Дляна пути к симптому), либо - Результат вычисления в проблемной точке (входит в формулу/запрос/возвращаемое значение), либо
- Ветвление выше по стеку, ведущее к этой точке.
Метод выделения — обратный обход:
- В точке симптома: какие переменные участвуют в ассерте/формуле? → ключевые.
- По графу вверх: какие переменные участвуют в условиях, ведущих к этой точке? → ключевые.
- Параметры процедур, передаваемые и трансформируемые по пути → ключевые.
- Глобальные параметры сеанса (текущий пользователь, дата актуальности, активная организация) — по умолчанию ключевые, если не доказано обратное.
НЕ ключевые: локальные переменные, используемые только для расчёта без влияния на ветвление и не возвращаются.
Сохранить как task_dir/.context/debug/<bug-id>/instrumentation-plan.md: какие пробы куда ставит, какие ключевые переменные в каждой.
6. Безопасная сериализация при логировании
В пробах agent-debug фиксировать значения переменных. НЕ дампить целиком:
| Тип | Что НЕ логировать | Что логировать вместо | |
|---|---|---|---|
| Документ/Справочник Объект | Весь объект | ТипЗнч, Ссылка, релевантные реквизиты по одному | |
| ТаблицаЗначений | Все строки | Количество(), поля первой/проблемной строки | |
| Структура | Сериализацию | Количество(), список ключей через запятую | |
| Соответствие | Сериализацию | Количество(), ключ-цель если ищем конкретный | |
| Объект формы | Целиком | Конкретные реквизиты формы по одному | |
| Запрос | Текст полностью | Имя, ключевые параметры | |
| Метаданные | Метаданные.X.<всё> | Только имя типа: Метаданные(Ссылка).Имя | |
| Двоичные данные | Содержимое | Размер() | |
| Пароли, токены, ПД | Никогда | Замаскировать или пропустить |
Правило главное: логируем только те поля объекта, которые код реально читает на пути к симптому (определяется по §5). Не дамп всего объекта.
Параметр-объект как ключевая переменная: если ключевая переменная — ссылка/объект, моделировать в эксперименте нужно именно тем объектом, на котором баг воспроизводится. Не подменять «похожим» из базы.
7. Лимит гипотез
По умолчанию: 5 гипотез. После 5-й неподтверждённой — эскалация.
Расширение +3 (max 8 всего): допустимо однократно, если:
- появилась конкретная следующая гипотеза с высокой уверенностью (есть прямые улики из трассы),
- запрос отправлен оркестратору с обоснованием,
- оркестратор согласовал.
Если уверенность низкая — НЕ просить расширение, эскалировать сразу.
Качество > количество. Каждая гипотеза в debug-report.md обязана иметь evidence_from_trace — на каком факте из собранной трассы она основана. Это блокирует «гипотезы наугад».
8. Критерий «локальный фикс vs возврат оркестратору»
Дебаггер чинит сам, если выполнены ВСЕ условия:
- Изменение в ≤ 2 файлах продкода ИЛИ ≤ 1 файл теста/сценария
- Не меняется публичный API (экспортные процедуры, их сигнатуры)
- Не меняется спека и technical-design
- Не затрагивает
protected_pathsиз bug-report - Фикс умещается в ~30 строк диффа
Возврат оркестратору в любом из случаев:
- Нужно менять спеку → Analyst
- Нужно менять технический дизайн или добавлять API → Architect
- Нужно переписывать > 2 файлов → Developer-Code
- Нужно менять
.featureили step-library широко → Scenario-Author / Scenario-Coder - Баг в данных, требует пересмотра подготовки тестового окружения → Developer-Tests или Scenario-Coder
После локального фикса — обязательная верификация:
- Перепрогнать упавший тест/сценарий → должен быть зелёным.
- Перепрогнать связанные unit-тесты модуля и Vanessa-сценарии с тем же тегом задачи.
- Проверить, что не сломалось ничего смежного (узкая регрессия).
- Если verification failed — это была ошибочная гипотеза, откатить фикс, вернуться в 3.N.4.
Локальный фикс ВСЕГДА проходит ревью (Reviewer scope=debug или соответствующий типу артефакта) — иначе минует контроль качества.
9. Шаблон 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 пройден
10. Антипаттерны
| Антипаттерн | Последствие | |
|---|---|---|
Гипотеза без evidence_from_trace | Угадывание; ресурс расследования тратится впустую | |
| Не снять пробы опровергнутой гипотезы перед следующей | Шум в трассе, путаница в интерпретации | |
| Оставить пробный фикс при опровергнутой гипотезе | Накопление мусора в коде | |
Дамп всего объекта в agent-debug точке | Переполнение ЖР, утечка данных | |
| Подмена тестового объекта «похожим» из базы | Баг не воспроизведётся, ложный отрицательный результат | |
| Поднять техжурнал без согласия пользователя | Нарушение политики; тяжёлый процесс зря | |
| 10+ проб H0 без чётких ключевых переменных | Широкое наблюдение, непонятный результат → разбить на гипотезы | |
| Пропустить очистку перед завершением | Маркеры AGENTDEBUG уйдут в коммит | |
| Пропустить верификацию после локального фикса | Ложный «починил», на самом деле сломали смежное |
depends_on:
- framework/skills/tool-usage/diagnostics/bug-reporting/SKILL.md
- framework/skills/tool-usage/diagnostics/agent-debug/SKILL.md
- framework/skills/tool-usage/diagnostics/event-log-analysis/SKILL.md
- framework/skills/tool-usage/diagnostics/tech-log-analysis/SKILL.md
- framework/skills/tool-usage/platform-data/platform-data-core/SKILL.md
- framework/skills/tool-usage/code-analysis/code-navigation/SKILL.md
- framework/skills/tool-usage/code-analysis/syntax-checking/SKILL.md
- framework/rules/source-of-truth.md