docs: review document for #482

Issue: #482
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-07 06:23:59 +00:00
parent 5c1175cebc
commit 91331041d3
+201
View File
@@ -0,0 +1,201 @@
# 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) — дельта
локальна, полный повторный разбор не требуется, обоснование ниже.
1. **Вердикт предыдущего раунда:** комментарий `claude`, 2026-09-07T06:15:24Z —
жёлтый · r1 · High: 0 · Medium: 1 → в задаче (M1, provenance/лицензия
векторного компаса). Документ: `docs/reviews/SPEC-REVIEW-482-r1.md`.
2. **Материал 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 не было.
3. **Дельта:** `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.
4. **`src/**` не тронут:** `git log --oneline 08aad891..HEAD -- src/` пуст —
ветка по-прежнему содержит только ТЗ и review-документы поверх
`v1.73.0-beta.3`; это по-прежнему этап spec, гейтов кода нет и не может
быть.
5. **Почему разбор сокращённый, а не полный:** дельта не задевает ни ребейз на
ушедший вперёд `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 commit `bf6bdd0dd3f247f1a320d44d13fecdeda18c071c`
(сам 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` (те два я обошёл через `gh`
CLI, у `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.
---
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/482-pdf-export-polish`, коммит `5c1175cebc8d` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `4237e7ddaa1fab740d71ebb69648c824f2dd45c8`
```
git log --all --format='%H %T' | grep 4237e7ddaa1f
```
- ТЗ `docs/specs/482-pdf-export-polish.md`, блоб `c6f4fbd7cf5b3e84473ec68513054c3e5ff1e0f9`
```
git log --all --find-object=c6f4fbd7cf5b3e84473ec68513054c3e5ff1e0f9 -- docs/specs/482-pdf-export-polish.md
```