From 0ebefbb1896a2789148169adc362ca6f65471f19 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 06:19:11 +0000 Subject: [PATCH] docs: review document for #593 Issue: #593 User-Visible: no --- docs/reviews/SPEC-REVIEW-593-r3.md | 135 +++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 docs/reviews/SPEC-REVIEW-593-r3.md diff --git a/docs/reviews/SPEC-REVIEW-593-r3.md b/docs/reviews/SPEC-REVIEW-593-r3.md new file mode 100644 index 00000000..cedb317d --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-593-r3.md @@ -0,0 +1,135 @@ +# SPEC-REVIEW-593-r3 — «Заменить все иконки библиотеки и расширить каталог до 60 плановых символов» + +Issue: [#593](https://github.com/Matysh/houseplan-card/issues/593) +Этап: spec (полный трек, унаследовано из r1 — критерий «одна поверхность» нарушен явно: `src/**`, генератор, i18n, PDF-путь, golden, бюджеты) +Заход: r3 · блокирующих циклов израсходовано на входе в раунд: 1 из 4 (дано конвейером; r1 — красный, спорный цикл засчитан; r2 — красный, но зелёный вердикт этого раунда бюджет не тратит — §4, #227) + +## Вердикт + +**Зелёный.** High: 0. Medium в скоупе: 0. Medium вне скоупа: 0. Low: 0. + +Разбор по дельте (§2.10): единственная блокирующая находка r2 (H1(new), Q3/AC10 — +провенанс) закрыта по существу двумя действиями владельца и правкой ТЗ (редакция 4). +Новых находок в затронутой дельтой области не обнаружено. + +## Материал раунда (входные данные разбора) + +- Тело issue #593 на момент разбора: `gh issue view 593 --json body` — редакция 4 от + 19.09.2026, раздел `## ТЗ`, сохранённое предложение автора выше него. +- Все 8 комментариев issue: `gh issue view 593 --json comments` (добавились три новых + относительно материала r2: ответ владельца на Q1–Q3 `#issuecomment-5739749394` уже + был учтён r2; новые — полноценный грант `#issuecomment-5739841899` (2026-09-19T06:09:00Z) + и ответ на красный вердикт r2 `#issuecomment-5739855252` (06:12:00Z), которым + поставлена `S4-spec-review`, заход r3). +- Предыдущий раунд: [`docs/reviews/SPEC-REVIEW-593-r2.md`](../../docs/reviews/SPEC-REVIEW-593-r2.md), + вердикт красный, материал зафиксирован в его собственном машинном блоке якорей: + ветка `dev`, коммит `dcd6657581ba205edb63713e011a498b51983a20`, дерево + `0b48707268e99ee38221c8e74fb1c48ce6793e35`, тело issue sha256 + `d3303755f955b90dcdf74279c7b76a98de9814103c65cfeb2a5455a49201d457`. +- Прецедент [#159](https://github.com/Matysh/houseplan-card/issues/159) — использован + повторно только в объёме, нужном для проверки, что новый грант (06:09:00Z) содержит + все три элемента, которые сам r2 процитировал из него дословно; заново не перечитывал + весь `docs/reviews/CODE-REVIEW-159-*` — это уже сделано r2 и не относится к дельте. +- Код: `test/furniture-assets.test.mjs` (тест `'release provenance is normalized to the + repository MIT grant'`, три `assert.match`: `issuecomment-5454085168`, + `issuecomment-5449707137`, SHA-256 архива 0.3.0), `assets/furniture/houseplan-0.3.0/README.md` + (для сверки структуры, которую редакция 4 обязана воспроизвести под новыми + значениями) — оба прочитаны заново для проверки закрытия H1(new). Полный grep + `houseplan-0.3.0` по `src/**`, `scripts/**`, `test/**`, `docs/**` — сверка §4 п.11 + («пять живых ссылок»). +- Ветка/код продукта: не создавались. `git log --oneline -- src/ custom_components/` + и `git diff origin/dev..HEAD -- src custom_components` — пусто; веток `issue/593-*` + нет. Рабочая копия на `HEAD = 2167d4396884c3c45ce7991ba603a91a13cdb381` (коммит + публикации документа r2). Гейты `typecheck`/`test`/`build`/`bundle:budget` не + запускал — этап ревью ТЗ, продуктовый код не существует; это же делали r1 и r2. + +## Закрытие раунда r2 + +| Находка r2 | Чем закрыта | Где это видно | +|---|---|---| +| **H1(new).** Ответ владельца на Q3 («Подтверждаю собственное авторство иконок») давал только один из трёх элементов прецедента #159 (авторство, но не разрешение под MIT и не привязку к архиву); ТЗ, удаляя каталог `houseplan-0.3.0`, не планировало ни новый SHA-256, ни обновление исполняемого провенанс-теста, вынуждая исполнителя либо выдумывать значения, либо молча ослабить единственную защиту от повторения истории #159. | Владелец опубликовал отдельным комментарием ([`#issuecomment-5739841899`](https://github.com/Matysh/houseplan-card/issues/593#issuecomment-5739841899), 2026-09-19T06:09:00Z) полноценный грант: «Я являюсь автором всех 93 SVG из архива `houseplan-furniture-0.4.0.zip`… SHA-256 `69BA5E0C398542D59F24269F637F57B8EBF31C2836C9D493F084AD29AB299FDE`, размер 695 379 байт, и разрешаю House Plan использовать, изменять и распространять их на условиях MIT License репозитория без обязательной отдельной атрибуции» — присутствуют все три элемента прецедента: (а) авторство, (б) разрешение на использование/изменение/распространение под MIT, (в) привязка к конкретному архиву/версии. Дополнительно владелец лично сверил байты вложения, поданного `nikitaevfz-commits`, с копией, переданной напрямую (совпадающие SHA-256 и размер) — это сильнее, чем было доступно в #159. ТЗ доведено до редакции 4: §4 п.10 вводит `assets/furniture/houseplan-0.4.0/README.md` как провенанс-документ (ссылка на грант, имя архива, SHA-256, запрет ручной правки generated-файлов) и требует обновить (не ослабить) провенанс-тест «на новые значения — число `assert.match` не уменьшается»; §4 п.11 перечисляет все пять живых ссылок на путь `houseplan-0.3.0`, которые нужно перевести на `0.4.0`; AC10 переписан под оба факта; в §8 добавлен мутант `furniture-provenance-doc-loses-its-hash`; риск добавлен в §11 с явной атрибуцией «найдено ревью r2». | Комментарий `#issuecomment-5739841899` (текст выше); тело issue редакция 4, §3 «Q3. Авторство и лицензия», §4 п.10–11, §8 «Доказательства» → «провенанс», §10 AC10, §11 (пункт «Потеря провенанса…»); комментарий владельца `#issuecomment-5739855252` фиксирует переход в `S4-spec-review`, заход r3. | + +Разбор закрытия — не по заявлению автора: см. «Как проверялось» ниже, где приведён построчный разбор нового текста гранта против трёх обязательных элементов прецедента и построчная сверка §4 п.11 с фактическим деревом. + +## Как проверялось (дельта r2→r3) + +1. **Три элемента гранта.** Сверил текст `#issuecomment-5739841899` построчно с шаблоном, который сам r2 процитировал из #159 («Я являюсь автором всех 77 SVG… и разрешаю… на условиях MIT License… без обязательной отдельной атрибуции»). Новый текст воспроизводит структуру предложение-в-предложение с заменой чисел (93 SVG вместо 77) и явно называет архив по имени (`houseplan-furniture-0.4.0.zip`) и версии, чего не хватало в предыдущем ответе («Подтверждаю собственное авторство иконок»). Все три элемента присутствуют одновременно в одном комментарии. +2. **Чистота цепочки поставки.** Прочитал добавленный владельцем абзац о совпадении байт вложения `nikitaevfz-commits` с копией, переданной напрямую (SHA-256 + размер). Это прямо снимает опасение H1(new) п.1 («тот же самый посторонний аккаунт второй раз подряд поставляет архив») — в отличие от #159, здесь есть явная проверка, а не только совпадение по умолчанию. +3. **Провенанс-документ и тест не выдуманы, а специфицированы количественно.** Перечитал текущий `test/furniture-assets.test.mjs:51-58` (3 `assert.match`: два URL на разные комментарии #159 + SHA-256 0.3.0) и `assets/furniture/houseplan-0.3.0/README.md` (структура: абзац гранта со ссылкой + абзац об архиве со второй ссылкой + SHA-256 + примечание про правку руками). §4 п.10 редакции 4 называет для нового README конкретные значения: ссылку на `#issuecomment-5739841899`, точное имя архива `houseplan-furniture-0.4.0.zip`, точный SHA-256 `69BA5E0C398542D59F24269F637F57B8EBF31C2836C9D493F084AD29AB299FDE`. Структура отличается от прецедента (там было два независимых URL — грант и отдельная attachment-комментарий стороннего аккаунта; здесь оба факта объединены в один комментарий владельца, поскольку архив был приложен в теле issue, а не отдельным комментарием стороннего участника, и тот же комментарий владельца уже содержит верификацию байт). Это техническое, не продуктовое расхождение (расположение и число ссылок в служебном README — деталь реализации, не то, что видит пользователь), и ТЗ фиксирует конкретные значения, а не оставляет их на усмотрение будущего исполнителя — угадывать нечего. Требование «число `assert.match` не уменьшается» (т.е. не менее 3) — измеримый порог. +4. **§4 п.11 — «пять живых ссылок» сверены с деревом.** `grep -rn "houseplan-0\.3\.0"` по `src/**`, `scripts/**`, `test/**`, `docs/**` (за вычетом `docs/reviews/**`, `docs/specs/**`, которые ТЗ явно исключает как исторические) даёт ровно перечисленные файлы: `scripts/generate-furniture-assets.mjs:9`, `test/furniture-path-join.test.mjs:40`, `test/furniture-assets.test.mjs:13,55` (две строки, как и написано — «(две — `pack.json` и `README.md`)»), `docs/FURNITURE.md:19`, `docs/STATUS.md:34`. Полное совпадение, ни одна ссылка не пропущена и не выдумана лишняя. +5. **Мутант `furniture-provenance-doc-loses-its-hash`.** Проверил `scripts/mutation-registry.mjs` на коллизию имени — вхождений нет, как и у четырёх мутантов, названных в r1/r2 (`furniture-legacy-shadows-designer-art`, `furniture-pack-accepts-foreign-symbol-count`, `furniture-cactus-lands-in-exercise`, `bundle-budget-lazy-ceiling-never-fires`). Мутант логически привязан к третьему столбцу AC10 и закрывает ровно тот путь деградации, который называла находка H1(new) п.6(б) («тихо ослабить тест»). +6. **Согласованность SHA-256/размера архива по всему документу.** Значение `69BA5E0C398542D59F24269F637F57B8EBF31C2836C9D493F084AD29AB299FDE` и «695 379 байт» повторяются в комментарии `#issuecomment-5739841899`, в §3 Q3 и в §4 п.10 ТЗ — все три вхождения совпадают побайтово (сверено копированием, не визуально), источник один — комментарий владельца; расхождений «одно число — два значения» не найдено. Формат строки (64 hex-символа) соответствует SHA-256. +7. **Отсутствие регрессии по остальным разделам.** Сверил, что редакция 4 не тронула ничего за пределами §3 Q3, §4 п.10–11, §8 (абзац «провенанс»), §9, §10 AC10, §11 (новый пункт риска), §12 (без изменений — продуктовые пункты по-прежнему отсутствуют, что и требуется после закрытия H1(r1)). Текст Q1/Q2, §5–§7, AC1-9/11, таблица мутантов (кроме добавленного пятого) — побайтово те же формулировки, что цитирует r2 — делали построчную сверку конкретно этих разделов, не полное построчное сравнение всего документа целиком. + +## Что проверено и корректно (унаследовано + новое) + +- Закрытие H1(new) — подтверждено по существу, см. таблицу и «Как проверялось» выше. +- §4 п.10 и п.11 — специфицированы количественно (конкретные значения ссылки/имени/хеша, точный список из пяти ссылок), не оставляют технического решения на угадывание исполнителя. +- Мутант `furniture-provenance-doc-loses-its-hash` не конфликтует по имени с реестром и логически закрывает найденный r2 путь тихого ослабления теста. +- Число и содержание release-артефактов (§9) согласовано с §4 п.10 (тот же путь `assets/furniture/houseplan-0.4.0/README.md`). +- Одно число — один источник: SHA-256 и размер архива фигурируют в трёх местах текста, все совпадают и восходят к одному комментарию владельца. + +## Унаследовано из r2 (и через него — из r1) + +Дельта r2→r3 ограничена §3 Q3, §4 п.10–11, §8 (абзац «провенанс»), §10 AC10, §11 — +всё остальное принято без повторной проверки в этом раунде, со ссылкой на +[`SPEC-REVIEW-593-r2.md`](../../docs/reviews/SPEC-REVIEW-593-r2.md) (материал: ветка +`dev`, коммит `dcd6657581ba205edb63713e011a498b51983a20`, дерево +`0b48707268e99ee38221c8e74fb1c48ce6793e35`) и, где отмечено, на +[`SPEC-REVIEW-593-r1.md`](../../docs/reviews/SPEC-REVIEW-593-r1.md) (коммит +`073c45b04308cd613182c700f30c75ebfa8d2ca7`): + +- Комплектность обязательных разделов §7.1 — проверена r1, дельта их не убирала. +- H1(r1) (продуктовые вопросы Q1/Q2 закрыты владельцем через `blocked` + отдельный + ответ, а не самоподтверждением автора) — закрыто в r2, дельта r3 этого не касалась. +- M1(r1) (AC9/бюджеты: два ленивых графа получают настоящий гейт вместо печати) — + закрыто в r2 (`lazyGraphCeilingViolation`, `LAZY_*_GZIP_CEILING`, мутант + `bundle-budget-lazy-ceiling-never-fires`), дельта r3 этого не касалась. +- Все фактические числа о текущем состоянии кода (состав `RETAINED_IDS`, + default-размеры 12 retained-символов, число ключей i18n 29/56 в исходном + состоянии, ловушка двойного объединения `FURNITURE`/`BY_ID`, состав golden-сцен, + существование npm-скриптов) — проверены r1 построчно, дельта их не меняла. +- Q1/Q2 содержательно (`cactus → plant`, 32 непустые категории, поведение при отказе + ленивого чанка для всех 60 предметов, снятие обещания `docs/FURNITURE.md`) — + проверены r2 по тексту и коду (`src/decor-image-editor.ts`, + `src/furniture-art-runtime.ts`, `toast.furniture_art_load_failed`), дельта r3 их + не трогала. +- Мутанты `furniture-legacy-shadows-designer-art`, `furniture-pack-accepts-foreign- + symbol-count`, `furniture-cactus-lands-in-exercise` — сверены на отсутствие + коллизий в r1/r2, не перепроверял заново. + +## Чего не проверял + +- Содержимое `houseplan-furniture-0.4.0.zip` побайтово (93 SVG, `pack.json`) — как и + в r1/r2, это предмет код-ревью, когда пакет окажется в дереве; полагаюсь на + проверенный аналитикой S2 прогон генератора («OK: 60 plan symbols, 33 menu icons») + и на личное подтверждение владельца о побайтовом совпадении вложения issue с + переданной напрямую копией. +- Не пересчитывал SHA-256 архива самостоятельно (не скачивал вложение) — находка + H1(new) была не о неверном хеше, а об отсутствии закреплённого механизма; сейчас + механизм закреплён, независимая перепроверка байтов — задача код-ревью. +- `npm run typecheck`, `npm test`, `npm run build`, `npm run bundle:budget`, + `golden:verify`, любые смоки — этап ревью ТЗ, продуктовый код не существует + (нет коммитов и веток `issue/593-*`); так же поступали r1 и r2. +- Полное построчное сравнение всего тела ТЗ редакция 3 vs редакция 4 — сравнивал + прицельно разделы, которые называет комментарий владельца о редакции 4 (§3 Q3, + §4 п.10–11, §8, §10 AC10, §11); не проверял, что где-то за пределами названного + диапазона не появилось незамеченного текстового расхождения — риск низкий, так как + сам процесс написания ТЗ (правки поверх сохранённого текста с явным указанием + «что меняется») уже дважды подряд (r1→r2, r2→r3) точно называл границы своих правок. +- Дубликаты (аналогичные issue) — не проверял повторно; r1 не нашёл признаков + дублирования, дельта r2→r3 не создаёт нового риска дублирования. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `2167d4396884` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `857164801ddbfc7450d2e95e1617b258d6704dd2` + ``` + git log --all --format='%H %T' | grep 857164801ddb + ``` +- Тело issue: `3a8d99615191f61cc781ac873210df277ce0951d828113e3efa89700a5b7b6a3` +- Вердикт конвейера: `green` · High 0