diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index ee1457b5..c80526cd 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,6 +1,6 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1017, issue: 359. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1018, issue: 359. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| @@ -34,6 +34,7 @@ | #618 | [SPEC-REVIEW-618-r1.md](SPEC-REVIEW-618-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | нотация h в B5 не встречается в коде | `docs/FILTERING.md` | | #617 | [SPEC-REVIEW-617-r1.md](SPEC-REVIEW-617-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | «новый необязательный параметр» уже существует | `src/backdrop-pick.ts` `houseplan-editor-runtime.ts` | | #615 | [SPEC-REVIEW-615-r1.md](SPEC-REVIEW-615-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 1 | AC3 называет несуществующую защиту от расползания на плашки цвета | `smoke_room_settings_form.mjs` `smoke_space_settings_form.mjs` `smoke_device_settings_form.mjs` `smoke_dialog_polish_605.mjs` `smoke_general_settings_form.mjs` | +| #615 | [SPEC-REVIEW-615-r2.md](SPEC-REVIEW-615-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — | | #614 | [SPEC-REVIEW-614-r1.md](SPEC-REVIEW-614-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #614 | [CODE-REVIEW-614-r1.md](CODE-REVIEW-614-r1.md) | code · r1 | 🟡 жёлтый | 0 | 1 | AC1/AC2/AC3 требуют unit-тест, а он не написан | `test/dialog-baseline.test.mjs` `test/space-dialog.test.mjs` `general-form-state.ts` `space-form-state.ts` `marker-form-state.ts` `tsconfig.test.json` `dialog-baseline.ts` `scripts/mutation-registry.mjs` | | #614 | [CODE-REVIEW-614-r2.md](CODE-REVIEW-614-r2.md) | code · r2 | 🟢 зелёный | 0 | 0 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-615-r2.md b/docs/reviews/SPEC-REVIEW-615-r2.md new file mode 100644 index 00000000..33defce1 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-615-r2.md @@ -0,0 +1,205 @@ +# SPEC-REVIEW — issue #615 · заход r2 + +**Задача:** «Плитки палитры после #605 всегда сплошные: «No lights» с прозрачностью 0 % выглядит насыщенным цветом» +**Этап:** ТЗ на ревью (S4-spec-review) · трек `small` · лимит циклов ревью ТЗ — 2 +**Заход:** r2 · блокирующих циклов израсходовано 1/2 до этого вердикта + +## Скоуп разбора + +Второй раунд — разбор по дельте (PROCESS.md §2.9, issue #214), не заново. Причина +сужения: единственная находка r1 (Medium M1, PROCESS.md §2.7) касалась ровно одного +столбца одной строки таблицы AC (AC3, «чем краснеет»/«чем доказан»), не задевала +контракт поведения как целое, не переоткрывала выбор между шахматкой/полосой альфы +и не меняла ни продуктовую рамку (сценарий, персона, поверхность), ни AC1/AC2/AC4. +Владелец подтвердил в комментарии r2 («Остальное ТЗ ревью r1 признало корректным, +там ничего не менялось»), что правка точечная. Дельта не подпадает ни под одно +условие полного разбора из брифинга (ребейз, смена контракта поведения, новая +подсистема, объём дельты ≈ объёму задачи): правка — это разбитая на (а)/(б)/(в) +формулировка AC3 плюс её эхо в скоупе, п.7 контракта, плане автотестов и рисках. +Поэтому разбор ограничен тем, что задевает эта дельта, остальное унаследовано (см. +раздел ниже) без повторной проверки. + +## Как найден заход r1 и материал этого раунда + +- Вердикт r1 найден в комментарии issue от `2026-09-24T00:55:49Z` (github-actions): + жёлтый, High 0, Medium 1 в задаче. Документ: `docs/reviews/SPEC-REVIEW-615-r1.md` + (файл присутствует в рабочей копии). +- SHA материала r1 в вердикте не назван отдельной строкой в issue-комментарии, но + документ r1 сам несёт якорь: ветка `dev` на коммите `9d1d27325d7f`, дерево + материала `2b3f9bb13865aa81206dba3cd06f7b1cf151dd93`, тело issue на тот момент — + хеш `160aa133569bbc2145349668472db875bb0326975c789bd2b48b76511222101f`. Для + спек-этапа код не менялся между r1 и r2 (обе редакции — правка текста issue), это + подтверждает независимая сверка: `git log --oneline -- docs/reviews/SPEC-REVIEW-615*` + и `git branch -a` не показывают отдельной ветки/PR для #615 — задача ещё не вышла + из этапа ТЗ. +- Дельта текста issue не доступна как git-diff (GitHub не версионирует тело issue + через API этого токена: `gh api repos/.../issues/615/timeline` не вернул событий + `edited` с содержимым правки). Источник дельты — комментарий владельца + `2026-09-24T02:23:00Z` («ТЗ r2 — ответ на SPEC-REVIEW-615-r1»), который прямо + перечисляет, что изменилось, и текущее тело issue (`## ТЗ` с явной пометкой + «Редакция r2»). Оба сверены построчно с находкой M1 из r1 (см. ниже) — расхождений + с заявленным перечнем правок не найдено. + +## Что проверено в этом раунде (дельта) + +Находка M1 указывала: AC3 утверждает, что защита от расползания режима на плашки +цвета (Wall fill, фон General и т. д.) «уже существует и остаётся» — а на деле +такой проверки нет ни в одном `demo/smoke_*.mjs`, ни в `test/`. + +Правка r2 заменяет это на явную новую проверку AC3(б). Я перепроверил каждую +техническую деталь новой формулировки против реального кода (не веря заявлению +«исправлено», а проверяя названные объекты): + +- `.hpf-colorfield` — существующий класс, `colorField()` в `src/editors/form-kit.ts:275`. +- `.hpf-opacity input` — существующий узел внутри `colorField()`, + `src/editors/form-kit.ts:278-284`. +- `data-card="plan"` — существующий id секции Wall fill, + `src/editors/general-settings-dialog.ts:140` (Wall fill — единственный `colorRow` + внутри этой секции, строки 143-154). +- `.hpf-card[data-card="plan"] .hpf-colorrow .hpf-opacity input` — не гипотетический + селектор: он уже используется сегодня в `demo/smoke_general_settings_form.mjs:65` + для того же самого действия (ввод числа в поле % Wall fill), только там + проверяется запись в конфиг, а не вычисленная непрозрачность. +- `flatSwatch && !coverSwatch` — соответствует реальным атрибутам компонента + (`src/hp-color-opacity.ts:76-77`, `flat-swatch`/`cover-swatch`); Wall fill в + разметке (`general-settings-dialog.ts:150`) имеет `flat-swatch` без + `cover-swatch` — ровно то условие, которое просит проверить AC3(б). +- «При α=1 (как у фона General, `showOpacity=false`) протечка не видна» — + подтверждено: `general-settings-dialog.ts:181`, `.opacity=${1} + .showOpacity=${false}` для `bg_color`. Значит выбор Wall fill (α=0.4, + `showOpacity=true`) как представительной плашки — не произвольный, а + единственный вариант, на котором протечка вообще проявится. +- «(а) … условие `opacity === '1'` в `oneSurface` для плиток заменяется проверкой + AC1» — сверено с реальной строкой `demo/smoke_dialog_polish_605.mjs:40` + (`getComputedStyle(painted).opacity === '1'` внутри `oneSurface`, которая сегодня + верна для всех плиток, потому что плитки сегодня всегда непрозрачны — то есть + после реализации AC1 это условие действительно станет неверным для `α<1` и + требует замены, как и написано). +- «Без (б) этот мутант [M-615-plate] выживает» — логически верно: сегодня в + `demo/*.mjs` и `test/` нет ни одной ассерции на `getComputedStyle(...).opacity` + для `.hpf-colorfield`/`.hpf-colorrow` (это и было находкой M1), и правка явно + добавляет её как часть AC3, а не оставляет как «уже есть». + +Итог: M1 закрыта не декларативно, а предметно — новая формулировка называет +реальные, существующие сегодня селекторы и значения, а не воображаемые. Ложного +ощущения прикрытого регресса, о котором предупреждало PROCESS.md §2.7, новая +редакция не создаёт. + +Дополнительно проверено остальное эхо этой дельты (обязательное действие §2.9 — +проверять и то, до чего дельта дотягивается, не только саму находку): +- Скоуп: добавлена строка «Новая проверка в смоке, что плашки цвета остаются + сплошными (AC3). Сегодня такой проверки нет» — согласуется с M1 и с кодом. +- Контракт п.7 (плашки остаются сплошными при любом α, `flat-swatch` без + `cover-swatch`) — переформулирует то, что раньше было только в «Не-скоупе», как + явный пункт контракта; поведенчески ничего нового не описывает (плашки и так + сплошные сегодня, это подтверждено r1), это не смена контракта, а его явное + проговаривание применительно к AC3(б). +- План автотестов: три мутанта вместо двух (добавлен M-615-plate) — согласуется с + таблицей AC3. +- Риски: «протечка на плашки… защита — новая проверка AC3(б) и мутант M-615-plate» + — согласуется, не противоречит остальным рискам. +- «Принято предположительно»: добавлен пункт про одну представительную плашку — + корректно помечен как решение, которое можно поменять свободно, продуктового + вопроса не требует (сама техника защиты — не то, что видит пользователь). +- Редакторское (не находка, как отметил и владелец): в AC2 восстановлено имя + свойства («вычисленный `color` подписи…») — сверено с текущим текстом, совпадает. + +Однозначность AC3 после правки: наблюдаемый результат, способ доказательства и +условие красноты не расходятся — таблица читается без домысливания. + +## Унаследовано из r1 + +Без повторной проверки в этом раунде приняты (документ `docs/reviews/SPEC-REVIEW-615-r1.md`, +материал на коммите `dev@9d1d27325d7f`, дерево `2b3f9bb13865aa81206dba3cd06f7b1cf151dd93`): + +- Обязательные разделы §7.1 присутствуют все, продуктовая рамка (сценарий, что + видит человек, персона — администратор дома, поверхность — General settings, + не View) верна и соответствует `docs/SCOPE.md`. +- Описание проблемы и её механизм (`src/hp-color-opacity.ts:852`, + `src/editors/form-kit.ts:316`, `src/logic.ts:1436-1438`) — точны. +- Скоуп/не-скоуп (кроме добавленной строки про новую проверку, см. выше) — + соответствуют реальному состоянию `src/editors/*.ts` и `docs/USER-GUIDE.ru.md`. +- AC1 и AC2 — полноценные, с реалистичной таблицей «чем краснеет»; правка r2 их не + трогала (кроме восстановленного имени свойства в AC2, проверено выше). +- AC4 — корректно ссылается на предрелизный гейт golden, не требует пересъёмки в + задаче. +- Классификация трека `small` (не `trivial`) — обоснована, дельта её не меняет. +- Отсутствие продуктовых вопросов владельцу — подтверждено повторно и в r2 + (комментарий владельца: «Продуктовых вопросов нет»); правка M1 была технической, + что и предписывает процесс («технический вопрос, вынесенный владельцу, — + замечание»), поэтому её решил сам владелец текстом ТЗ, а не вопросом. + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| M1 (Medium, в скоупе): AC3 называет несуществующую защиту плашек («остаётся», «краснеет») как факт, хотя такой проверки сегодня нет ни в `demo/*.mjs`, ни в `test/` | AC3 разбит на (а) существующие проверки для плиток / (б) новая проверка этой задачи, явно названная как отсутствующая сегодня и создаваемая в рамках этой же задачи / (в) регресс-смоки. «Остаётся» заменено на конкретный сценарий: `flatSwatch && !coverSwatch` у всех `hp-color-opacity` внутри `.hpf-colorfield` General, плюс проверка Wall fill после ввода `40` — `.swatch` opacity `'1'`, `.trigger` backgroundImage `'none'`. Названо, почему без (б) мутант M-615-plate выживает | Тело issue #615, раздел «Критерии приёмки», строка AC3 (столбцы «Наблюдаемый результат» / «Чем доказан» / «Чем краснеет»); эхо в разделах «Скоуп», «Контракт поведения» п.7, «План автотестов», «Риски», «Принято предположительно» | + +## Находки + +Нет. Ни High, ни Medium в этом раунде не обнаружено. + +## Что проверено и корректно + +- Все выше перечисленные технические детали AC3(б) (селекторы, атрибуты, значения) + сверены построчно с `src/editors/form-kit.ts`, `src/editors/general-settings-dialog.ts`, + `src/hp-color-opacity.ts` и с существующими `demo/smoke_dialog_polish_605.mjs`, + `demo/smoke_general_settings_form.mjs` — расхождений нет. +- Выбор Wall fill как представительной плашки логически обоснован кодом (только у + неё `showOpacity=true` и `α≠1` по умолчанию среди плашек General), а не + произволен. +- Новая формулировка AC3 не открывает продуктового вопроса и не меняет видимое + поведение — это по-прежнему только описание того, как задача защищает + существующий (не меняющийся) не-скоуп. +- Однозначное число, видимое пользователю (`%`, hex, вычисленная непрозрачность + свотча) — не дублируется независимыми источниками: подпись `%` и опорная + непрозрачность CSS-слоя оба выводятся из одного и того же `α` конфигурации; + задача не вводит второй источник этого числа. `test/single-source-numbers.test.mjs` + здесь не задет диффом текста ТЗ и не требует прогона на этом этапе (кода ещё + нет). + +## Чего не проверял + +- Реализация ещё не существует (этап ТЗ) — `typecheck`/`test`/`build`/`golden`/ + мутанты не прогонялись, неприменимо. +- AC1, AC2, AC4, сценарий, не-скоуп (кроме одной добавленной строки), i18n, модель + данных — не перепроверялись заново в этом раунде, так как дельта их не касается; + приняты по r1 (см. «Унаследовано из r1»). +- Точный список золотых кадров, которые изменит правка (AC4) — как и в r1, это + ответственность хендоффа/предрелизного гейта, не спецификации. +- Само существование мутанта #605 рядом в реестре — как и в r1, подтверждено, что + его нет; создание мутантов (M-615-tile/label/plate и, если нужно, для #605) — + часть будущей реализации, не находка ни в одном из раундов. + +## Вердикт + +Единственная находка предыдущего раунда закрыта предметно, новых находок нет. +По §2.4/§4 PROCESS.md — зелёный вердикт. Бюджет циклов не расходуется (зелёный +вердикт цикла не образует, #227): израсходовано остаётся 1/2. + +--- + +## Материал раунда + +- Issue: #615, репозиторий Matysh/houseplan-card. +- Материал: тело issue (раздел `## ТЗ`, редакция r2) на момент разбора, плюс + комментарий владельца `2026-09-24T02:23:00Z` как источник объявленной дельты. +- Предыдущий раунд: r1, документ `docs/reviews/SPEC-REVIEW-615-r1.md`, вердикт + жёлтый, материал — тело issue на момент разбора r1 (хеш тела + `160aa133569bbc2145349668472db875bb0326975c789bd2b48b76511222101f`, привязан к + `dev@9d1d27325d7f`). +- Вердикт этого раунда: зелёный · High 0 · Medium 0. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `4de5c0c0b52f` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `76cc0be454bbeaef33572c4613230b39b506fd9e` + ``` + git log --all --format='%H %T' | grep 76cc0be454bb + ``` +- Тело issue: `c97b73a26ff6fd7f6f98066a8188d815fbfac1ad9db4ed0085317efe13f01a30` +- Вердикт конвейера: `green` · High 0