quality-gate · diff

git:20260907.21971b5 to git:20260907.b401583

112 added, 244 removed. Audit A to A.

---
name: quality-gate
description: >-
Оркестратор контроля качества 1С-разработки. Определяет профиль изменения по трём осям
(объём правки, архетипы кода, сложность), выбирает глубину каждого контура, запускает
проверки, формирует отчёт с машиночитаемым следом и снимает блокирующий гейт.
Вызывать после правок BSL или XML метаданных 1С, перед завершением работы и коммитом.
Триггеры: «прогони гейт качества», «проверь код перед коммитом», «сними гейт»,
«отревьюй что я написал», «проверь по стандартам», «готов ли код к коммиту».
license: MIT
---
# quality-gate — оркестратор контроля качества 1С
- Единственная точка входа плагина. Контуры проверки (`code`, `arch`, `xml`, `hygiene`) не
- вызываются напрямую: сначала определяется **профиль изменения**, и уже он решает, какие
- контуры и на какой глубине запускать.
+ Единственная точка входа плагина. Контуры (`code`, `arch`, `xml`, `hygiene`) не вызываются
+ напрямую: сначала считается **профиль изменения**, он решает глубину.
> **Главное правило.** Полный прогон на правке комментария — налог, из-за которого гейт
- > начинают обходить. Пропуск проверки без следа — ложная зелень. Поэтому глубина
- > адаптивная, но **любой пропуск фиксируется явной записью с причиной**.
+ > начинают обходить; пропуск без следа — ложная зелень. Глубина адаптивная, но **любой
+ > пропуск фиксируется явной записью с причиной**.
<ЖЁСТКИЙ-ШЛЮЗ>
- По умолчанию — только проверка и отчёт. НЕ переписывай бизнес-логику и НЕ меняй метаданные
- по своей инициативе. Правки применяются лишь в режиме `--fix` и только из безопасных
- категорий. Находки уровня Critical и любые изменения логики, проведения, запросов, прав —
- никогда без явного подтверждения пользователя.
+ По умолчанию — только проверка и отчёт. НЕ переписывай бизнес-логику и НЕ меняй метаданные по
+ своей инициативе. Правки — только в режиме `--fix`, из безопасных категорий. Critical и любые
+ изменения логики, проведения, запросов, прав — никогда без явного подтверждения пользователя.
</ЖЁСТКИЙ-ШЛЮЗ>
---
## Инварианты прогона
- Восемь утверждений, без которых результат недействителен. Если из всего навыка усвоено
- только это — прогон ещё имеет смысл; если нарушено любое из них — уже нет.
+ Девять утверждений: усвоен только этот блок — прогон ещё имеет смысл; нарушено любое —
+ уже нет.
- 1. **Профиль считается один раз**, до контуров, и контуры его не пересчитывают.
- 2. **Глубина — по профилю, а не по привычке.** Не гонять архитектуру на опечатке и не
+ 1. **Профиль считается один раз**, до контуров; контуры его не пересчитывают.
+ 2. **Глубина — по профилю, не по привычке**: не гонять архитектуру на опечатке, не
ограничиваться гигиеной на новом модуле проведения.
- 3. **Контур исполняется вызовом навыка**, а не воспроизведением по памяти.
- 4. **Строку следа инструментальной проверки печатает инструмент** — она не сочиняется и
- не переписывается по смыслу.
- 5. **Любой пропуск — запись `skipped` с причиной.** Молчание неотличимо от выполнения, и
- это единственная ошибка, которая обесценивает плагин целиком.
- 6. **Вердикт «чисто» обязан признавать непроверяемое** — записью `not_verified`.
- 7. **Каждая находка — с номером стандарта, кодом диагностики или названием эвристики** и
- измеренным значением против порога; 🔴 и 🟠 блокируют вердикт «Чисто». Вне `--fix` —
- только отчёт.
+ 3. **Контур исполняется вызовом навыка**, а не по памяти.
+ 4. **Строку следа печатает инструмент**, где он есть — не модель по смыслу.
+ 5. **Любой пропуск — запись `skipped` с причиной.** Молчание неотличимо от выполнения.
+ 6. **Вердикт «чисто» признаёт непроверяемое** — записью `not_verified`.
+ 7. **Находка — с номером стандарта, кодом диагностики или эвристикой** и значением против
+ порога; 🔴/🟠 блокируют «Чисто», вне `--fix` — только отчёт.
8. **Гейт снимается утилитой** `gate.mjs release`, а не удалением файла состояния.
+ 9. **План печатает `gate.mjs plan`**; модель вправе поднять глубину с причиной, понизить —
+ нет.
---
- ## Шаг 1. Профиль изменения — три оси
+ ## Шаг 1. План
- Считается **один раз**, до запуска контуров.
+ ### Путь к инструментам плагина (`$QG`)
- **Пороги берутся из проекта, а не по памяти.** До расчёта осей выполни:
+ Все команды ниже используют `$QG` — каталог плагина. Под OpenCode он готов в `QG_ROOT`; в
+ Claude Code `CLAUDE_PLUGIN_ROOT` доступна хукам, но не оболочке — путь через неё схлопнулся
+ бы в `/tools/...`.
+ Разреши путь **первой командой прогона**, дальше подставляй значение буквально. Кандидат —
+ только после `test -d "$QG/tools"`: переменная сама по себе не гарантирует актуальный плагин.
+
```bash
- node "$QG/tools/config.mjs" show
+ 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; }
```
- Команда печатает действующие значения и источник каждого. Значения в таблицах ниже —
- **умолчания**; если вывод расходится с ними, считай по выводу. Последняя строка вывода —
- готовое поле `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 |
- | Интеграция, HTTP | `integration` | `HTTPСоединение`, `WSПрокси`, `Новый COMОбъект` | L2 | ур. 1 |
- | Права, RLS | `rights` | XML ролей, `УстановитьПривилегированныйРежим` | L2 | ур. 2 |
- | CFE-перехват | `cfe-patch` | `&Перед`, `&После`, `&Вместо`, `&ИзменениеИКонтроль` | L2 | ур. 1 |
- | Регламентное, фоновое | `scheduled-job` | подписка регл. задания, `ФоновыеЗадания` | L2 | — |
- | Клиент-сервер | `client-server` | директивы компиляции | L1 | **ур. 1** |
- | **Диалог посреди логики** | `user-dialog` | `ПоказатьВопрос`, `ВопросАсинх`, `ОповещениеОЗавершении` | L1 | **ур. 1** |
- | Модуль формы | `form-module` | путь `Forms/*/Module.bsl` | L1 | ур. 1 при `loc > 400` |
- | Асинхронный клиент | `async-client` | `Асинх`, `Ждать`, `Обещание` | L1 | — |
- | **Новый общий модуль** | `new-common-module` | новый файл `CommonModule` | L1 | **ур. 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`).
+ `sort -V` не декоративен: без него сессия честно отчитывается, что проверок «не существует»,
+ работая инструментами устаревшей версии. Разбор — `references/run-environment.md`.
- ### Итог: правило разрешения
+ ### Профиль и план прогона
- > **глубина контура = max(по объёму, максимум минимумов по сработавшим архетипам, по сложности)**
+ ```bash
+ node "$QG/tools/gate.mjs" plan --files <f> [<f> ...] [--no-analyzer]
+ ```
- Отдельно фиксируется **`driver`** — что именно подняло глубину: объём, конкретный архетип
- или сложность. Без него вердикт виден, а логика нет, и первое же «почему так долго на трёх
- строках?» превращается в спор.
+ Без `--files` — состав из взведённой сессии (`gate.mjs status`). Печатает профиль по трём
+ осям, строку `scope` (с `config=...`), инструменты по порядку, что закрыть в следе.
+ `--no-analyzer` пропускает ось сложности — только когда платформы заведомо нет.
- ### Понижающий модификатор: эталонная правка
+ **Строку `[qg scope: ...]` перенеси в отчёт дословно** — валидатор пересчитывает профиль сам.
+ Расхождение — сверь порог: `node "$QG/tools/config.mjs" show`. **Профиль можно поднять,
+ нельзя понизить**: увидел то, чего план не видит (правка тише архетипа, но реально трогает
+ деньги) — подними, добавь «глубина поднята: <причина>»; обратное валидатор не пропустит.
- Понижает глубину до C1 независимо от объёма, если выполнены **три условия сразу**:
- (а) все фрагменты — кальки типового эталона того же механизма с точечной адаптацией имён и
- полей; (б) уже прошли предметный верификатор механизма с нулём ошибок; (в) не трогают
- транзакции, блокировки и права. Хотя бы одно не выполнено — модификатор не применяется.
+ Почему оси устроены так — `references/profile-axes.md`; данные — `tools/profile.mjs`,
+ `tools/gate.mjs`.
---
- ## Шаг 2. Матрица глубин по объёму (базовый уровень)
+ ## Шаг 2. Инструменты
- | Контур | C0 | C1 | C2 | C3 |
- |---|---|---|---|---|
- | `hygiene` | полный | полный | полный | полный |
- | `code` | пропуск | L1 | L1 + L2 | L1 + L2, предложить аудит |
- | `arch` | пропуск | пропуск | ур. 1–2 | ур. 3 |
- | `xml` | пропуск | не применим, если XML не менялся | изменённые объекты + **регистрация** | полный: валидация + сироты в обе стороны + права ролей |
- | компилируемость | — | если платформа доступна | да | да |
+ Выполни команды раздела «## Инструменты» плана по порядку — файлы уже подставлены. У части
+ есть исполняемый инструмент: он печатает строку следа (`[qg applied: ...]` / `[qg skipped:
+ ...]`) сам — переноси дословно, не сочиняй.
- `hygiene` гоняется всегда: стоимость околонулевая, а ловит он то, что проявляется позже
- всего и объясняется хуже всего. Разовое отклонение от расчётной глубины — `--deep` /
- `--quick`.
+ Прогон отмечается в журнале `qg-runs.jsonl`: валидатор сверяет по нему каждую запись
+ `applied` — инструмент видел **весь** состав правки, а не файл из десяти; `skipped ...
+ reason=not_applicable` — тоже утверждение о работе. Прогоны по частям складываются.
+ `platform-context-run.mjs`, когда включён планом, обязателен: анализатор знает имена
+ конфигурации, но не платформы. `query-lint` берёт и изменённые XML, не только `.bsl`.
+ **Перед повторным прогоном слоя проверь `gate.mjs status`:** отработавший по этому
+ содержимому слой пропускается с причиной `verified_earlier` (`references/evidence-format.md`).
+
---
- ## Шаг 3. Прогон контуров
+ ## Шаг 3. Контуры
- Запускай только те контуры и глубины, которые дал шаг 2. Каждый контур обязан вернуть
- запись `applied` либо `skipped` — **молчание не допускается**.
+ Запускай контуры и глубины из `resolved: code=... arch=... xml=... hygiene=...` плана.
+ Каждый контур обязан вернуть `applied` либо `skipped` — **молчание не допускается**.
- | Контур | Навык | Состояние |
- |---|---|---|
- | `code` | `bsl-code-review` — стандарты, антипаттерны, верификация API | готов |
- | `arch` | `bsl-architecture-review` — принципы, паттерны, границы модулей | готов |
- | `xml` | `xml-structure-review` — структура метаданных, регистрация, права | готов |
- | `hygiene` | `file-hygiene` — кодировки, BOM, символы, переводы строк | готов |
+ | Контур | Навык |
+ |---|---|
+ | `code` | `bsl-code-review` |
+ | `arch` | `bsl-architecture-review` |
+ | `xml` | `xml-structure-review` |
+ | `hygiene` | `file-hygiene` |
- Передавай контуру профиль целиком: класс, сработавшие архетипы, список изменённых файлов.
- Пересчитывать профиль контур не должен — иначе оси разъедутся и решение о глубине перестанет
- быть проверяемым.
+ Передавай контуру профиль целиком: класс, архетипы, файлы.
### Контур исполняется вызовом навыка, а не по памяти
- Таблица называет навыки, а не проверки: чем именно проверяется признак, написано в 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-analysis` | `tools/analyzer-run.mjs` |
- | `platform-api` | `tools/platform-context-run.mjs` (сервер справки заводится сам) |
- | `query-alias-shadowing`, `query-top-order` | `tools/query-lint.mjs` (`.bsl` и `.xml`) |
- | `transaction-nesting`, `enum-string-assign`, `unbounded-string-column`, `attribute-access`, `form-attribute-shadowing`, `dispatch-fallback`, `db-read-in-loop` | `tools/bsl-lint.mjs` |
- | `stale-local-calls` | `tools/rename-check.mjs` |
- | `file-encoding` | `tools/hygiene-check.mjs` |
- | `registration-check` | `tools/xml/orphan-check.mjs` |
- | `uuid-uniqueness` | `tools/xml/uuid-unique.mjs` |
- | `structure-validation` | `tools/xml/meta-validate.py` |
- | `form-binding` | `tools/xml/form-validate.py` |
- | `ai-antipatterns`, `platform-antipatterns` | `tools/catalog.mjs` (аттестация результата читателя) |
-
- **Есть модули — сверка со справочником платформы обязательна.** Валидатор требует не успеха, а
- отчёта: движок сам печатает и `applied`, и `skipped` с причиной. Этот класс дефектов не
- закрывает больше ничто — анализатор знает имена конфигурации, но не платформы.
-
- Остальные проверки (архитектурные признаки, разбор стандартов, ручная сверка API там, где
- движок промолчал) инструмента не имеют: журнала для них не требуется. Полный словарь имён — `tools/evidence-scopes.mjs`;
- имя вне словаря валидатор отвергает, потому что закрывает требование, которого не выполняло.
+ Таблица называет навыки, а не проверки: чем проверяется признак — в SKILL.md контура. Прогон
+ без открытия навыка — чеклист для чтения глазами, не проверка
+ (`references/run-environment.md`).
### Субагенты в составе прогона
- Четыре штатных, **только читающие**: записи следа они не пишут, агент возвращает факты, запись
- формирует контур. Три дешёвые; `antipattern-reader` — на модели уровня контура, не haiku:
- семантика антипаттернов LLM-кода не механизируется до дешёвой.
+ Четыре штатных, **только читающие**: возвращают факты, запись формирует контур. Три дешёвые;
+ `antipattern-reader` — на модели уровня контура: семантика LLM-антипаттернов не
+ механизируется до haiku.
- | Субагент | Кем вызывается | Зачем | Спавнов |
+ | Субагент | Вызывает | Факты | Спавнов |
|---|---|---|---|
- | `bsl-verifier` | контур `code`, верификация API | сигнатуры платформы, экспортность общих модулей, состав метаданных | один на весь список файлов |
- | `antipattern-reader` | контур `code`, каталог антипаттернов | кандидаты по индексу триггеров с цитатами; результат аттестует catalog.mjs | один на прогон контура |
- | `bsl-scout` | контур `arch`, признаки по графу вызовов | вызывающие, экспорты модуля, триггеры в XML | один на вопрос, независимые — параллельно |
- | `xml-runner` | контур `xml` | сверка «диск ↔ состав», валидаторы структуры, разбор их вывода | один на прогон контура |
-
- Недоступность субагента, контура или инструмента проверку не отменяет: она выполняется сама
- либо получает `skipped` с точной причиной. Границы применения и список причин деградации —
- `references/run-environment.md`.
+ | `bsl-verifier` | `code` | сигнатуры платформы, экспортность модулей, метаданные | на список файлов |
+ | `antipattern-reader` | `code` | кандидаты с цитатами; аттестует `tools/catalog.mjs` | на контур |
+ | `bsl-scout` | `arch` | вызывающие, экспорты, триггеры XML | по вопросу |
+ | `xml-runner` | `xml` | «диск ↔ состав», валидаторы структуры | на контур |
- **Перед повторным прогоном слоя проверь `gate.mjs status`:** слой, уже отработавший по этому
- содержимому, пропускается с причиной `verified_earlier`, а любая правка файла снимает его
- отметку. Механика — `references/evidence-format.md`.
+ Недоступность субагента, контура или инструмента проверку не отменяет — она проходит сама
+ либо получает `skipped` с причиной (`references/run-environment.md`).
---
- ### Слой 3 контуров: состязательный аудит
+ ### Слой 3: состязательный аудит
- Самая дорогая проверка и единственная, которая **никогда не запускается сама**. Контуры
- предлагают её в отчёте при классе C3 с находками 🔴 или 🟠; запуск — только после явного
- согласия пользователя. Методология, пороги и поведение при недоступной оркестрации —
- в `references/adversarial-audit.md`.
+ Самая дорогая проверка, никогда не запускается сама: контуры предлагают её при классе C3 с
+ находками 🔴/🟠, запуск — только по явному согласию пользователя
+ (`references/adversarial-audit.md`).
---
## Шаг 4. Sentinel — проверка живости источника стандартов
- Один раз за прогон запроси через MCP `v8std` заведомо существующий стандарт — тот, чей номер
- задан в `sentinel.id` проектной настройки (умолчание `std454`, фактическое значение — в
- выводе `config.mjs show` из шага 1): `v8std_get_page("<sentinel.id>")`. Ожидание — страница
- найдена.
+ Один раз за прогон запроси через MCP `v8std` стандарт, чей номер — `sentinel.id` настройки
+ (умолчание `std454`): `v8std_get_page("<id>")`, ожидание — страница найдена.
- Без этой проверки «нарушений стандартов не найдено» неотличимо от «сервис стандартов
- недоступен»: неподтверждённый часовой делает прогон недостоверным, и валидатор следа
- отклонит снятие гейта. Почему номер вынесен в настройку — `references/run-environment.md`.
+ Без неё «нарушений не найдено» неотличимо от «сервис недоступен»: неподтверждённый часовой
+ делает прогон недостоверным (`references/run-environment.md`).
---
## Шаг 5. Отчёт и след
- Отчёт для человека — находки по важности (🔴 Critical / 🟠 Major / 🟡 Minor) в формате
- контура. Ниже, в секции `## quality evidence`, — машиночитаемый след: одна строка на
- проверку. Формат, полный список причин и правила валидатора — `references/evidence-format.md`.
+ Отчёт для человека — находки по важности (🔴 Critical / 🟠 Major / 🟡 Minor). Ниже, в
+ `## quality evidence`, — машиночитаемый след: строка на проверку
+ (`references/evidence-format.md`).
- **Каждая запись `not_verified` повторяется в человекочитаемой части одной фразой** — «Ошибок: 0»
- рядом с невидимым `not_verified` читается как «проверено». Фраза короткая и по делу:
- «текст запроса статически чист; выполнимость не проверялась — платформы нет».
+ **Каждая запись `not_verified` повторяется в человекочитаемой части фразой**: «Ошибок: 0»
+ рядом с невидимым `not_verified` читается как «проверено».
- Обязательный минимум следа: одна запись `scope` (с полем `config` из шага 1), одна
- `sentinel`, по записи от каждого запущенного или пропущенного контура, и — если
- компилируемость тел модулей не проверялась — запись `not_verified: dimension=compilation`.
- Компилируемость не проверяется ничем, кроме платформы, поэтому полностью зелёный отчёт без
- такой записи валидатор отклоняет.
+ Минимум следа: `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`
- считает такие файлы и печатает запись сам — переноси её дословно; число непроверенных
- уходит в журнал, и промолчать о них валидатор не даст.
-
- Проверить след перед снятием:
+ **Файл, до которого не добрался анализатор, не проверен** — `analyzer-run.mjs` печатает
+ запись сам, переноси дословно.
```bash
node "$QG/tools/evidence-validator.mjs" <файл отчёта> --gate
```
---
## Шаг 6. Снятие гейта
- Гейт снимается **только** утилитой — не удалением файла состояния вручную:
+ Гейт снимается **только** утилитой, не удалением файла состояния:
```bash
- # по результатам прогона (след проверяется, дефектный след снятие не пропустит)
- node "$QG/tools/gate.mjs" release --evidence <файл отчёта>
-
- # правка не требует проверки — допустимо только для C0/C1, причина обязательна
- node "$QG/tools/gate.mjs" release --class C0 --reason "<почему>"
+ node "$QG/tools/gate.mjs" release --evidence <файл отчёта> # по результатам прогона
+ node "$QG/tools/gate.mjs" release --class C0 --reason "<почему>" # C0/C1 без прогона
```
- НЕ снимай гейт, если прогон прерван на полпути и отчёт не сформирован: гейт должен
- остаться, чтобы проверка прогналась заново.
-
- **Чужие сессии не трогай.** Состояние гейта разделено по сессиям. Если `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"`**: существование переменной или каталога ещё не значит,
- что там лежит этот плагин — установка могла быть частичной, устаревшей или чужой.
-
- ```bash
- 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`.
+ **Чужие сессии не трогай.** Гейт разделён по сессиям: несколько в `gate.mjs status` —
+ `verify`/`release` без `--session <id>` отказывают, «самая свежая» может быть чужой.
+ Идентификатор — в подсказке при взводе и в сообщении о блокировке
+ (`references/run-environment.md`).