diff --git a/docs/reviews/CODE-REVIEW-677-r1.md b/docs/reviews/CODE-REVIEW-677-r1.md new file mode 100644 index 00000000..769a8166 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-677-r1.md @@ -0,0 +1,139 @@ +# CODE-REVIEW-677-r1 + +**Issue:** #677 «Гигиена, волна 0 — секреты и приватная инфраструктура вон из публичных доков (эпик #674)» +**Материал раунда:** `94712afb55249531cbbe835d322754a268a4920d` (рабочая копия проверена на этом SHA, `git diff` пуст, `git status` чист) +**Заход:** r1 · блокирующих циклов израсходовано 0 из 4 +**Вердикт:** зелёный + +> Ниже намеренно не цитируются значения удалённых секретов (пароль стенда, +> имя SSH-ключа, хост/порт/IP домашнего инстанса и стенда) — по требованию +> самого ТЗ («в комментариях задачи и ревью значения не цитировать»). +> Проверка велась через `git grep` по этим токенам с подсчётом совпадений, +> без вывода строк с находками. + +## Скоуп + +Единственный коммит `94712afb`, класс C (документация, `docs/**`), трейлеры +`Issue: #677` / `User-Visible: no` на месте (доки не описывают продуктовое +поведение — верно). Три файла, +8/−60: + +- `docs/TESTING-DEMO.md:4` — учётные данные basic-auth dev-стенда убраны из + строки про `dev.houseplan.tech`. +- `docs/STATUS.md` — из строки `GitHub` убран хвост про SSH-ключ и место + хранения PAT; строка `Home instance` удалена целиком; из строки + `Demo stand` убраны хост-с-ключом, IP и ссылка на заметку памяти. +- `docs/DEVELOPMENT.md` — разделы «Deployment to the dacha» (SSH, порт, путь + конфигурации, curl-проверка) и «Production objects in HA» (имена + дашборда/сущностей домашнего инстанса) удалены; вместо первого — три + строки «Deployment» про самообновление через HACS. Дополнительно снят + раздел «Environment (cowork sessions)» — не в исходном чек-листе ТЗ, см. + находку L-1. + +Это ровно объём эпика #674, волна 0 (без переписывания git-истории — решение +эпика, зафиксированное отдельно и в этой задаче не пересматривается). + +## Как проверялось + +| Гейт | Статус | Как | +|---|---|---| +| `typecheck`, `npm test`, `npm run build` + `bundle-policy --verify` | не перегонялись повторно | Validate зелёный на этом же SHA `94712afb` (run 36333295924, ссылка дана в задаче ревью) — доверяю по правилу «дешёвые гейты уже подтверждены» | +| `node scripts/check-docs.mjs --external --screenshots=warn` | прогнал сам | `Documentation checks passed (7 files, 12 external links)`, exit 0; diff не трогает `src/**`, так что этот гейт формально не обязателен по общему правилу REVIEWER.md, но назван самим ТЗ как способ доказательства — прогнал | +| Отсутствие секретов в дереве (пароль стенда, имя SSH-ключа `ha_jb`, IP стенда, домен домашнего инстанса, `.git-credentials`) | прогнал сам | `git grep -c` по каждому токену (кроме `docs/reviews/`, `legacy/`) — везде 0 совпадений, кроме генерического порта `22222`, все 5 совпадений которого — тестовые фикстуры (`test/logic.test.mjs`, `test/space-reference-repair.test.mjs`, unproven-diff фикстура), не относящиеся к SSH | +| Целостность ссылок/якорей на удалённые разделы | прогнал сам | `git grep` по заголовкам «Deployment to the dacha», «Production objects in HA», «Environment (cowork sessions)», «Home instance» — нигде в дереве, кроме самого `DEVELOPMENT.md` до правки, никто не ссылался; `check-docs.mjs` (`PUBLIC_DOCS`) эти три файла не покрывает вовсе (список — `README*`, `USER-GUIDE*`, `TOUCH-SUPPORT.md`, `DECOR-EDITOR.md`, `VACUUM.md`), поэтому доказательство целиком ручное, как и требует зависимость из ТЗ | +| `test/release-gate.test.mjs:139-146` (раздел Release в `DEVELOPMENT.md` не задет) | прогнал сам (чтением) | раздел `## Release` остался на месте (`docs/DEVELOPMENT.md:517`), содержит все четыре фразы, которые матчит тест; diff их не касается | +| Смоки, golden, pytest, invariants, performance | не прогонялись | diff не трогает ни `src/**`, ни `custom_components/**/*.py`, ни геометрию/её ссылки; ни один не назван в AC — неприменимо, а не пропущено | + +## Проверка AC (по чтению, не исполнением — доменные доки, автотестов на прозу нет) + +| AC | Чем доказан | Результат | +|---|---|---| +| `TESTING-DEMO.md:4` без пароля стенда | чтение файла + `git grep` по паролю (0 совпадений в дереве) | выполнено | +| `STATUS.md:45/49/55` без ключа/PAT/хоста/порта/пути/IP | чтение файла + `git grep` по каждому токену (0 совпадений) | выполнено | +| `DEVELOPMENT.md` без разделов «Deployment to the dacha» / «Production objects» | чтение файла — оба раздела отсутствуют, реальные позиции (`:766-772` для второго, а не заявленные в ТЗ `:736-741`) сам автор сверил и назвал расхождение — файл сдвинулся, не ошибка | выполнено | +| Ссылки/якоря на другие документы не сломаны | `git grep` по заголовкам удалённых разделов вне `DEVELOPMENT.md` — пусто; `check-docs.mjs` зелёный | выполнено | +| Раздел Release не задет | чтение `DEVELOPMENT.md:517-533`, совпадает с regex из `release-gate.test.mjs` | выполнено | +| История git не переписывается | коммит только добавляет новый коммит поверх `dev`, `git log` линейный | выполнено | + +Защитных AC (валидация/гард/лимит/отказ/инвариант) в этой задаче нет — это +документная чистка, а не код с рантайм-поведением, поэтому таблица +«AC · чем доказан · чем краснеет» не требуется. + +## Находки + +### L-1 (Low, принято ревьюером с записью) — раздел «Environment (cowork sessions)» снят сверх заявленного объёма ТЗ + +**Файл:** `docs/DEVELOPMENT.md` (был `:20-40` в родителе коммита) +**Что увидел:** ТЗ issue #677 в разделе «Не входит» прямо пишет: «Остальная +чистка `STATUS.md`/`DEVELOPMENT.md` — волна 3» (issue #680). Раздел +«Environment (cowork sessions)» не значился ни в одном из трёх пунктов +объёма ТЗ, но был удалён этим же коммитом. `PROCESS.md` §12 явно запрещает +«попутные правки „раз уж я здесь“». +**Почему не блокирую:** мера смягчения покрывает риск целиком — +1. содержимое раздела само по себе было секретом того же класса, что и + цель эпика (имя SSH-ключа и место хранения PAT в исходном тексте, тот же + класс, что STATUS.md/TESTING-DEMO.md) — то есть это не постороннее + расширение скоупа, а найденный по пути **пропуск в самом ТЗ волны 0**; +2. автор явно назвал это в комментарии «Сделано» отдельной строкой со + словами «сверх объёма, из волны 3 (#680)»; +3. issue #680 (следующая волна того же эпика) уже правлен: пункт + «Environment (cowork)» там вычеркнут с явной ссылкой `— снят волной 0 + (#677, )` — дублирования работы не будет, эпик согласован. + +Итог: реальный вред отсутствует, раскрытие полное, смежный issue +синхронизирован. Понижаю до Low и снимаю без возврата автору; фиксирую как +прецедент для будущих ревью этого эпика — если подобное повторится в +следующих волнах без такой же явной сверки, это уже Medium. + +## Что проверено и корректно + +- Все три пункта объёма ТЗ (`TESTING-DEMO.md:4`, `STATUS.md:45/49/55`, + `DEVELOPMENT.md` deployment/production-objects) выполнены полностью, + секреты в дереве отсутствуют (кроме git-истории, что явно вне скоупа + эпика). +- Новый раздел «Deployment» в `DEVELOPMENT.md` не противоречит `PROCESS.md` + §12 (не описывает ручное копирование) и остаётся информативным + (HACS-по-тегу, авто-деплой закрытого стенда). +- Формулировка `TESTING-DEMO.md:4` не потеряла смысл строки (закрытый + стенд, доступ у владельца, тот же demo/demo дальше) — читатель документа + не теряет ориентир, что дев-стенд существует и защищён. +- Прозе `STATUS.md` после правок читается связно, без оборванных + предложений или висящих ссылок. +- Единственный оставшийся в дереве путь `/mnt/data/supervisor/homeassistant` + (`demo/stand/install.sh:4`) — стандартный путь конфигурации HAOS в + usage-примере скрипта, а не адрес доступа к чьему-то инстансу; не секрет. +- Трейлеры коммита корректны: `Issue: #677`, `User-Visible: no` (не + продуктовое изменение), класс C. +- `git diff origin/dev...HEAD` = ровно этот один коммит, ничего лишнего в + диапазоне материала. + +## Чего не проверял + +- Полные `typecheck` / `npm test` / `npm run build` / `bundle:release` + + сверку трёх копий бандла — не перегонял, они уже зелёные на этом же SHA + (Validate run 36333295924, ссылка в описании раунда); diff их не + затрагивает (только `docs/**`). +- Браузерные смоки, `golden:verify`, `pytest tests_backend`, + `npm run invariants` — не прогонял: diff не касается `src/**`, + `custom_components/**/*.py` ни геометрии; ни один из них не назван в AC + задачи. `smoke-select.mjs` не запускал по той же причине (нет изменений в + поверхностях, которые он матчит). +- Смену пароля basic-auth на dev-стенде и подтверждение владельца — это вне + код-ревью по определению ТЗ (отдельное подтверждение в issue, статус + `blocked` до него); не блокирует зелёный вердикт кода. +- Полный текст `docs/reviews/` и `legacy/` на предмет тех же секретов — вне + скоупа (git-историю эпик решил не переписывать; `docs/reviews/**` — + архив прошлых ревью, туда эта задача не лезет). + +--- + + + +## Материал раунда + +- Ветка: `issue/677-hygiene-wave0`, коммит `94712afb5524` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `3cc1fd568d38e2e4759e13c02ac7be9c02c2ced5` + ``` + git log --all --format='%H %T' | grep 3cc1fd568d38 + ``` +- Тело issue: `dc094a81871219380544d0cd43d49c2458165bc6b9f16bebc265c1751d85d4ba` +- Вердикт конвейера: `green` · High 0