framework/skills/tool-usage/diagnostics/bug-reporting/SKILL.md
Эскалация бага после лимита самовосстановления агента
npx skillsauth add steelmorgan/1c-agent-based-dev-framework bug-reportingInstall 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.
Проблема становится багом для дебаггера только если выполнены ВСЕ условия:
clarification_needed → пользователь.clarification_needed → Architect через оркестратор.environment_error, идёт оркестратору как infra-проблема, не дебаггеру.Если хотя бы одно условие не выполнено — bug-report НЕ заводится.
| Ситуация | Куда идёт | |---|---| | Опечатка в формуле своего кода, видна сразу | self-fix | | Тест не компилируется после своей же правки | self-fix | | Стиль/покрытие/оформление | Reviewer BLOCK | | Спека противоречива/неполна | clarification → пользователь | | В дизайне нет нужной API | clarification → Architect | | Тест/сценарий упал, причина неочевидна за лимит попыток | bug-report → debugger | | Vanessa Red-гейт зелёный, мок не очевиден | bug-report → debugger | | Поведение в коде расходится с ассертом, причина неясна | bug-report → debugger | | 1С не запущена, фикстуры не подняты | environment_error → оркестратор |
| Агент | Что чинит сам | Лимит | Когда заводит bug-report |
|---|---|---|---|
| developer-code | Свой синтаксис/логика в своём коде | 2 попытки | Тест падает не из-за моего кода ИЛИ 2 попытки исчерпаны без понимания причины |
| tester | Технические ошибки в коде теста (логика теста не меняется) | 3 попытки | Падение не лечится правкой кода теста ИЛИ 3 попытки исчерпаны |
| scenario-coder | Свои step-implementations | 2 попытки | Red-гейт зелёный без объяснения; шаг падает с неочевидной причиной; 2 попытки исчерпаны |
Остальные агенты (developer-tests, scenario-author, analyst, architect, explorer, reviewer) bug-report не создают — они либо не запускают код, либо обрабатывают замечания через цикл Reviewer.
bug-report.jsonРасположение: task_dir/.context/bugs/<bug-id>.json
ID: bug-<task-id>-<seq>, например bug-T-042-001. Нумерация в рамках задачи, sequential.
Обязательные поля помечены *.
{
"id": "bug-T-042-001", // *
"status": "open", // * open | in_investigation | fixed_locally | returned_to_author | escalated_to_user
"reporter": { // *
"agent": "developer-code", // *
"phase": "3d", // *
"timestamp": "2026-04-27T14:32:00Z" // *
},
"symptom": { // *
"what_ran": "unit-test 'РасчётСкидки_GivenVIP_Returns20'", // *
"command": "1c-ai-agent-cli test ...", // *
"fail_location": "tests/unit-РасчётСкидки.bsl:42", // *
"error_message": "Expected 20, got 15", // * verbatim, не пересказ
"log_path": "task_dir/runs/2026-04-27T14-30/test.log", // *
"deterministic": true // * true | false | unknown
},
"expectation": { // *
"source": "spec.md §3.2", // * file + section
"quote": "Для VIP-клиентов скидка MUST составлять 20%." // * verbatim из источника
},
"scenario_context": { // * (см. §4 — может быть incomplete)
"incomplete": false, // если true — указать reason
"incomplete_reason": null,
"action": "проведение документа РасходТовара",
"user": {
"name": "Иванов И.И.",
"roles": ["Менеджер"],
"is_admin": false
},
"input_data": {
"kind": "document", // document | processor | function_call | report
"document": {
"type": "Документ.РасходТовара",
"is_new": true,
"header": {
"Дата": "2026-04-27",
"Организация": "ООО Ромашка",
"Контрагент": "<пусто>"
},
"tabular_sections": {
"Товары": {
"rows_count": 2,
"rows_sample": [
{"Номенклатура": "Товар А", "Количество": 5, "Цена": 100}
]
}
}
}
},
"system_state": {
"current_date": "2026-04-27",
"active_session_params": {"ТекущаяОрганизация": "ООО Ромашка"},
"relevant_db_state": "не проверялось"
}
},
"debug_trigger": { // recommended, * если репортёр знает как вызвать код
"context": "server", // client | server | unknown
"preferred_method": "yaxunit", // yaxunit | vanessa | ui_mcp | mcp_tool | http | scheduled_job | unknown
"run_after_breakpoint": "запустить один unit-test РасчётСкидки_GivenVIP_Returns20",
"entry_point": {
"module": "ОбщийМодуль.Скидки",
"procedure": "РассчитатьСкидку",
"line_hint": null
},
"target_hint": {
"user": "AgentAI",
"infobase_session_number": null,
"client_kind": "unit-test"
},
"timeout_hint_seconds": 30
},
"self_fix_attempts": [ // * минимум одна запись
{"what_tried": "проверил формулу в РассчитатьСкидку()", "result": "формула совпадает со спекой"},
{"what_tried": "перепрогнал тест после rebuild", "result": "то же значение 15"}
],
"stopping_reason": "after_2_attempts", // * after_N_attempts | suspected_other_layer | out_of_scope
"hypotheses": [ // опционально, но если есть — с reasoning
{
"layer": "data", // code | test | scenario | step | data | spec | unknown
"agent": "developer-tests", // подозреваемый владелец
"reasoning": "тест ожидает VIP-категорию у клиента, но в фикстуре её может не быть"
}
],
"context": { // *
"files_touched_this_phase": [ // * что менялось в этой фазе
"src/CommonModules/Скидки/Module.bsl"
],
"related_artifacts": [ // *
"spec.md",
"tests/unit-РасчётСкидки.bsl"
],
"protected_paths": [], // что дебаггеру НЕ трогать
"blocked_paths": [] // занято другими задачами
}
}
expectation.source + quote обязательны. Без явной цитаты из источника правды bug-report не принимается. Это снимает «по моему мнению должно быть иначе».symptom.error_message — verbatim. Прямая цитата ассерта/исключения/лога, не пересказ.self_fix_attempts — минимум одна запись. Даже «прочитал код, причины не вижу» — артефакт. Это блокирует «выкинул через стенку».hypotheses — опциональны, но если указаны — с reasoning. Гипотеза без обоснования = шум.context.files_touched_this_phase обязательно. Дебаггер должен знать, что менялось недавно.debug_trigger заполнять всегда, когда известно как вызвать код. Это не инструкция дебаггеру обязательно использовать DAP; это стартовая подсказка для выбора между DAP и trace через ЖР.scenario_context — что и как заполнятьДебаггер не сможет воспроизвести и смоделировать без понимания, какое действие выполнялось, под каким пользователем и с какими данными.
action — конкретное действие в системе: «проведение документа X», «запуск обработки Y», «вызов функции Z», «формирование отчёта».
user — обязательно. В 1С много ветвлений по правам.
input_data.kind определяет, какие подполя заполнять:
document → document.type, is_new (важно — у нового документа нет ссылки), header (реквизиты шапки), tabular_sections (количество строк + первая/проблемная строка).processor → processor.name, form_fields (значения на форме).function_call → module, procedure, arguments (фактические значения).report → name, parameters.Что НЕ дампить:
Объект формы, СправочникОбъект.<ВсеПоля>) — только релевантные реквизиты.rows_count + первая/проблемная строка.Метаданные.Документы.X.<всё>) — только имя типа.is_new: true/false критично — у нового документа нет ссылки и многих реквизитов.
relevant_db_state — заполняется только если репортёр уже проверил состояние БД (platform-data-core § Query Execution); иначе "не проверялось". Дебаггер сам проверит.
debug_trigger — как дебаггеру инициировать кодdebug_trigger описывает, как воспроизвести выполнение после того, как Debugger поставит breakpoint или подготовит trace.
Заполнять:
context — где исполняется основной код: client, server, unknown.preferred_method — самый узкий способ запуска: yaxunit, vanessa, ui_mcp, mcp_tool, http, scheduled_job, unknown.run_after_breakpoint — что именно запускать после установки breakpoint: команда, тест, сценарий, UI-действие, tool-вызов.entry_point — модуль/процедура/строка, если репортёр знает предполагаемую точку входа.target_hint — пользователь, номер сеанса ИБ, тип клиента или другие признаки target, если видны из прогона.timeout_hint_seconds — 30 для быстрого кода; для тяжёлой операции указать осознанный предел или null с пояснением в self_fix_attempts.Если способ запуска неизвестен, ставить preferred_method: "unknown" и объяснить, что именно неизвестно. Не выдумывать target или строку breakpoint.
scenario_context.incomplete: trueЕсли репортёр не может заполнить контекст полностью (например, Developer-Code не видит, как тест готовит документ):
incomplete: true и incomplete_reason (что именно не удалось установить).function_call).Лучше неполный отчёт с пометкой incomplete, чем выдуманные данные.
developer-code (Phase 3d)Триггер: unit-тест не проходит, причина не в моём коде ИЛИ 2 self-fix попытки исчерпаны.
Заполнение:
symptom.what_ran — имя теста + полный путь.symptom.error_message — assertion verbatim из stdout/event-log.expectation.source — секция спеки или ассерт-строка из теста.scenario_context.input_data.kind = "function_call" если упал unit на конкретной функции; добавить document если тест прогоняется на документе.debug_trigger.preferred_method = "yaxunit"; run_after_breakpoint — команда запуска одного теста; entry_point — функция/процедура из падающего стека, если известна.hypotheses — если подозрение на test/data/scenario/step, указать с reasoning.context.files_touched_this_phase — все BSL/XML, изменённые в Phase 3d.tester (Phase 4)Триггер: после 3 попыток исправить тест не помогло ИЛИ падение не лечится правкой теста.
Заполнение:
scenario_context — Tester видит сценарий end-to-end и обязан заполнить максимум.symptom.what_ran — имя теста / .feature / scenario name.expectation.source — спека ИЛИ Acceptance Scenario из спеки ИЛИ ассерт.debug_trigger — заполнить по фактическому способу запуска: yaxunit для unit, vanessa для сценария, ui_mcp если действие воспроизводилось через тестовый клиент.hypotheses — текущая классификация Tester (test_error / implementation_error / spec_mismatch) перекладывается в hypotheses[].layer.self_fix_attempts — все 3 попытки с описанием что меняли и результатом.scenario-coder (Phase 3c)Триггер:
Заполнение:
symptom.what_ran — имя .feature + конкретный сценарий + шаг.expectation.source — Acceptance Scenario из спеки + ожидаемое поведение Red-гейта (должен быть красным).scenario_context.action — что делает сценарий (Given-блоки .feature дают данные).scenario_context.input_data — из Given-шагов сценария.debug_trigger.preferred_method = "vanessa"; если шаг реализован через клиентские UI-действия — добавить target_hint тест-клиента, если он известен.hypotheses — например layer: step если подозрение на скрытый мок в реализации шага.| Статус | Кто меняет | Когда |
|---|---|---|
| open | reporter | При создании |
| in_investigation | orchestrator | При запуске debugger |
| fixed_locally | debugger | После локального фикса + верификации |
| returned_to_author | debugger | Если фикс масштабный, возврат профильному агенту |
| escalated_to_user | orchestrator | После исчерпания гипотез или 2-х циклов bug→fix→bug |
Контроль дублей: если тот же симптом (совпадение symptom.fail_location + symptom.error_message) — обновляется существующий bug-report (новый self_fix_attempts запись, новые hypotheses), новый НЕ создаётся.
| Антипаттерн | Почему плохо |
|---|---|
| error_message пересказан своими словами | Теряются точные signature и stack trace |
| expectation.quote отсутствует или «ну, по логике…» | Нет источника правды → дебаггер не знает, с чем сравнивать |
| Дамп всего объекта в scenario_context | Засоряет отчёт, может содержать чувствительные данные |
| Гипотеза без reasoning | Шум, дебаггер не может расставить приоритет |
| self_fix_attempts: [] пустой | Не было даже попытки разобраться → значит не баг для дебаггера |
| Создание нового bug-report при том же симптоме | Дубли мешают трекингу; обновлять существующий |
| scenario_context с выдуманными данными вместо incomplete: true | Дебаггер пойдёт по ложному следу |
| debug_trigger пустой при известном способе запуска | Дебаггер тратит время на восстановление того, что репортёр уже знает |
depends_on:
development
1C server maintenance webhooks: container restart and external component cache cleanup
development
Interactive DAP debugging of a single BSL procedure
tools
Rules for using RLM tools for project search and navigation in 1C/BSL
development
Creates web applications and routes on Winow (a web server on OneScript and Autumn). Use when working with a web server on OneScript, routing, or Winow controllers.