bsl-code-review — контур кода

SkillDev tools

BSL code review loop: static analyzer diagnostics, performance anti-patterns and platform mechanics, #stdNNN development standards, naming, API signature verification and common module existence checks. Works at the 'inside method body' level, issues fixable by replacing lines. Invoked by the orche

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the bsl-code-review — контур кода skill

What this skill tells your AI

The instructions your AI receives, as published by romandredan/1c-quality-gate in skills/bsl-code-review/SKILL.md and read by ahel’s review.

Проверяет то, что чинится внутри тела метода: замена строк, без нового шва. Всё, что требует выделения метода, переноса в другой модуль, нового экспорта или изменения «кто кого вызывает», принадлежит контуру bsl-architecture-review — граница и правила отсева повторов находок в shared/routing-contract.md.

<ЖЁСТКИЙ-ШЛЮЗ> Только проверка и отчёт. НЕ переписывай логику, запросы, транзакции и права по своей инициативе. В режиме --fix допустимы лишь безопасные категории (см. ниже). </ЖЁСТКИЙ-ШЛЮЗ>

Инварианты контура

Пять утверждений, без которых прогон контура недействителен.

  1. Каталог антипаттернов проходится всегда — читателем либо самостоятельно, но след печатает catalog.mjs attest.
  2. Строку следа инструментальной проверки печатает инструмент — переноси дословно, своих находок этого класса не добавляй: результат детерминирован.
  3. Каждое замечание доказуемо: номер стандарта, код диагностики или название антипаттерна плюс строка кода. «Так лучше» — не находка.
  4. Пропуск фиксируется. Недоступный инструмент или субагент даёт skipped с причиной; молчание неотличимо от выполнения.
  5. Файл, который анализатор не разобрал, не проверен — вердикт «чисто» по нему невозможен, и в отчёте он назван поимённо.

Вход

От оркестратора: класс изменения (C0…C3), сработавшие архетипы, список изменённых файлов. Глубину (Слой 1 / Слой 1+2 / Слой 1+2 с предложением Слоя 3) печатает план (gate.mjs plan, поле resolved: code=...) — архетип может поднять её сверх класса, понизить нельзя. При прямом вызове — определи профиль сам по правилам quality-gate.


Слой 1а — статический анализ

Строка плана для analyzer-run.mjs — одна команда: она находит корень конфигурации, прогоняет только изменённые файлы, проверяет часового и формирует записи следа. Вывод — находки по файлам и готовый блок ## quality evidence. Перенеси его в отчёт как есть: записи следа по слою code сочинять руками не нужно и нельзя.

Твоя работа здесь — триаж, а не припоминание. Список нарушений детерминирован. От тебя требуется отделить то, что надо чинить сейчас, от того, что является осознанной нормой этого проекта, и назвать последствие каждой оставленной находки. Коды расшифровывай через v8std_explain_diagnostics и привязывай к номеру стандарта.

Четыре режима вывода, каждый из которых меняет то, что можно утверждать по результату:

  • Информационные находки свёрнуты в одну строку, полный список — флаг --all. В след коды попадают в любом случае.
  • Проект без основной конфигурации (репозиторий одного расширения): диагностики о неразрешённых именах понижены до информационных — обратно не поднимай, отличить их от настоящих ошибок в этом режиме нечем.
  • «НЕ РАЗОБРАНО файлов» — по этим файлам не проверено ничего. Назови их в отчёте поимённо: вердикт «чисто» по ним невозможен.
  • Часовой status=not_found — прогон недостоверен, вердикт «чисто» запрещён; разберись с анализатором и повтори.

Что стоит за каждым режимом и известные случаи — references/analyzer-output.md. Гейтовый анализ идёт с конфигом из состава плагина: проектный subsystemsFilter вывести изменённые файлы из проверки не может.

Если анализатор недоступен — команда сама запишет [qg skipped: layer=code, scope=static-analysis, planned=[bslls:*], reason=analyzer_unavailable] и вернёт код 1. Продолжай со Слоя 1б: он ловит другое и от анализатора не зависит.

Второй движок — сверка со справочником платформы

Строка плана для platform-context-run.mjs. Ловит то, чего анализатор не видит вовсе: несуществующий член платформенного типа, значение системного перечисления, конструктор, свойство объекта. Всё это компилируется и падает при выполнении. Сервер справки движок заводит сам: ищет поднятый, а не найдя — ставит закреплённый релиз и поднимает свой по установленной платформе. Где платформы на машине нет, пишет skipped с причиной и возвращает код 1 — это законный исход.

Два правила: info «низкая уверенность» не отбрасывать (класс смешанный) и часовой not_found — «чисто» запрещено. Остальное — references/platform-api.md.

Слой 1б — то, чего анализатор не видит

1. Каталог антипаттернов — субагент antipattern-reader

Строка плана для catalog.mjs index печатает индекс триггеров; полная карточка читается по попаданию, не заранее. Сначала сохрани git diff HEAD -- по изменённым .bsl в файл — признаку qg:AI-11 нужно сравнение версий — у читателя нет оболочки, чтобы построить его самому, а attest вычисляет diff сам и без него карточку не пропустит; переданный файл лишь сверяется. Сравнивать не с чем (новый файл без истории) — attest --no-diff-available печатает честный skipped вместо молчания.

Делегируй субагенту antipattern-reader: передай вывод index, список изменённых .bsl и путь к файлу диффа. Он не знает задачи и возвращает JSON — сохрани в файл: путь к нему, список файлов и путь к диффу — в строку плана "$QG/tools/catalog.mjs" attest --diff <файл>.

Инструмент сверяет полноту списка проверенных признаков, состав файлов и цитату каждой находки с самим файлом, после чего печатает строки следа ai-antipatterns и platform-antipatterns и пишет журнал. Отвергнутый результат — повтори запуск читателя с его замечаниями, не правь JSON руками. Читателя в среде нет — прогони индекс сам по той же процедуре и аттестуй так же: строку следа в обоих случаях печатает инструмент.

Признаки с инструментом (bsl-lint, query-lint, rename-check) в проход не входят — их строки печатают инструменты, а карточка нужна для «как чинить»: node "$QG/tools/catalog.mjs" card <ID>.

2. Проверки по тексту кода

Команды — строки плана для query-lint.mjs, bsl-lint.mjs, rename-check.mjs: план печатает их только когда применимо, а полный список признаков с разбором каждого — в references/catalog/INDEX.md (qg:BSL-UNBOUNDED-STRING-COLUMN там же — механическая половина AI-16). XML идёт в query-lint наравне с .bsl: <query> СКД и <QueryText> динамического списка — тоже носитель запроса.

attribute-access покрыт инструментом лишь частично. Доказать ссылочность в пределах одного файла удаётся не всегда: ссылка из чужой функции или из недокументированного параметра остаётся неопознанной. clean здесь означает «механическая часть чиста» и разбора #std437 глазами не отменяет — инструмент задаёт нижнюю границу, а не верхнюю.

Записи следа обоих — по инварианту 2, дословно, без своих находок.

Граф вызовов оба не строят: запрос, собранный конкатенацией или СтрШаблон, виден им лишь частями, и вердикт «чисто» этого не закрывает — разбор приближений в справочнике правила.

3. Стандарты под архетип

Не весь свод подряд — только релевантное: справочники и разделы checklist-code.md печатает план (gate.mjs plan) — общие разделы всегда, прочие под архетип; перечень — BASE_CHECKLIST и ARCHETYPES в tools/profile.mjs. Глубокая вложенность и длинные методы архетипом не считаются и в план не попадают — при такой правке открывай bsl-refactoring.md сам. Тексты самих стандартов запрашивай через MCP v8std по номеру.

4. Именование

#std454 — частая и легко пропускаемая ошибка: сокращения-префиксы, не-CamelCase, булево не в утвердительной форме. Детали и примеры — в references/checklist-code.md.

5. Символы в исходнике

В коде и комментариях только ASCII-дефис. Длинное тире и его родственники дают у анализатора ошибку недопустимого символа. Кавычки-ёлочки допустимы.

6. Верификация API — субагент bsl-verifier

Сигнатуры платформенных методов, существование и экспортность общих модулей, состав объектов метаданных. Процедура — references/api-verification.md.

Делегируй субагенту bsl-verifier, передав ему список изменённых .bsl-файлов. Он дешёвый, работает по той же процедуре и возвращает вердикт, список нарушений с локациями и раздел «Не проверено». Вызов один на весь список: каждый лишний инстанс поднимает свою сессию индекса кода, а справочник платформы на stdio-транспорте вдобавок не переносит параллельных обращений.

Если прогнан второй движок слоя 1а, платформенная часть уже закрыта: субагенту остаются общие модули, метаданные и контекст доступности.

Субагента в среде может не быть — тогда прогоняй api-verification.md сам. Результат обязан попасть в след одинаково в обоих случаях (инвариант 4):

[qg applied: layer=code, scope=api-verification, ids=[qg:API-SIGNATURE,qg:API-MODULE], verdict=clean]
[qg skipped: layer=code, scope=api-verification, reason=platform_unavailable]

Для класса C1 на этом контур завершается — переходи к отчёту.


Слой 2 — ревью логики моделью

Вызови advisor(). Более сильная модель видит весь транскрипт: задачу, шаги, написанный код. Ловит то, что статика не видит в принципе — неверную бизнес-логику, упущенные сценарии, неучтённые состояния. Замечаниям давай весомый вес.

Холодный читатель — второй взгляд с противоположным входом

Дополнительно к advisor(), когда цена ошибки высока: класс C3 либо затронуты проведение, деньги, права, необратимые операции. Ценность даёт противоположность входов, а не второе мнение — почему, разбирает references/cold-reader.md.

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

Три вопроса, на которые он отвечает:

  1. Что этот код делает как написан, а не как задуман?
  2. На каких входных данных он ломается или ведёт себя неожиданно?
  3. Какое ожидаемое поведение из него не следует?

Модель не дешевле основной: уровень не ниже модели сессии. Расхождение с advisor() — сигнал, а не шум: код допускает два прочтения.

Слой заканчивается записью следа — иначе его пропуск на C3 неотличим от прогона; дефект без своего признака — qg:LOGIC-CONTRACT или qg:LOGIC-CASE-LOSS:

[qg applied: layer=code, scope=logic-review, ids=[qg:LOGIC-CONTRACT], verdict=violation:qg:LOGIC-CONTRACT]
[qg skipped: layer=code, scope=logic-review, reason=advisor_unavailable]

Слой 3 — состязательный аудит (только по подтверждению)

Никогда не запускается сам — контур лишь предлагает его в отчёте и ждёт явного согласия.

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

Состав измерений, пороги, правила голосования, асимметрия для находок 🔴 и порядок действий, когда оркестрация недоступна, — в ../quality-gate/references/adversarial-audit.md.


Автофикс (--fix)

Можно: именование (через переименование символа анализатором, не текстовой заменой), форматирование и отступы, канонические ключевые слова, магические литералы на системные константы, очевидные quick-fix анализатора.

Нельзя без подтверждения: любая правка логики, проведения, запросов; транзакции и блокировки; права и привилегированный режим; всё, помеченное 🔴; сигнатуры экспортных методов (ломает вызывающих).

После автофикса прогони Слой 1 заново — правки могли внести новые диагностики.


Выход

Находки

[🔴/🟠/🟡] <краткая суть>
Где: <путь:строка>
Правило: #stdNNN п.X | антипаттерн «<название>» | #bslls:<Код>
Проблема: <что именно не так здесь>
Как исправить: <конкретно; для 🔴 — со ссылкой на пример из справочника>
Уверенность: средняя | требует проверки — опускается при высокой

При не-высокой уверенности следом — проверка, которая находку закроет. Довод, снимающий находку без такой проверки, обязан опираться на прочитанный источник — правило и пример в ../quality-gate/references/evidence-format.md.

Ключ локации <путь>::<Метод>:<строка> обязателен — по нему оркестратор дедуплицирует находки с архитектурным контуром (правила — в shared/routing-contract.md).

Записи следа

Минимум одна на каждый слой — выполненный или пропущенный:

[qg applied: layer=code, scope=query-in-loop, ids=[std436,bslls:QueryInLoop], verdict=clean]
[qg applied: layer=code, scope=attribute-access, ids=[qg:BSL-REF-DOT-ACCESS,std437], verdict=violation:qg:BSL-REF-DOT-ACCESS]
[qg skipped: layer=code, scope=static-analysis, planned=[bslls:*], reason=analyzer_unavailable]

Вторую строку печатает инструмент: написанная руками, она валидатор не проходит.

Формат — ../quality-gate/references/evidence-format.md.

Два измерения контур закрыть не может и обязан об этом сказать. Компилируемость тел модулей проверяет только платформа: без запуска проверки конфигурации нужна запись [qg not_verified: dimension=compilation, reason=no_platform], иначе полностью чистый вердикт валидатор отклонит. Выполнимость запроса — то же самое при сработавшем архетипе «Запрос»:

[qg applied: layer=code, scope=query-execution, ids=[qg:QRY-EXECUTED], verdict=clean]
[qg not_verified: dimension=query-execution, reason=no_platform]

Проверка по тексту кода (пункт 2 Слоя 1б) её не заменяет — «Поле не найдено» и несовместимость типов в ОБЪЕДИНИТЬ всплывают только при выполнении. Почему оба измерения устроены так — ../quality-gate/references/evidence-format.md.

Signals

GitHub stars
25
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
bsl-code-review
Source
github.com/romandredan/1c-quality-gate