17 KiB
SPEC-REVIEW-482-r2 — Доводка экспорта пространства в PDF
- Issue: https://github.com/Matysh/houseplan-card/issues/482
- Этап: ревью ТЗ (PROCESS.md §2.4)
- ТЗ:
docs/specs/482-pdf-export-polish.md - Трек: полный (не пересматривается в r2 — решение аналитики #482 не задето дельтой)
- Заход: r2 · блокирующих циклов израсходовано 1 из 4 (до этого вердикта)
Скоуп ревью
Второй заход, разбор по дельте (PROCESS.md §2.10, issue #214) — дельта локальна, полный повторный разбор не требуется, обоснование ниже.
- Вердикт предыдущего раунда: комментарий
claude, 2026-09-07T06:15:24Z — жёлтый · r1 · High: 0 · Medium: 1 → в задаче (M1, provenance/лицензия векторного компаса). Документ:docs/reviews/SPEC-REVIEW-482-r1.md. - Материал r1 взят из блока «Материал раунда» в конце того документа:
ветка
issue/482-pdf-export-polish, коммитbc93babdf8e7dc346e3465a72b8f2927875095d7. SHA живой, не осиротел:git cat-file -t bc93babdf8e7→commit; дерево38bf116ad9ad52b85ed8e0aaee3799819a5a1e58резолвится тем же коммитом (git log --all --format='%H %T' | grep 38bf116ad9ad→ одна строка, тот же SHA). Дельта объявляется напрямую по SHA, без content-addressing якорей — ребейза между r1 и r2 не было. - Дельта:
git diff bc93babd..HEAD(HEAD =5c1175cebc8d393f0b08488f76c11411ed686cd0, коммит «docs: pin PDF compass provenance»). Единственный содержательный файл —docs/specs/482-pdf-export-polish.md, 16 insertions / 5 deletions, целиком внутри раздела «13. Векторный компас». Второй изменившийся файл —docs/reviews/SPEC-REVIEW-482-r1.md, который дельту не образует: это публикация предыдущего вердикта, ожидаемый артефакт конвейера, а не правка автора. Тела issue #482 и комментариев дельта не касается: сверил текущее тело issue и полный список комментариев (5 шт.) — новых продуктовых вопросов или уточнений владельца после r1 нет, последний комментарий владельца — анонс фикса M1. src/**не тронут:git log --oneline 08aad891..HEAD -- src/пуст — ветка по-прежнему содержит только ТЗ и review-документы поверхv1.73.0-beta.3; это по-прежнему этап spec, гейтов кода нет и не может быть.- Почему разбор сокращённый, а не полный: дельта не задевает ни ребейз на
ушедший вперёд
dev(SHA r1 жив в текущей истории), ни новую подсистему, ни контракт поведения — правка меняет только текст обоснования provenance одного SVG-ассета. Объём дельты (11 чистых строк) несопоставим с исходной задачей (485 строк ТЗ, 12 AC, 6 подсистем). Единственный AC, чьё доказательство эта дельта задевает, — AC8 (§17, «license сохранена»,docs/specs/482-pdf-export-polish.md:393).
Как проверялось
- Перечитал §13 ТЗ целиком (
docs/specs/482-pdf-export-polish.md:308-338) — и старую версию наbc93babd, и новую наHEAD, построчно черезgit diff bc93babd..5c1175ce -- docs/specs/482-pdf-export-polish.md. - Сверил формулировку M1 (r1) с текстом финта: старая ссылка на
master(.../blob/master/icons/travel/compass-line.svg) заменена на три ссылки на неизменяемый upstream commitbf6bdd0dd3f247f1a320d44d13fecdeda18c071c(сам commit, файл в нём,LICENSEв нём) — это устраняет именно тот дефект, который называл r1: ссылка на движущуюсяmasterне может уехать и стать неверной незаметно, потому что коммит зафиксирован по SHA. - Проверил, что новая формулировка не скрывает несовпадение SHA-256:
старый текст утверждал «совпадает по path с каноническим ассетом» без
уточнений; новый прямо признаёт, что файл владельца не совпадает
побайтово с upstream (SVG Repo добавил обёртку и
800×800вместо36×36), и указывает, что совпадают именноviewBoxи обаd— то есть сузил claim ровно до того, что можно проверить сравнением текста, а не расширил его. Это соответствует одному из трёх путей закрытия, которые предлагал r1 («заменить ссылку на master точным commit/blob»), хотя автор не добавил формальную пометку «принято предположительно» — см. ниже, почему это не считаю новым замечанием. - Попытался независимо дойти до upstream
LICENSEиcompass-line.svgна зафиксированном commit черезWebFetch— инструмент запросил разрешение и не получил его в этой сессии (тот же результат, что в r1 при попытке черезmcp__github__get_issue/WebFetch; ограничение окружения, не находка). Поэтому байт-в-байт я по-прежнему не подтверждаю и не опровергаю — см. «Чего не проверял». - Проверил AC8 (
docs/specs/482-pdf-export-polish.md:393) — текст критерия и способ доказательства («license check» отдельным пунктом в списке методов) не менялись дельтой и не нуждались в изменении: AC8 уже предполагал отдельную проверку лицензии на этапе код-ревью (когда ассет реально вендорится и появляется файл, который можно сравнить построчно), а не на этапе ТЗ. Пиннинг на неизменяемый commit — это именно то, что делает такую будущую проверку осмысленной (проверять фиксированный SHA, а не «текущее состояние master»). - Проверил остальные части ТЗ (§1–§12, §14–§20) на предмет того, не появилось ли противоречий или ссылок, которые эта правка могла разбалансировать — дельта географически изолирована в §13, соседние разделы (§12 — layout, §14 — footer/i18n) не ссылаются на provenance компаса и не пострадали.
- Дешёвые гейты кода (
tsc/test/build) не гонял:src/**не менялся ни в r1, ни в дельте r2 — гонять их не по чему, как и в r1.
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
M1 — provenance/лицензия компаса заявлены как факт со ссылкой на движущуюся master, без воспроизводимого способа перепроверить |
Ссылка на master заменена тремя ссылками на неизменяемый upstream commit bf6bdd0dd3f247f1a320d44d13fecdeda18c071c (сам коммит, файл, LICENSE); дополнительно текст перестал скрывать несовпадение SHA-256 владельца с upstream и объяснил его источником обёртки SVG Repo, сузив claim до проверяемого (viewBox + оба d) |
docs/specs/482-pdf-export-polish.md:312-329 (diff bc93babd..5c1175ce); коммит 5c1175cebc8d393f0b08488f76c11411ed686cd0 «docs: pin PDF compass provenance» |
Считаю M1 закрытой без выхода за скоуп: правка того же раздела того же ТЗ, не новая подсистема.
Остаточное наблюдение (не новое Medium/Low, входит в «чего не проверял»):
фраза «Provenance проверен перед реализацией» звучит как уже свершившийся факт,
хотя ни в r1, ни в r2 никто с доступом к вебу это не подтвердил — у меня
WebFetch не авторизован в обеих сессиях. Это не возвращаю как отдельную
находку, потому что: (а) сама правка отвечает на процессуальное требование
r1 — reproducibility ссылки, а не немедленное личное подтверждение
ревьюером; (б) AC8 уже называет «license check» отдельным методом
доказательства, который по своей природе относится к моменту, когда ассет
реально появляется в репозитории на этапе кода — это точка, где сравнение
станет механическим (файл в коммите против зафиксированного upstream SHA), а
не вопросом доверия к прозе ТЗ. Рекомендую код-ревью этой задачи явно
подтвердить совпадение путём чтения обоих файлов (или через веб-доступ, если
он будет у код-ревьюера), а не принимать формулировку ТЗ как готовое
доказательство.
Унаследовано из r1
Всё содержимое ТЗ вне §13 принято без повторной проверки в этом раунде — оно
не входит в дельту (git diff bc93babd..5c1175ce не касается ничего, кроме
§13.) Основание: docs/reviews/SPEC-REVIEW-482-r1.md, вердикт жёлтый на
коммите bc93babdf8e7dc346e3465a72b8f2927875095d7 (дерево
38bf116ad9ad52b85ed8e0aaee3799819a5a1e58), раздел «Что проверено и
корректно»:
- продуктовая рамка и предложение «до/после» (§1–§2 ТЗ);
- скоуп/не-скоуп и изменяемый контракт (§4–§6);
- нормализация контуров, включая корневую причину ложной диагонали (§8);
- локальная дедупликация противоположных сторон (§9);
- полосы размещения размеров (§10);
- материал стен/штриховка и компоновка листа (§11–§12);
- footer/i18n (§14);
- модель/миграция/rollback, touch/a11y/perf/security (§15–§16);
- AC1–AC7, AC9–AC12 (§17) — не переоткрывались, дельта их доказательств не задевает;
- тест-план и Windows/Linux границы golden (§18);
- документация и release-артефакты (§19), карта изменений (§20).
Наследование не распространяется на AC8 и §13 — они разобраны заново выше.
Находки
Нет. High: 0. Medium: 0 (M1 закрыта, новых не появилось).
Что проверено и корректно
- M1 закрыта воспроизводимым способом: ссылка на неизменяемый commit вместо движущейся ветки — именно то процессуальное требование, которое не выполнялось в r1 (аналогия с #159, где ссылка тоже не была проверяемой).
- Текст стал честнее, а не более уверенным: явно признано несовпадение SHA-256 файла владельца с upstream и указана причина — это снижает, а не создаёт риск «выдать догадку за факт», потому что граница знания названа прямо (совпадают path/viewBox, не совпадает контейнер).
- AC8 и способ его доказательства не нуждались в изменении: «license check» как отдельный метод уже покрывает верификацию на этапе кода.
- Дельта не задела ни одну другую подсистему ТЗ; соседние разделы (§12 layout, §14 footer) остались согласованными сами с собой и с §13.
src/**не менялся — код по задаче ещё не написан, дешёвые гейты неприменимы на этом этапе, как и в r1.
Чего не проверял
- Не подтверждал независимо через веб, что зафиксированный upstream commit
bf6bdd0dd3f247f1a320d44d13fecdeda18c071cв репозиторииvmware-archive/clarity-assetsдействительно содержит указанныйcompass-line.svgсviewBox 0 0 36 36и обоимиd-путями, и чтоLICENSEв том же коммите — действительно MIT с copyright VMware 2018:WebFetchзапросил разрешение и не получил его в этой сессии, как иmcp__github__get_issue/get_issue_comments(те два я обошёл черезghCLI, уWebFetchтакого обхода нет). Это не молчаливый пропуск — то же ограничение зафиксировано в r1, и я явно оставляю его на код-ревью (см. «Закрытие раунда r1» выше). - Не перепроверял AC1–AC7, AC9–AC12 — дельта их не касается, основание наследования указано в разделе выше.
- Не гонял
tsc/test/build/golden/смоки/инварианты модели —src/**не менялся ни разу за всю историю ветки, гонять нечего; это верно и для r1, и для r2. - Не проверял
docs/specs/README.md/docs/STATUS.mdна актуальность записи — дельта их не касается (эти файлы не менялись междуbc93babdиHEAD, кроме самого добавления записи в r1, уже принятой).
Вердикт
Единственная находка предыдущего раунда (M1, Medium в скоупе) закрыта воспроизводимым способом; новых High/Medium/Low находок дельта не породила. Зелёный вердикт цикла не образует и бюджет не тратит (PROCESS.md §4, #227): израсходованный бюджет остаётся 1 из 4, заход — r2.
Материал раунда
- Ветка:
issue/482-pdf-export-polish, коммит5c1175cebc8d— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
4237e7ddaa1fab740d71ebb69648c824f2dd45c8git log --all --format='%H %T' | grep 4237e7ddaa1f - ТЗ
docs/specs/482-pdf-export-polish.md, блобc6f4fbd7cf5b3e84473ec68513054c3e5ff1e0f9git log --all --find-object=c6f4fbd7cf5b3e84473ec68513054c3e5ff1e0f9 -- docs/specs/482-pdf-export-polish.md