quality-gate

Оркестратор контроля качества 1С-разработки. Определяет профиль изменения по трём осям (объём правки, архетипы кода, сложность), выбирает глубину каждого контура, запускает проверки, формирует отчёт с

SKILL.md

GitHub

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 печатает запись сам, переноси дословно.

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).