From 9a1d922b241a7a4298de0accc715ecf73fc4c7c2 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 27 Sep 2026 16:34:40 +0000 Subject: [PATCH] docs: review document for #678 Issue: #678 User-Visible: no --- docs/reviews/CODE-REVIEW-678-r1.md | 202 +++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 docs/reviews/CODE-REVIEW-678-r1.md diff --git a/docs/reviews/CODE-REVIEW-678-r1.md b/docs/reviews/CODE-REVIEW-678-r1.md new file mode 100644 index 00000000..5f297d31 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-678-r1.md @@ -0,0 +1,202 @@ +# 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