Оркестратор контроля качества 1С-разработки. Определяет профиль изменения по трём осям (объём правки, архетипы кода, сложность), выбирает глубину каждого контура, запускает проверки, формирует отчёт с машиночитаемым следом и снимает блокирующий гейт. Вызывать после правок BSL или XML метаданных 1С, перед завершением работы и коммитом. Триггеры: «прогони гейт качества», «проверь код перед коммитом», «сними гейт», «отревьюй что я написал», «проверь по стандартам», «готов ли код к коммиту».
Installs into .claude/skills of the current project.
Are you the author of Quality Gate?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/romandredan-quality-gate)
---
name: quality-gate
description: >-
Оркестратор контроля качества 1С-разработки. Определяет профиль изменения по трём осям
(объём правки, архетипы кода, сложность), выбирает глубину каждого контура, запускает
проверки, формирует отчёт с машиночитаемым следом и снимает блокирующий гейт.
Вызывать после правок BSL или XML метаданных 1С, перед завершением работы и коммитом.
Триггеры: «прогони гейт качества», «проверь код перед коммитом», «сними гейт»,
«отревьюй что я написал», «проверь по стандартам», «готов ли код к коммиту».
license: MIT
---
# quality-gate — оркестратор контроля качества 1С
Единственная точка входа плагина. Контуры (`code`, `arch`, `xml`, `hygiene`) не вызываются
напрямую: сначала считается **профиль изменения**, он решает глубину.
> **Главное правило.** Полный прогон на правке комментария — налог, из-за которого гейт
> начинают обходить; пропуск без следа — ложная зелень. Глубина адаптивная, но **любой
> пропуск фиксируется явной записью с причиной**.
<ЖЁСТКИЙ-ШЛЮЗ>
По умолчанию — только проверка и отчёт. НЕ переписывай бизнес-логику и НЕ меняй метаданные по
своей инициативе. Правки — только в режиме `--fix`, из безопасных категорий. Critical и любые
изменения логики, проведения, запросов, прав — никогда без явного подтверждения пользователя.
</ЖЁСТКИЙ-ШЛЮЗ>
---
## Инварианты прогона
Девять утверждений: усвоен только этот блок — прогон ещё имеет смысл; нарушено любое —
уже нет.
1. **Профиль считается один раз**, до контуров; контуры его не пересчитывают.
2. **Глубина — по профилю, не по привычке**: не гонять архитектуру на опечатке, не
ограничиваться гигиеной на новом модуле проведения.
3. **Контур исполняется вызовом навыка**, а не по памяти.
4. **Строку следа печатает инструмент**, где он есть — не модель по смыслу.
5. **Любой пропуск — запись `skipped` с причиной.** Молчание неотличимо от выполнения.
6. **Вердикт «чисто» признаёт непроверяемое** — записью `not_verified`.
7. **Находка — с номером стандарта, кодом диагностики или эвристикой** и значением против
порога; 🔴/🟠 блокируют «Чисто», вне `--fix` — только отчёт.
8. **Гейт снимается утилитой** `gate.mjs release`, а не удалением файла состояния.
9. **План считает и исполняет `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` печатает
запись сам, переноси дословно.
```bash
node "$QG/tools/evidence-validator.mjs" <файл отчёта> --gate --session <id>
```
---
## Шаг 6. Снятие гейта
Гейт снимается **только** утилитой, не удалением файла состояния:
```bash
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`).