Files
houseplan-card/legacy/reviews/v1.68.0/SPEC-REVIEW-223-r3.md
T
Claudeandclaude[bot] 0991c45374 fix(tools): архив переписывает относительные ссылки перенесённых документов (#682)
Ревью #682 r1, Medium: перенос добавляет документу уровень вложенности
(`docs/reviews/X.md` → `legacy/reviews/<тег>/X.md`, `docs/specs/` →
`legacy/specs/`), а относительные ссылки внутри перенесённых документов и в
соседях, ссылавшихся на них, никто не пересчитывал — на `97d19268` 53 битые
ссылки в 46 файлах (заявление «все 26 резолвятся» в `7feb6177` было верно
только до переноса документов ревью). Гейты архив не смотрят.

`reviews-archive.mjs`: `repairLinks` пересчитывает ссылку, если она не
резолвится от нового места, а цель находится от нового или старого места
через карту переносов; битая и до переноса ссылка не трогается. `--apply`
делает это само, `--repair-links=<rev>` — для всех переименований
`<rev>..HEAD`, `--check-links` печатает битые. Этим коммитом
`--repair-links=origin/dev` переписал ровно 53 ссылки в 46 файлах; остались
две прежние «...»-заглушки в CODE-REVIEW-448-r2 (битые и на dev). Тесты:
перенесённый документ, сосед со ссылкой в архив, ТЗ со ссылкой на позже
перенесённое ревью, битая-до-переноса не трогается, в `legacy/` битых нет;
мутант `reviews-archive-links-from-new-place-only`. PROCESS §2.10 и
DEVELOPMENT › Release называют переписывание и `--check-links`.

Issue: #682
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
2026-09-27 22:10:47 +00:00

15 KiB
Raw Blame History

SPEC-REVIEW-223-r3

  • Issue: #223 «Оптимизировать планы» должна канонизировать координаты, а не консервировать floating-point шум
  • ТЗ: docs/specs/223-optimize-coordinate-canonicalization.md на коммите 8c9e5feae3503c086cc9f987d57f676e5435e537 (HEAD)
  • Раунд: r3/4
  • Вердикт: зелёный

Скоуп ревью (по дельте, PROCESS.md §2.10)

Round r2 получен на 965711ee2005b8ec2587b9c70fb9b14735c7756e (SHA назван в самом документе docs/reviews/SPEC-REVIEW-223-r2.md, вердикт жёлтый, High: 0, Medium: 1). Предмет этого раунда — git diff 965711e..HEAD. Диапазон состоит из двух коммитов:

  • 981d3d6 — публикация документа docs/reviews/SPEC-REVIEW-223-r2.md (артефакт самого ревью, не правка ТЗ);
  • 8c9e5fe («docs: clarify optimize report terminology») — единственная содержательная правка: 4 вставки / 4 удаления в docs/specs/223-optimize-coordinate-canonicalization.md, три места — §7 (текст диалога), строка AC6 и строка риска в §11. Меняется только слово «нормализовано»/«normalized» → «обновлено»/«updated» для существующего счётчика c; структура, семантика, доказательная матрица AC не затронуты.

Дельта локальна текстом (§2.10): нет ребейза, нет смены контракта поведения, не задета новая подсистема, объём (8 строк) на порядок меньше и исходного ТЗ (~230 строк), и даже правки r2 (42 строки). Полный разбор не открывается.

Отдельно проверено, не расширяет ли эта правка скоуп и не ломает ли AC, которые r1/r2 уже приняли (§2.10 п.5, регрессия по образцу #102) — нет: правка меняет исключительно пользовательскую метку одного и того же существующего показателя c, не его состав, не структуру OptimizeReport, не AC4/AC5/§6/§8.

Как проверялось

  1. Восстановлен вердикт r2 и его SHA командой gh issue view 223 --json comments — 965711e, назван в документе r2 (в этом раунде замечание «SHA не назван» не применимо — второй раунд подряд его исправно называет).
  2. git show 8c9e5fe — построчный разбор правки, единственная содержательная правка в диапазоне.
  3. Проверено буквальное закрытие находки r2: grep -in "нормализ|normali" docs/specs/223-optimize-coordinate-canonicalization.md — осталось ровно два вхождения: (а) §6, «нормализованного числа» — легитимное употребление термина в его устоявшемся во всём проекте значении (координата 0..1 холста, никак не связано со счётчиком c); (б) §11, строка риска, где слово упомянуто явно как «занятый термин, не используемый для c» — то есть подтверждение отказа от него, а не остаточное использование. Нового употребления «нормализовано»/«normalized» как метки счётчика c не осталось нигде.
  4. Проверено, не создаёт ли выбранная замена («обновлено»/«updated») новую коллизию того же класса, которую уже дважды находил этот цикл ревью (находка r1 №2 — «канонизировано» дважды; находка r2 — «нормализовано» занято координатной системой):
    • grep -rn "\bupdated\b" docs/CANVAS.md docs/ARCHITECTURE.md — ноль совпадений: слово не занято описанием координатной системы ни в одном каноническом документе;
    • grep -rn "обновлен" docs/*.md — единственное релевантное совпадение вне CHANGELOG.ru.md (журнал, не термин) — toast.room_updated / «Комната обновлена» (src/i18n/ru.json:562, en.json:562): это обобщённое подтверждение сохранения формы редактора комнаты, не термин геометрии и не соседствует с координатным текстом Optimize — коллизии смысла нет;
    • docs/CANVAS.md §9.5 (строка 421) — канонический документ фичи называет операцию, которую считает c, термином «exact open-span canonicalisation»; «обновлено»/«updated» нейтрально по отношению к этому термину и не конкурирует с ним за то же слово, в отличие от отвергнутых «канонизировано» и «нормализовано»;
    • выбранное слово — буквально один из двух вариантов по умолчанию, предложенных самим ревью r2 в качестве примера («например "обновлено"/"updated"»); автор использовал предложенный дефолт, а не самостоятельно ввёл новый термин, что снижает риск третьей итерации той же коллизии.
  5. Сверено, что правка синхронна во всех трёх местах (§7, AC6, риск §11) и в обоих языках (RU/EN) — да, во всех трёх местах пара «обновлено»/«обновлённые»/«spaces updated» согласована, расхождений между местами нет.
  6. Перечитаны комментарии issue #223 целиком на предмет незаявленного расширения скоупа — не найдено; хендофф r2→r3 (комментарий 2026-08-20 19:13:25Z) точно описывает сделанную правку.
  7. Проверено происхождение семантики c в коде: src/plan-optimizer.ts:404-500 — canonicalized++ инкрементируется по каждому элементу цикла for (let i = 0; i < config.spaces.length; i++), то есть ровно по пространствам (space), чьё сериализованное представление open_spans/open_to/walls изменилось. Формулировка «обновлено пространств: {c}» / «spaces updated: {c}» точно соответствует коду, который считает счётчик.

Код не проверялся: реализация не написана, этап spec, ни один файл класса A/B в диапазоне 965711e..HEAD не менялся (git diff --stat — только docs/reviews/** и docs/specs/**).

Закрытие раунда r2

Находка r2 Чем закрыта Где видно
Medium — замена «нормализовано»/«normalized» для c заново создаёт коллизию того же класса: слово устойчиво занято координатной системой 0..1 во всём проекте, включая канонический документ фичи (CANVAS.md), который к тому же называет саму операцию c термином «canonicalisation», а не «normalisation» Термин «нормализовано»/«normalized» заменён на «обновлено»/«updated» во всех трёх местах — §7 (диалоговая строка), AC6 (доказательная формулировка), §11 (строка риска); слово выбрано ровно из набора дефолтов, предложенных самим ревью r2, и не пересекается ни с «канонизировано» (занято p), ни с «нормализовано» (занято координатной системой) docs/specs/223-optimize-coordinate-canonicalization.md §7, AC6 (таблица §9), §11, коммит 8c9e5fe

Закрытие точное и полное: grep не находит остаточного использования слова в роли пользовательской метки счётчика, а выбранная замена проверена на тот же класс коллизии, который дважды всплывал в предыдущих раундах (r1 №2, r2), и не воспроизводит его в третий раз.

Находки

Новых находок нет. High: 0, Medium: 0.

Что проверено и корректно

  • Находка r2 закрыта буквально и без побочной коллизии (см. выше).
  • Три места правки (§7/AC6/§11) синхронны между собой и с новой пользовательской формулировкой; ни AC4/AC5/§6/§8/§9(остальные AC)/§10/§12/§13, ни структура OptimizeReport/AlignReport дельтой не задеты.
  • c семантически описан точно тому, что делает код (plan-optimizer.ts:500).
  • Скоуп задачи не расширился и не сузился; продуктовых вопросов по-прежнему нет, дельта чисто терминологическая.
  • Обязательные разделы ТЗ по PROCESS.md §7.1 присутствуют полностью (не повторная проверка формы — унаследовано, см. ниже, — но сам факт, что правка не удалила и не сломала ни один раздел, проверен диффом).

Чего не проверял

  • Код реализации — не написан, этап spec.
  • Гейты (typecheck/test/build) — не запускались; дельта не затрагивает класс A/B (только docs/specs/** и docs/reviews/**), гейты для этапа spec не требуются.
  • Текст docs/USER-GUIDE.ru.md/docs/CANVAS.md/docs/CHANGELOG* после будущей реализации — они по плану переписываются в реализации (AC9, §12), не в ТЗ; r3 проверял только формулировку самого ТЗ.
  • Все AC и разделы, которых дельта 965711e..HEAD не касается (AC1, AC2, AC3, AC4, AC5, AC7, AC8, AC9, AC10, §1–§6, §8, §10, §12, §13) — унаследованы из r2 без повторной проверки, ниже.

Унаследовано из r2

Принято без повторной проверки в этом раунде, по документу docs/reviews/SPEC-REVIEW-223-r2.md на SHA 965711ee2005b8ec2587b9c70fb9b14735c7756e:

  • скоуп по docs/SCOPE.md (J6) и выбор обычного трека — не изменился, дельта трек-критерии не затрагивает;
  • обязательные разделы ТЗ по PROCESS.md §7.1 присутствуют и по форме верны (подтверждено ещё в r1, дельта r2 и r3 разделов не удаляла);
  • подтверждённая причина и порядок величин шума (issue, §3 ТЗ) — арифметика EPS/GRID_STEP_N из src/align-grid.ts:62-72, не менялась ни в r2, ни здесь;
  • контракт снапа §6, идемпотентность (AC5), исключение проёмов из счётчика, отсутствие вызовов snapN() вне align-grid.ts, отсутствие роста moved/maxShift* от near-node замен — код и раздел §6 не входят в дельту ни r2, ни r3;
  • AC4/partitions/wall_columns (находка r1 №1) — закрыта в r2, дельта r3 этих разделов (§9 AC4, §10, §11 соответствующей строки риска) не касается;
  • AC1, AC2, AC3, AC4, AC5, AC7, AC8, AC9, AC10 — доказательство ни одного из них дельта r3 не задевает (правка только в §7-фрагменте, строке AC6 и строке риска §11, причём даже внутри AC6 меняется только слово, а не сама проверяемая формулировка контракта);
  • ссылка issue ↔ ТЗ в docs/specs/README.md, release-артефакты §12 — не входят в дельту;
  • отсутствие продуктовых вопросов владельцу — подтверждено r1 и r2, дельта r3 чисто терминологическая правка одной пользовательской строки, новых продуктовых вопросов не порождает.

Вердикт

Вердикт: зелёный · цикл r3/4 · High: 0 · Medium: 0

Обе находки предыдущих раундов (r1 №1, r1 №2/r2) закрыты по существу, третья попытка того же класса коллизии не воспроизвелась. ТЗ готово к переходу в «Готово к разработке».