Files
houseplan-card/docs/reviews/SPEC-REVIEW-399-r2.md
T
2026-08-31 01:31:41 +00:00

172 lines
15 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.
# SPEC-REVIEW-399-r3
- Issue: https://github.com/Matysh/houseplan-card/issues/399
- ТЗ: `docs/specs/399-backend-gate-honesty.md`
- Материал: SHA `bb635298c153ba8d5104e19a70e695d1fcf1a5c5` (ветка
`issue/399-backend-gate-honesty`, ревизия 3 поверх `dev`; merge-base с
`origin/dev` = `f7fb3369` = текущий tip `dev` — рёбейза не было)
- Заход: **r3**, не r2 — см. «Расхождение с заданием раунда» ниже
- Блокирующих циклов израсходовано: 2/4 (r1 жёлтый, r2 жёлтый; зелёный цикла
не тратит, #227)
- Трек: полный (не изменился, наследуется из r1/r2)
- Вердикт: **зелёный**
## Расхождение с заданием раунда (нужно проговорить явно)
Задание на этот прогон присвоило заходу номер r2 и указало «блокирующих
циклов израсходовано 1 из 4». Это не соответствует фактическому состоянию
issue:
- на #399 уже стоят **два** реальных комментария-вердикта: `Вердикт: жёлтый
· заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 1 → в задаче`
(2026-08-31T01:14:00Z) и `Вердикт: жёлтый · заход r2 · блокирующих циклов
1/4 · High: 0 · Medium: 1 → в задаче` (2026-08-31T01:23:10Z);
- на каждый из них автор ответил правкой: `6d229c66 docs: #399 spec revision
2 per SPEC-REVIEW-399-r1`, затем `bb635298 docs: #399 spec revision 3 per
SPEC-REVIEW-399-r2` (комментарий автора «Ревизия 3 — Medium закрыт»,
2026-08-31T01:26:20Z);
- файл `docs/reviews/SPEC-REVIEW-399-r1.md` в репозитории существует, но
содержит текст, который сам себя называет «SPEC-REVIEW-399-r2» (шаг
публикации предыдущего прогона присвоил ему имя `r1` по (тоже ошибочному)
заданию того прогона, затерев исходный документ r1 — тот же класс сбоя,
который этот прогон обязан не повторить).
То есть реально состоялись **два** цикла (r1 и r2), оба жёлтые, оба стоили
бюджета: 2/4. Присвоение этому прогону имени `r2` создало бы риск нового
столкновения — второй комментарий-вердикт с заголовком «заход r2» на одной
issue — и заняло бы неверную позицию в бюджете (1/4 вместо фактических 2/4).
Поэтому документ и вердикт этого прогона используют номер **r3**, полученный
из вердиктов и коммитов issue, а не из присланного заголовка задания. Далее —
процедура §2.9/§2.10 для «не первого» цикла.
## Дельта, которая является предметом этого раунда
`git diff 6d229c66..bb635298 -- docs/specs/399-backend-gate-honesty.md` —
ровно три места:
1. строка «Ревизия» в шапке (3, со ссылкой на SPEC-REVIEW-399-r2 и причиной:
«план тестов повторял снятую формулировку AC5»);
2. раздел «План автотестов», пункты 4–5 переписаны: пункт 4 теперь описывает
перебор каталога `.github/workflows/*.yml` целиком и явно фиксирует «списка
обходимых файлов в тесте нет и быть не должно»; пункт 5 добавлен и
называет вывод проверки на реальном дереве («девять workflow, установка
python-зависимостей — в двух»);
3. в раздел «Мутанты» добавлена новая запись `workflow-scan-hardcodes-the-list`
(замена перебора каталога на фиксированный список имён обязана красить
пункт 4 плана).
Ничего за пределами этих трёх мест не менялось: контракт п.(3), AC5 сам текст,
разделы (1) M3, (2) Low «а», скоуп/не-скоуп, AC1–AC4/AC6, риски, откат,
release-артефакты — байт в байт те же, что видел r2.
## Закрытие раунда r2
| Находка r2 | Чем закрыта | Где видно |
|---|---|---|
| Medium: «План автотестов» п.4 дословно повторял снятую (ревизия 2) формулировку AC5 — «явный список обходимых файлов зафиксирован; добавление нового файла без обновления списка краснеет» — то есть описывал именно ту хардкод-конструкцию, от которой переписанный AC5 уходит | П.4 переписан: «Каталог `.github/workflows/*.yml` перебирается целиком… краснеет **без** правки каких-либо списков в тесте… Списка обходимых файлов в тесте нет и быть не должно — файл, не ставящий python-зависимостей, распознаётся по собственному содержимому.» Формулировка теперь дословно исключает хардкод-список, а не допускает его как законное прочтение | `docs/specs/399-backend-gate-honesty.md:155-159` (план, п.4), `:170-172` (новый мутант `workflow-scan-hardcodes-the-list`, закрепляющий это как проверяемый контракт для код-ревью), SHA `bb635298` |
Находка закрыта по существу, а не переформулирована уклончиво: старая фраза
«список… без обновления списка краснеет» заменена на прямой запрет
(«списка… нет и быть не должно»), и добавлен мутант, ловящий именно откат к
списку, если реализация всё же попытается его завести — то есть контракт
теперь не только описан текстом плана, но и зафиксирован как проверяемая
точка для код-ревью.
## Унаследовано из r2 (без повторной проверки)
Со ссылкой на `docs/reviews/SPEC-REVIEW-399-r1.md` (файл содержит текст
раунда r2), SHA `6d229c66`:
- §7.1: все обязательные разделы на месте (сценарий, что увидит человек,
проблема по пунктам, скоуп/не-скоуп, UX/данные/i18n — н/п обоснованно, AC с
доказательствами, риски, откат, release-артефакты) — делта их не трогает.
- Контракт п.(3) и текст AC5 (перебор каталога, а не списка; два исхода на
файл) — не менялись этой ревизией, r2 их принял.
- AC1–AC4, AC6 — текст не менялся, доказательства признаны однозначными в
r1/r2.
- Факт «в репозитории девять workflow, python-зависимости ставят два
(`validate.yml`, `mutation-gate.yml`)» — перепроверялся в r2 на дереве той
ревизии; в этом раунде перепроверен заново (см. ниже), так как та же цифра
теперь дополнительно фигурирует в новом п.5 плана — расхождений нет.
- Классификация трека (полный, класс B, три несвязанные поверхности) — не
меняется.
- Продуктовое обрамление и персоны SCOPE.md (задача инфраструктурная,
`User-Visible: no`, ни одна J-строка Core user jobs не затронута) — не
изменилось.
- «Чего не проверял» из r1/r2 (сетевое содержимое `package_constraints.txt`
тега `2026.8.3`, объём ruff-долга при исходе (2), аудит-документ вне
репозитория) — остаётся в силе, эта делта их не касается.
- Расхождение задания/факта в самом r2 (там заход был неверно назван `r1` в
задании, скорректирован до `r2`) — исторический факт, не влияет на эту
ревизию, кроме того, что от него унаследована необходимость сверять номер
захода по вердиктам issue, а не по заголовку задания (сделано выше).
## Как проверялось
- перечитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` целиком, включая §2.9,
§2.10 (объём по дельте), §4 (лимит циклов, разница «заход»/«цикл»), §7.1
(обязательные разделы), §12 (запрещено);
- прочитано тело issue #399 и все 4 комментария (`gh api
repos/Matysh/houseplan-card/issues/399/comments`) — восстановлена реальная
последовательность r1 → ревизия 2 → r2 → ревизия 3;
- сверены SHA каждого раунда с `git log` по `docs/specs/399-backend-gate-
honesty.md` и по `docs/reviews/SPEC-REVIEW-399-r1.md`;
- дельта `git diff 6d229c66..bb635298` построчно сверена с находкой r2 —
проверено, что новая формулировка п.4 не оставляет читателю законного
прочтения «список с ручным обновлением»;
- независимо перепроверен факт AC5/п.5 на текущем дереве: `ls
.github/workflows/*.yml | wc -l` → 9; `git grep -l "pip install"
.github/workflows/*.yml` → ровно `mutation-gate.yml` и `validate.yml`.
Совпадает с текстом ТЗ дословно;
- формат нового мутанта (`workflow-scan-hardcodes-the-list`, kebab-case,
структура записи) сверен с существующими `id:` в `scripts/mutation-gate.mjs`
— согласуется с уже принятым в репозитории стилем;
- проверено отсутствие рёбейза: `git merge-base origin/dev HEAD` совпадает с
tip `origin/dev` (`f7fb3369`) — делта локальна, полный разбор с нуля не
требуется по критериям §2.10.
## Находки
Нет. Делта закрывает находку r2 по существу, не вводит новых противоречий
между разделами, факты в новом тексте перепроверены и точны.
## Что проверено и корректно (в дополнение к унаследованному)
- П.4 и п.5 плана автотестов теперь непротиворечивы контракту п.(3) и AC5:
оба говорят про каталог, оба явно запрещают список для ручного обновления,
оба ссылаются на один и тот же синтетический третий workflow.
- Новый мутант `workflow-scan-hardcodes-the-list` даёт код-ревью проверяемую
точку для отлова именно того отката к списку, который стал возможен между
ревизией 2 и 3 (риск, который сама находка r2 и описывала) — то есть закрытие
сделано не только словами ТЗ, но и обязательством для реализации.
- Изменение не трогает трек, скоуп/не-скоуп, риски, критерии приёмки как
формулировки (AC5 не редактировался), не переносит вопрос владельцу.
- Заголовок «Ревизия 3» корректно ссылается на SPEC-REVIEW-399-r2 (тот факт,
что физически это `docs/reviews/SPEC-REVIEW-399-r1.md`, — не ошибка автора,
а последствие сбоя предыдущего шага публикации, разобранного выше).
## Чего не проверял
- Сетевое содержимое `package_constraints.txt` тега `2026.8.3`
`home-assistant/core` (претензия M3) — не относится к этой делте (раздел
(1) не менялся), недоступно и в этой среде; будет видно на код-ревью.
- Объём ruff-долга при исходе (2) для Low «а» — делта его не касается.
- `npm test`/`npx tsc --noEmit`/`npm run build` — это ревью документа (ТЗ), а
не кода; делта правит только `docs/specs/399-backend-gate-honesty.md`, кода
нет вовсе. Дешёвые гейты §2.10 в этом раунде неприменимы буквально (нет
предмета для typecheck/test/build), они будут прогнаны на этапе код-ревью,
когда появится реализация.
- Аудит-документ `AUDIT-2026-08-31-v1700beta1.md` вне репозитория — как и в
r1/r2, не найден локально, тело issue самодостаточно.
## Вердикт
Зелёный: делта раунда — три места в «Плане автотестов»/«Мутантах», все
закрывают находку r2 по существу (проверено построчно, не на слово автора),
новых расхождений между разделами ТЗ не введено, факты (9 workflow, 2 ставят
python-зависимости) перепроверены и точны. Блокирующих находок нет — High: 0,
Medium: 0. Зелёный вердикт цикла не образует и бюджет не тратит (#227):
израсходовано 2/4 (r1, r2), после этого раунда — по-прежнему 2/4. Задача
может двигаться дальше по конвейеру (`S5-ready`/реализация) без ещё одного
цикла ревью ТЗ.