quality-gate
Оркестратор контроля качества 1С-разработки. Определяет профиль изменения по трём осям (объём правки, архетипы кода, сложность), выбирает глубину каждого контура, запускает проверки, формирует отчёт с
SKILL.mdskills/quality-gate/SKILL.md
GitHubquality-gate — оркестратор контроля качества 1С
Единственная точка входа плагина. Контуры (code, arch, xml, hygiene) не вызываются
напрямую: сначала считается профиль изменения, он решает глубину.
Главное правило. Полный прогон на правке комментария — налог, из-за которого гейт начинают обходить; пропуск без следа — ложная зелень. Глубина адаптивная, но любой пропуск фиксируется явной записью с причиной.
<ЖЁСТКИЙ-ШЛЮЗ>
По умолчанию — только проверка и отчёт. НЕ переписывай бизнес-логику и НЕ меняй метаданные по
своей инициативе. Правки — только в режиме --fix, из безопасных категорий. Critical и любые
изменения логики, проведения, запросов, прав — никогда без явного подтверждения пользователя.
</ЖЁСТКИЙ-ШЛЮЗ>
Инварианты прогона
Девять утверждений: усвоен только этот блок — прогон ещё имеет смысл; нарушено любое — уже нет.
- Профиль считается один раз, до контуров; контуры его не пересчитывают.
- Глубина — по профилю, не по привычке: не гонять архитектуру на опечатке, не ограничиваться гигиеной на новом модуле проведения.
- Контур исполняется вызовом навыка, а не по памяти.
- Строку следа печатает инструмент, где он есть — не модель по смыслу.
- Любой пропуск — запись
skippedс причиной. Молчание неотличимо от выполнения. - Вердикт «чисто» признаёт непроверяемое — записью
not_verified. - Находка — с номером стандарта, кодом диагностики или эвристикой и значением против
порога; 🔴/🟠 блокируют «Чисто», вне
--fix— только отчёт. - Гейт снимается утилитой
gate.mjs release, а не удалением файла состояния. - План считает и исполняет
gate.mjs run; модель вправе поднять глубину с причиной, понизить — нет.
Шаг 1. План
Путь к инструментам плагина ($QG)
Все команды ниже используют $QG — каталог плагина. Хук его уже назвал (сообщение
блокировки, подсказка взвода) — подставляй буквально: node "$QG/tools/gate.mjs" run. Не назван —
одна команда для bash и PowerShell: находит плагин и исполняет run, аргументы — после --.
node -e "const f=require('fs'),p=require('path'),ok=d=>d&&f.existsSync(p.join(d,'tools','gate.mjs'));let q=[process.env.QG_ROOT,process.env.CLAUDE_PLUGIN_ROOT].find(ok);try{const j=JSON.parse(f.readFileSync(p.join(require('os').homedir(),'.claude','plugins','installed_plugins.json'),'utf8')).plugins,k=Object.keys(j).find(n=>n.startsWith('1c-quality-gate@'));if(!q&&ok(j[k][0].installPath))q=j[k][0].installPath}catch{}if(!q){console.error('1c-quality-gate: plugin not found');process.exit(1)}process.exit(require('child_process').spawnSync(process.execPath,[p.join(q,'tools','gate.mjs'),'run',...process.argv.slice(1)],{stdio:'inherit'}).status??1)" [-- --files <f> ...]
Источники: QG_ROOT, CLAUDE_PLUGIN_ROOT, installed_plugins.json — кэш не перебирается
(references/run-environment.md). Вывод называет QG=<путь> — дальше подставляй буквально.
Профиль и инструменты — той же командой
gate.mjs run [--files <f> ...] [--only <инструмент,...>] [--no-analyzer]: поиск пути и
прогон занимают один ход. Без --files — состав из взведённой
сессии (gate.mjs status). Печатает QG=<путь> для следующих команд, профиль, строку
scope (с config=...), сводку инструментов, вывод тех, у кого находки и сбои, черновик
следа и что осталось модели. Полный вывод, сравнение версий и индекс каталога — в каталоге
прогона, не в контексте. --no-analyzer — когда анализатор недоступен или падает; ось
сложности тогда not_computed.
Строку [qg scope: ...] перенеси в отчёт дословно — валидатор пересчитывает профиль сам.
Расхождение — сверь порог: node "$QG/tools/config.mjs" show. Профиль можно поднять,
нельзя понизить: увидел то, чего план не видит (правка тише архетипа, но трогает деньги) —
подними, добавь «глубина поднята: <причина>»; обратное валидатор не пропустит.
Почему оси устроены так — references/profile-axes.md; данные — tools/profile.mjs,
tools/gate.mjs.
Шаг 2. Инструменты
Их исполнил run. Строки следа печатают сами инструменты — переноси черновик дословно, не
сочиняй. СБОЙ в сводке: строки за упавший инструмент нет — перезапусти его (--only) либо
закрой skipped с причиной. После правки кода повтори run: после принятого отчёта это проход по
исправлению — run печатает базу, прошлый отчёт и его находки, слоям — fix.diff
(references/fix-pass.md). platform-context-run.mjs обязателен и при --only:
анализатор знает имена конфигурации, но не платформы. Субагентам называй каталог
прогона: готовый вывод они читают оттуда, а не гоняют инструменты заново.
Прогон отмечается в журнале qg-runs.jsonl: валидатор сверяет по нему каждую запись
applied — инструмент видел весь состав правки; skipped ... reason=not_applicable —
тоже утверждение о работе. Прогоны по частям складываются.
Перед повторным прогоном слоя проверь gate.mjs status: отработавший по этому
содержимому слой пропускается с причиной verified_earlier (references/evidence-format.md).
Шаг 3. Контуры
Запускай контуры и глубины из resolved: code=... arch=... xml=... hygiene=... плана.
Каждый контур обязан вернуть applied либо skipped — молчание не допускается.
| Контур | Навык |
|---|---|
code |
bsl-code-review |
arch |
bsl-architecture-review |
xml |
xml-structure-review |
hygiene |
file-hygiene |
Передавай контуру профиль целиком: класс, архетипы, файлы.
Контур исполняется вызовом навыка, а не по памяти
Таблица называет навыки, а не проверки: чем проверяется признак — в SKILL.md контура. Прогон
без открытия навыка — чеклист для чтения глазами, не проверка
(references/run-environment.md).
Субагенты в составе прогона
Только читающие: возвращают факты, запись формирует контур. Дешёвые, кроме
antipattern-reader и cold-reader: семантика и суждение до haiku не сводятся.
| Субагент | Вызывает | Факты | Спавнов |
|---|---|---|---|
bsl-verifier |
code |
сигнатуры платформы, экспортность модулей, метаданные | на файлы |
antipattern-reader |
code |
кандидаты с цитатами; аттестует tools/catalog.mjs |
на контур |
cold-reader |
code |
слой 2: чтение без замысла | на контур |
bsl-scout |
arch |
вызывающие, экспорты, триггеры XML | по вопросу |
xml-runner |
xml |
«диск ↔ состав», валидаторы структуры | на контур |
Недоступность субагента, контура или инструмента проверку не отменяет — она проходит сама
либо получает skipped с причиной (references/run-environment.md).
Слой 3: состязательный аудит
Самая дорогая проверка, никогда не запускается сама: контуры предлагают её при классе C3 с
находками 🔴/🟠, запуск — только по явному согласию пользователя
(references/adversarial-audit.md).
Шаг 4. Sentinel — проверка живости источника стандартов
Один раз за прогон запроси через MCP v8std стандарт, чей номер — sentinel.id настройки
(умолчание std454): v8std_get_page("<id>"), ожидание — страница найдена.
Без неё «нарушений не найдено» неотличимо от «сервис недоступен»: неподтверждённый часовой
делает прогон недостоверным (references/run-environment.md).
Шаг 5. Отчёт и след
Отчёт для человека — находки по важности (🔴 Critical / 🟠 Major / 🟡 Minor). Ниже, в
## quality evidence, — машиночитаемый след: строка на проверку
(references/evidence-format.md).
Находки — по разделам, которые читает валидатор: ## Открыто в правке (строка в методах и
диапазонах из ## Задето правкой вывода run), ## Вне правки (нетронутый код: гейт не держат,
в этом цикле не исправляются — техдолг; 🔴 вне правки — в «Нужно решение»), ## Нужно решение пользователя (что сам оценить не можешь; 🔴 в правке туда не попадает). Каждая находка —
заголовок с уровня: ### 🟠 <суть>; списком валидатор не читает. Проходов на цикл три,
четвёртый — только с --decision. Со второго прохода — ## Закрыто: находки прошлого отчёта,
закрытие которых проверено по коду, с их идентификаторами.
Каждая запись not_verified повторяется в человекочитаемой части фразой: «Ошибок: 0»
рядом с невидимым not_verified читается как «проверено».
Минимум следа: scope (Шаг 1), sentinel (Шаг 4), запись от каждого контура и всё из плана
«Закрыть в следе» — включая 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 --session <id>
Шаг 6. Снятие гейта
Гейт снимается только утилитой, не удалением файла состояния:
node "$QG/tools/gate.mjs" release --evidence <файл отчёта> # по результатам прогона
node "$QG/tools/gate.mjs" release --class C0 --reason "<почему>" # C0/C1 без прогона
Отчёт — в файл из строки Отчёт прохода: вывода run (временный каталог, не проект): release копирует его в архив вне git;
ссылайся на путь Копия отчёта: (references/run-environment.md).
НЕ снимай гейт, если прогон прерван на полпути и отчёт не сформирован: он должен остаться для повторной проверки.
Чужие сессии не трогай. Гейт разделён по сессиям: несколько в gate.mjs status —
verify/release без --session <id> отказывают, «самая свежая» может быть чужой.
Идентификатор — в подсказке при взводе и в сообщении о блокировке
(references/run-environment.md).