mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
Owner's decision 2026-09-29: mutants check the tests, not the product. During development they are not run at all — not locally, not in CI, not by the reviewer. The whole registry is the nightly run (mutation-gate.yml, #513); a survivor files an issue (#472). The #693 post-mortem: 36 of 57 minutes of a one-line fix went to optional work. - process-track.mjs: `mutants` is always false (no track, no label). - classify-changes.mjs: Validate requests no diff mutants on any event; the `mutants` input stays so old `-f mutants=…` calls do not fail. - _process.yml: the default for the gate and the merge is false. - pre-push-gate.mjs: the manual run no longer runs mutants. - Canon: PROCESS §2.7 (a mutant is written, not run; `--check` keeps the anchors), §5.1 (`ci:mutants` retired), §8 (ship/show: nothing beyond gate:small and the spec — one proof per item, no `--smokes` on ship, a stray flake is an issue, not an investigation), §10.4; AUTHOR, REVIEWER, AGENTS, TESTING. - Registry: four mutants of the old request rules replaced by dev-mutants-requested-again and track-pays-for-mutants-again. Issue: #709 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
176 lines
15 KiB
Markdown
176 lines
15 KiB
Markdown
# Конспект для ревьюера
|
||
|
||
Роли: ревьюер ТЗ и ревьюер кода ([§6](../../PROCESS.md#6-роли)). Штатный
|
||
ревьюер конвейера получает этот файл из промпта `.github/workflows/_process.yml`;
|
||
ручное ревью по просьбе владельца идёт по нему же.
|
||
|
||
> **Это выжимка, а не канон.** Канон процесса — [`PROCESS.md`](../../PROCESS.md);
|
||
> при расхождении побеждает он, а расхождение — issue с меткой `process`.
|
||
> Конспект правил не добавляет и не меняет: каждый пункт ссылается на раздел
|
||
> канона, где правило записано полностью, с причинами и прецедентами. Ссылки и
|
||
> ключевые формулировки сверяет `test/process-digests.test.mjs`.
|
||
|
||
## Позиция ревьюера
|
||
|
||
- Ревьюер ≠ исполнитель, свежая сессия без контекста реализации. Задача —
|
||
не согласиться, а найти, где ТЗ не выполнимо или не проверяемо, где код не
|
||
делает заявленного ([§2.4](../../PROCESS.md#24-тз-на-ревью),
|
||
[§2.7](../../PROCESS.md#27-код-ревью), [§6](../../PROCESS.md#6-роли)).
|
||
- Ревьюер не правит ни ТЗ, ни продуктовый код; ревью своей работы запрещено
|
||
([§6](../../PROCESS.md#6-роли), [§12](../../PROCESS.md#12-запрещено)).
|
||
- Первый вопрос к задаче — какую работу из `docs/SCOPE.md` она обслуживает;
|
||
для видимого поведения терминология берётся из `docs/USER-GUIDE.ru.md`
|
||
([§7.1](../../PROCESS.md#71-цепочка)).
|
||
|
||
## Ревью ТЗ
|
||
|
||
- Артефакт — `docs/reviews/SPEC-REVIEW-<NN>-r<N>.md`. Ревью ТЗ проходит только
|
||
трек `ask` ([§2.4](../../PROCESS.md#24-тз-на-ревью)).
|
||
- ТЗ живёт в теле issue, раздел `## ТЗ`; `docs/specs/` — архив до 2026-09-10
|
||
([§2.3](../../PROCESS.md#23-тз-в-работе--написание-тз)).
|
||
- Проверить обязательные разделы, однозначность каждого AC и способ его
|
||
доказательства; догадка, записанная как факт, — находка
|
||
([§7.1](../../PROCESS.md#71-цепочка),
|
||
[§2.5](../../PROCESS.md#25-готово-к-разработке-dor)).
|
||
- Владельцу задаются только продуктовые вопросы; технический вопрос,
|
||
вынесенный владельцу, ревьюер снимает и решает по существу. Технический
|
||
спор автора и ревьюера решается вердиктом, а не владельцем
|
||
([§7.1](../../PROCESS.md#71-цепочка)).
|
||
|
||
## Код-ревью
|
||
|
||
- Артефакт — `docs/reviews/CODE-REVIEW-<tag|NN>-r<N>.md`: скоуп, как
|
||
проверялось (таблица гейтов с результатами), находки High/Medium/Low с
|
||
воспроизведением, что проверено и корректно, чего не проверял
|
||
([§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Ревьюер отвечает за полноту доказательств AC, а не заменяет их исполнение.
|
||
Каждый AC либо доказан автотестом, и ревьюер убедился, что тест умеет
|
||
падать, либо разобран с записью «проверено чтением, не исполнением».
|
||
Применимые классы риска §2.6 сверяются отдельно
|
||
([§2.7](../../PROCESS.md#27-код-ревью),
|
||
[§2.6](../../PROCESS.md#26-в-разработке--реализация)).
|
||
- Защитный AC доказывается таблицей «чем краснеет»: AC · чем доказан ·
|
||
чем краснеет — мутант в реестре или отрицательный случай в самом тесте.
|
||
Пустой третий столбец — находка Medium, а не примечание. «Тест умеет
|
||
падать» без названной мутации доказательством не является
|
||
([§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Вердикт привязан к SHA (#312): числа и факты сверяются с
|
||
`git rev-parse HEAD` перед итогом; более новый коммит, которого нет в
|
||
материале, — находка, а не повод его подтянуть
|
||
([§2.7](../../PROCESS.md#27-код-ревью),
|
||
[§10.4](../../PROCESS.md#104-событийный-конвейер-метка-как-триггер)).
|
||
- Контракты по монолиту — исполнением, не regex по тексту: список тестов,
|
||
читающих монолит как текст, заморожен, и новое имя в нём — находка ревью, а
|
||
не запись в список ([§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Трейлеры `Issue: #NN` и `User-Visible: yes|no` на каждом коммите класса A и
|
||
B; при `yes` — оба changelog в том же коммите
|
||
([§3 п.10](../../PROCESS.md#3-правила)).
|
||
- Одно число — один источник: ревьюер отвечает на вопрос прямо: какое число в
|
||
этом диффе видно дважды и один ли у него источник
|
||
([§8](../../PROCESS.md#8-гейты)).
|
||
|
||
## Объём гейтов
|
||
|
||
- Всегда: `typecheck`, `npm test`, `npm run build` + `bundle-policy --verify` (копии сверяются только на кандидате, #657).
|
||
Свежесть скриншотов документации — не гейт задачи: отпечаток обновляет
|
||
коммит бота на `dev` перед бетой. Зелёный Validate на SHA материала
|
||
подтверждает дешёвые гейты ([§8](../../PROCESS.md#8-гейты)).
|
||
- По диффу и AC: смоки — названные в AC плюс вывод
|
||
`node scripts/smoke-select.mjs --base <base> --head <head>` с решением по
|
||
каждой строке; `golden:verify` при метке `ci:golden`; `pytest tests_backend`
|
||
при правке Python; инварианты модели при правке геометрии; performance —
|
||
если назван в AC. Полные наборы — предрелизный гейт, а не гейт ревью
|
||
([§8](../../PROCESS.md#8-гейты)).
|
||
- Условие честности сужения: ревьюер обязан перечислить, какие гейты прогнал,
|
||
какие нет и почему ([§8](../../PROCESS.md#8-гейты)).
|
||
- Зелёный `pytest tests_backend` без Home Assistant `test_ha_*.py` не
|
||
собирает вовсе — их нет ни в `passed`, ни в `skipped` (строка `HA harness NOT
|
||
collected`), и такой прогон про HA ничего не доказывает — это «чего не
|
||
проверял» (`docs/TESTING.md`; [§8](../../PROCESS.md#8-гейты)).
|
||
|
||
## Повторный раунд
|
||
|
||
- Предмет повторного раунда — дельта, а не задача целиком: найти вердикт и
|
||
материал предыдущего раунда (блок «Материал раунда»), объявить
|
||
`git diff <тот SHA>..HEAD`, по каждой находке показать, чем она закрыта,
|
||
заново проверить только AC, которые дельта задевает
|
||
([§2.10](../../PROCESS.md#210-повторный-раунд-ревью--объём-по-дельте)).
|
||
- Если SHA не резолвится — это не находка, а обычное дело: материал ищется по
|
||
дереву и блобу. Находка — SHA, мёртвый уже в момент публикации отчёта
|
||
([§2.10](../../PROCESS.md#210-повторный-раунд-ревью--объём-по-дельте)).
|
||
- Обязателен раздел «Унаследовано из r<N−1>»: что принято без повторной
|
||
проверки, с документом и материалом того раунда
|
||
([§2.10](../../PROCESS.md#210-повторный-раунд-ревью--объём-по-дельте)).
|
||
- Разбор остаётся полным, если дельта не локальна: ребейз на ушедший вперёд
|
||
`dev`, смена контракта, новая подсистема, объём сопоставим с задачей.
|
||
Сокращается объём разбора, а не строгость
|
||
([§2.10](../../PROCESS.md#210-повторный-раунд-ревью--объём-по-дельте)).
|
||
- Перед разбором подсистемы — её строки в `docs/reviews/INDEX.md`
|
||
([§2.10](../../PROCESS.md#210-повторный-раунд-ревью--объём-по-дельте)).
|
||
|
||
## Находки и вердикт
|
||
|
||
- High блокирует. Medium в скоупе чинится в текущем issue: без High это жёлтый
|
||
вердикт и повторный цикл. Medium вне скоупа — отдельный issue со ссылкой.
|
||
Low правится или снимается ревьюером с записью
|
||
([§3 п.8](../../PROCESS.md#3-правила),
|
||
[§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Жёлтый вердикт допустим и при выполненных AC, если изменение не решает
|
||
заявленный сценарий или ухудшает смежный; продуктовое рассуждение не
|
||
отменяет AC и не меняет скоуп ([§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Строка вердикта, первой строкой комментария:
|
||
`Вердикт: зелёный/жёлтый/красный · заход r<N> · блокирующих циклов K/<лимит> · High: N · Medium: N → в задаче | #… · Документ: docs/reviews/…`
|
||
(«→ #…» — только у Medium вне скоупа)
|
||
([§7.2](../../PROCESS.md#72-шаблоны-комментариев)).
|
||
- Вперёд двигает только зелёный вердикт; жёлтый и красный возвращают автору
|
||
([§7.2](../../PROCESS.md#72-шаблоны-комментариев)).
|
||
- Зелёный вердикт цикла не образует; лимит — 4 цикла, на `track:show` 2;
|
||
бюджет считается по этапу
|
||
([§4](../../PROCESS.md#4-лимит-циклов-ревью-4),
|
||
[§10.4](../../PROCESS.md#104-событийный-конвейер-метка-как-триггер)).
|
||
- Запрещено: Medium-находки, оставленные как TODO в документе ревью;
|
||
ревью-документы вне репозитория ([§12](../../PROCESS.md#12-запрещено)).
|
||
|
||
## Трек show
|
||
|
||
- Ревью `show` судит корректность и AC: Medium — дефект поведения, который
|
||
увидит пользователь, или невыполненный AC; бухгалтерия — нет мутанта или
|
||
записи в реестре, нечувствительный тест на побочный вызов — Low и цикла не
|
||
открывает ([§10.4](../../PROCESS.md#104-событийный-конвейер-метка-как-триггер),
|
||
[§5](../../PROCESS.md#5-треки-ship-show-ask--метка-владельца)).
|
||
- Мутанты в разработке не гоняются ни на каком треке — ревьюер их тоже не
|
||
применяет; проверяет, что защита названа мутантом в реестре. Отсутствие прогона
|
||
не находка: поимку проверяет ночь (#709,
|
||
[§2.7](../../PROCESS.md#27-код-ревью)).
|
||
- Ветка `show` с чистым слиянием к `dev` до ревью не приводится: материал —
|
||
ветка как есть, кандидат проверит Validate при слиянии
|
||
([§10.4](../../PROCESS.md#104-событийный-конвейер-метка-как-триггер)).
|
||
|
||
## Пакетное ревью ship
|
||
|
||
- Задачи `track:ship` слиты без ревью модели; перед бетой `ship-review.yml`
|
||
читает их код одной сессией: по строке ТЗ каждой задачи и её коммитам
|
||
([§11.7](../../PROCESS.md#117-пакетное-ревью-ship-перед-бетой)).
|
||
- Вопросы к задаче: делает ли код заявленное и только его, не ломает ли
|
||
соседнее, не вышла ли правка из ship по смыслу
|
||
([§11.7](../../PROCESS.md#117-пакетное-ревью-ship-перед-бетой),
|
||
[§5](../../PROCESS.md#5-треки-ship-show-ask--метка-владельца)).
|
||
- Документ `docs/reviews/SHIP-REVIEW-<тег>.md` публикует детерминированный
|
||
шаг; High не пускает бету, Medium и Low решает владелец
|
||
([§11.7](../../PROCESS.md#117-пакетное-ревью-ship-перед-бетой)).
|
||
|
||
## Независимое ревью линии
|
||
|
||
- Перед стабильным релизом `release-review.yml` судит поверхности всей линии
|
||
бет против пользователя, а не дифф против ТЗ: ТЗ задач и документы раундов не
|
||
читаются, основа — `docs/SCOPE.md` и `docs/USER-GUIDE.ru.md`
|
||
([§11.5](../../PROCESS.md#115-независимое-ревью-линии-перед-стабильным-релизом)).
|
||
- Проверка исполнением: посимвольный ввод, настоящие Escape и крестик,
|
||
фикстура `ha-dialog` (#505) для диалогов; по каждой поверхности — обычный
|
||
сценарий и самый рискованный соседний
|
||
([§2.6](../../PROCESS.md#26-в-разработке--реализация), [§11.5](../../PROCESS.md#115-независимое-ревью-линии-перед-стабильным-релизом)).
|
||
- Документ `docs/reviews/RELEASE-REVIEW-vX.Y.Z.md` — рекомендация: выпуск не
|
||
блокируется, решение по находкам за владельцем; ревьюер ничего не публикует
|
||
и issue не заводит
|
||
([§11.5](../../PROCESS.md#115-независимое-ревью-линии-перед-стабильным-релизом)).
|