mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
103 lines
18 KiB
Markdown
103 lines
18 KiB
Markdown
# SPEC-REVIEW-668-r1
|
||
|
||
**Issue:** [#668](https://github.com/Matysh/houseplan-card/issues/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 → в задаче
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/668-user-guide`, коммит `2f857a0f6b81` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||
- Дерево материала: `1ccf52c4df9d7dfc33d3e5cbb63baf142eab53a2`
|
||
```
|
||
git log --all --format='%H %T' | grep 1ccf52c4df9d
|
||
```
|
||
- Тело issue: `6f92c0a35cb43dd19a414618b4d1f9c48394a8107b95c61bacbe7fbf03d8bef9`
|
||
- Вердикт конвейера: `yellow` · High 0
|