mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
171 lines
16 KiB
Markdown
171 lines
16 KiB
Markdown
# SPEC-REVIEW-276-r2
|
||
|
||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/276
|
||
- **Этап:** ТЗ на ревью (PROCESS.md §2.4)
|
||
- **Заход:** r2 · блокирующих циклов израсходовано 1 из 4 (r1 — красный, 1
|
||
цикл; зелёный вердикт цикла не образует, #227)
|
||
- **ТЗ:** `docs/specs/276-coincident-partition-reconciliation.md`
|
||
- **Предыдущий раунд:** `docs/reviews/SPEC-REVIEW-276-r1.md`, получен на
|
||
commit `a06c94b9` (первая редакция ТЗ, 249 строк)
|
||
- **Вердикт:** зелёный · High: 0 · Medium: 0
|
||
|
||
## Скоуп
|
||
|
||
Обычный трек (issue не помечен `small`/`trivial`), ТЗ — отдельный файл.
|
||
Предмет этого раунда — **дельта по §2.10**, а не документ целиком: диапазон
|
||
`a06c94b9..ca516643` по файлу
|
||
`docs/specs/276-coincident-partition-reconciliation.md` (commit `ca516643`,
|
||
42 добавленные / 7 удалённых строк, единственный тронутый файл — проверено
|
||
`git show --stat ca516643`). Продуктовый код не менялся ни в одном из двух
|
||
коммитов раунда. Дельта не ребейзилась на ушедший вперёд `dev`, не меняет
|
||
контракт поведения и не задевает новую подсистему — основания для полного
|
||
разбора вместо разбора по дельте (§2.10, «разбор остаётся полным, если…») не
|
||
возникло.
|
||
|
||
Замечание к трассируемости раунда: хендофф-комментарий автора называет
|
||
«Коммит дельты: `cf92519` (фактический SHA см. ветку)» — такого объекта в
|
||
репозитории не существует (`git cat-file -t cf92519` → `Not a valid object
|
||
name`). Фактический коммит дельты — `ca516643`, найден по `git log
|
||
--oneline` на ветке `issue/276-reconcile-coincident-partition`, время
|
||
коммита (04:56:33 +0300 = 01:56:33Z) совпадает с временем комментария
|
||
(01:56:36Z) — это опечатка/недописанный short SHA, а не подмена содержания:
|
||
дифф соответствует описанным правкам. Low, не блокирует; снимаю с записью
|
||
здесь, правильный SHA зафиксирован выше. На будущее: находка того же типа,
|
||
что требование §2.10 «SHA в вердикте не назван — находка», только с
|
||
обратной стороны — автору стоит подставлять реальный SHA, а не плейсхолдер.
|
||
|
||
## Как проверялось
|
||
|
||
- Перечитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` §2.4, §2.5, §2.10,
|
||
§4, §7.1, §7.2.
|
||
- Найден вердикт r1 и SHA ТЗ, на котором он получен (`a06c94b9`) — по
|
||
`docs/reviews/SPEC-REVIEW-276-r1.md` и комментарию-вердикту в issue.
|
||
- Дельта объявлена явно: `git show --stat ca516643` и полный `git show
|
||
ca516643 -- docs/specs/276-coincident-partition-reconciliation.md`.
|
||
- По каждой находке r1 (H1, M1, M2, M3) проверено текстом дифф-патча, чем
|
||
именно она закрыта — не по заявлению автора в хендоффе, а по строке в
|
||
файле (см. таблицу «Закрытие раунда r1» ниже).
|
||
- Перепроверены только AC и DoR-пункты, которые дельта задевает: AC7 (Redo),
|
||
DoR «риски перечислены» (M1), DoR «файлы и модули перечислены» (M2),
|
||
корректность ссылки на канонический документ (M3). Остальные AC (AC1–AC6,
|
||
AC8–AC14) дельтой не затронуты, наследуются из r1 без повторной проверки —
|
||
см. раздел «Унаследовано из r1».
|
||
- Сверка новых утверждений §10.1 с фактическим деревом: `find`/`ls` по
|
||
`src/**`, `test/**`, `demo/**`, `scripts/**` — все перечисленные
|
||
существующие файлы (`src/plan-optimizer.ts`, `src/partition-openings.ts`,
|
||
`src/plan-geometry-preflight.ts`, `src/houseplan-card.ts`,
|
||
`test/plan-optimizer.test.mjs`, `test/partition-openings.test.mjs`,
|
||
`test/plan-geometry-preflight.test.mjs`, `scripts/mutation-gate.mjs`)
|
||
подтверждены; новый `src/coincident-partition-reconciliation.ts` заявлен
|
||
как новый модуль корректно (не существует и не должен). Именование смока
|
||
`demo/smoke_optimize_coincident_partition.mjs` соответствует действующему
|
||
паттерну (`demo/smoke_optimize_*.mjs` — три таких смока уже есть).
|
||
- Сверка переформулированного AC7/§6 (одноразовый server Undo без Redo) с
|
||
`docs/USER-GUIDE.ru.md:1444` — текст спека («Отдельного Redo у Optimize
|
||
нет; следующая edit-операция делает server backup устаревшим по
|
||
действующему контракту») точно отражает уже задокументированный контракт
|
||
(«После оптимизации доступна одна серверная отмена… Новый edit делает
|
||
резервную копию оптимизации устаревшей»). Само существование этого
|
||
контракта в коде (`_alignOptimizedConfirm`/`_undoPlanOptimization`,
|
||
`src/houseplan-card.ts:15120–15208`) уже проверено чтением в r1 и дельтой
|
||
не пересматривается.
|
||
- Проверено, что упоминания несуществующего `docs/PLAN-OPTIMIZE.md` не
|
||
остались где-либо в файле: `grep -n "PLAN-OPTIMIZE" docs/specs/276-*.md` —
|
||
0 совпадений (кроме, ожидаемо, самого документа r1, который описывает
|
||
прошлое состояние и не переписывается).
|
||
- Гейты `typecheck`/`test`/`build`/`check-docs` не прогонялись: дельта r2, как
|
||
и вся ветка на данный момент, не трогает `src/**` — продуктовый код не
|
||
менялся ни в одном из двух коммитов ТЗ. Применимости этих гейтов к
|
||
спек-ревью нет (то же основание, что в r1).
|
||
|
||
## Закрытие раунда r1
|
||
|
||
| Находка r1 | Чем закрыта | Где это видно |
|
||
|---|---|---|
|
||
| **H1** (High) — заявлен несуществующий Redo для серверной отмены Optimize (§6, AC7) | Формулировка Redo убрана из §6 и AC7, заменена точным описанием действующего one-shot server Undo с истечением после следующей edit | `docs/specs/276-*.md:130–132` («Отдельного Redo у Optimize нет; следующая edit-операция делает server backup устаревшим по действующему контракту») и `:234` (AC7: «одноразовый server Undo восстанавливает исходную форму и становится недоступен после следующей edit по действующему контракту»); `grep -i redo` по файлу даёт только эти две строки, обе формулируют отсутствие Redo, а не его наличие |
|
||
| **M1** (Medium, в скоупе) — отсутствовал обязательный по DoR §2.5 раздел «Риски» | Добавлен раздел «10.2. Риски и меры» — таблица из 8 рисков с мерами, покрывающая все ключевые AC (partial/rehost/duplicate/preflight/idempotence/Redo/perf/rollback) | `docs/specs/276-*.md:204–215` |
|
||
| **M2** (Medium, в скоупе) — не перечислены затронутые файлы/модули, обязательный пункт DoR §2.5 | Добавлен раздел «10.1. Затронутые файлы и модули» с явным списком продуктовых/тестовых/demo/i18n модулей и явным non-scope backend | `docs/specs/276-*.md:183–202`; все названные существующие файлы подтверждены в дереве (см. «Как проверялось») |
|
||
| **M3** (Medium, в скоупе) — ссылка на несуществующий `docs/PLAN-OPTIMIZE.md` (шапка, §14) | Ссылка заменена на реально существующие `docs/USER-GUIDE.ru.md` и `docs/ARCHITECTURE.md` в обоих местах | `docs/specs/276-*.md:12` (шапка «Связано») и `:263` (§14 список документации); `grep PLAN-OPTIMIZE` по файлу — 0 совпадений |
|
||
|
||
Все находки r1 закрыты по существу, а не переформулированы текстом без
|
||
изменения контракта — H1 меняет и наблюдаемое поведение AC7 (нет Redo, есть
|
||
expiry), а не только слово в тексте.
|
||
|
||
## Унаследовано из r1
|
||
|
||
Принято без повторной проверки в этом раунде, дельта не задевает:
|
||
`docs/reviews/SPEC-REVIEW-276-r1.md`, SHA `a06c94b9`.
|
||
|
||
- Продуктовая рамка (§1 сценарий/персона, §2 подтверждённая причина) —
|
||
соответствует `docs/SCOPE.md` J4/J6, root-cause подтверждён документами
|
||
(`WALL-THICKNESS.md` §9, `USER-GUIDE.ru.md:555`), ни одна упомянутая
|
||
функция не выдумана.
|
||
- Условие безопасной канонизации §4 и негативная матрица AC2 — консервативно,
|
||
не требует продуктового вопроса владельцу.
|
||
- Разведение со смежными issue #277 (Resize ambiguity) и #278 (общий
|
||
wall-union fallback) — корректно исключены из скоупа.
|
||
- AC1–AC6, AC8–AC14 (кроме переформулированного текста AC7) — у каждого
|
||
указан способ доказательства, ни один не оставлен без него; дельта их не
|
||
меняла.
|
||
- Производительность (§10, бюджеты ≤15%/25 ms) и touch (§11, «новых жестов
|
||
нет») — закрывают DoR-пункты явными числами/утверждением.
|
||
- Preflight-механизм #199, на который опирается §4.8/AC9, существует и
|
||
тестируем (`src/plan-geometry-preflight.ts`,
|
||
`test/plan-geometry-preflight.test.mjs`).
|
||
- i18n: конкретные ключи не названы буквально — Low, оставлено на решение
|
||
автора при реализации (не блокирует).
|
||
- Стилистическая тонкость: продуктовые «сценарий» и «что человек увидит»
|
||
размазаны по §1/§6, а не сведены в одну фразу — r1 сознательно не завёл
|
||
это отдельной находкой (граница с полноценным замечанием тонкая); дельта
|
||
этого не трогала, решение остаётся в силе.
|
||
|
||
## Находки
|
||
|
||
Нет. Все находки r1 закрыты по существу (см. таблицу выше), дельта не
|
||
вносит новых противоречий с кодом, канонической документацией или процессом.
|
||
Единственное новое наблюдение — неверный SHA в хендофф-комментарии автора —
|
||
Low, снят с записью (см. «Скоуп»), не возвращается автору.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- Все четыре находки r1 (1 High, 3 Medium) закрыты предметно: изменено
|
||
наблюдаемое поведение AC7, а не только слово; добавлены оба обязательных
|
||
по DoR §2.5 раздела; исправлена ссылка на несуществующий документ.
|
||
- Новые утверждения §10.1 (список файлов/модулей) фактически точны — каждый
|
||
названный существующий файл присутствует в дереве под тем же путём.
|
||
- Новая формулировка §6/AC7 (one-shot server Undo без Redo) буквально
|
||
совпадает с уже опубликованным пользовательским контрактом
|
||
`docs/USER-GUIDE.ru.md:1444`.
|
||
- DoR §2.5 теперь полностью закрыт по всем пунктам: ТЗ существует, ревью
|
||
предыдущего раунда пройдено с найденными и закрытыми находками, AC1–AC14
|
||
пронумерованы с доказательством, файлы/модули перечислены (§10.1), i18n
|
||
файлы названы (конкретные ключи — Low, за автором), миграция решена
|
||
(«без schema migration», §14 без автоматического обратного пересоздания
|
||
partition), производительность и touch названы явно, release-артефакты и
|
||
откат описаны, продуктовых вопросов нет (§3), риски перечислены (§10.2).
|
||
|
||
## Чего не проверял
|
||
|
||
- Не запускал `npx tsc --noEmit` / `npm test` / `npm run build` /
|
||
`node scripts/check-docs.mjs` — ни один из двух коммитов раунда (r1→r2)
|
||
не трогает `src/**`, продуктовый код не менялся; гейты реализации к
|
||
спек-ревью неприменимы.
|
||
- Не запускал browser smoke / golden / инварианты модели — geometry/wall
|
||
код ещё не написан, это код будущей реализации.
|
||
- Не оценивал сложность/трудозатраты реализации — вне компетенции
|
||
спек-ревью.
|
||
- Не проверял реальный пользовательский экспорт (владелец не приложил его
|
||
из-за пользовательских данных) — синтетическая fixture в ТЗ признана
|
||
корректной заменой ещё в r1, дельта этого не касалась.
|
||
|
||
## Вывод
|
||
|
||
Единственная High-находка (H1) и все три Medium-находки (M1–M3) закрыты по
|
||
существу: контракт Undo/Redo Optimize теперь описан точно и совпадает с
|
||
действующим кодом и `USER-GUIDE.ru.md`, обязательные разделы DoR «Риски» и
|
||
«Затронутые файлы и модули» добавлены и фактически верны, ссылка на
|
||
несуществующий канонический документ заменена реальными источниками. Дельта
|
||
не вносит новых противоречий. DoR (§2.5) выполнен полностью. Открытых
|
||
продуктовых вопросов владельцу нет. Вердикт — зелёный, ТЗ готово к переходу
|
||
в `S5-ready`.
|