From f1f05198a55f0ef17aa09ca5b0bf9e096ccf3e72 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 12:05:55 +0000 Subject: [PATCH] docs: review document for #478 Issue: #478 User-Visible: no --- docs/reviews/SPEC-REVIEW-478-r1.md | 209 +++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-478-r1.md diff --git a/docs/reviews/SPEC-REVIEW-478-r1.md b/docs/reviews/SPEC-REVIEW-478-r1.md new file mode 100644 index 00000000..46c41213 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-478-r1.md @@ -0,0 +1,209 @@ +# SPEC-REVIEW — issue #478, заход r1 + +- **Issue:** https://github.com/Matysh/houseplan-card/issues/478 +- **Этап:** spec (PROCESS.md §2.4) +- **ТЗ:** `docs/specs/478-remove-room-drafts.md` +- **Ветка/SHA:** `issue/478-remove-room-drafts` @ `30a16ed36461246e06d395f2bab7f4b6d9e12eaa` +- **Заход:** r1 · блокирующих циклов израсходовано 0 из 4 (первый заход, бюджет §4 не тратится) +- **Вердикт: зелёный** + +## Скоуп ревью + +Задача не помечена `small` (метки: `P2`, `S4-spec-review`, `tech-debt`; автор сам +классифицировал её как полный трек — миграция схемы v9→v10, несколько +поверхностей, изменение контракта сохранения незамкнутой цепочки). Поэтому ТЗ +обязано жить в `docs/specs/`, что и сделано; файла лишнего в теле issue нет. +Диапазон изменений этого раунда — только `docs/specs/478-remove-room-drafts.md` +и одна строка в `docs/specs/README.md` (класс C, документация, ожидаемо для +этапа spec): + +``` +docs/specs/478-remove-room-drafts.md | 531 +++++++++++++++++++++++ +docs/specs/README.md | 1 + +``` + +Продуктового кода в ветке нет — это правильно для стадии `S4-spec-review`. + +## Как проверялось + +1. Прочитан `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` §2.4/§7.1/§4/§7.2/§12. +2. Прочитано тело issue #478 целиком и все 3 комментария (аналитика, занятие, + передача на ревью, решения владельца от 06.09.2026). +3. Прочитан ТЗ целиком (531 строка, разделы 1–20). +4. Прочитаны канонические документы, которые ТЗ обязуется обновить при + реализации: `docs/CANVAS.md`, `docs/WALL-THICKNESS.md`, + `docs/CONFIG-COMPATIBILITY.md`, `docs/ARCHITECTURE.md`, + `docs/USER-GUIDE.ru.md` — сверена терминология («черновик», «независимая + стена», resume-жест) с тем, что уже описано там сегодня. +5. Технические утверждения ТЗ и исходного текста issue сверены с текущим + кодом на `origin/dev` (`fc5973c2`), а не приняты на слово: + - `MAX_ROOM_DRAFTS=200`, `MAX_DRAFT_SEGMENTS=2000`, `MAX_PARTITIONS=2000` — + существуют в `src/houseplan-card.ts`, `src/houseplan-editor-runtime.ts`, + `custom_components/houseplan/validation.py` ровно как описано; + - `_offerWallFaces`, `_offerExistingWallFace`, `_wallGraphSources`, + `_planStructuralGeometrySnapshot` — существуют в + `src/houseplan-editor-runtime.ts` с сигнатурами, соответствующими + описанию в issue; + - `fixedTopologyWallLineageHints` — существует в `src/wall-segment-model.ts` + и используется в `houseplan-editor-runtime.ts`; + - `partitionsReconciled` / `redundantDraftsRemoved` — существуют в + `src/plan-optimizer.ts` и `src/coincident-partitions.ts` ровно с той + семантикой, которую ТЗ предлагает свести к нулю; + - `draft-live-preflight.ts` / `draft-live-commit.ts` (Fast path #461) — + существуют, есть тест `test/draft-live-preflight.test.mjs`; + - `WALL_SEGMENT_MODEL_VERSION` и `PLAN_MODEL_VERSION` действительно равны + `9` сегодня и исторически бампались синхронно (`git log -p` по обеим + константам) — заявленный переход v9→v10 не расходится с прецедентом; + - `wall_model_client_outdated` — существующий код ошибки + (`src/houseplan-card.ts`, `src/space-copy-runtime.ts`, все локали), а не + изобретённый в ТЗ; + - `mutation-gate` как механизм (AC13 требует «мутант... краснит gate») — + реально существующая инфраструктура (`scripts/mutation-gate.mjs`, + `test/mutation-gate.test.mjs`, `docs/TESTING.md`), не выдуманный + инструмент. +6. Сверена таблица `docs/specs/README.md`: новая строка вставлена без колонки + «Статус ТЗ» — соответствует зачистке из PROCESS.md §7.3 п.1, уже принятой в + остальной таблице. +7. Проверено соответствие §7.1 (обязательные разделы) и формату AC (каждый + пункт называет способ доказательства). + +Гейты (typecheck/test/build) не гонялись: на этом этапе (spec) продуктового +кода в ветке нет, гонять их не над чем. Это не пропуск гейта, а его +неприменимость к диапазону изменений раунда. + +## Разбор по требованиям процесса + +### §7.1 — обязательные разделы + +Все присутствуют, хотя «контракт поведения» не оформлен единым заголовком, а +распределён по §8–12 (активная цепочка / face detection / Undo-Redo / limits / +import-export) — это не нарушение, содержание есть и логично сгруппировано: + +сценарий (§1) · что человек увидит (§2) · проблема (§3) · скоуп/не-скоуп (§5) · +контракт поведения (§8–12) · UX/i18n (§13) · модель данных и миграция (§6–7) · +критерии приёмки AC1–AC15, каждый со способом доказательства (§14) · план +автотестов (§15) · риски (§17) · откат (§18) · release-артефакты (§19). + +Два продуктовых раздела («сценарий», «что человек увидит») идут первыми, как +требует PROCESS.md, и оба не используют термины реализации. + +### Продуктовые вопросы vs технические + +Открытых продуктовых вопросов нет: владелец 06.09.2026 ответил ровно на два +продуктовых вопроса (жест возобновления контура; подсветка незамкнутых стен), +и оба ответа перенесены в §4 ТЗ дословно. Раздел 20 «Принятые технические +предположения» содержит только техническое: имя/расположение +session-состояния, переименование файлов fast-path, источник fallback ID, +место экстракции reconciliation-логики, судьба deprecated-счётчика, механизм +CSS-подсветки. Ни один из этих семи пунктов не задевает то, что видит +пользователь — деление между продуктовым и техническим сделано верно, ничего +техническое не выдано владельцу, и ничего продуктовое не спрятано в +«технические предположения». + +### Догадка, выданная за факт + +Не найдена. Каждое нетривиальное техническое утверждение («уже сегодня +предложение комнаты работает и на чужих партициях», «дубли схлопывает только +оптимизатор», названные функции и константы) проверено против кода и +подтвердилось — см. предыдущий раздел. Формулировки вида «предполагаю» +отсутствуют там, где нужно было бы решение, потому что владелец их уже принял. + +### Однозначность AC + +15 AC, каждый называет способ доказательства (`unit`, `unit + Python parity`, +`smoke`, `performance + mutation`, `golden verify`, `typecheck+unit+build+docs +review`). Формулировки конкретны и допускают проверку «упало/не упало»: +например AC7 требует «итог содержит одну masonry, нет coincident partitions» +— проверяемо инвариантом, а не оценочно. AC13 явно требует существования +красного мутанта на «coincident partition либо draft» — это ровно дисциплина +«тест должен уметь падать», перенесённая в план ещё до кода. + +### Миграция и откат + +Миграция v9→v10 нормативно описана (§7.1–7.3): один partition на одно legacy +edge, без слияния/дедупликации, детерминированные ID с указанным источником +энтропии, требование TS/Python parity. Откат (§18) корректно разделяет +кодовый revert (безопасен) и уже сохранённый v10-конфиг (несовместим со старой +карточкой по замыслу, downgrade запрещён явно) — это соответствует +`docs/CONFIG-COMPATIBILITY.md`, где подобные необратимые migrate-on-write +переходы уже прецедент. + +### Соответствие docs/SCOPE.md + +Задача — tech debt/миграция модели, устраняющая дублирующую сущность и +невидимо накапливающийся артефакт (`room_drafts`, не отличимый от обычной +стены после reload, блокирующий resize соседней стены). Это поддерживает J6 +(«Keep the plan true as the home evolves») — упрощает и делает надёжнее +механизм разметки контура/комнаты, не расширяя видимый функционал за пределы +уже существующего поведения. Новых кнопок, настроек или диалогов ТЗ явно не +вводит (§5.2, §13) — соответствует принципу «View mode остаётся продуктом», +редакторская сложность не растёт для пользователя. + +### Release-артефакты и User-Visible + +`User-Visible: yes` обоснован верно (§19): исчезает resume персистентного +черновика, меняется видимое поведение незамкнутых стен после reload. Список +документов для обновления полный и включает оба changelog, что при реализации +обязано попасть в тот же коммит по AGENTS.md. + +## Что проверено и корректно + +- Обязательные разделы §7.1 — все на месте. +- Каждый AC — с методом доказательства, формулировки допускают падение теста. +- Технические утверждения ТЗ и предпосылки issue — верны по факту чтения кода + `origin/dev`, догадок, выданных за решённый факт, не найдено. +- Продуктовые решения владельца зафиксированы дословно и исчерпывающе; + раздел «технические предположения» не содержит скрытых продуктовых развилок. +- Скоуп/не-скоуп конкретны и проверяемы, границы задачи не размыты. +- Миграция и откат внутренне согласованы и соответствуют прецеденту + `docs/CONFIG-COMPATIBILITY.md`. +- `docs/specs/README.md` обновлён в формате, уже принятом для остальной + таблицы (без колонки статуса). + +## Чего не проверял + +- Не гонял `npx tsc --noEmit`/`npm test`/`npm run build` — в ветке нет + продуктового кода, гонять их не над чем на этапе spec. +- Не проверял `npm run invariants` — геометрия ещё не реализована, инварианты + модели проверять не на чем. +- Не читал полностью весь текст `docs/CANVAS.md`/`docs/WALL-THICKNESS.md`/ + `docs/ARCHITECTURE.md` построчно — выборочно сверил только фрагменты, + относящиеся к `room_drafts`/lineage/reconciliation, поскольку остальное не + затрагивается этим ТЗ. +- Не оценивал реализуемость помодульно (файлы/хелперы) — ТЗ прямо и верно + относит это к техническим решениям вне продуктового ревью (§20, PROCESS.md + §7.1 «всё, чего пользователь не наблюдает, агенты решают сами»). +- Не связывался с #477/#461/#173/#282/#314 по существу — они упомянуты как + контекст связи, не как обязательства этого ТЗ; не-скоуп (§5.2) явно + исключает пересечение с #461. + +## Находки + +Нет ни одной находки уровня High или Medium. Low-находок, требующих правки или +пометки waived, тоже нет. + +## Итог + +ТЗ полное, однозначное, все обязательные разделы на месте, каждый AC проверяем +и называет способ доказательства, продуктовых вопросов не осталось, а +технические утверждения подтверждены чтением актуального кода, а не приняты на +веру. Задача полностью укладывается в `docs/SCOPE.md` (J6) и не расширяет +скоуп за счёт незаявленной пользователю функциональности. + +**Вердикт: зелёный · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 0** + +--- + + + +## Материал раунда + +- Ветка: `issue/478-remove-room-drafts`, коммит `30a16ed36461` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `66116fde28ee91b0ee64d7dc0d3125b82c972505` + ``` + git log --all --format='%H %T' | grep 66116fde28ee + ``` +- ТЗ `docs/specs/478-remove-room-drafts.md`, блоб `8817d2c4307eed78b4eba9f731b3b6fd7c5270c3` + ``` + git log --all --find-object=8817d2c4307eed78b4eba9f731b3b6fd7c5270c3 -- docs/specs/478-remove-room-drafts.md + ```