From d35a52a3f13d03eb47d815f07f3b4da2608bdd48 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:57:28 +0000 Subject: [PATCH] docs: review document for #647 Issue: #647 User-Visible: no --- docs/reviews/CODE-REVIEW-647-r1.md | 209 +++++++++++++++++++++++++++++ docs/reviews/INDEX.md | 3 +- 2 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 docs/reviews/CODE-REVIEW-647-r1.md diff --git a/docs/reviews/CODE-REVIEW-647-r1.md b/docs/reviews/CODE-REVIEW-647-r1.md new file mode 100644 index 00000000..e57f7350 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-647-r1.md @@ -0,0 +1,209 @@ +# CODE-REVIEW-647-r1 + +Issue: #647 · Этап: code · Заход: r1 · SHA материала: `f0ba7c5da97418e2b81a257d7b8eda4604e3a41e` + +## Скоуп + +ТЗ (редакция r2, спор закрыт SPEC-REVIEW-647-r2, зелёный) требует: +убрать текстовый счётчик устройств «N устр.» из шапки основной панели; +вынести × закрытия редактора из активной кнопки режима в отдельный +слот постоянного размера 24×24 px сразу после группы кнопок режимов; +слот пустой и инертен (`aria-hidden`, без фокуса) вне редактора; слот +виден на любой ширине, где видны кнопки режимов, включая 721–1100 px, +где раньше скрывался счётчик; ширина шапки и позиции соседних +контролов не меняются при входе/выходе/переключении редакторов; +кликабельная зона × не меньше 24×24 px; настраиваемая метрика +«Количество устройств» сводной панели (#437) не затрагивается. + +Диапазон материала — один коммит `44fed222`/`f0ba7c5d` поверх `dev` +(`27d78801`; `dev` с тех пор получил только неконфликтующий коммит +приёмки golden `632d6a2f`). Правка: `src/houseplan-card.ts` (шапка), +`src/styles/chrome.styles.ts` (слот и ×), `src/styles/dialogs.styles.ts` +(удаление `.count`/медиа-правила), 4 словаря i18n (удаление +`count.devices`), новый смок `demo/smoke_toolbar_stable_width.mjs`, +3 переведённых смока, 6 мутантов, документы (`UX-MODES.md`, +`STYLING-HOOKS.md`, `data-hp-contract.json`), оба changelog, бандл. + +## Как проверялось + +Дешёвые гейты подтверждены зелёным Validate на этом SHA (run +36113808861): `typecheck`, `npm test`, `npm run build`+сверка копий +бандла. Их не перегонял. Сам прогнал то, что Validate не покрывает и +что требует эта задача (визуальный/раскладочный диф): + +| Гейт | Команда | Результат | +|---|---|---| +| Пересборка бандла для смоков | `npm run bundle:sync` | OK, рабочее дерево после сборки совпало с закоммиченным (без диффа) | +| Юниты (перепроверка) | `npm test` | 3070/3070 pass, совпадает с заявленным | +| `check-docs` (режим, которым реально пользуется Validate) | `node scripts/check-docs.mjs --screenshots=warn` | `Documentation checks passed (7 files, 12 external links)`; предупреждение о несвежих скриншотах — ожидаемо, §11.4 (см. «Чего не проверял») | +| `mutation-gate --check` (якоря 6 новых мутантов целы) | `node scripts/mutation-gate.mjs --check` | все 6 `toolbar-*` — `ok` | +| Новый смок | `node demo/smoke_toolbar_stable_width.mjs` | OK, все проверки true на 1400/1000/768/390 px + ru | +| Мутант AC6 (медиа-скрытие слота ≤1100px) | правка `chrome.styles.ts` → сборка → смок → откат | смок красный: `FAILED (9)` — совпадает с заявленным в хендоффе числом | +| Мутант AC2 (слот `display:none` вне редактора) | то же | `FAILED (8)` — совпадает | +| Мутант AC5 (переменная размера слота 13px) | то же | `FAILED (12)` — совпадает | +| 3 переведённых смока | `smoke_editor_tabs`, `smoke_edge_cases`, `smoke_hidden_flag` | все OK | +| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | — | 3 прямых совпадения (`smoke_decor`, `smoke_modes`, `smoke_space_settings`), 41 слабая связь через общие имена `_mode`/`stopPropagation` | +| Прямые совпадения smoke-select | `smoke_decor.mjs`, `smoke_modes.mjs`, `smoke_space_settings.mjs` | все OK (см. «Находки», Low-1 — `smoke_decor` не был назван в перечне гейтов автора) | +| AC8 (сводная панель) | `demo/smoke_summary_panel.mjs` | OK | +| Смежные header-смоки из перечня автора (переисполнены выборочно) | `smoke_kiosk`, `smoke_houseplan_panel`, `smoke_dialog_footer_width` | все OK | +| `count.devices` действительно не используется больше нигде | `grep -rn "count.devices" src/ demo/ scripts/` | пусто — ключ мёртв, удаление безопасно | +| Бюджет ядра | `node --test test/core-file-budget.test.mjs` | 7/7 pass; фактически 12886 строк при потолке 12889 (под потолком, не «ровно на потолке», как написано в хендоффе — расхождение безвредное, не находка) | + +Слабые связи smoke-select (41 файл, общие символы `_mode`/`stopPropagation`) +не прогонялись поштучно: диф ограничен CSS-раскладкой шапки и разметкой +одного элемента, названные символы в них встречаются по всему ядру не +по смежной причине (PDF-экспорт, стены, декор и т.д. не читают шапку). +Прямые совпадения и AC-названные смоки покрывают risk surface этой +задачи. + +## AC · разбор + +Таблица «AC · чем доказан · чем краснеет» в теле issue заполнена по +всем защитным AC (AC1–AC6), включая AC7 (регресс, без мутанта — верно +помечено как таковой) и AC8 (существующие мутанты сводной панели). +Пустых третьих столбцов нет. + +- **AC1 (К1, нет числа).** Прочитано: `` и i18n-ключ + `count.devices` удалены из шапки и всех 4 словарей + (`src/houseplan-card.ts` дифф, `src/i18n/{en,ru,de,fr}.json`). + `grep` подтвердил отсутствие иных чтений ключа. Смок + `w*_noHeaderCount` + `ru_noHeaderCount` — зелёные, лично прогнал. +- **AC2 (К2, ширина шапки стабильна) / AC3 (К3, соседи не прыгают).** + Слот вынесен из кнопки режима как отдельный `` + с фиксированным `width/height: var(--hp-editor-close-size)` = 24px + что вне редактора, что внутри — размер не зависит от содержимого. + Кнопки `.modetab` больше не содержат `×` ни в одном состоянии. + Смок `w*_widthAndTabsStable`/`w*_idleSlotKeepsSize` — зелёные; + мутант «слот схлопывается вне редактора» лично воспроизведён, + краснеет (8 FAILED, совпадает с заявленным). +- **AC4 (К4, × только в редакторе, слот инертен).** `aria-hidden` + выставлен ровно при `this._mode === 'view'`; в этом состоянии CSS + `[aria-hidden='true']{pointer-events:none}` и в дереве нет кнопки + (тернарник `this._mode !== 'view' ? html\`