Files
houseplan-card/docs/process/REVIEWER.md
T
Claude baf283c50f ci: thin default-branch callers invoke reusable bodies at @dev (#623)
Six workflows run from the default branch (issues, schedule, workflow_run):
process, process-resume, process-reconcile, mutation-gate, nightly,
process-metrics. Their bodies move to _<name>.yml (on: workflow_call); the
original files keep only triggers, run-name, permissions, concurrency and one
job `uses: Matysh/houseplan-card/.github/workflows/_<name>.yml@dev` with
`secrets: inherit`. A pipeline change becomes one commit to dev.

- caller job permissions = union of body job permissions (#556 minimum kept
  per job inside the body); caller `if` repeats the body guard for process and
  process-resume so unrelated events stay skipped;
- dispatch inputs forwarded via workflow_call inputs of the same names;
- _mutation-gate.yml keys evidence/marker on job.workflow_sha (the body SHA):
  in a called workflow github.workflow_sha belongs to the caller in main;
- action-pins: narrow exception for this repo's _*.yml at @dev with a reason;
- preflight workflow_sync compares all six thin callers (was 3 of 6);
  performance.yml excluded: its schedule judges main with main's own body;
- tests read bodies from _*.yml; new test/default-branch-workflows.test.mjs;
  six mutants; PROCESS.md §10.4, AGENTS.md, REVIEWER.md updated.

Issue: #623
User-Visible: no
2026-09-24 10:23:28 +03:00

131 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Конспект для ревьюера
Роли: ревьюер ТЗ и ревьюер кода ([§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`, на лёгком треке —
комментарий ([§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` со сверкой копий бандла; при
диффе по `src/**` — ещё `node scripts/check-docs.mjs`. Зелёный Validate на
SHA материала подтверждает дешёвые гейты ([§8](../../PROCESS.md#8-гейты)).
- По диффу и AC: смоки — названные в AC плюс вывод
`node scripts/smoke-select.mjs --base <base> --head <head>` с решением по
каждой строке; `golden:verify` при видимом изменении; `pytest tests_backend`
при правке Python; инварианты модели при правке геометрии; performance —
если назван в AC. Полные наборы — предрелизный гейт, а не гейт ревью
([§8](../../PROCESS.md#8-гейты)).
- Условие честности сужения: ревьюер обязан перечислить, какие гейты прогнал,
какие нет и почему ([§8](../../PROCESS.md#8-гейты)).
- Зелёный `pytest tests_backend` без Home Assistant скипает `test_ha_*.py` и
ничего не доказывает — это «чего не проверял» (`AGENTS.md`, «Gates»;
[§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 цикла, на лёгком и коротком
треке 2; бюджет считается по этапу
([§4](../../PROCESS.md#4-лимит-циклов-ревью-4),
[§10.4](../../PROCESS.md#104-событийный-конвейер-метка-как-триггер)).
- Запрещено: Medium-находки, оставленные как TODO в документе ревью;
ревью-документы вне репозитория ([§12](../../PROCESS.md#12-запрещено)).