ревью: гейт, прогнанный до ревью, засчитывается по отпечатку дерева

Повтор той же команды на неизменившемся дереве снят: ступень автотестов
засчитывает прогон, сделанный шагом opsx:apply или шагом гейта обслуживания.
Признак — отпечаток рабочего дерева, снятый дважды; любое расхождение ведёт
к честному прогону. Журнал — тема 73.
This commit is contained in:
av
2026-08-23 13:42:58 +03:00
parent 813345192d
commit 17be316634
7 changed files with 165 additions and 13 deletions
+43 -2
View File
@@ -221,6 +221,10 @@ description: "Конвейер ревью изменения, устроенны
- **метка, его глубина и режим** прогона — чтобы проход знал, что писать в
границы покрытия.
**Ступень 1 получает сверх этого исход гейта, прогнанного до ревью** — сводку,
путь к логам шагов и отпечаток дерева, — если вызывающий скилл его дал. Зачем и
что происходит при расхождении — «Ступень 1 — Автотесты».
Чего проход **не** получает ни в каком режиме — выводов других проходов. См.
«Порядок прогона».
@@ -734,8 +738,9 @@ change**: у работы, не меняющей поведения, дельт
## Ступень 1 — Автотесты (обязательна при любой метке)
Агент `review-autotests`, тема `autotests`. Запускает команду гейта из семантики
гейта в `CLAUDE.md` и интерпретирует вывод.
Агент `review-autotests`, тема `autotests`. Гонит команду гейта из семантики
гейта в `CLAUDE.md` — либо засчитывает прогон, сделанный до ревью, — и
интерпретирует вывод.
**Тема и проход названы одинаково намеренно, а «гейт» осталось именем команды.**
Раньше тема звалась `autotests`, а проход — `gate`: одна сущность под двумя
@@ -743,6 +748,42 @@ change**: у работы, не меняющей поведения, дельт
Слово «гейт» теперь значит ровно одно — барьер, который проект запускает; тема
шире него ровно на «чего в гейте намеренно нет».
**Гейт, прогнанный до ревью, второй раз не гоняется.** Задача приходит на ревью
с зелёным гейтом: сценарий решения доводит его до зелёного шагом `opsx:apply`,
сценарий обслуживания — своим шагом гейта. Повтор на неизменившемся дереве
вернёт тот же вывод, а стоит он минут — то есть платит ими ни за что.
**Признак один и проверяемый — отпечаток рабочего дерева.** Его снимают дважды:
тот, кто прогнал гейт, сразу после прогона, и проход перед началом работы.
<!-- дом: отпечаток-дерева -->
```sh
{ git rev-parse HEAD; git status --porcelain -uall; git diff HEAD;
git ls-files -o --exclude-standard -z | xargs -0 -r git hash-object; } | sha1sum
```
<!-- /дом: отпечаток-дерева -->
Сводку прошлого прогона, путь к логам шагов и отпечаток проход получает
**заданием** — их передаёт вызывающий скилл. Отпечатки совпали — проход читает
готовую сводку и логи, команду не запускает. Разошлись, отпечатка в задании нет,
логи недоступны — проход гонит гейт сам и ни у кого не спрашивает.
**Отказ здесь безопасен по построению.** Лишний прогон стоит минут, а
засчитанный чужой — красноты, которой никто не увидел. Временный каталог проекта
из отпечатка выпадает сам: `--exclude-standard` отбрасывает игнорируемое, а логи
шагов гейт пишет именно туда. У проекта, держащего временный каталог под git,
отпечатки не совпадут никогда — и он получит честный прогон вместо тихого
засчитывания.
**Переиспользуется команда, а не проход.** Тема `autotests` закрывается целиком:
логи проход читает сам, находки об отсутствующей верификации выдаёт как обычно.
Переиспользование он объявляет строкой сводки и строкой границ покрытия — чем
гейт прогнан, когда и на каком отпечатке. Молчащее переиспользование неотличимо
от собственного прогона, а разница между ними в том, кто видел вывод своими
глазами.
**Пока гейт красный — проходы с мнением не запускаются.** Оркестратор чинит и
перезапускает гейт. Исключение одно: отказ, унаследованный от базовой ветки
(гейт проверяет это прогоном на базе) — тогда он фиксируется находкой и не