20 KiB
Код-ревью #459 — заход r2
Настройка «Zigbee links»: подсказка о функции, её ограничениях и легенда цветов, пунктира и стрелок.
Ветка issue/459-zigbee-links-help, HEAD 50bc1d6955dc59ffbd9c10cc31be26418bf1674d, база origin/dev = 7320937f627f18d0f473ca526d68906bea620a27 (после ребейза; #457 уже влился в dev).
Почему разбор ПОЛНЫЙ, а не по дельте
Раунд r2 открыт не находкой ревьюера, а ребейзом: код-ревью r1 (951cbd01) вынесло зелёный вердикт (комментарий 9), но к моменту его публикации dev продвинулся на 10 коммитов и слияние конфликтовало (комментарии 10–11). Автор сделал git rebase origin/dev, запушил 50bc1d69 и вернул S7-code-review (комментарий 12).
Ребейз на ушедший вперёд dev — это один из явно названных случаев, когда разбор остаётся полным независимо от размера дельты (§7.2, §2.9): база изменилась, а не только правка автора. Поэтому я:
- заново прогнал все дешёвые гейты на текущем
HEAD(ниже); - заново подтвердил каждый AC самостоятельно (тестом или чтением);
- отдельно проверил, что именно изменилось при ребейзе и что — нет.
Материал ребейза: что реально изменилось
Побайтовое сравнение продуктовых файлов задачи между 951cbd01 (материал r1) и 50bc1d69 (текущий HEAD):
git diff 951cbd0174bb HEAD -- src/hp-zigbee-topology-settings.ts src/i18n/topology.ts
— пусто. Файл-компонент и резолвер hasTopologyTranslation не изменились ни на символ.
Блок тестов #459 в test/zigbee-topology.test.mjs (от маркера // #459. до конца файла) сравнен построчно — идентичен. Дифф всего файла между теми же SHA показывает изменения (162 строки), но это тесты #457, добавленные в dev после 951cbd01, не пересекающиеся с блоком #459.
Четыре словаря topology/{en,ru,de,fr}.json получили от #457 три новых ключа (route_device_not_on_plan, route_coordinator_not_on_plan, route_other_space) — не пересекаются со строками help/help_aria этой задачи и добавлены во все четыре языка одинаково (паритет AC6 не пострадал — проверено гейтом ниже).
scripts/mutation-gate.mjs: два мутанта topology-help-* этой задачи не менялись; #457 добавил в тот же файл свои четыре мутанта рядом.
Конфликт при ребейзе (по словам автора, комментарий 12) был только в производных/документационных файлах: docs/CHANGELOG*.md (обе записи, #457 и #459, сохранены — проверил чтением, обе на месте в обоих языках), docs/images/screenshots.json (отпечаток источника, пересчитан штатно) и весь закоммиченный бандл (пересобран заново). Я подтвердил это сверкой дифф-статов и содержимого, а не принял на слово.
src/hp-help.ts, hp-zigbee-topology-overlay.ts, device-presentation.ts, logic.ts — не тронуты ни этой задачей, ни ребейзом (git diff origin/dev...HEAD по этим путям пуст). Контракт §5 ТЗ («что не меняется») держится.
Как проверялось
Материал — git log --oneline origin/dev..HEAD (5 коммитов) и git diff origin/dev...HEAD (42 файла: 8 продуктовых/тестовых + генерируемые + документация). Зелёного Validate на 50bc1d69 нет: единственный прогон на этом SHA (33954914944) — failure, один упавший джоб «Смоки в браузере (шард 1 из 3)», лог которого называет ровно FAIL smoke_furniture — то же самое, что автор описал в комментарии 12 и на что завёл отдельный #460 (trivial, S6-in-progress, не про #459). Проверил сам, не на слово: gh run view 33954914944 --log-failed показывает единственную причину падения — smoke_furniture, диф #459 этот файл не трогает.
Поэтому дешёвые гейты прогнал сам, на 50bc1d69:
| Гейт | Результат |
|---|---|
npx tsc --noEmit |
OK, без ошибок |
npm test |
1987 pass / 0 fail / 1 skip (1988 тестов, npm run inventory подтверждает то же число); все 7 тестов #459 (AC1, AC2, AC3, AC3b, AC4, AC5, AC6) — ok |
npm run build |
чисто, git status после сборки пуст — закоммиченный dist byte-for-byte совпадает со свежей сборкой |
npm run bundle:sync |
пересборка + синхронизация custom_components/houseplan/frontend и demo/srv/assets; git status после — чисто, три копии совпадают |
npm run bundle:budget |
initial View 297 496 Б (потолок 298 000±2000, budget 300 000) — совпадает с заявленным автором числом; потолок не поднимался; предупреждение о низком запасе — унаследованный долг #367, не новый |
node scripts/check-docs.mjs |
passed, 7 файлов, 12 внешних ссылок |
node scripts/mutation-gate.mjs --check |
463 якоря (совпадает с заявленным автором «Реестр 457 → 459»), оба мутанта topology-help-* — ok; один посторонний FAIL — backend-гейт tests_backend/test_ha_websocket.py падает из-за отсутствующего локально модуля pytest, окружение не задевает custom_components/**/*.py (не тронут этой задачей) |
node scripts/mutation-gate.mjs --id=topology-help-renders-without-aria |
лично применил мутацию — целевой тест покраснел, дерево вернулось чистым |
node scripts/mutation-gate.mjs --id=topology-help-drops-arrow-legend |
то же — покраснел, поймано |
node demo/smoke_zigbee_topology_hover.mjs (AC8) |
OK, 21/21 проверок true — оверлей, цвета, стрелки, default-off, ленивая загрузка не изменились |
node scripts/smoke-select.mjs --base origin/dev --head HEAD |
НЕОПРЕДЕЛЁННОСТЬ — 2 изменённых файла src/**, 7 символов (DICTIONARIES, Lang, TopologyI18nKey, _help, hasTopologyTranslation, langOf, topologyT), ни один не связан ни с одним из 223 смоков доказуемо. Единственный смок, названный в AC (smoke_zigbee_topology_hover, AC8), прогнан отдельно выше вручную — инструмент про него не обязан знать, так как оверлей сам не менялся |
npm run golden:verify |
153/153 passed, 0 расхождений — включая general-color-popover-desktop-en, единственную сцену, задетую этой задачей (принятый на r1 эталон пережил ребейз без нового расхождения) |
node --test test/single-source-numbers.test.mjs |
3/3 pass (общий гейт «одно число — один источник», диф его не расширяет и не нарушает) |
Не прогонял: python -m pytest tests_backend (диф не трогает custom_components/**/*.py); полные performance-профили (не названы в AC, диф не задевает чувствительные пути); npm run invariants (диф не касается стен/layout/marker.space/open_spans — задача только про словарь и один компонент настройки, геометрия не затронута).
Проверка по AC — заново, не по памяти r1
- AC1 —
render()кладёт${this._t('title')}${this._help()}в.section(строка 187 файла, не изменилась с r1), не в.toggle. Тестподсказка вызывается из блока настройки топологиипроверяет именно эту разметку — прогнан, зелёный. Открытие по наведению/фокусу/клику — поведение самогоhp-help.ts(не тронут). - AC2 —
_help()проверяетhasTopologyTranslation(lang,'help')и...'help_aria'до рендера, иначеnothing. Мутантtopology-help-renders-without-ariaлично применён и пойман (см. таблицу выше). - AC3 / AC3b — тест
подсказка называет все шесть пунктов легендыпроверяет 10 паттернов по нормативной ru-строке (LQI, 40, 180, пунктир, исходящая→координатор, входящие, «без стрелки», «подпись на конце стрелки», «отсутствие стрелки»); отдельный тест ловит оговорку о приближённости (дерево маршрут,не путь пакета). Прогнаны — зелёные. Мутантtopology-help-drops-arrow-legendлично применён и пойман. - AC4 — тест импортирует
lqiColorиз собранногоtest-build/logic.jsи берётhue(40)=0,hue(180)=120из функции, затем ищет те же числа в тексте — границы не захардкожены в тесте отдельной константой. Прогнан — зелёный. - AC5 — для всех четырёх словарей: нет
\nвhelp, обе строки (help,help_aria) непустые. Прогнан — зелёный. - AC6 — гейт паритета ключей и плейсхолдеров четырёх словарей против английского; проверил, что три новых ключа
route_*от#457не сломали паритет (все четыре языка получили одинаковый набор). Прогнан — зелёный. - AC7 —
core-file-budgetне задет (файл не входит в список ядровых),bundle:budget— 297 496 Б, на 2 Б меньшеdevпо словам автора; лично прогнал и подтвердил число, потолок не поднимался. - AC8 —
smoke_zigbee_topology_hover.mjsлично прогнан, все проверкиtrue.
Утверждённый нормативный текст §4.1 (654 знака ru) сверен посимвольно (len(help)==654 в Python) — совпадает дословно с текстом, зафиксированным владельцем в теле issue. Переводы en/de/fr прочитаны целиком: каждый несёт все пункты легенды и оговорку о приближённости без потерь смысла.
Закрытие раунда r1
Раунд r1 (комментарий 9, документ docs/reviews/CODE-REVIEW-459-r1.md, SHA 951cbd01) вынес зелёный вердикт без Medium — переоткрытия по существу не было, только вынужденный технический возврат из-за конфликта слияния (комментарий 11). Формальных «находок к исправлению» из r1 нет; ниже — судьба трёх Low, отмеченных там:
| Находка r1 (Low) | Статус в r2 |
|---|---|
| Отчёт реализации называл «шесть новых тестов», в дифе — семь | не тронуто и не требовалось: чисто редакторская неточность отчёта, к коду отношения не имеет |
Новый _help() не проставляет data-help-key (в отличие от houseplan-editor-runtime.ts:1232, houseplan-onboarding-runtime.ts:58) |
не исправлено, по-прежнему так — проверил чтением всех трёх мест повторно; не блокирует ни один AC, поведение кружка не страдает |
Гейт паритета AC6 лёг в test/zigbee-topology.test.mjs, а не в test/i18n.test.mjs, как называли «Затронутые файлы» ТЗ |
не тронуто — организационное расхождение, гейт работает (перепроверил падением не требовалось: тест сам содержит зелёную/фейлящую пару сценариев) |
Ни одна не блокирует и в r2 не эскалируется — все три и раньше были приняты без правки с запиской, а код с тех пор не менялся.
Унаследовано из r1 без повторного построчного разбора
Ниже — то, что я не выводил заново с нуля, а принял на основании доказанной побайтовой идентичности кода (раздел «Материал ребейза» выше) и полного документа docs/reviews/CODE-REVIEW-459-r1.md (SHA 951cbd01):
- построчная сверка контракта §1–§5 ТЗ с кодом (импорт
hp-help, локальный_help(), namespacetopologyT, отказ от переиспользования редакторского_help()) — код не менялся, вывод r1 в силе; - перевод легенды на en/de/fr сверен вручную построчно в r1; я самостоятельно перечитал все три файла в этом раунде (раздел AC выше) и подтверждаю тот же вывод независимо, а не только по ссылке;
- откат (§ ТЗ «Откат») — не проверялся заново, код рендера и словарей не менялся, ревертить по-прежнему нечего кроме вызова хелпера.
Каждый AC при этом я подтвердил заново сам (гейты и тесты выше), а не принял на слово — «унаследовано» здесь относится только к смысловому построчному разбору контракта, не к проверяемости.
Что проверено и корректно
- Все восемь AC доказаны прогонами на текущем
HEAD, не на памяти о r1. - Оба мутанта реально ловятся — применил лично, не поверил реестру.
golden:verify— 153/153, включая сцену, задетую этой задачей и ребейзом.- Ребейз не потерял ни одной записи
CHANGELOG, не сломал паритет словарей, не задел оверлей/hp-help/logic.ts. - Единственный красный CI на
50bc1d69— независимо подтверждённый предсуществующий флейкsmoke_furniture(#460), не имеющий отношения к#459и не тронутый этим диффом. - Трейлеры коммитов:
Issue: #459на всех пяти,User-Visible: yesвfeat-коммите сопровождается правкой обоих changelog в том же коммите;Release:/Baseline-Reviewed:на коммитах, трогающихdemo/golden/baselines/**.
Чего не проверял и почему
python -m pytest tests_backend—custom_components/**/*.pyв дифе нет.- Полные performance-профили — не названы в AC, диф не задевает чувствительные к перфу пути (текст словаря и один компонент настройки).
npm run invariants— диф не касается стен,layout,marker.space,open_spansили иных геометрических ссылок.- Остальные 222 браузерных смока сверх названного в AC8 — инструмент отбора вернул НЕОПРЕДЕЛЁННОСТЬ, тематически ни один не относится к namespace-компоненту без побочных эффектов на других поверхностях.
Итог
Продуктовый код и тесты этой задачи не изменились ни на символ со времени зелёного r1 — ребейз задел только производные файлы и документацию, и это подтверждено сравнением, а не заявлено. Полный самостоятельный прогон гейтов на текущем HEAD (50bc1d69) — тесты, сборка, бюджет, документация, мутанты, golden, целевой смок — зелёный. Восемь AC доказаны заново. Три Low из r1 остаются в силе, без блокировки. Красный CI на этом SHA — подтверждённо посторонний флейк, заведённый отдельным issue.
Вердикт: зелёный.
Материал раунда
- Ветка:
issue/459-zigbee-links-help, HEAD50bc1d6955dc59ffbd9c10cc31be26418bf1674d. - База:
origin/dev=7320937f627f18d0f473ca526d68906bea620a27. - Предыдущий материал (r1, зелёный):
951cbd0174bbbc4cb069cf5f8832da8cc49f2ace, документdocs/reviews/CODE-REVIEW-459-r1.md. - Побайтовое сравнение продуктовых файлов
951cbd01→50bc1d69:src/hp-zigbee-topology-settings.ts,src/i18n/topology.ts— пусто (идентичны); блок#459вtest/zigbee-topology.test.mjs— идентичен построчно.
Материал раунда
- Ветка:
issue/459-zigbee-links-help, коммит50bc1d6955dc— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
4cb9c23fd0ca54ef2841de18ac1b353fc54c5c3cgit log --all --format='%H %T' | grep 4cb9c23fd0ca