Files
houseplan-card/docs/reviews/CODE-REVIEW-678-r1.md
T
2026-09-27 16:34:40 +00:00

17 KiB
Raw Blame History

CODE-REVIEW-678-r1

Материал раунда: git log --oneline origin/dev..HEAD / git diff origin/dev...HEAD, SHA c081f59a156bc74dd5ca64e3ae57ebfe9847e6be, origin/dev = 16cf4331. Один коммит, класс C (docs/скрипты) с двумя строками класса A (комментарии-пути в src/open-spans.ts, custom_components/houseplan/validation.py).

Скоуп

Волна 1 эпика #674: удалить мёртвые demo-скрипты и разовые/архивные документы без живых читателей, перенести историческую часть docs/ в legacy/docs/ и поправить все ссылки на перенесённые пути. Работа инфраструктурная (гигиена репозитория), маршрут без ТЗ-стадии (## ТЗ в issue нет по намерению — «Маршрут инфраструктурный: реализация → S7-code-review»). docs/SCOPE.md этот класс работы не гейтит job-строкой: изменение не касается продуктового поведения, только состав дерева документации и демо-скриптов, что подтверждено User-Visible: no на коммите.

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

По объёму из тела issue (6 пунктов чек-листа) и по разделу «Чем доказано» / комментарию-отчёту автора: для каждого удалённого или перенесённого имени файла — git grep -n по всему дереву (кроме legacy/**, docs/reviews/**, docs/CHANGELOG*), затем прогон гейтов из раздела «Зависимости и машинные проверки» issue.

Гейты — что прогнано в этом раунде

Гейт Результат Источник
npx tsc --noEmit, npm run build + сверка бандла не гонял Validate зелёный на c081f59a (run 36333078086) — дешёвые гейты подтверждены §8, дифф не трогает исполняемый код
npm test зелёный: 3191 pass, 0 fail, 1 skip, 3170 подтестов прогнал сам
node scripts/check-docs.mjs --screenshots=warn «passed (7 files, 12 external links)»; один WARN — устаревший отпечаток скриншотов прогнал сам; WARN объяснён ниже
node scripts/check-inputs.mjs --coverage чисто (без вывода = 0 расхождений) прогнал сам
node scripts/mutation-registry.mjs --check чисто прогнал сам
node scripts/process-gate.mjs --range origin/dev..HEAD пройден, 1 WARN (п.0, legacy/ вне классов A/B/C/D) прогнал сам
node scripts/process-gate.mjs --range origin/dev..HEAD --issues пройден, +1 WARN (п.3, класс A без ТЗ) прогнал сам
node test/reviews-index.test.mjs, test/testing-notes-index.test.mjs, test/check-inputs.test.mjs (уже входят в npm test) зелёные отдельно прогнал сам для локализации
node scripts/smoke-select.mjs --base origin/dev --head HEAD «НЕОПРЕДЕЛЁННОСТЬ»: 1 файл src/**, 0 символов на изменённых строках прогнал сам, решение ниже
npm run golden:verify не гонял дифф не меняет рендер (единственная правка src/ — путь в докблоке комментария, ни один символ проекта не задет)
python -m pytest tests_backend не гонял правка validation.py — комментарий-путь, поведение Python-кода не меняется; npm test уже гоняет TS-часть контракта
npm run invariants не гонял дифф не трогает геометрию модели
performance не гонял не назван в AC

Решение по smoke-select: «НЕОПРЕДЕЛЁННОСТЬ» с 0 символами на изменённых строках src/** — единственная правка там (src/open-spans.ts:2) меняет только путь внутри JSDoc-комментария, других строк src/** дифф не трогает. Прочитал diff построчно: изменение не может повлиять на исполняемый код. Смоки не гонял — считаю связь опровергнутой чтением, а не «не доказана».

Ручная проверка ссылок (шире, чем check-docs.mjs, который валидирует

только PUBLIC_DOCS)

Для каждого удалённого/перенесённого имени — git grep -n --fixed-strings по всему дереву, исключая legacy/**, docs/reviews/**, docs/CHANGELOG*:

  • Все девять demo-скриптов и scripts/dev/styles-split.mjs, docs/README.ru.md, весь удалённый legacy/-снимок (audit-v1.58.0, 089-draft, implementation-plans, PRODUCT-2026-07-05, PRODUCT-IMPROVEMENT-PLAN.ru, dbg_click, repro_issue3), demo/README.md — ноль совпадений вне legacy/ и docs/reviews/.
  • docs/superpowers/specs — 8 совпадений, все уже переписаны на legacy/docs/superpowers/specs/... (validation.py:1211, FILTERING.md:7, ТЗ 006/007/058, testing-notes/devices.md ×2, src/open-spans.ts:2).
  • docs/QUALITY-560 — 1 совпадение, smoke_household_journeys.mjs:14, уже legacy/docs/QUALITY-560.md.
  • docs/ROADMAP.md — 1 совпадение, SCOPE.md:10, уже legacy/docs/ROADMAP.md.
  • docs/STATUS-FEATURES.md — 1 совпадение, STATUS.md:60, уже legacy/docs/STATUS-FEATURES.md.

Итог: ни одной висящей ссылки не найдено.

Проверка перемещений (история сохранена)

git diff origin/dev...HEAD показывает similarity index 100% / rename from/to для docs/QUALITY-560.md, docs/ROADMAP.md, docs/STATUS-FEATURES.md и 11 файлов docs/superpowers/specs/; git log --follow по каждому пути продолжает историю до исходного коммита. legacy/README.md переписан: опись из пяти оставшихся путей (включая причину, почему SUN-CONTRAST.md и superpowers/specs/ остаются активной ссылкой из кода/ТЗ) плюс отдельный список «удалено насовсем» — сверил построчно с фактическим ls legacy/ legacy/docs/ — совпадает, legacy/demo/ пуст и удалён вместе с обоими файлами (не перенос, а чистое удаление, как и требовал пункт объёма).

Проверка зависимых гейтов из issue

  • scripts/check-inputs.mjs: глоб demo/shot_*.mjs в NOT_AN_INPUT остаётся валиден для оставшихся shot_backdrop/room_joins/sun* (NOT_AN_INPUT — это шаблон, не перечень, точечная правка не нужна); benchmark_coordinate_write_barrier.mjs ни в одном месте check-inputs.mjs не упомянут отдельно — только групповые глобы demo/benchmark_*.mjs, так что коду скрипта правка не требовалась, а ложное покрытие снято удалением самого файла; --coverage подтверждает.
  • docs/testing-notes/core-checklist.md:622: маркер benchmark_coordinate_write_barrier убран из строки автопроверки, соседние model-invariants.test/mutation-gate остались — прочитал контекст (строки 605–626), маркер был ложным (скрипт нигде не запускался), убирать — верно.
  • scripts/process-gate.mjs: WARN п.0 (legacy/ вне классов) и WARN п.3 (класс A без ТЗ) воспроизводятся, оба — не ошибки гейта, а зафиксированные автором в hand-off ограничения текущей волны, разобраны ниже как продуктовое суждение, а не находка.

AC — по пунктам чек-листа issue

AC (пункт объёма) Чем доказан Проверено
Скрипты без читателей удалены git grep по каждому имени, ноль ссылок; check-inputs --coverage чист чтением + исполнением гейта
docs/README.ru.md удалён git grep, ноль ссылок вне legacy/README.md (переписан на README.ru.md+USER-GUIDE.ru.md) чтением
Старый legacy/ (снимки/черновики/планы/диагностики) удалён, SUN-CONTRAST.md оставлен ls legacy/docs/ содержит SUN-CONTRAST.md, не содержит удалённых имён; SCOPE.md/STATUS.md/legacy/README.md переписаны чтением
docs/superpowers/specs/ → legacy/, ссылки поправлены git log --follow (rename 100%), 8 обратных ссылок переписаны, включая незаявленные src/open-spans.ts, validation.py чтением
QUALITY-560/ROADMAP/STATUS-FEATURES → legacy/, ссылки поправлены renames подтверждены, 3 обратные ссылки переписаны чтением
demo/README.md — удалить, одна строка в AGENTS.md файл отсутствует, AGENTS.md содержит перечисление golden/performance/guard/stand с их README — все четыре существуют на диске чтением + ls
Зависимые гейты (check-inputs, core-checklist маркер, check-docs, index-тесты) все прогнаны в этом раунде, зелёные исполнением

Ни один AC этой задачи не защитный в смысле §2.7 (нет валидации, гарда, лимита) — это гигиена дерева, а не поведенческая защита; таблица «чем краснеет» неприменима, и это не находка.

Находки

Нет. Продуктовое суждение по одному пункту разобрано ниже, но не поднято до находки.

Разобрано, но не поднято до находки: комментарий-путь в src/ и стоимость отпечатка скриншотов

Автор прямо указал: правка src/open-spans.ts:2 (путь в докблоке) и validation.py:1211 — единственная причина, по которой visualFingerprint устаревает (отпечаток считается по всему src/**), и предложил альтернативу — оставить в коде путь на уже несуществующий docs/superpowers/specs/..., если ревьюер сочтёt, что актуальность пути не стоит этой цены.

Решение: держать код-комментарии, указывающие на реальный путь документа, важнее одноразового docs:accept --identical на кандидате — иначе src/open-spans.ts и validation.py первыми же читателями (следующая задача по open-spans/wall-columns) поведут по мёртвой ссылке. Правка самого текста — путь в комментарии, не идентификатор и не логика; это корректно классифицируется как класс A по правилу «трогает src/**», а не по существу риска. WARN process-gate --issues п.3 (класс A без ТЗ) — ожидаемое трение процесса на не-продуктовой правке двух путей в комментариях, а не признак пропущенного контракта: маршрут issue намеренно без ТЗ-стадии, а сама правка не меняет ни одного видимого или исполняемого поведения (0 символов на изменённых строках подтверждает smoke-select). Оставляю как принятое решение, не как долг.

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

  • Полнота удаления и переноса по каждому из 6 пунктов чек-листа (таблица AC выше).
  • Отсутствие висящих ссылок во всём дереве, включая места, не названные в issue явно (src/open-spans.ts, validation.py) — автор их нашёл и поправил сверх заявленного списка, я перепроверил git grep.
  • История файлов сохранена (rename, не delete+add) для всех перенесённых документов.
  • Трейлеры коммита: Issue: #678, User-Visible: no — корректно, правка не меняет пользовательское поведение; changelog не тронут и не должен быть.
  • Зависимые гейты (check-inputs, ложный маркер в core-checklist.md, check-docs, mutation-registry, process-gate) зелёные/ожидаемые WARN, npm test зелёный целиком (3191/3191).
  • legacy/README.md точно описывает текущее содержимое legacy/ (сверено построчно с ls).

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

  • npx tsc --noEmit, npm run build + трёхкопийная сверка бандла — положился на зелёный Validate на этом же SHA (run 36333078086); дифф не содержит исполняемого кода, только пути в комментариях и docs.
  • npm run golden:verify, npm run invariants, performance-профили, python -m pytest tests_backend — не гонял: ни один не относится к этому диффу (нет изменений рендера, геометрии модели или поведения Python), в AC задачи не назван.
  • Полный набор смоков по матрице — smoke-select дал «НЕОПРЕДЕЛЁННОСТЬ» с 0 затронутыми символами; закрыл чтением диффа, а не прогоном (см. раздел «Решение по smoke-select» выше).
  • Не проверял состояние волн 2/4/5 эпика #674 (документация подсистем, testing-notes/, legacy/ в CLASS_C) — прямо вне объёма этой подзадачи по тексту issue («Не входит»).

Вердикт

Все шесть пунктов объёма выполнены и подтверждены чтением и исполнением гейтов; ссылок на удалённые/перенесённые пути не осталось нигде за пределами legacy/, docs/reviews/ и changelog; зависимые гейты зелёные. Находок нет.


Материал раунда

  • Ветка: issue/678-hygiene-wave1, коммит c081f59a156b — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: febd9dda209dfe9b00ae5a3f571e08fa6b67b46b
    git log --all --format='%H %T' | grep febd9dda209d
    
  • Тело issue: db8486883039b846b021c6e5d7e585295b3175a90e073f63c0078c81519769f9
  • Вердикт конвейера: green · High 0