Files
houseplan-card/docs/reviews/SPEC-REVIEW-668-r1.md
T
2026-09-27 09:18:50 +00:00

18 KiB
Raw Blame History

SPEC-REVIEW-668-r1

Issue: #668 — «EN user guide отстаёт от RU» (перевод/синхронизация docs/USER-GUIDE.md с docs/USER-GUIDE.ru.md, выделено из #667 п.8) Этап: spec (S4-spec-review) · трек: полный (метки P2, docs, S4-spec-review; ни small, ни trivial не выставлены) Заход: r1 · блокирующих циклов израсходовано 0 из 4 Материал: тело issue #668, раздел ## ТЗ (получено gh issue view 668 --json body), плюс 1 комментарий-аналитика («Взял: аналитик», оценка P2/полный трек, «принято предположительно», передача на ревью). Прежних вердиктов на этом issue нет — раздел «Унаследовано из r0» не применим. Роль: ревьюер ТЗ, независимая сессия, без контекста автора.

Скоуп проверки

ТЗ описывает синхронизацию структуры и смысла docs/USER-GUIDE.md (EN) с актуальным docs/USER-GUIDE.ru.md: сейчас EN короче на ~40 заголовков (57 против 98 на dev) и не покрывает самостоятельные пользовательские сценарии — мобильную шапку, Merge/Split/Resize/толщину стен, настройки проёмов/замков, скрытые/деактивированные устройства, живой текст, мебель, свои изображения, солнце/пылесос, оптимизацию плана и памятку безопасности. Задача обслуживает J4 и J6 из docs/SCOPE.md: README и HACS ведут на EN-руководство, поэтому разрыв бьёт по основному пути онбординга англоязычного администратора. Продукт, UI, i18n-файлы и RU-руководство не меняются; User-Visible: no.

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

  1. Прочитаны целиком docs/SCOPE.md, docs/process/REVIEWER.md; по ссылкам конспекта открыт PROCESS.md §2.3–§2.5, §7.1, §7.2, §4, §12.
  2. Прочитано тело issue #668 (проблема + ## ТЗ, все подразделы) и комментарий-аналитика полностью.
  3. Проверены обязательные разделы ТЗ по §7.1 (список, порядок, полнота) — см. таблицу ниже.
  4. Сверена фактическая база ТЗ с текущим dev (рабочая копия, HEAD 2f857a0f):
    • заголовки RU (grep -n '^#' docs/USER-GUIDE.ru.md): 23 нумерованных ##-раздела (1…23) + отдельный ненумерованный H2 «Краткая памятка безопасности» между разделами 22 и 23 — совпадает с формулировкой AC1 дословно.
    • заголовки EN (grep -n '^#' docs/USER-GUIDE.md): те же 23 номера присутствуют, но подавляющее большинство H3/H4 из RU отсутствует (например, RU §5 «Режимы интерфейса» — 4 подраздела, EN §5 «Interface modes» — 1; RU §14 «Редактор подложки» — 5 подразделов, EN §14 «Background editor» — 0) — подтверждает описанный в issue разрыв, тема из Scope реально отсутствует, а не преувеличена.
    • каждая тема из списка «обязательно покрыть» сверена построчно с текущими RU-подзаголовками — расхождений не найдено, список точный.
  5. Прочитан scripts/check-docs.mjs целиком (260 строк) — там уже есть частичный структурный гейт (<!-- docs-section: … -->, строки 172–185), сверяющий порядок/состав маркеров для docs/USER-GUIDE.md/.ru.md по 14 из 23 разделов; см. находку ниже.
  6. Проверено, что ветка issue/668-user-guide существует и её diff с origin/dev пуст (git diff origin/dev...origin/issue/668-user-guide --stat) — код/документ ещё не тронуты, DoR не нарушено преждевременной реализацией.
  7. Проверено существование команд, названных в AC/тест-плане: npm run gate:small (scripts/gate-small.mjs), npm run bundle:clean (bundle-policy.mjs --clean) — есть в package.json; scripts/gate-small.mjs в собственном комментарии подтверждает, что check-docs в строгом режиме в него не входит — согласуется с тем, что AC5 называет его отдельной командой.

Обязательные разделы (§7.1)

Требуется В ТЗ Порядок
Сценарий «Пользовательский сценарий» ✓ 1-й
Что человек увидит до/после «Что человек видит до и после» ✓ 2-й
Проблема «Проблема» (плюс дублирующий обзор до ## ТЗ) ✓ 3-й
Скоуп/не-скоуп «Scope» / «Не-scope» ✓
Контракт поведения / UX «Контракт документации и UX» (объединены — оправдано: для документационной задачи это одно и то же) ✓
Модель данных и миграция «Модель данных и миграция» — «нет» ✓
i18n «i18n» — словари не меняются, EN-термины сверяются с src/i18n/en.json ✓
AC1…ACn с доказательством 7 критериев, у каждого есть метод доказательства ✓ (см. находку)
План автотестов «План автотестов» ✓
Риски «Риски и меры» ✓
Откат «Откат» ✓
Release-артефакты «Release-артефакты» ✓

Все обязательные разделы присутствуют в правильном порядке — пропусков нет.

Находки

Medium — AC4 смешивает две проверки под одним недоопределённым методом доказательства

Где: issue #668, раздел ## ТЗ → ### Acceptance criteria, строка AC4: «EN и RU показывают одинаковую отметку актуальной версии; содержание/порядок RU и продуктовый код задачей не изменены. Доказательство: unit + проверка diff».

В чём проблема: AC4 объединяет два разных утверждения под одним методом:

  1. равенство отметки версии («Current for v1.73.0» / «Актуально для v1.78.0-beta.5» — это обычная строка текста перед ## Содержание, а не заголовок);
  2. отсутствие изменений в RU-файле и продуктовом коде — по сути переформулировка «Не-scope», а не отдельно проверяемое поведение.

Раздел «План автотестов» описывает только один новый unit-тест — структурный паритет заголовков H2–H4 (порядок, уровень, номер). Строка версии заголовком не является и текстом теста нигде не упомянута: ни один описанный тест не читает и не сравнивает эту строку. Слово «unit» в AC4 отсылает к тесту, которого нет ни в плане автотестов, ни в остальном ТЗ. Часть 2 («RU/код не менялись») тестом типа unit в обычном смысле не проверяется — это ревью diff, а не автоматическая проверка данных.

Итог: у AC4 по факту единственный реальный метод доказательства — «проверка diff» (ручная, на код-ревью), а «unit» — либо неточная формулировка, либо пропущенный пункт тест-плана. Как ни трактовать, § 7.1 требует однозначного указания способа доказательства для каждого AC, а здесь оно не совпадает с тест-планом того же ТЗ.

Почему это не оставить как есть: без исправления код-ревьюер имеет ровно тот же документ и не сможет определить, обязан ли он был увидеть автоматический тест на строку версии, — доказательство AC4 останется голословным «unit», который на самом деле никогда не запускался.

Как чинится (в скоупе, без нового issue): один из двух вариантов на выбор автора — (a) убрать «unit» из AC4 и оставить только «проверка diff» для обеих частей; либо (b) явно добавить в «План автотестов» пункт «строка версии сравнивается тем же/отдельным тестом» и указать, что именно он проверяет (совпадение подстроки версии, а не заголовков). Любой из вариантов — правка одной-двух строк текста ТЗ, не требует нового цикла реализации.

Low (снято ревьюером, для протокола) — пересечение с существующим гейтом check-docs.mjs

scripts/check-docs.mjs:172-185 уже сравнивает EN/RU по маркерам <!-- docs-section: … --> (сейчас 14 из 23 разделов промаркированы, порядок и состав должны совпадать — иначе errors.push). Новый AC6-тест (полное сравнение дерева заголовков H2–H4) по объёму перекрывает эту существующую проверку для тех разделов, что уже промаркированы, но ТЗ никак не упоминает существующий механизм и не говорит, должен ли новый тест его заменить, расширить (промаркировать оставшиеся 9 разделов) или существовать параллельно. Не блокирую: это чисто техническое решение о раскладке тестов («агенты решают сами», §7.1), и обе проверки, работая независимо, не противоречат друг другу — риск лишь в дублировании усилий у реализатора. Оставляю как заметку для код-ревью: если после реализации docs-section-маркеры и новый unit-тест утверждают структуру по-разному, это будет находка код-ревью, а не спека.

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

  • Численные утверждения в «Проблеме»/«Аналитике» (57 vs 98 заголовков) и точный список отсутствующих тем сверены с реальным dev и подтверждены построчно — не «догадка, записанная как факт».
  • AC1 «23 нумерованных раздела + краткая памятка безопасности» — сверено с обоими файлами, совпадает дословно на этом SHA.
  • AC6 (защитный AC на дрейф структуры) — метод доказательства явно назван и специфицирует «чем краснеет»: негативная проба на временных фикстурах, пропущенный заголовок / неверный уровень должны явно падать. Это ровно то, что требуется от защитного критерия уже на этапе ТЗ.
  • Contract-раздел закрывает три реалистичных риска до того, как они стали открытыми вопросами: сохранение внешних/внутренних ссылок, обязательность сверки с EN i18n вместо буквального переноса RU-терминов, и явный протокол на случай, если RU расходится с фактическим продуктом (уходит отдельной issue, а не тянется в #668 как факт).
  • Не-scope корректно исключает переписывание RU, дословный перевод и новые скриншоты/changelog — не даёт скоупу расползтись на соседние поверхности.
  • «Модель данных и миграция», i18n, откат, release-артефакты — по существу «нет изменений», что верно для чисто документационной задачи и не притворяется, что где-то есть скрытый эффект.
  • User-Visible: no для документационного изменения соответствует правилу AGENTS.md («документация, которая не меняет продукт»), а не является попыткой спрятать пользовательское изменение от changelog.
  • Ветка создана от актуального dev, диффа с dev нет — код к моменту ревью ТЗ не тронут, DoR не нарушено гонкой вперёд.
  • Открытых продуктовых вопросов к владельцу в ТЗ нет; две единственные технические развилки («принято предположительно») — про формат языка (смысловой, не побуквенный, паритет) и про то, что RU считается базой с проверкой по коду — обе корректно помечены как несущественные для владельца и не эскалированы искусственно.

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

  • Не запускал npm test / npx tsc --noEmit / npm run build / npm run gate:small — на этапе ТЗ кода ещё нет (ветка пуста), эти гейты неприменимы к спек-ревью и относятся к код-ревью.
  • Не проверял node scripts/check-docs.mjs --external в строгом смысле (сетевые ссылки) — не нужно на этом этапе; команда лишь прочитана и подтверждена как существующая с ожидаемым поведением.
  • Не оценивал качество будущего перевода/содержания — его ещё не существует; AC2/AC3 по договорённости ТЗ доказываются на код-ревью чек-листом тем и сверкой с src/i18n/en.json.
  • Не сверял каждый пункт списка тем (мебель, живой текст, замки и т.д.) с каноническими документами подсистем (WALL-THICKNESS.md, SUN.md, TOUCH-SUPPORT.md) построчно — это работа автора реализации и код-ревьюера при написании фактического текста, не предмет проверки формулировки ТЗ.

Вердикт

Вердикт: жёлтый · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 1 → в задаче


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

  • Ветка: issue/668-user-guide, коммит 2f857a0f6b81 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 1ccf52c4df9d7dfc33d3e5cbb63baf142eab53a2
    git log --all --format='%H %T' | grep 1ccf52c4df9d
    
  • Тело issue: 6f92c0a35cb43dd19a414618b4d1f9c48394a8107b95c61bacbe7fbf03d8bef9
  • Вердикт конвейера: yellow · High 0