mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,161 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user