# SPEC-REVIEW-377-r2 - Issue: https://github.com/Matysh/houseplan-card/issues/377 — «Персист цвета декора по умолчанию в серверный конфиг» - Этап: ТЗ на ревью (PROCESS.md §2.4), полный трек (унаследовано из r1) - ТЗ: `docs/specs/377-decor-default-persist.md`, ревизия 2, зафиксирована комментарием автора на dev `6a217271` - Предыдущий вердикт: SPEC-REVIEW-377-r1 (`docs/reviews/SPEC-REVIEW-377-r1.md`), жёлтый, получен на SHA `e2e4cec1` (SHA в тексте r1 не назван явно — найдено сопоставлением: `docs/specs/377-decor-default-persist.md` появился именно в этом коммите, а r1 описывает файл как «зафиксирована ... ревизии 1») - Заход: r2 · блокирующих циклов израсходовано 1 из 4 ## Дельта раунда `git diff e2e4cec1..6a217271 -- docs/specs/377-decor-default-persist.md` — 13 строк (9 добавлено, 4 удалено), правка исключительно пункта 7 «Контракта поведения» (формат ключа) и строки ревизии в шапке. Остальной текст файла байт-в-байт не менялся. Полный `git diff --stat e2e4cec1..6a217271` по репозиторию затрагивает только `docs/**` (два review-документа других задач, review-документ r1 и сам файл ТЗ) — `src/**` и `custom_components/**` не тронуты. Разбор этого раунда — по дельте: заново проверен только пункт 7 и его согласованность с AC2 (единственное место, которое дельта задевает). Остальные разделы ТЗ дельта не касается — унаследованы из r1 без повторной построчной сверки с кодом (код не менялся между раундами, см. ниже). ## Закрытие раунда r1 | Находка (r1) | Чем закрыта | Где это видно | |---|---|---| | M1 — контракт (п.7) утверждал, что `DecorStyle` snake_case, со ссылкой на `types.ts:78`, которая на деле показывает camelCase; поле не помечено как предположение | Пункт 7 переписан: явно разведены snake_case ключа настроек и camelCase `DecorStyle`, дан маппинг по каждому из 6 полей, снабжён пометкой «принято предположительно» и ссылкой на аналогичную существующую конвертацию `geometry.ts:144` | `docs/specs/377-decor-default-persist.md:63-70` | Проверено построчно, не на слово автора: - `src/editors/decor/types.ts:78-85` — `DecorStyle` объявлен camelCase (`color, opacity, widthCm, fill, fillColor, fillOpacity`) — новая формулировка п.7 корректно называет это camelCase (в r1 было названо ошибочно snake_case). - `src/editors/decor/geometry.ts:144-148` (`decorStylePatch`) — существующая ручная конвертация `widthCm → width_cm`, `fillColor → fill_color`, `fillOpacity → fill_opacity` — аналогия, на которую ссылается п.7, подтверждена дословно на HEAD (код не менялся между раундами). - Маппинг в новом тексте (`color↔color`, `opacity↔opacity`, `width_cm↔widthCm`, `fill↔fill`, `fill_color↔fillColor`, `fill_opacity↔fillOpacity`) покрывает все 6 полей `DecorStyle` без пропусков. - Формулировка снабжена явной пометкой неопределённости («принято предположительно») — ровно то, чего не хватало в r1, и по тому же образцу, что уже был у предшественника #376 (SPEC-REVIEW-376-r1, «Принятые предположения»). M1 закрыта полностью, новой правки не требует. ## Проверено в этом раунде (кроме закрытия M1) - Согласованность п.7 с AC2 (`docs/specs/377-decor-default-persist.md:100-102`, не изменён дельтой, но на него ссылается новая фраза «чтобы AC2 доказывал мердж всех шести полей»). AC2 остался тем же генеральным текстом («конфиг с ключом → мердж поверх `DEFAULT_DECOR_STYLE`; частичный ключ (только `color`) наследует остальные поля дефолта»). Формулировка не называет явно разноимённые поля (`width_cm`, `fill_color`, `fill_opacity`), но и не ограничивает тестовые данные одним полем `color` — «конфиг с ключом» без уточнения естественно читается как полный набор из 6 полей, что при добросовестной реализации теста покрывает именно тот риск, ради которого заведена M1 (не замержить переименованные поля). Формулировка на грани строгости, но не ложна и не резервирует новый цикл — граница между «доказано» и «недосказано технически, решает автор кода» здесь не превышена (см. критерий §7.1 out of scope для технических деталей теста). Не поднимаю как находку. - Пересчёт классификации: пункт «Приоритет» (полный трек, критерий §5) не затронут дельтой и не оспаривается — унаследовано из r1. - Проверено, что дельта не меняет контракт поведения по существу (записи, чтения, дебаунс, откат, riски, i18n, release-артефакты) — правка чисто терминологическая/уточняющая для одного пункта, продуктовый сценарий и видимое поведение не меняются. ## Унаследовано из r1 Без повторной проверки в этом раунде принято из `docs/reviews/SPEC-REVIEW-377-r1.md` (документ на SHA `e2e4cec1`, код между `e2e4cec1` и `6a217271` не менялся — подтверждено `git diff --stat`, различия только в `docs/**`): - Классификация полного трека (критерий §5, «нет новых compatibility-полей» не проходит) — унаследована из SPEC-REVIEW-376-r1 H1, ещё раз подтверждена в r1. - Соответствие `docs/SCOPE.md` (polish уже принятой фичи #360, Background- редактор, admin-only поверхность, View не получает новых путей записи). - Наличие и полнота всех обязательных разделов §7.1 (сценарий, до/после, проблема, скоуп/не-скоуп, контракт п.1-6, UX, модель данных, i18n, AC1-AC7, план автотестов, риски, откат, release-артефакты) — их текст дельта не трогала. - Построчная сверка пунктов контракта 1-6 с кодом (`_decorStyle` in-memory поле, `_writeConfig`/`expected_rev`/#340, паттерн `bg_color`/`fill_colors` для удаления ключа при дефолте, ограничение записи editor-runtime, холодный View #357 не задет). - Диапазоны валидации в наброске схемы (opacity 0..1, width_cm 0.1..100, fill_opacity 0..1) — совпадают с уже принятыми диапазонами для decor-фигур, не придуманы заново. - AC6 корректно ограничен по объёму (полный экспорт/импорт, не пространственный `build_space_merge`). - Отсутствие открытых продуктовых вопросов владельцу — решение «персистить в серверный конфиг» уже принято 29.08 и зафиксировано в теле issue. - Низкая находка r1 (нет явной строки «touch: нет» для DoR §2.5) — оставлена снятой с записью, как и в r1; правки в r2 её не касаются, новой строки не требую. ## Гейты Диапазон правки этого раунда и всей ветки #377 на сегодня — только `docs/**` (см. «Дельта раунда» выше). `src/**` и `custom_components/**` не тронуты продуктовым кодом ни разу с начала работы над #377. Гейтам, завязанным на код (`npx tsc --noEmit`, `npm test`, `npm run build`, `check-docs.mjs`, инварианты модели, browser-смоки, `pytest`), на стадии ТЗ нечего доказывать — не прогонял, тот же вывод, что и в r1, для того же диапазона правки. Зелёного Validate на `6a217271` не требовалось искать по этой же причине. ## Вердикт Единственная находка r1 (M1) закрыта точным попаданием в предложенную правку: пункт 7 теперь корректно разводит snake_case ключа настроек и camelCase `DecorStyle`, даёт маппинг по всем 6 полям и явно маркирует решение как предположение. Новых High- или Medium-находок в дельте не найдено. ТЗ готово к передаче в код. `Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0`