quality-gate — оркестратор контроля качества 1С

SkillDev tools

Quality control orchestrator for 1C development. Determines the change profile along three axes (edit size, code archetypes, complexity), selects the depth of each check loop, runs verifications, generates a report with a machine-readable trace, and releases the blocking gate. Invoke after edits to

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 quality-gate — оркестратор контроля качества 1С skill

What this skill tells your AI

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

Единственная точка входа плагина. Контуры проверки (code, arch, xml, hygiene) не вызываются напрямую: сначала определяется профиль изменения, и уже он решает, какие контуры и на какой глубине запускать.

Главное правило. Полный прогон на правке комментария — налог, из-за которого гейт начинают обходить. Пропуск проверки без следа — ложная зелень. Поэтому глубина адаптивная, но любой пропуск фиксируется явной записью с причиной.

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


Инварианты прогона

Восемь утверждений, без которых результат недействителен. Если из всего навыка усвоено только это — прогон ещё имеет смысл; если нарушено любое из них — уже нет.

  1. Профиль считается один раз, до контуров, и контуры его не пересчитывают.
  2. Глубина — по профилю, а не по привычке. Не гонять архитектуру на опечатке и не ограничиваться гигиеной на новом модуле проведения.
  3. Контур исполняется вызовом навыка, а не воспроизведением по памяти.
  4. Строку следа инструментальной проверки печатает инструмент — она не сочиняется и не переписывается по смыслу.
  5. Любой пропуск — запись skipped с причиной. Молчание неотличимо от выполнения, и это единственная ошибка, которая обесценивает плагин целиком.
  6. Вердикт «чисто» обязан признавать непроверяемое — записью not_verified.
  7. Каждая находка — с номером стандарта, кодом диагностики или названием эвристики и измеренным значением против порога; 🔴 и 🟠 блокируют вердикт «Чисто». Вне --fix — только отчёт.
  8. Гейт снимается утилитой gate.mjs release, а не удалением файла состояния.

Шаг 1. Профиль изменения — три оси

Считается один раз, до запуска контуров.

Пороги берутся из проекта, а не по памяти. До расчёта осей выполни:

node "$QG/tools/config.mjs" show

Команда печатает действующие значения и источник каждого. Значения в таблицах ниже — умолчания; если вывод расходится с ними, считай по выводу. Последняя строка вывода — готовое поле config=... для записи scope: перенеси её дословно, валидатор пересчитывает эту отметку сам и написанное по памяти отвергает. Почему именно так — references/profile-axes.md.

Ось 1: объём (скаляр)

Что тронуто и пересекает ли правка границы.

КлассПризнаки
C0 Косметикакомментарии, форматирование, переименование без изменения смысла; тела методов не менялись
C1 Точечнаяфайлов ≤ volume.c1MaxFiles (умолчание 1), изменённых строк ≤ volume.c1MaxLines (умолчание 40), правка внутри существующих методов; нет новых экспортов, изменённых сигнатур, новых модулей и объектов метаданных
C2 Модульная>1 метода, ИЛИ новый экспортный метод, ИЛИ изменена сигнатура, ИЛИ превышен порог строк либо файлов — в пределах существующих модулей
C3 Структурнаяновый модуль / объект метаданных / форма, ИЛИ изменение проведения и бизнес-логики, ИЛИ новая интеграция, ИЛИ затронуто ≥4 модуля разных подсистем

Источник данных: git diff --stat и git diff по рабочему дереву, либо явно названные пользователем файлы. Состав правки — из node "$QG/tools/gate.mjs" status.

Ось 2: архетипы кода (множество меток)

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

АрхетипМетка в следеМаркер в измененияхМин. codeМин. arch
ЗапросqueryНовый Запрос, правка текста запросаL2
Транзакция, блокировкиtransactionНачатьТранзакцию, ЗаблокироватьL2
Запись наборов записейrecord-setЗаписать(Истина), СоздатьНаборЗаписейL2
Обработчик события объектаobject-eventПередЗаписью, ПриЗаписи, ОбработкаПроведенияL2ур. 1
Интеграция, HTTPintegrationHTTPСоединение, WSПрокси, Новый COMОбъектL2ур. 1
Права, RLSrightsXML ролей, УстановитьПривилегированныйРежимL2ур. 2
CFE-перехватcfe-patch&Перед, &После, &Вместо, &ИзменениеИКонтрольL2ур. 1
Регламентное, фоновоеscheduled-jobподписка регл. задания, ФоновыеЗаданияL2
Клиент-серверclient-serverдирективы компиляцииL1ур. 1
Диалог посреди логикиuser-dialogПоказатьВопрос, ВопросАсинх, ОповещениеОЗавершенииL1ур. 1
Модуль формыform-moduleпуть Forms/*/Module.bslL1ур. 1 при loc > 400
Асинхронный клиентasync-clientАсинх, Ждать, ОбещаниеL1
Новый общий модульnew-common-moduleновый файл CommonModuleL1ур. 2
Новый объект метаданныхnew-metadata-objectновый XML в src/L1ур. 3

Обязательные чеклисты по каждому архетипу перечисляет контур в своём SKILL.md: продублируй их здесь — и они разъедутся с тем, что контур делает на самом деле.

Колонка «Метка в следе» — ровно то, что пишется в поле archetypes записи scope. Метка не переводится и не сокращается: queries вместо query означает не «почти то же самое», а «правило не сработало», и снятие гейта валидатор не пропустит. Свои архетипы проект заводит в секции archetypes.custom (имя, маркеры, minCode, minArch), их имена — тоже законные метки. Почему минимумы по двум контурам асимметричны — references/profile-axes.md.

Ось 3: сложность (скаляр)

Закрывает случай «мало строк, но код тяжёлый», когда архетипа может не быть вовсе. Считается по изменённым методам: вложенность ≥ complexity.maxNesting (4), длина метода

complexity.maxMethodLines (120), параметров ≥ complexity.maxParams (7), цепочка ветвлений ≥4, рекурсия. Срабатывание поднимает code до L2 и arch до уровня 1.

Метрики — из отчёта tools/analyzer-run.mjs --json (functions, complexity, cognitive_complexity), считать самому не нужно. Анализатор запускается с гейтовым конфигом из состава плагина: проектный может отсечь изменённые файлы фильтром подсистем и оставить правдоподобно пустой отчёт (references/profile-axes.md).

Итог: правило разрешения

глубина контура = max(по объёму, максимум минимумов по сработавшим архетипам, по сложности)

Отдельно фиксируется driver — что именно подняло глубину: объём, конкретный архетип или сложность. Без него вердикт виден, а логика нет, и первое же «почему так долго на трёх строках?» превращается в спор.

Понижающий модификатор: эталонная правка

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


Шаг 2. Матрица глубин по объёму (базовый уровень)

КонтурC0C1C2C3
hygieneполныйполныйполныйполный
codeпропускL1L1 + L2L1 + L2, предложить аудит
archпропускпропускур. 1–2ур. 3
xmlпропускне применим, если XML не менялсяизменённые объекты + регистрацияполный: валидация + сироты в обе стороны + права ролей
компилируемостьесли платформа доступнадада

hygiene гоняется всегда: стоимость околонулевая, а ловит он то, что проявляется позже всего и объясняется хуже всего. Разовое отклонение от расчётной глубины — --deep / --quick.


Шаг 3. Прогон контуров

Запускай только те контуры и глубины, которые дал шаг 2. Каждый контур обязан вернуть запись applied либо skippedмолчание не допускается.

КонтурНавыкСостояние
codebsl-code-review — стандарты, антипаттерны, верификация APIготов
archbsl-architecture-review — принципы, паттерны, границы модулейготов
xmlxml-structure-review — структура метаданных, регистрация, праваготов
hygienefile-hygiene — кодировки, BOM, символы, переводы строкготов

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

Контур исполняется вызовом навыка, а не по памяти

Таблица называет навыки, а не проверки: чем именно проверяется признак, написано в SKILL.md контура. Прогон без открытия навыка воспроизводит контур как чеклист для чтения глазами — вердикт выглядит результатом проверки, но им не является, и происходит это не по небрежности (references/run-environment.md).

У части проверок есть исполняемый инструмент. Для них строку следа печатает сам инструмент — не сочиняй её. Прогон отмечается в журнале (qg-runs.jsonl в каталоге состояния гейта: .claude/.state/ в Claude Code, .opencode/.state/ в OpenCode) вместе с путями файлов, и валидатор сверяет по нему каждую запись applied: и то, что инструмент запускался, и то, что он видел весь состав правки. Прогон по одному файлу из десяти заявление обо всех десяти не закрывает; skipped ... reason=not_applicable — тоже утверждение о работе инструмента.

Гонять инструмент по частям можно, прогоны складываются: передавай все изменённые файлы его вида, список даёт gate.mjs status. query-lint принимает не только .bsl — он читает <query> схем компоновки и <QueryText> динамических списков, поэтому изменённые XML идут и в него.

Проверка (scope)Инструмент
static-analysistools/analyzer-run.mjs
platform-apitools/platform-context-run.mjs (сервер справки заводится сам)
query-alias-shadowing, query-top-ordertools/query-lint.mjs (.bsl и .xml)
transaction-nesting, enum-string-assign, unbounded-string-column, attribute-access, form-attribute-shadowing, dispatch-fallback, db-read-in-looptools/bsl-lint.mjs
stale-local-callstools/rename-check.mjs
file-encodingtools/hygiene-check.mjs
registration-checktools/xml/orphan-check.mjs
uuid-uniquenesstools/xml/uuid-unique.mjs
structure-validationtools/xml/meta-validate.py
form-bindingtools/xml/form-validate.py

Есть модули — сверка со справочником платформы обязательна. Валидатор требует не успеха, а отчёта: движок сам печатает и applied, и skipped с причиной. Этот класс дефектов не закрывает больше ничто — анализатор знает имена конфигурации, но не платформы.

Остальные проверки (архитектурные признаки, разбор стандартов, ручная сверка API там, где движок промолчал) инструмента не имеют: журнала для них не требуется. Полный словарь имён — tools/evidence-scopes.mjs; имя вне словаря валидатор отвергает, потому что закрывает требование, которого не выполняло.

Субагенты в составе прогона

Три штатных, все дешёвые и только читающие. Записи следа они не пишут: агент возвращает факты, запись формирует контур.

СубагентКем вызываетсяЗачемСпавнов
bsl-verifierконтур code, верификация APIсигнатуры платформы, экспортность общих модулей, состав метаданныходин на весь список файлов
bsl-scoutконтур arch, признаки по графу вызововвызывающие, экспорты модуля, триггеры в XMLодин на вопрос, независимые — параллельно
xml-runnerконтур xmlсверка «диск ↔ состав», валидаторы структуры, разбор их выводаодин на прогон контура

Недоступность субагента, контура или инструмента проверку не отменяет: она выполняется сама либо получает skipped с точной причиной. Границы применения и список причин деградации — references/run-environment.md.

Перед повторным прогоном слоя проверь gate.mjs status: слой, уже отработавший по этому содержимому, пропускается с причиной verified_earlier, а любая правка файла снимает его отметку. Механика — references/evidence-format.md.


Слой 3 контуров: состязательный аудит

Самая дорогая проверка и единственная, которая никогда не запускается сама. Контуры предлагают её в отчёте при классе C3 с находками 🔴 или 🟠; запуск — только после явного согласия пользователя. Методология, пороги и поведение при недоступной оркестрации — в references/adversarial-audit.md.


Шаг 4. Sentinel — проверка живости источника стандартов

Один раз за прогон запроси через MCP v8std заведомо существующий стандарт — тот, чей номер задан в sentinel.id проектной настройки (умолчание std454, фактическое значение — в выводе config.mjs show из шага 1): v8std_get_page("<sentinel.id>"). Ожидание — страница найдена.

Без этой проверки «нарушений стандартов не найдено» неотличимо от «сервис стандартов недоступен»: неподтверждённый часовой делает прогон недостоверным, и валидатор следа отклонит снятие гейта. Почему номер вынесен в настройку — references/run-environment.md.


Шаг 5. Отчёт и след

Отчёт для человека — находки по важности (🔴 Critical / 🟠 Major / 🟡 Minor) в формате контура. Ниже, в секции ## quality evidence, — машиночитаемый след: одна строка на проверку. Формат, полный список причин и правила валидатора — references/evidence-format.md.

Каждая запись not_verified повторяется в человекочитаемой части одной фразой — «Ошибок: 0» рядом с невидимым not_verified читается как «проверено». Фраза короткая и по делу: «текст запроса статически чист; выполнимость не проверялась — платформы нет».

Обязательный минимум следа: одна запись scope (с полем config из шага 1), одна sentinel, по записи от каждого запущенного или пропущенного контура, и — если компилируемость тел модулей не проверялась — запись not_verified: dimension=compilation. Компилируемость не проверяется ничем, кроме платформы, поэтому полностью зелёный отчёт без такой записи валидатор отклоняет.

Сработал архетип «Запрос» — выполни запрос до вердикта: в консоли запросов, на тестовых параметрах, прогоном обработки. Для всех инструментов текст запроса остаётся строковым литералом, и «Неоднозначное поле» доживает до продуктива. Выполнить негде — законный исход, но записанный:

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

Изменённый файл, до которого не добрался анализатор, не проверен. analyzer-run.mjs считает такие файлы и печатает запись сам — переноси её дословно; число непроверенных уходит в журнал, и промолчать о них валидатор не даст.

Проверить след перед снятием:

node "$QG/tools/evidence-validator.mjs" <файл отчёта> --gate

Шаг 6. Снятие гейта

Гейт снимается только утилитой — не удалением файла состояния вручную:

# по результатам прогона (след проверяется, дефектный след снятие не пропустит)
node "$QG/tools/gate.mjs" release --evidence <файл отчёта>

# правка не требует проверки — допустимо только для C0/C1, причина обязательна
node "$QG/tools/gate.mjs" release --class C0 --reason "<почему>"

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

Чужие сессии не трогай. Состояние гейта разделено по сессиям. Если gate.mjs status показывает несколько, verify и release без --session <id> отказывают — выбор «самой свежей» брал чужую. Идентификатор напечатан в подсказке при взводе гейта и в сообщении о блокировке; свою сессию видно по составу правок (references/run-environment.md).


Путь к инструментам плагина ($QG)

Все команды выше используют $QG — каталог установленного плагина. Под OpenCode он приходит готовым в QG_ROOT; в Claude Code CLAUDE_PLUGIN_ROOT доступна хукам, но не оболочке — в шелле она пуста, и путь через неё схлопнулся бы в /tools/....

Разреши путь первой командой прогона и дальше подставляй полученное значение буквально (состояние оболочки между вызовами не сохраняется). Каждый кандидат принимается только после проверки test -d "$QG/tools": существование переменной или каталога ещё не значит, что там лежит этот плагин — установка могла быть частичной, устаревшей или чужой.

QG="${QG_ROOT:-}"
[ ! -d "$QG/tools" ] && QG="${CLAUDE_PLUGIN_ROOT:-}"
[ ! -d "$QG/tools" ] && QG="$(node -e "const p=require(require('node:os').homedir()+'/.claude/plugins/installed_plugins.json').plugins;const k=Object.keys(p).find(n=>n.startsWith('1c-quality-gate@'));if(k&&p[k][0])process.stdout.write(p[k][0].installPath)" 2>/dev/null)"
[ ! -d "$QG/tools" ] && QG="$(ls -d ~/.claude/plugins/cache/*/1c-quality-gate/*/ 2>/dev/null | sort -V | tail -1)" && QG="${QG%/}"
test -d "$QG/tools" && echo "$QG" || { echo "Плагин не найден ни в одном харнессе" >&2; exit 1; }

sort -V не декоративен: без него сессия работает инструментами устаревшей версии и честно отчитывается, что проверок «не существует». Разбор — references/run-environment.md.

Signals

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