14 KiB
SPEC-REVIEW-306-r4
- Issue: #306 — Редактор плана: заменить виртуальные стены обычными стенами толщиной 0
- Этап: ревью ТЗ (PROCESS.md §2.4, повторный раунд — §2.10)
- Заход: r4 · блокирующих циклов израсходовано (до этого вердикта) 2 из 4
- ТЗ:
docs/specs/306-zero-thickness-walls.md, HEAD веткиissue/306-zero-thickness-walls=3d7395abc354b072d4ed8ae48809972509dde41(«docs: align zero-wall spec limits») - Метка issue:
S4-spec-review(полный трек, неsmall/trivial)
Расхождение метаданных запуска с фактическим состоянием issue (процессная находка, не по ТЗ)
Входные метаданные этого запуска указывали «Заход: r2 · блокирующих циклов
израсходовано 1 из 4». Это не совпадает с состоянием GitHub — тот же класс
расхождения, который уже фиксировали SPEC-REVIEW-306-r2.md и
SPEC-REVIEW-306-r3.md для своих запусков:
- r1 (
904c47e4) — жёлтый, High 0, Medium 3 (2026-08-25T16:49:42Z) — 1 цикл; - r2 (
2c801bf5) — зелёный, High 0, Medium 0 (2026-08-25T16:57:24Z) — цикл не тратит; - r3 (SHA на момент ревью не разрешается локально: документ r3 называет
abbd4904, этот коммит недостижим в текущей истории — по датам и содержимому (то же сообщение «docs: adapt zero-wall spec to model v8», 2026-08-26T07:21:56+03:00) это переписанный при rebase-на-devэквивалент коммита9283d2ee; между r2 и r3 в лог влиты посторонние коммитыdev, например93054823, что и есть след rebase) — жёлтый, High 0, Medium 1 (M1: устаревший лимит500вместоMAX_WALL_SEGMENTS=200000), 2026-08-26T07:31:54Z — 2-й цикл; - автор исправил M1 в
3d7395ab(«docs: align zero-wall spec limits», 2026-08-26T07:33:20+03:00) и передал «на финальный spec-review r4/4» (2026-08-26T07:33:36Z).
Провожу разбор как r4 по фактическому состоянию GitHub, а не как r2. Это находка процесса запуска ревью, а не находка по содержанию ТЗ #306 — отдельный issue не заводится (параметр одного прогона, не продуктовый дефект, прецедент — сам этот issue в r2/r3).
Скоуп этого раунда
Дельта между содержимым, разобранным в r3 (эквивалент 9283d2ee), и текущим
HEAD (3d7395ab):
git diff 9283d2ee..3d7395ab -- docs/specs/306-zero-thickness-walls.md
даёт 11 изменённых строк в трёх местах документа (§10 шаг 10, §13, §17 AC13) — ровно та правка, которую предписал вердикт r3 для закрытия M1. Правка не меняет ни одного контракта поведения, не задевает новую подсистему и не сопоставима по объёму с исходной задачей — это учебный пример локальной дельты по критерию §2.10. Разбор по дельте: заново проверено только M1 и AC13/§10/§13, чьё доказательство эта правка задевает; остальное — раздел «Унаследовано».
Как проверялось
git diff 9283d2ee..3d7395ab -- docs/specs/306-zero-thickness-walls.md— единственный источник дельты, прочитан целиком построчно;grep -n '\b500\b' docs/specs/306-zero-thickness-walls.md— пусто: устаревшая цифра из трёх мест M1 (§10 п.10, §13, §17 AC13) удалена полностью, замена на`MAX_WALL_SEGMENTS` (сейчас 200 000)/ «любого другого актуального backend-лимита»;custom_components/houseplan/validation.py:1047-1048—MAX_WALLS = MAX_WALL_SEGMENTS = 200_000подтверждено текущим кодом (та же строка, что и в r3, повторно проверена — правка ссылается на реальную константу, не на новую догадку);:1056MAX_OPEN_SPANS = 500— как и в r3, это предел удаляемого поля, не итогового каталога, ТЗ его не использует;- §20 «Риски и защита» (строка «Atomization превысит лимит» → «atomic failure, no truncation») уже была сформулирована без конкретной цифры — делта её не касалась, четвёртое место M1 не требовало правки;
node --test test/docs-accept.test.mjs test/process-gate.test.mjs— 41 passed, 0 failed, 0 skipped (Linux; автор указывал 40 passed + 1 ожидаемый Windows-skip — расхождение по площадке, не по существу);- секции 1 «Сценарий» и 2 «Что человек увидит до и после» (закрытие M1 r1)
и ссылка на
docs/SCOPE.mdJ4/J6 перечитаны на текущем HEAD (строки 9-26) — дельта их не касалась, текст не откатился; docs/SCOPE.md—J4/J6существуют в документе (grep -n "J4\|J6"), утверждение §1 не голословно.
Закрытие раунда r3
| Находка r3 | Чем закрыта | Где видно |
|---|---|---|
M1 (Medium, в скоупе) — лимит wall_segments[] в ТЗ назван устаревшим числом 500 в трёх местах (§10 п.10, §13, §17 AC13), противоречит уже слитому #282 (MAX_WALL_SEGMENTS=200_000) |
Все три места переписаны на именованную константу/обобщённую формулировку без хардкода цифры | docs/specs/306-zero-thickness-walls.md:351-353 («При превышении MAX_WALL_SEGMENTS (сейчас 200 000) или любого другого актуального backend-лимита отказать целиком»), :423-424 («Лимит authoritative-каталога остаётся равен backend-константе MAX_WALL_SEGMENTS (сейчас 200 000)»), :605-606 AC13 («Превышение любого актуального backend-лимита… отклоняет весь candidate без truncation/partial apply») — коммит 3d7395ab |
| Low, снято с записью r1/r3 (нет единого консолидированного блока предположений) | Не переоткрывается — r1 и r3 уже признали формат достаточным при отсутствии открытых продуктовых вопросов | без изменений в этом раунде |
Других находок r3 не было (High 0, Medium 1 — только M1).
Унаследовано из r1/r2/r3
Без повторной проверки по существу в этом раунде — дельта 9283d2ee..3d7395ab
их не касается ни текстуально, ни по содержанию:
- продуктовые решения владельца по световому режиму (таблица dashed/solid,
запрет фиктивной толщины, единый resolver для Glow и солнца, инвалидация
кэшей при переключении, RU/EN copy под селектором) — проверены в
SPEC-REVIEW-306-r1.md/r2.md/r3.mdна SHA904c47e4/2c801bf5/ эквиваленте9283d2ee; §4 п.4-7, §9.1, §15 текущего файла не менялись; - соответствие
docs/SCOPE.md(J4/J6) и отсутствие конфликта с out-of-scope — §1, §21 не в дельте; - присутствие
docs/USER-GUIDE.ru.mdв §16/§19 (закрытие M2 r1) — строки 484, 683 текущей ревизии, не в дельте; - статусы compatibility-реестра
deprecated-read/migrate-on-write(закрытие M3 r1) — §6.2, строки ~172-175, проверены в r3 прямым обращением кscripts/config-field-registry.mjs/docs/CONFIG-COMPATIBILITY.md, не в дельте r3→r4; - целевая модель v8→v9 на authoritative
wall_segments[], stable ID/lineage #282, backend-диапазоныcmдляwall_segments/room_drafts/partitions/wall_columns— проверены в r3 по коду (validation.py), эта дельта их не меняет; - AC1, AC2, AC3, AC4, AC5, AC6, AC7, AC8, AC9, AC10, AC11, AC12, AC14, AC15, AC16, AC18 — не в дельте, наследуются из r3 без повторного разбора;
- i18n-таблица §15, touch/accessibility §14 — не в дельте;
- release-артефакты §19 (оба changelog, оба user-guide, канонические документы подсистем) — не в дельте.
AC13 и связанный текст §10 п.10, §13 — единственные места, разобранные заново в этом раунде (см. «Как проверялось» и таблицу закрытия выше); AC17 (перф-бюджеты) перечитан целиком заново, так как его формулировка находится в §13, но сам перф-контракт (fingerprint, отсутствие rebuild на HA tick, benchmark-пороги) не изменился словом — дельта тронула только соседнюю строку про лимит записей.
Находки
Нет. High: 0, Medium: 0.
Что проверено и корректно
- M1 закрыт по существу, не декларативно: три из трёх мест исправлены идентичной по смыслу формулировкой, привязанной к реальной именованной константе, а не к новому хардкоду; четвёртое упомянутое в r3 место (§20) не требовало правки, так как не содержало числа;
- исправление не создало нового технического долга: вместо конкретной цифры документ теперь ссылается на «текущий backend-лимит» — формулировка переживёт будущее изменение константы без повторного устаревания;
- docs/process gate зелёный (
node --test test/docs-accept.test.mjs test/process-gate.test.mjs— 41/41); - секции 1-2 (§7.1), ссылка на
docs/SCOPE.md, i18n, touch, release-артефакты не откатились и не пострадали от точечной правки — дельта минимальна и не затронула соседний текст.
Чего не проверял
- Не перепроверял AC1-AC12, AC14-AC18 по существу заново — они не в дельте
r3→r4 и не зависят от лимита
wall_segments[]; их закрытие наследуется из r3 (см. раздел «Унаследовано»); - не прогонялись
npm run typecheck/npm test/npm run build, browser-смоки, golden,python -m pytest tests_backend— на этапе ревью ТЗ src не менялся ни в этой дельте, ни в дельте r3→r4; это гейты код-ревью (PROCESS.md §2.7, §8), здесь неприменимы; - не проверял заново реестр
docs/CONFIG-COMPATIBILITY.md/scripts/config-field-registry.mjs— сделано в r3, дельта их не касается; - не восстанавливал точную историю rebase (
abbd4904→9283d2ee) коммит-за-коммитом — установил только, что это тот же контент по времени, сообщению коммита и последующему diff; для целей этого ревью достаточно, что дельта М1 считается от контента, который r3 реально видел.
Вердикт
M1 закрыт по существу на всех трёх упомянутых местах, новых находок дельта не создала. High: 0, Medium: 0 — зелёный.
Вердикт: зелёный · заход r4 · блокирующих циклов 2/4 · High: 0 · Medium: 0 → в задаче