From 92f1d3cbbfeae193fa5a470eb327158aa14d5114 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:03:04 +0000 Subject: [PATCH] docs: review document for #377 Issue: #377 User-Visible: no --- docs/reviews/SPEC-REVIEW-377-r2.md | 125 +++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-377-r2.md diff --git a/docs/reviews/SPEC-REVIEW-377-r2.md b/docs/reviews/SPEC-REVIEW-377-r2.md new file mode 100644 index 00000000..5be96250 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-377-r2.md @@ -0,0 +1,125 @@ +# 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`