Files
houseplan-card/docs/reviews/SPEC-REVIEW-454-r2.md
T
2026-09-04 16:58:31 +00:00

162 lines
16 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 — issue #454 · заход r2
- Issue: https://github.com/Matysh/houseplan-card/issues/454
- Этап: ТЗ на ревью (PROCESS.md §2.4), заход r2, блокирующих циклов израсходовано 1 из 4
- Материал: `docs/specs/454-review-round-counter.md` на коммите `f3e60578` (комментарий автора «Замечание r1 (M1) исправлено, ТЗ обновлено: `f3e60578`», ветка `issue/454-review-round-counter`)
- Предыдущий раунд: r1, жёлтый, документ `docs/reviews/SPEC-REVIEW-454-r1.md`, материал `ebcf1223`
- Ревьюер: свежая сессия, без контекста написания ТЗ и r1
## Скоуп разбора
Разбор по дельте (PROCESS.md §2.9/§2.10). Дельта — один коммит `f3e60578`,
`git diff ebcf1223..f3e60578 -- docs/specs/454-review-round-counter.md`:
32 строки в одном файле, три места:
1. одна строка таблицы «Факты по #449» (маркер в теле код-вердикта 16:01);
2. абзац под таблицей, объясняющий эту строку, плюс следствие в «не-скоупе»
про необратимую потерю `spent` первого спек-раунда #449;
3. переформулировка **AC2** + новый **AC2b** + синхронный абзац в «Плане
тестирования».
Ребейза не было (родитель дельты — тот же `ebcf1223`, на котором получен r1).
Контракт поведения (§1–§5 ТЗ), скоуп/не-скоуп по составу, карта реализации,
риски, release-артефакты — не тронуты дельтой, разбираю их по r1, без
повторной проверки. Задета только доказательная база одного AC и одна
фактическая иллюстрация в разделе «Подтверждённая проблема» — сокращённый
разбор оправдан, дельта локальна.
## Как проверялось
Правки не вношу — только читаю и перепроверяю исполнением/рассуждением на
реальных данных.
- Прочитан диф `git diff ebcf1223..f3e60578` целиком (не только резюме автора).
- Independently (не со слов автора) снят фактический снимок #449 на сегодня:
- `gh issue view 449 --repo Matysh/houseplan-card --json comments` — все
комментарии-вердикты с их точным текстом;
- `git show origin/dev:docs/reviews/SPEC-REVIEW-449-r1.md` /
`…-r2.md` / `CODE-REVIEW-449-r1.md` / `…-r2.md` — содержимое и
собственная итоговая строка вердикта каждого файла;
- `git show <blob>:docs/reviews/SPEC-REVIEW-449-r1.md` на трёх исторических
блобах (`1ce62613`, `070c276e`, `b39f99b3`), названных автором, чтобы
подтвердить, что `-r1.md` физически содержит тело второго раунда, а
`-r2.md` — третьего.
- По этим данным вручную пересчитаны обе формулы контракта §1–§3 ТЗ для
фикстур AC2 и AC2b (см. «Закрытие раунда r1» ниже) — не поверил заявлению
автора на слово, получил числа заново из первичных данных.
- Прочитан весь остаток документа (шапка, скоуп/не-скоуп, контракт,
крайние случаи, AC1–AC9, карта реализации, риски, release-артефакты,
принятые предположения) на предмет того, не сломала ли дельта что-то,
что дельта не должна была трогать — не сломала.
Гейты (`tsc`/`test`/`build`/`check-docs`/`invariants`/смоки/`golden`) не
гонял: класс изменения — документация ТЗ, реализации на ветке нет
(`scripts/review-doc-guard.mjs`, `test/review-doc-guard.test.mjs` на ветке
задачи отсутствуют), это унаследовано из r1 и дельтой не задето.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **M1** (Medium, в скоупе): AC2 требовала `attempt=3, spent=2` на фикстуре «реальные данные #449», но буквальный пересчёт по реальным файлам/комментариям даёт `spent=1` — план тестирования не указывал, какое из двух прочтений (буквальное или реконструкция) имеется в виду | AC2 переписан на буквальный слепок (`attempt=3, spent=1`), добавлен отдельный AC2b на реконструкцию («история, прожитая с исправлением», `attempt=4, spent=2`); «План тестирования» называет обе фикстуры по имени и раздельно; в «не-скоупе» явно зафиксировано, что `spent=1` на сегодняшних данных — правильный ответ, а не недосчёт | `docs/specs/454-review-round-counter.md:96‑111,174‑194` (коммит `f3e60578`). Перепроверено мной независимо: `SPEC-REVIEW-449-r1.md` на `origin/dev` содержит тело раунда 2 (собственная финальная строка — «жёлтый вердикт... возвращается автору»), `…-r2.md` — тело раунда 3 (финал — «зелёный вердикт... бюджет циклов не тратит»); `attemptFromFiles=max(1,2)+1=3`, `spentFromFiles=1` (только `-r1.md` блокирующий); `spentFromComments`: из трёх комментариев маркер несут два (14:56, 15:17), из них блокирующий один (14:56) → `1`. `max(1,1)=1`. Совпадает с новой формулировкой AC2 |
| L1 (Low, была снята с записью в r1, без обязательства правки) — нет разделов «UX»/«i18n»; r1 предлагал добавить строки-заглушки «заодно», если раунд правит документ | Не добавлено — но это была необязательная опция («было бы уместно… не отдельным циклом»), не требование; L1 уже была закрыта самим r1 без возврата автору | Текущий текст ТЗ: шапка по-прежнему содержит только `Touch editor: not exposed`, строк «UX:»/«i18n:» нет — не регрессия, а неиспользованная опция |
| L2 (Low, к сведению, не в счёт вердикта) — cohesion `review-doc-guard.mjs` | Не поднималась к правке в r1 и не поднимается сейчас — technical, оставлена автору кода | Карта реализации не изменилась дельтой |
## Унаследовано из r1
Без повторной проверки принимаю из `docs/reviews/SPEC-REVIEW-454-r1.md`
(материал `ebcf1223`) — дельта этих мест не касается:
- **Контракт §1** (источник истины — файлы, `max+1`, а не количество) и его
проверка на крайних случаях (дыра в нумерации, пустое множество файлов).
- **Контракт §2** (строка вердикта, `жёлт`/`красн` без учёта регистра) —
совпадает с существующим `process.yml:100`.
- **Контракт §3** (страховка максимумом) — `max(a,b)` не может дать
перерасчёт при данном построении источников.
- **AC1, AC3–AC7** — формулировки однозначны, способ доказательства достижим;
AC4/AC5/AC7 согласованы с уже действующими инвариантами #227/#89.
- **AC8, AC9** — синхронизация `process.yml` main/dev через существующий шаг
Validate; логика в тестируемом модуле, а не в inline-shell.
- **Не-скоуп** (ручная правка задним числом комментария #449, восстановление
`SPEC-REVIEW-449-r1.md`, обязательный гейт «назови файл») — исключения
корректны и не додуманы.
- **Ограничение «`process.yml` идентичен в main и dev»**, **план отката**,
**release-артефакты** (`User-Visible: no`, класс B, трейлеры).
- Технические наблюдения L1/L2 (не блокируют, см. таблицу выше).
## Что проверено и корректно (дельта)
- **AC2 (новая формулировка).** Число `attempt=3, spent=1` подтверждено
независимым пересчётом по первичным данным (см. «Как проверялось» и
таблицу закрытия) — не осталось расхождения, из-за которого r1 вернул ТЗ.
Фикстура названа однозначно («буквальный слепок сегодняшнего состояния
ветки»), способ доказательства не изменился (unit).
- **AC2b (новый).** Формула контракта §1/§3, применённая к трём
независимым файлам (`r1` жёлтый, `r2` жёлтый, `r3` зелёный), даёт
`attemptFromFiles=max(1,2,3)+1=4`, `spentFromFiles=2` (r1, r2 блокирующие,
r3 нет) — совпадает с заявленным `attempt=4, spent=2`. Формулировка не
оставляет второго прочтения: явно названа «реконструкция», а не факт.
- **Правка в «Подтверждённая проблема» про код-вердикт 16:01.** Автор
дополнительно (сверх M1) исправил собственную фактическую ошибку: красный
код-вердикт 16:01 содержит подстроку `CODE-REVIEW` в свободном тексте
(«путь соберёт шаг публикации, `CODE-REVIEW-449-r1`»), а не отсутствует,
как было написано раньше. Проверено дословно по тексту комментария
(`gh issue view 449 --json comments`, комментарий `2026-09-04T16:01:28Z`,
последний абзац) — подстрока действительно там. Утверждение «guard видит…
один код-вердикт из одного (`attempt=2`, верно)» было точным на момент
написания дельты (единственный код-вердикт на #449 в тот момент — этот
красный). Это иллюстрация в разделе с фактажом, не часть контракта или
AC — её точность на дальнейшее развитие живого issue #449 не влияет на
доказательность AC2/AC2b, которые используют замороженную (unit-)фикстуру,
а не пересчёт по живому issue при каждом прогоне теста.
- **Внутренняя согласованность документа после правки.** Прочитан документ
целиком: старое утверждение «дефект повторится на первом же возврате #449
в S7-code-review» удалено (заменено на факт про 16:01), нигде в остальном
тексте (скоуп, контракт, карта реализации, риски) на него больше нет
ссылок — висячих противоречий не осталось.
## Чего не проверял
- Не гонял гейты (`tsc`/`test`/`build`/`check-docs`/`invariants`/смоки/
`golden`/`pytest`) — класс изменения документация, кода на ветке нет;
унаследовано из r1, дельта тоже только в `.md`.
- Не проверял `gh api`/`git ls-remote` на предмет реальной способности
перечислить файлы `docs/reviews/` на произвольной ветке без checkout —
унаследовано из r1 как «техническая деталь реализации, не продуктовое
ограничение», дельта эту часть контракта (§4 ТЗ) не трогает.
- Не проверял дальнейшую судьбу код-этапа #449 после комментария 16:01: на
момент этого ревью на issue #449 уже существует второй код-вердикт
(зелёный, `2026-09-04T16:22:58Z`, опубликован как
`docs/reviews/CODE-REVIEW-449-r2.md` без коллизии имени — комментарий сам
явно называет свой документ). Это не расходится с текстом ТЗ (иллюстрация
фиксирует факт на момент авторской правки, а не обещание, что живой issue
#449 остановится) и не требует правки ТЗ — привожу для полноты, не как
находку.
- Не проверял отдельно раздел «Карта реализации»/«Риски» повторно — дельта
их не касается, инвариант «унаследовано из r1» покрывает их.
## Итог
Находка предыдущего раунда (M1) закрыта и перепроверена исполнением по
первичным данным, а не со слов автора: `spent=1` для буквальной фикстуры и
`spent=2` для реконструкции — оба числа независимо пересчитаны и совпадают с
новыми AC2/AC2b. Новых High или Medium дельта не создала. Остаток контракта
не тронут и наследуется из r1 без повторной проверки. Вердикт — зелёный,
бюджет цикла не тратится.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/454-review-round-counter`, коммит `f3e60578d443` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `983c66cca25d56b4a147e535608bce8f2261ad05`
```
git log --all --format='%H %T' | grep 983c66cca25d
```
- ТЗ `docs/specs/454-review-round-counter.md`, блоб `b5af292101a495e4699d839397e837a3a2467c85`
```
git log --all --find-object=b5af292101a495e4699d839397e837a3a2467c85 -- docs/specs/454-review-round-counter.md
```