15 KiB
SPEC-REVIEW-273-r2
- Issue: #273 — Optimize сохраняет sub-grid островок толщины у T-узла: 22→15→22
- Этап: ТЗ на ревью (
S4-spec-review), заход r2, блокирующих циклов израсходовано 1 из 4 - Артефакт ТЗ:
docs/specs/273-optimize-topology-island.md - Проверено на SHA:
e2de0dbcc4f09b0a3c7085db4fbf0961f7e3d970(текущий HEAD веткиissue/273-optimize-topology-island) - Предыдущий раунд: r1, вердикт жёлтый, документ
docs/reviews/SPEC-REVIEW-273-r1.md, проверен на SHAb5fbe633a60f8a2091552204fc7ff9e3da67fb06 - Лёгкий/короткий трек: нет (
small/trivialне назначены; лейблы —bug,P1,S4-spec-review) — ТЗ обязано жить файлом, что соблюдено - Вердикт: зелёный
Скоуп раунда
git diff b5fbe633..e2de0dbc -- . показывает, что между SHA r1 и текущим HEAD изменился только docs/specs/273-optimize-topology-island.md (плюс коммит r1-ревью docs/reviews/SPEC-REVIEW-273-r1.md, который является артефактом самого процесса, не предметом проверки). Никакой продуктовый код, AGENTS.md, PROCESS.md, docs/SCOPE.md, канонические документы подсистемы (docs/WALL-THICKNESS.md и др.) не менялись. Тело issue #273 после хендоффа автора на r1 не редактировалось; новых сообщений владельца между r1 и r2, кроме хендоффа «ТЗ обновлено по ревью r1», нет.
Раунд признан локальным (не полным разбором) по критерию из инструкции: дельта не задевает ребейз, не меняет контракт поведения, не касается новой подсистемы, объём дельты (34 строки, один файл) несопоставим с объёмом исходной задачи. Разбор в этом раунде — по дельте: закрытие двух находок r1 плюс проверка, что сама правка не создала новых противоречий в документе.
Как проверялось
- Восстановлен вердикт и SHA r1 из
docs/reviews/SPEC-REVIEW-273-r1.mdи из истории комментариев issue (gh issue view 273 --json comments) — SHA r1 в тексте вердикта был назван прямо (b5fbe633a60f8a2091552204fc7ff9e3da67fb06), в отличие от типового случая «SHA не назван», здесь автор его указал в хендоффе. - Дельта объявлена и получена:
git diff b5fbe63..e2de0db -- docs/specs/273-optimize-topology-island.md(34 строки) иgit diff b5fbe63..e2de0db --stat(подтверждение, что больше ничего не менялось). - По каждой находке r1 (Medium + Low) построчно сверено, чем именно она закрыта в дельте — таблица ниже.
- Проверена техническая точность нового текста §14 п.4 («optimizer helper получает только room profile и
open_spans, а неspace.partitions/drafts») — это то же самое техническое утверждение, которое я уже проверял в r1 чтениемsrc/plan-optimizer.ts:99-200(сборкаnodesтолько изroomPoly()иopenCuts) иsrc/wall-thickness.ts:2311-2313(комментарий «Independent partitions/columns are deliberately not accepted here»). Поскольку сам код не менялся между r1 и r2 (см. п.1 «Скоуп раунда»), это наследуется без повторного чтения кода — только сверено, что новая формулировка в ТЗ не противоречит уже проверенному факту. - Проверено, что новая формулировка §6.2/§6.3 не противоречит остальному документу: единственные упоминания «partition/draft» в файле теперь — только в §14 п.4 (assumption), других следов удалённой категории в §5 «Не входит», §12 «Риски», AC3/AC4 не осталось (grep по файлу).
- Проверено, что все AC (AC1–AC8) теперь содержат явную строку «Доказательство:» с названием механизма (unit-файл/smoke/mutation-script) — это закрывает Low-находку r1.
- Продуктовых вопросов владельцу в дельте нет — правка чисто техническая (сужение заявленного контракта + документирование admission), новых развилок поведения не появилось.
Гейты кода в этом раунде не гоняются: продуктовый код не менялся, изменился только spec-документ — на этапе ТЗ это ожидаемо, не упущение.
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium — §6.2/§6.3 обещали блокировку при совпадении synthetic endpoint с independent partition/draft axis boundary, но ни AC, ни код это не покрывают | Автор выбрал вариант 1 из трёх предложенных: убрал пункт из нормативного контракта и перенёс его в §14 явным техническим допущением | docs/specs/273-optimize-topology-island.md:137-138 — из §6.2 убрано «endpoint другого physical axis», заменено на «вторым room-topology endpoint»; :151-158 — из §6.3 полностью убрана строка «второй endpoint совпадает с отдельной room/partition/draft axis boundary»; :337-342 — новый §14 п.4 прямо называет допущение: helper видит только room profile и open_spans, совпадение с partition/draft не классифицируется, меняет только cm central span на уже доказанную соседями толщину, identity-aware защита не заявляется этой задачей |
| Low — AC3/AC4/AC5/AC7 не называли явно способ доказательства по шаблону §2.5 | Строка «Доказательство: …» добавлена во все ACs, у которых её не было (в т.ч. и AC2/AC6/AC8, которые r1 уже засчитал как достаточные по тексту прозы) | :209-210 (AC2), :218-219 (AC3), :231-232 (AC4), :240-241 (AC5), :254 (AC6), :261-262 (AC7), :270 (AC8) |
Обе находки закрыты вариантом, предложенным самим ревью r1 (пункт 1 списка «правка на выбор автора»), а не спором и не эскалацией — по правилам раунда это устраняет цикл без обращения к владельцу.
Проверка точности закрытия (не просто «слова совпали»)
- Новая формулировка §6.2 («второй endpoint не является room vertex, endpoint opening/open span, или вторым room-topology endpoint») технически корректно описывает то же самое:
isTopologyNode()— это объединение room-vertex и open-cut checks, так что «room-topology endpoint» как третий пункт покрывает первые два; редундантность есть, но она не создаёт логической ошибки и не ослабляет guard — второй endpoint всё ещё обязан быть вне полного множества topology nodes. Не нахожу здесь дефекта, достойного находки. - §14 п.4 не выдаёт технический факт за решённое поведение — он явно помечен как «Принятое техническое предположение», что и требовалось по итогам r1: раздел прямо называет, что коллизия «не классифицируется» и «не заявляется этой задачей», не обещая скрытой защиты.
- AC4 попутно уточнён («offset/perpendicular/parallel coincidence с room profiles/open cuts») — это устраняет тень неоднозначности: без уточнения читатель мог бы думать, что этот тест покрывает и partition-коллизию. Уточнение корректно сужает формулировку синхронно с §6.3.
- Переупорядочение пунктов §14 (бывший п.4 про #271 стал п.5, бывший п.5 про отсутствие продуктовых вопросов стал п.6) — механическое смещение, семантика не изменена.
Новых находок delta не создала: правка строго сужает заявленный контракт до того, что реализация фактически может доказать, и документирует ранее недекларированное ограничение как предположение, а не как факт.
Унаследовано из r1
Всё содержание документа, не затронутое дельтой, принимается без повторной проверки со ссылкой на docs/reviews/SPEC-REVIEW-273-r1.md, полученный на SHA b5fbe633a60f8a2091552204fc7ff9e3da67fb06:
- соответствие job J6 из
docs/SCOPE.mdи обоснование сценария (§1 ТЗ); - полнота обязательных разделов §7.1 PROCESS.md (сценарий, до/после, причина, скоуп/не-скоуп, контракт §6.1 «Базовые условия #198», UX/accessibility/touch/security/perf, данные и совместимость, i18n, риски, откат, release-артефакты);
- построчное соответствие «Обязательные регресс-тесты» из тела issue → AC1–AC9 (таблица в r1);
- корректность порога
0.5 × GRID_PITCHи арифметики из приведённого в issue экспорта; - корректность терминологии «opening/open-span» =
openCuts/open_spans, не спутана с дверными/оконными маркерами (проверено r1 поtest/plan-optimizer.test.mjs:236-266); - отсутствие продуктовых вопросов владельцу (единственная развилка была решена контрактом §6.1–6.3 уже в r1; правка r2 её не трогает, кроме сужения одного пункта);
- реалистичность release-артефактов и rollback (§11, §13) — не описывают несуществующую миграцию;
- проверка «одно число — один источник» (PROCESS.md): новых пользовательских чисел не вводится,
wallsMergedпереиспользуется как есть.
§6.1 «Базовые условия #198» и §6.4 «Результат» не входят в дельту r2 и не переоценивались повторно.
Что проверено и корректно (дополнительно к наследию)
git diff --statподтверждает: между r1 и r2 не менялисьAGENTS.md,PROCESS.md,docs/SCOPE.md,docs/WALL-THICKNESS.mdи любой продуктовый код — предпосылка «делать разбор по дельте» выполнена, а не предположена.- SHA r1 был явно назван автором в хендоффе — не пришлось восстанавливать его из истории коммитов как отдельную находку.
- Дельта не расширяет and не меняет AC-контракт по существу (не добавляет и не убирает тестируемое поведение из позитивного сценария AC1–AC2), поэтому повторная проверка соответствия AC1–AC9 регресс-требованиям issue не нужна: только AC3/AC4 упомянуты в дельте, и оба сужены в сторону уже покрытого негативного случая, а не расширены на новый.
Чего не проверял
- Не перечитывал заново код
src/plan-optimizer.ts/src/wall-thickness.ts— он не менялся с r1, техническая точность §14 п.4 наследуется из уже проведённой в r1 проверки (см. «Как проверялось», п.4). - Не запускал
npm test/typecheck/build/check-docs.mjs— продуктовый код не менялся, гонять их не над чем; это ожидаемо на этапе ТЗ, не упущение. - Не проверял golden/smoke/performance/mutation-gate — они относятся к этапу код-ревью, здесь код ещё не написан.
- Не проверял частотность partition-коллизии на реальных планах (тот же пробел, что в r1) — теперь это явное предположение §14 п.4, а не непроверенное заявление, поэтому вопрос закрыт как «принято осознанно», а не как открытый риск.
Итог
Обе находки r1 (Medium и Low) закрыты корректно и по существу, а не только текстуально. Новых High/Medium делта не создала. Продуктовых вопросов владельцу нет.