# CODE-REVIEW-86-r5 - **Issue:** #86 — Тексты подсказок к настройкам: очередь и правила (Party 1) - **Заход:** r5 · блокирующих циклов израсходовано 3 из 4 - **Материал:** `git log --oneline origin/dev..HEAD`, `git diff origin/dev...HEAD` - **HEAD:** `fa146fb1` · **origin/dev:** `2b0ac0c0` (включает #44, merge-base == origin/dev) - **Спецификация:** `docs/specs/086-settings-help-content-party1.md` (актуализирована 2026-08-30, коммит `20883c31` до ребейза) ## Почему разбор снова полный, а не по дельте После зелёного вердикта r4 (на `7408f8af`) `dev` продвинулся на 5 коммитов — слияние #44 «discovery filters become visible, explained and previewable» (`d14cf769..2b0ac0c0`, включая собственный цикл ревью #44 с фиксами M1‑M2). Ветка `issue/86-settings-help-party1` перебазирована на этот новый `dev`. Все SHA из документов r1–r4 (`7408f8af`, `96bd3e3e`, `18ab3779` и т.д.) более не существуют в истории (`git cat-file -t` → `fatal: Not a valid object name` для каждого) — это не косметика, а другое дерево (PROCESS.md §2.10/§7.2). Это ровно случай, для которого прямо предписан полный разбор. Важное обстоятельство: `git merge-base HEAD origin/dev == origin/dev`, то есть диапазон `origin/dev...HEAD` — это **весь** вклад ветки #86 целиком (в dev уже влит #44, в ветке сверх него — только #86). Это даёт полный и единственный источник правды для разбора, без необходимости реконструировать историю по кускам. Дополнительная проверка ребейза: #44 и #86 модифицируют одни и те же файлы (`src/houseplan-editor-runtime.ts`, `src/i18n/{en,ru,de,fr}.json`, `src/styles/dialogs.styles.ts`, `docs/images/screenshots.json`, `docs/CHANGELOG*.md`). Список конфликтов, зафиксированный в issue перед финальным ребейзом, содержал только сгенерированные бандлы и changelog — никаких конфликтов в `src/**`/`i18n/**`. Прочитал итоговый diff этих файлов: изменения #86 (add `_help(...)` triggers, новые `.help`/`.help.aria` ключи) корректно легли поверх кода #44 (`_renderDiscoveryFilters`, новые i18n-ключи дискавери) без потерь с обеих сторон — рекомбинация чистая. ## Что проверялось и как ### Гейты, прогнанные лично на `fa146fb1` | Гейт | Результат | | --- | --- | | `npx tsc --noEmit` | зелёный, без ошибок | | `npm test` | 1615 тестов, 1614 pass, 0 fail, 1 skip (тот же приватный `#281`-скип, что и в r1–r4) | | `npm run build` + `git status --porcelain` после build | 0 diff — закоммиченный `dist/` побайтово совпадает со свежей сборкой | | `node scripts/bundle-sync.mjs` | 0 diff в `custom_components/houseplan/frontend` и `demo/srv/assets` — три канонические копии синхронны | | `node scripts/bundle-budget.mjs` | initial View 280 678 B / 300 000 B бюджета, headroom 19 322 B — в норме | | `node scripts/no-new-any.mjs` | «Новых any нет» (119 добавленных строк в 3 файлах) | | `node scripts/check-docs.mjs --external` | «Documentation checks passed (7 files, 10 external links)» — фингерпринт скриншотов не протух, sha256 каждого PNG совпадает с манифестом (тот самый канал, что в r1 поймал H1 — здесь чисто) | | `node scripts/mutation-gate.mjs --id=settings-help-party1-placement-removed` | мутант поймал `test/i18n.test.mjs` — «покраснел, как обязан» | | `npm run golden:verify` | 147/147 `passed`, 0 different/missing (полный лог сохранён) | | 13/13 smoke «прямого совпадения» из `smoke-select.mjs` | все `OK`, все party1-флаги в `smoke_help_affordance.mjs` — `true` | Почему прогнал сам, а не принял «Validate зелёный» на веру: разобрался в устройстве последнего прогона (run 33310161342, `headSha=fa146fb1`) — job «Классификация изменённых файлов» сравнивал только `04da7eb1..fa146fb1` (3 файла `docs/images/**`), потому что предыдущий push (`04da7eb1`, реальный ребилд бандла) получил **cancelled** прогон (run 33310044199, перекрыт следующим push тремя минутами позже), а не зелёный. В итоге `frontend`, `golden`, `smoke`, `backend` в финальном прогоне — не «переиспользованы по хешу» (шаг reuse-маркеров явно вернул `Cache not found` по всем четырём), а **skipped** классификацией. То есть ни один реальный CI-прогон после финального ребейза не исполнил тяжёлые гейты по-настоящему. Заявление «Validate на `fa146fb1` зелёный ⇒ дешёвые гейты подтверждены» из вводных раунда не подтвердилось при проверке — пришлось прогонять самому. Отдельно завёл **#387** (infra, P2, вне скоупа #86) с точным описанием механизма и предложением чинки; на вердикт #86 не влияет, так как содержимое проверено мной исполнением напрямую и оказалось корректным. ### Не прогонял и почему - **18 «слабых связей» смоков** (`smoke-select.mjs`, общий символ `_config`) — контент партии 1 не менялся с r3, риск для этих смоков уже признавался низким в r2/r3/r4; не нашёл оснований пересматривать. - **`python -m pytest tests_backend`** — diff не касается ни одного `.py` файла (`git diff origin/dev...HEAD --stat` не содержит `custom_components/**/*.py`). - **`npm run invariants`** / модельные инварианты — diff не трогает геометрию, `layout`, `marker.space`, `open_spans`, толщину стен; ТЗ §11 прямо фиксирует «Config, backend, layout и storage не меняются», подтверждено чтением diff (только шаблоны рендера и i18n). - **`performance_smoke`** — ни ТЗ, ни diff не касаются путей, чувствительных к перфу (чисто DOM/CSS-триггеры уже существующего `hp-help` из #68). - Полный `demo/smoke_*.mjs` набор (206 файлов) — не запускал целиком; `smoke-select.mjs` даёт 13 прямых совпадений (все прогнаны) и не находит оснований для более широкого прогона. ### Одно число — один источник Diff не добавляет и не меняет ни одной пользовательской величины (числа, единицы, отображаемые значения) — только текстовые подсказки и разметку (`id=`/`