Files
2026-09-27 09:29:49 +00:00

16 KiB
Raw Permalink Blame History

CODE-REVIEW-668-r1

Issue: #668 «Английское руководство пользователя отстаёт от русского» Материал раунда: 85cba3d8b4e335b0519f8f089f1c534eabf89e9f (HEAD, origin/dev..HEAD) Коммиты в материале:

  • 85cba3d8 docs: синхронизировать английское руководство (#668) — Issue: #668, User-Visible: no
  • cbc39cea, d24b0f0e — документы SPEC-REVIEW r1/r2 (не относятся к коду)

Класс изменения: C (документация) + B (scripts/user-guide-parity.mjs, test/user-guide-parity.test.mjs, правка scripts/check-docs.mjs). Класс A (src/**, custom_components/**) не тронут.

Скоуп

Задача выделена из #667 (п. 8): синхронизировать смысл и структуру docs/USER-GUIDE.md с docs/USER-GUIDE.ru.md, покрыть перечисленный в Scope список отсутствующих тем, расширить структурный гейт scripts/check-docs.mjs полным профилем H2–H4 и отметкой версии. Не-scope: продукт, UI, i18n, RU-руководство, changelog/release notes — задача этого не трогает (проверено diff'ом, см. ниже). Обслуживает J4/J6 из docs/SCOPE.md (онбординг и поддержание плана англоязычным администратором).

Прошёл spec-review в двух раундах: r1 — жёлтый (Medium в скоупе: AC4 требовал «unit», которого не было в плане автотестов), r2 — зелёный (AC4 переписан явно на два доказательства). Это первый заход код-ревью.

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

Прочитаны в указанном порядке: docs/SCOPE.md, docs/process/REVIEWER.md, AGENTS.md, тело issue #668 и все 7 комментариев (аналитика → ТЗ → SPEC-REVIEW r1 → правка → SPEC-REVIEW r2 → хендофф реализации), docs/USER-GUIDE.ru.md (как источник терминологии), а также канонические SUN.md, VACUUM.md — разделы, которых касается новый EN-текст.

Дельта разбиралась не по дельте предыдущего раунда (это первый код-ревью-заход задачи), а целиком, как и полагается для r1.

Прочитаны построчно: scripts/user-guide-parity.mjs, test/user-guide-parity.test.mjs, диф scripts/check-docs.mjs, весь docs/USER-GUIDE.md (итоговый файл, 1444 строки) и параллельно сверялся с docs/USER-GUIDE.ru.md по позиции разделов.

Автоматически сверен полный профиль заголовков EN/RU (node с логикой, эквивалентной guideHeadingProfile) — 97 заголовков H2–H4 с обеих сторон совпадают позиционно, номера 23 нумерованных H2 идентичны, порядок и уровни идентичны.

Точечно сверены с кодом/каноном спорные фактические утверждения:

  • инвариант замка (docs/SCOPE.md «Lock invariant») — раздел «Lock» не ослабляет формулировку, добавляет явное «a plan tap never toggles a lock»;
  • кнопки диалога закрытия настроек «Continue»/«Discard» — найдены буквально в src/i18n/settings/en.json:50-51 (dialog.discard_confirm: "Discard", dialog.discard_keep: "Continue"), автор заявил это как сверенное — подтверждено;
  • термины «Show hidden on plan», «Select all ({count})», «Hide selected ({count})» — найдены дословно в src/i18n/en.json;
  • разбивка фаз солнца по часам (05:00–08:00 и т. д.), порог 3°, фейд 2 с, переход окружения 1,1 с (1100 мс) — совпадают с docs/SUN.md;
  • калибровка пылесоса 40 см, сглаживание пути 17.5 см, буфер 4000 точек — совпадают с docs/VACUUM.md;
  • брейкпоинт телефонной шапки ≤ 480 px — совпадает с src/houseplan-card.ts:10837, src/header-menu.ts (issue #616);
  • список из 8 скриншотов (images/0N-*.png) в EN и RU расположен в одинаковых по смыслу местах.

Выполнены гейты, не покрытые ссылкой на зелёный Validate этого SHA (Validate подтверждает typecheck/test/build/docs, но AC требует явного исполнения и демонстрации, что защитный тест умеет падать):

  • node --test test/user-guide-parity.test.mjs — 4/4 green (структурный тест на реальных файлах + три отрицательные пробы).
  • Мутационная проверка «тест умеет падать» на реальных файлах (не только на строковых фикстурах теста): временно вырезан заголовок ### Lock из docs/USER-GUIDE.md, тест сразу покраснел (not ok 1), затем рабочая копия восстановлена (cp бэкапа, подтверждено git status --porcelain — пусто).
  • Контрольная проверка, что чисто текстовая правка заголовка того же уровня (без изменения количества/уровня заголовков) тест не ловит — ожидаемо, т.к. AC1/AC6 специфицируют защиту структуры (порядок/уровень), а не текста; содержательное соответствие — предмет AC2 (ревью кода), не автотеста. Разночтения не найдено.
  • node scripts/check-docs.mjs --external — green: «Documentation checks passed (7 files, 12 external links)» → AC5 подтверждён исполнением.
  • node --check на всех трёх изменённых .mjs-файлов — синтаксически чисты.
  • git diff origin/dev...HEAD --stat -- docs/USER-GUIDE.ru.md src/ custom_components/ — пусто → AC4 (неизменность RU/продукта) подтверждён.
  • git diff origin/dev...HEAD --stat -- dist/ custom_components/houseplan/frontend/ demo/golden/baselines/ — пусто → бандл и golden-эталоны в коммит не попали (часть AC7).
  • Версии Current for **v1.78.0-beta.5**. / Актуально для **v1.78.0-beta.5**. — идентичны (AC4).

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

  • npx tsc --noEmit, полный npm test, npm run build со сверкой бандла, npm run gate:small целиком — не перегонялись повторно: Validate на этом же SHA (85cba3d8) уже завершился success (https://github.com/Matysh/houseplan-card/actions/runs/36308972032), и диф не касается src/**/custom_components/**/*.py, так что риска регрессии в собираемости не вижу.
  • Browser-смоки, golden:verify, pytest tests_backend, инварианты модели, performance — не запускал: задача документационная, исполняемое и визуальное поведение продукта не меняет (нет правок src/**), AC не называют эти гейты, а smoke-select.mjs для чисто docs/scripts-диффа предметно не даёт прямых совпадений (диф не касается кода карточки/демо). Явно не прогонял node scripts/smoke-select.mjs --base <base> --head <head> — прошу считать это осознанным пропуском по диффу (только docs/**, scripts/check-docs.mjs, scripts/user-guide-parity.mjs, test/**), а не недосмотром: инструмент разбирает связи изменённого продуктового/демо-кода со смоками, а здесь такого кода нет.
  • Не вычитывал построчно весь текст EN-руководства против RU слово-в-слово (объём ~1444 строк); выборочно проверил структуру целиком (автоматически) и содержание — по разделам с наибольшим риском фактической ошибки (безопасность/замок, солнце, пылесос, диалоги, брейкпоинты, i18n-термины) и по перечню тем из Scope. Чек-лист тем из Scope (мобильная шапка, контекстные подсказки, Merge/Split/Resize/толщина/нулевая толщина, проёмы/режимы/замок/толстые стены, авто-появление маркеров/скрытые/деактивированные, жесты/действия/подложка/активность/отображение/бейджи/иконки/матрица, заливки/наследование/источник света, инструменты подложки/двойной клик/живой текст/мебель/свои изображения, солнце/калибровка/путь пылесоса, оптимизация/сохранения/риск-отмена, памятка безопасности) — сверен по заголовкам и содержанию, все присутствуют по существу (AC2).
  • Не сверял английские термины i18n построчно для каждого упоминания в тексте (только выборочно для контролов, упомянутых в самых чувствительных разделах); полное построчное сопоставление 1444 строк с src/i18n/en.json не выполнялось — это соразмерное для документационной задачи сужение (§8), а не пропуск конкретного риска.
  • npm run inventory не запускал — документ не содержит счётчиков тестов, которые требовалось бы актуализировать.

Находки

Не найдено находок уровня High или Medium. Один пункт снят как Low без действия:

  • Low, снято, не блокирует. В scripts/check-docs.mjs для пары docs/USER-GUIDE.md/docs/USER-GUIDE.ru.md теперь работают два параллельных структурных гейта: старый по 13 именованным docs-section-маркерам (строки ~175-186) и новый полный H2–H4/version профиль (guideParityErrors, строки 188-191). Это было явно предвидено в SPEC-REVIEW-668-r1 (Low, снято ревьюером) с оговоркой «если после кода это разъедется — находка код-ревью». Разъезда не произошло: список из 13 маркеров идентичен и в том же порядке в обоих файлах (проверено grep), а старый гейт остаётся нужен отдельно для пары README.md/README.ru.md, которую новая функция не покрывает — то есть он не read-only дубль, а разделяет ответственность (README vs. полная структура USER-GUIDE). Оставляю как есть, без действия.

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

  • AC1 — H2–H4 профиль и 23 нумерованных раздела совпадают позиционно между EN/RU; unit node --test test/user-guide-parity.test.mjs green.

  • AC2 — все перечисленные в Scope темы присутствуют содержательно и в соответствующих разделах (сверено по чек-листу выше).

  • AC3 — выборочно проверенные названия контролов (Show hidden on plan, Select all/Hide selected, Continue/Discard) дословно совпадают с src/i18n/en.json и src/i18n/settings/en.json; несуществующего поведения в проверенных разделах не встретил.

  • AC4 — отметки версии идентичны (v1.78.0-beta.5); RU и продуктовый код не изменены (diff пуст).

  • AC5 — node scripts/check-docs.mjs --external green.

  • AC6 — защитный тест доказан таблицей:

    AC Чем доказан Чем краснеет
    AC6 (пропуск подраздела) test/user-guide-parity.test.mjs кейс 2 на строковой фикстуре подтверждено также мутацией реального docs/USER-GUIDE.md (удалён ### Lock) — not ok 1, тест-прогон приведён выше
    AC6 (смена уровня) кейс 3 на строковой фикстуре #### Деталь вместо ### Detail красит heading profiles differ
    AC6 (версия) кейс 4 на строковой фикстуре разные версии красят current versions differ
  • AC7 — bundle:clean-состояние подтверждено: dist/**, custom_components/houseplan/frontend/**, demo/golden/baselines/** не в диффе; трейлеры Issue: #668 и User-Visible: no на коммите на месте (докрутка changelog не требуется).

  • Трейлеры и класс изменения соответствуют AGENTS.md: User-Visible: no, оба changelog не тронуты (и не должны были).

  • Число «одна версия — один источник» (§8): версия v1.78.0-beta.5 встречается в EN и RU и берётся из одного и того же места по построению (структурный гейт сравнивает их напрямую); других видимых пользователю чисел, продублированных в этом диффе, не встретил.

Вердикт

Зелёный. AC1–AC7 выполнены и доказаны; единственная Low-находка снята без действия, High/Medium нет.


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

  • Ветка: issue/668-user-guide, коммит 85cba3d8b4e3 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 08ee50612259632359530b8c7a8226782d45f9a0
    git log --all --format='%H %T' | grep 08ee50612259
    
  • Тело issue: aeef91d8b412d0d7dddc4e4c9179746e50a716ed6a80a3078c645cdd925fd5b2
  • Вердикт конвейера: green · High 0