diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index 6c93ced5..7669a1b9 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,6 +1,6 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 341, issue: 173. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 342, issue: 174. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| @@ -10,6 +10,7 @@ | бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — | | #813 | [SPEC-REVIEW-813-r1.md](SPEC-REVIEW-813-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #812 | [SPEC-REVIEW-812-r1.md](SPEC-REVIEW-812-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | Нет — ни в скоупе, ни вне скоупа | `test/performance-budget.test.mjs` | +| #811 | [SPEC-REVIEW-811-r1.md](SPEC-REVIEW-811-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #810 | [CODE-REVIEW-810-r1.md](CODE-REVIEW-810-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #809 | [CODE-REVIEW-809-r1.md](CODE-REVIEW-809-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #808 | [CODE-REVIEW-808-r1.md](CODE-REVIEW-808-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-811-r1.md b/docs/reviews/SPEC-REVIEW-811-r1.md new file mode 100644 index 00000000..ee584a17 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-811-r1.md @@ -0,0 +1,184 @@ +# SPEC-REVIEW-811-r1 + +- Issue: https://github.com/Matysh/houseplan-card/issues/811 +- Материал: тело issue #811, раздел `## ТЗ` (комментарии 0–3, автор — Matysh/агент + Codex, сессия findings-2026-10-07). Трек `track:ask`, этап `S4-spec-review`, + заход r1, блокирующих циклов израсходовано 0/4. +- Ревьюер: Claude (роль «ревьюер ТЗ»), независимая сессия, устных пояснений + автора не читал — только тело issue и его комментарии. +- Сверка технических утверждений ТЗ — с рабочей копией на `dev` @ `a106b717` + (тем же SHA, что назван автором как база анализа). + +## Скоуп + +ТЗ объединяет девять находок (F2–F6, F20, F22, F29, F30) из общего разбора +findings-2026-10-06/07, относящихся к конвейеру ревью и производным данным: +расчёт git-диапазона для Validate после ребейза/force-push (F2), устойчивость +парсера вердикта/счётчиков/находок `reviews-index.mjs` к пересказу чужого +раунда (F3/F4/F20), свежесть генератора индекса относительно слитого дерева +(F22), рассинхронизация числового инвентаря browser-guard между CLI и unit +(F29), предел доказательств по артефакту F30 (обновление отпечатков без PNG, +уже исправленное в beta.7). Продуктовый код, HA, UI, схема плана — вне скоупа; +это явно заявлено и выдержано по всему тексту ТЗ. + +## Как проверялось + +Это ревью ТЗ (`PROCESS.md` §2.4), а не код-ревью: реализации ещё нет, прогонять +`gate:small`/`typecheck`/`npm test`/`npm run build` не для чего — АС рассчитаны +на будущий код. Вместо этого я проверил, что технические утверждения +«Проблема и доказательства» не являются догадками, записанными как факты +(§7.1), прочитав код и git-историю, на которые ссылается ТЗ: + +- **F2** (`resolveValidationRange`/`clampIssueBranchRange`): прочитан + `scripts/validate-commit-provenance.mjs:162-180` и + `scripts/process-gate.mjs:861-917`. Подтверждено: `resolveValidationRange` + всегда возвращает диапазон вида `merge-base(comparison, head)..head`, поэтому + `base` в этом диапазоне по построению уже является предком `head`; гвард + `clampIssueBranchRange`'а `if (isAncestor(base, head)) return range` в этой + композиции всегда истинен и сужения не происходит. Воспроизводимо по коду, + не по пересказу. +- **F3** (`validate-red` читается как красный): прочитаны регэкспы + `scripts/reviews-index.mjs:35-63`. У `VERDICT_LINE_RE`/`COLOUR_RE` есть + отрицательный lookahead после цветового слова (`(?![а-яёa-z])`), но нет + запрета на символ ПЕРЕД словом — подстрока `-red` в `validate-red` матчится + как «red» так же, как отдельное слово. Подтверждено по тексту регэкспа. +- **F3/F4/F20 пример `403-r2`/`662-r3`**: оба файла существуют + (`legacy/reviews/v1.70.0/SPEC-REVIEW-403-r2.md`, + `docs/reviews/SPEC-REVIEW-662-r3.md`). Прочитан `parseCounts` + (`scripts/reviews-index.mjs:315-339`): собственный текст `403-r2` даёt + вердикт «зелёный» без числа High рядом, но ownText-фильтрация блока «## 1. + Вердикт r1 и SHA» верна (пересказ исключён), однако последний fallback + (`text.matchAll(/High:\s*(\d+)/g)` на строках 323-327) сканирует + **нефильтрованный** `text`, а не `ownText`, и единственное во всём файле + число `High: 1` стоит именно в исключённом пересказе r1 — отсюда + выдаваемое «High 1» вместо собственного 0. Это реальный путь в текущем + коде, а не гипотетический. Для `662-r3` аналогично прочитан файл: заголовки + `### Находка Medium-1`/`### Находка Medium-2` и собственная сводка + `High: 0 · Medium: 2` присутствуют буквально. +- **F29** (инвентарь browser-guard): прочитаны `mutation-registry-check.mjs` + (членство ID: `missingReasons`/`staleReasons`, множества, не числовая + таблица) и `test/mutation-gate.test.mjs:212` (`assertBrowserGuardInventory` — + отдельная копия проверки для unit). Подтверждено: это действительно два + независимых места расчёта с разной формой данных, способные разойтись при + ребейзе. +- **F30** (отпечатки beta.6 без PNG): `git show --stat ab9dc1fb` (добавление + настройки батареи) и `e49083d6` (кандидат beta.6, трейлеры `Issue: #806`, + `Issue: #807`, `Release: v1.80.0-beta.6`) подтверждены по git-истории; + `e49083d6` не содержит изменений `*.png` в списке файлов — отпечаток + действительно обновлён без перегенерации PNG, что и описывает находка. + Исправление `150b5a16` — реальный коммит в `git log` текущей ветки. +- Проверено существование всех файлов и тестов, названных в скоупе и плане + автотестов: `scripts/{process-gate,reviews-index,rebase-generated, + merge-candidate,mutation-gate,mutation-registry-check, + mutation-browser-policy,validate-commit-provenance}.mjs`, + `test/{process-gate,commit-provenance,reviews-index,rebase-generated, + merge-candidate,mutation-gate,docs-accept,png-identical}.test.mjs` — ни + одного придуманного пути. + +Таким образом «Проблема и доказательства» — не пересказ, а проверяемые по +коду утверждения; ни одно не потребовало отдельного вопроса автору. + +### Чего не проверял + +- Не прогонял `npm run gate:small`, `npx tsc --noEmit`, `npm test`, + `npm run build` — на этапе S4-spec-review их не для чего прогонять, кода + ещё нет (`PROCESS.md` §2.3/§2.4); Validate на `a106b717` зелёный и + подтверждает только текущее состояние `dev`, а не будущую реализацию. +- Не проверял поведение будущего безопасного механизма запуска генератора + индекса из слитого дерева при доверенном dev-снимке остальных управляющих + скриптов (AC5) — способ явно оставлен «принято предположительно, поменять + свободно» и будет предметом код-ревью реализации, а не этого ревью. +- Не проверял golden/скриншоты, HA-harness, touch, perf — задача их не + затрагивает по собственному заявлению ТЗ (раздел «UX, данные, миграция и + i18n»), и это согласуется с кодом/скоупом файлов. +- Не выполнял смоки/инварианты геометрии — не применимо, задача не трогает + геометрию плана или UI. + +## Проверка по чек-листу ТЗ (§7.1) и DoR (§2.5) + +Обязательные разделы присутствуют и в порядке: Сценарий → Что человек увидит +до и после → Проблема и доказательства → Скоуп и не-скоуп → Контракт поведения +→ UX/данные/миграция/i18n → Критерии приёмки AC1–AC8 → План автотестов → +Риски/откат/release-артефакты → «Принято предположительно». + +- **AC1–AC8**: каждый пронумерован, у каждого назван способ доказательства + (unit/integration/CLI/audit) и явно описан отрицательный случай + («снимает именно границу/фильтрацию», «не наследует High 1», «отвергает…», + «возвращает список путей и исходное состояние», «не обновляет fingerprint») + — это и есть требуемая для защитных AC запись «чем краснеет» на уровне ТЗ; + таблица с мутантом/отрицательным случаем — дело код-ревью реализации. +- **Файлы и модули**: перечислены поимённо в «Скоуп и не-скоуп». +- **i18n**: «Новых ключей i18n нет» — явный ответ. +- **Миграция/compatibility**: «Пользовательские данные и конфигурация не + меняются, миграция не нужна» — явный ответ. +- **Производительность**: «Перф продукта не затронут; проверки должны + оставаться дешёвыми, без браузерных прогонов» — явный ответ. +- **Touch** (`TOUCH-SUPPORT.md`): «Интерфейс Home Assistant и touch не + меняются» — явный ответ, продукт не задет. +- **Release-артефакты**: «Release bundle, PNG/golden и миграции не требуются; + изменяемые артефакты — индекс и вычислимые ячейки документации» — явный + ответ. +- **Откат**: описан (revert инфраструктурного коммита + регенерация + производных частей). +- **Открытые продуктовые вопросы**: ТЗ заявляет «нет». Задача инфраструктурная, + видимого пользователю поведения не меняет (нет HA UI, нет i18n, нет данных) — + согласуется с docs/SCOPE.md (эта работа — «надёжность поставки J1–J7», не + новая пользовательская функция). Я отдельно проверял, не спрятан ли под + видом технического вопроса продуктовый — не нашёл: единственный оставленный + открытым пункт (AC5, способ безопасного исполнения генератора) — техническое + решение по определению §7.1 («где стоит гвард, механика миграции» — тот же + класс), правомерно отнесённое в «принято предположительно, поменять + свободно», а не продуктовый вопрос владельцу. + +Все пункты DoR (§2.5) закрыты текстом ТЗ; оснований держать issue вне +«Готово к разработке» не нашёл. + +## Находки + +Ни одной High- или Medium-находки. Низкая (Low), не блокирующая: + +- **Low.** Способы доказательства AC названы как `unit`/`integration`/`CLI`/ + `audit`, тогда как DoR (`PROCESS.md` §2.5) перечисляет канонический набор + `unit`/`backend`/`smoke`/`golden`/«ревью кода». Для чисто инфраструктурной + задачи без продукта/HA/UI эти категории неприменимы буквально; `integration` + и `CLI` — содержательно то же самое, что `unit`/«ревью кода» в контексте + Node-тулинга, `audit` для AC8 прямо описан как «unit + аудит свидетельств». + Терминология не создаёт двусмысленности и не требует правки — снимаю без + возврата автору, с этой записью. + +## Что проверено и корректно + +- Все девять находок (F2–F6, F20, F22, F29, F30) грounded в реальном коде и + git-истории на `a106b717`, не являются пересказом или догадкой. +- Критерии приёмки однозначны, у каждого назван способ доказательства и + явно описан отрицательный/краевой случай. +- Скоуп и не-скоуп непротиворечивы; примыкающие закрытые/параллельные задачи + (#779, #643/#657, #749, #767, #810, #812–#814) учтены, дублирования работы + не обнаружено — F6 корректно закрывается ссылкой на #810, F23 корректно + разделена между #812/#814 без дублирования реализации. +- UX/данные/миграция/i18n/touch/perf разделы явно отвечают «нет изменений» с + обоснованием, соответствующим факту (задача не трогает `src/**` и + `custom_components/houseplan/**`). +- Открытых продуктовых вопросов действительно нет — задача не видна ни одной + из персон `docs/SCOPE.md`; единственное оставленное технически открытым + место (AC5, безопасный запуск генератора из недоверенной ветки) корректно + помечено как решение реализации, а не спрятанный продуктовый вопрос. + +## Вердикт + +Зелёный. ТЗ готово к разработке. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `a106b717621a` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `e33c8365dc06eaa9167f1c479f6dff350d3094cf` + ``` + git log --all --format='%H %T' | grep e33c8365dc06 + ``` +- Тело issue: `6608e85df603b44d546b3ce6373e0dec6f0d48d9074b22df7a953bc49b755a8a` +- Вердикт конвейера: `green` · High 0 · маршрут `fix` +