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

16 KiB
Raw Blame History

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 без повторной проверки. Вердикт — зелёный, бюджет цикла не тратится.


Материал раунда

  • Ветка: 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