mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -1,11 +1,12 @@
|
||||
# Индекс ревью
|
||||
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1107, issue: 396. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1108, issue: 396. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
|
||||
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|
||||
|---|---|---|---|---:|---:|---|---|
|
||||
| #676 | [SPEC-REVIEW-676-r1.md](SPEC-REVIEW-676-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 2 | AC8 не называет проверку двух из трёх ветвей подавления подсказки; риск «рамка перехватывает события под другим инструментом» не привязан ни к одному AC; не задан tie-break для равного протяжки по обеим осям (снимаю сам) | `src/stairs-editor-model.ts` `stairs-view.ts` `demo/smoke_stairs.mjs` `src/furniture.ts` |
|
||||
| #676 | [SPEC-REVIEW-676-r2.md](SPEC-REVIEW-676-r2.md) | spec · r2 | 🟡 жёлтый | 0 | 1 | AC8/К8 перечисляют четыре ветви stairTargetState, а не пять; состояние self выпадает из… | `src/stairs-editor-model.ts` `docs/STAIRS.md` `src/stairs.ts` `stairs-view.ts` |
|
||||
| #676 | [SPEC-REVIEW-676-r3.md](SPEC-REVIEW-676-r3.md) | spec · r3 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #675 | [CODE-REVIEW-675-r1.md](CODE-REVIEW-675-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #673 | [CODE-REVIEW-673-r1.md](CODE-REVIEW-673-r1.md) | code · r1 | 🟡 жёлтый | 0 | 0 | docs/images/screenshots.json: закоммиченный sourceFingerprint не совпадает с тем, что р…; Комментарий автора в issue #673 называет SHA реализации 557d4e38e26b647437f2c931454737f… | `docs/images/screenshots.json` `demo/golden/matrix.mjs` `scripts/source-fingerprint.mjs` `accept.mjs` `policy.mjs` `AGENTS.md` `baselines-index.json` |
|
||||
| #673 | [CODE-REVIEW-673-r2.md](CODE-REVIEW-673-r2.md) | code · r2 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
# SPEC-REVIEW-676-r3
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/676
|
||||
- **Этап:** `S4-spec-review` (ревью ТЗ, PROCESS.md §2.4)
|
||||
- **Трек:** полный (метки `bug`, `P1`, `S4-spec-review`; лёгкий трек — нет,
|
||||
подтверждено аналитиком в r1: несколько поверхностей, новый UX-контракт
|
||||
размещения протяжкой и подсказки, сложность > 3).
|
||||
- **Материал:** тело issue #676, раздел `## ТЗ` (редакция 3, 27.09,
|
||||
`sha256 72bccdff…2183`) + 7 комментариев (добавился ровно один — «редакция
|
||||
3» — и вердикт r2).
|
||||
- **Заход:** r3 · блокирующих циклов израсходовано 2 из 4 (лимит для
|
||||
полного трека — 4; зелёный вердикт этого раунда цикл не тратит)
|
||||
- **Роль:** ревьюер ТЗ (не автор)
|
||||
|
||||
## Скоуп ревью (по дельте, PROCESS.md §2.10)
|
||||
|
||||
Предмет r3 — ровно одна точечная правка редакции 3, объявленная автором в
|
||||
комментарии `IC_kwDOTOcLQM8AAAABXQSkCA`: «К8 сформулирован инверсией —
|
||||
подсказка только при `stairTargetState === 'active'`, то же условие, что
|
||||
делает лестницу ссылкой; остальные четыре состояния перечислены поимённо,
|
||||
включая `self`. AC8 получил пятый шаг смока: `target_space_id: 'f1'` на
|
||||
этаже `f1` → подсказки нет.»
|
||||
|
||||
Это единственная находка Medium раунда r2 («AC8/К8 перечисляют четыре ветви
|
||||
`stairTargetState`, а не пять; состояние `self` выпадает из контракта
|
||||
тултипа»). Код задачи по-прежнему не существует: ветки `issue/676-*` нет
|
||||
(`git branch -a | grep -i 676` — пусто), `git diff 9fe7f88c..HEAD --stat`
|
||||
между материалом r2 и текущим `HEAD` (`19edda83`) показывает только
|
||||
публикацию документа `SPEC-REVIEW-676-r2.md` и обновление
|
||||
`docs/reviews/INDEX.md` — ни одной строки продуктового кода. Дифф кода для
|
||||
этой задачи не существует, гейты `typecheck`/`npm test`/`npm run build`/
|
||||
`check-docs.mjs`/смоки/`golden:verify`/инварианты — неприменимы на этом
|
||||
этапе, как и в r1/r2 (см. «Чего не проверял»).
|
||||
|
||||
Остальные разделы ТЗ (Сценарий, Скоуп/Не-скоуп, К1–К7, UX, модель данных,
|
||||
i18n, план автотестов кроме строки AC8, риски, откат, release-артефакты,
|
||||
«принято предположительно») дельтой r2→r3 не задеты — построчно сверены с
|
||||
содержанием, процитированным/подтверждённым в r1 и r2, расхождений нет; они
|
||||
наследуются без повторной проверки (см. «Унаследовано из r2»).
|
||||
|
||||
**SCOPE-проверка (`docs/SCOPE.md`):** не меняется относительно r1/r2 —
|
||||
сценарий закрывает J6 (редактирование объектов плана без регресса в
|
||||
сохранённых данных) и J1/J2 через корректную навигацию/подсказку лестницы в
|
||||
Просмотре.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
1. Подтверждено, что кода задачи всё ещё нет: `git branch -a | grep -i 676`
|
||||
не находит рабочую ветку; `git diff 9fe7f88c..HEAD --stat` (материал
|
||||
r2 → текущий `HEAD`) — только `docs/reviews/INDEX.md` (+3/-1) и добавление
|
||||
`docs/reviews/SPEC-REVIEW-676-r2.md` (211 строк, публикация отчёта r2).
|
||||
Никаких файлов `src/**`/`test/**`/`demo/**` в диффе нет.
|
||||
2. Прочитано тело issue #676 целиком (`gh issue view 676 --json body`,
|
||||
sha256 `72bccdff…2183`) и все 7 комментариев (`gh issue view 676 --json
|
||||
comments`), включая новый (редакция 3, `IC_…XQSkCA`) и вердикт r2
|
||||
(`IC_…XQQAzQ`).
|
||||
3. Сверена ровно одна правка редакции 3 с текстом находки r2 построчно:
|
||||
- **Medium (self, r2):** требовал либо переформулировать К8/AC8 как
|
||||
инверсию с пятым смоук-шагом на `self`, либо явно обосновать пропуск.
|
||||
Новый К8: «Подсказка показывается **только** когда
|
||||
`stairTargetState(...) === 'active'` — то же условие, что делает
|
||||
лестницу ссылкой… все остальные **четыре** состояния функции —
|
||||
`missing`… `self`… `deleted`… `fixed`… — подсказки не дают» — это ровно
|
||||
формулировка-инверсия из варианта (а), рекомендованного r2, с явным
|
||||
перечислением всех пяти исходов по имени. Новый AC8: «все **пять**
|
||||
состояний `stairTargetState`: `active`… `missing`… **`self`
|
||||
(`target_space_id: 'f1'` на этаже `f1`) — `null`**… `deleted`…
|
||||
`fixed`…» — пятый шаг добавлен буквально так, как просил r2.
|
||||
4. Перепроверена не только текстуально, а по исходной функции: заново
|
||||
прочитан `src/stairs-editor-model.ts:97-104` (`stairTargetState`,
|
||||
актуальный код на `HEAD` `19edda83`) — сигнатура и порядок веток не
|
||||
изменились с r2: возвращает `active | missing | self | deleted | fixed`;
|
||||
ветка `self` — `stair.target_space_id === currentSpaceId` (строка 101),
|
||||
проверяется до `spaceIds.has(...)`. Формулировка К8/AC8 редакции 3
|
||||
(«`self` — цель, совпадающая с текущим пространством», пример
|
||||
`target_space_id: 'f1'` на этаже `f1`) буквально соответствует этому
|
||||
коду — не является догадкой.
|
||||
5. Перепроверено, что не-скоуповый код Просмотра (`src/stairs-view.ts:64`,
|
||||
актуальная строка на `HEAD`: `const active = interactive && targetState
|
||||
=== 'active';`) уже применяет ровно ту же инверсию к навигации, что К8
|
||||
редакции 3 теперь явно требует для тултипа — новая формулировка
|
||||
контракта согласована с уже работающим соседним поведением, а не
|
||||
противоречит ему (одно условие `=== 'active'`, один источник истины для
|
||||
«когда лестница активна»).
|
||||
6. Сверено, что `docs/STAIRS.md:21-23` («A missing, self or deleted target
|
||||
leaves the stair visible and editable but shows a repair warning…») не
|
||||
противоречит новой формулировке К8 — канон уже группирует `self` с
|
||||
`missing`/`deleted` как непроходной для активации исход, задача лишь
|
||||
явно называет его вместо того, чтобы полагаться на «остальное».
|
||||
7. Разделы, не тронутые дельтой r2→r3 (Сценарий, Скоуп/Не-скоуп, К1–К7 кроме
|
||||
упомянутого в п. 3, UX, модель данных, i18n, план автотестов кроме
|
||||
строки AC8, риски, откат, release-артефакты, «принято предположительно»),
|
||||
не перечитывались заново построчно против кода — они уже проверены в
|
||||
r1/r2 и текстуально идентичны в текущем теле issue (сверено чтением
|
||||
полного текущего тела против содержания, процитированного в
|
||||
SPEC-REVIEW-676-r1.md и SPEC-REVIEW-676-r2.md); см. «Унаследовано из r2».
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. Единственная находка r2 (Medium, ветка `self` в К8/AC8) закрыта именно
|
||||
так, как r2 рекомендовал технически (вариант «а» — инверсия условия плюс
|
||||
пятый смоук-шаг), формулировка проверена по актуальному коду
|
||||
(`stairs-editor-model.ts`, `stairs-view.ts`) и не расходится с ним. Новых
|
||||
несоответствий, внесённых самой правкой r3, не найдено.
|
||||
|
||||
## Закрытие раунда r2
|
||||
|
||||
| Находка r2 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| Medium: АС8/К8 перечисляют четыре ветви `stairTargetState`, а не пять; `self` выпадает из контракта тултипа | К8 переформулирован как инверсия («подсказка только при `active`», остальные четыре ветви — включая `self` — перечислены поимённо); AC8 получил пятый смоук-шаг для `self` | Тело issue #676, редакция 3, разделы «Контракт поведения → К8» и таблица «Критерии приёмки → AC8» (комментарий `IC_kwDOTOcLQM8AAAABXQSkCA`); подтверждено чтением `src/stairs-editor-model.ts:97-104` на `HEAD` `19edda83` — сигнатура и ветка `self` совпадают с текстом К8/AC8 |
|
||||
|
||||
## Унаследовано из r2 (и транзитивно из r1)
|
||||
|
||||
Принято без повторной построчной проверки против кода в этом раунде —
|
||||
проверено ранее и не задето дельтой r2→r3:
|
||||
|
||||
- Обязательные разделы §7.1 (Сценарий, Что человек увидит, Проблема,
|
||||
Скоуп/Не-скоуп, Контракт К1–К7, UX, Модель данных и миграция, i18n, План
|
||||
автотестов кроме строки AC8, Риски, Откат, Release-артефакты, Принято
|
||||
предположительно) — присутствуют и однозначны (SPEC-REVIEW-676-r1.md,
|
||||
раздел «Как проверялось» пп. 4–8; SPEC-REVIEW-676-r2.md, раздел «Что
|
||||
проверено и корректно»).
|
||||
- Диагностика «Проблема» и фактический фундамент контракта (константы
|
||||
`STAIR_MIN_CM`/`STAIR_MAX_CM`/`FURN_WALL_CELLS`, существующие функции
|
||||
`resizeFurnitureTransform`, `fieldToCm`/`clampWallCm`, порядок отрисовки
|
||||
`wallbodies` vs `_renderTextFrame`, единый CSS-класс курсора, i18n-паритет,
|
||||
4 golden-сцены лестниц) — сверены с кодом на материале r1
|
||||
(`f1a87fba`/`4c3048e8`) и не менялись с тех пор ни в issue, ни в
|
||||
соответствующем коде (точечно перепроверено для `stairs-editor-model.ts`
|
||||
и `stairs-view.ts` в этом раунде, см. «Как проверялось» пп. 4–5; остальные
|
||||
файлы не тронуты дельтой и не перечитывались).
|
||||
- AC12 (инертность рамки узлов под другими инструментами) и его связь с К2 —
|
||||
закрыты в r2, текст не менялся в r3 (SPEC-REVIEW-676-r2.md, «Что проверено
|
||||
и корректно»).
|
||||
- Tie-break диагонали 45° в К1 — закрыт в r2 (низкая находка r1), текст не
|
||||
менялся в r3.
|
||||
- Все 9 исходных дефектов из «Что происходит» сведены к контрактам К1–К8 и
|
||||
покрыты AC1–AC11 (плюс AC12 из r2) без пропусков — установлено в r1, не
|
||||
затронуто дельтой r2→r3 (SPEC-REVIEW-676-r1.md, «Что проверено и
|
||||
корректно»).
|
||||
- Откат и модель данных не меняются, `docs/CONFIG-COMPATIBILITY.md` не
|
||||
задевается — установлено в r1, текст раздела не менялся.
|
||||
|
||||
## Что проверено и корректно (этот раунд)
|
||||
|
||||
- Правка редакции 3 текстуально и по коду закрывает ровно ту находку, ради
|
||||
которой был начат раунд r3 — не больше и не меньше (не расширяет и не
|
||||
сужает скоуп, не меняет ничего в других разделах ТЗ).
|
||||
- Новая формулировка К8 согласована с уже существующим, не-скоуповым кодом
|
||||
Просмотра (`stairs-view.ts:64`, инверсия `=== 'active'`) — один источник
|
||||
истины для «когда лестница активна», а не два разных условия для
|
||||
тултипа и навигации.
|
||||
- AC8 остаётся однозначным и называет способ доказательства (`smoke`, пять
|
||||
отдельных шагов с отдельными флагами) для каждого из пяти состояний
|
||||
функции — буквальная реализация по тексту не может закрыть AC8, пропустив
|
||||
`self`, как это было возможно с редакцией 2.
|
||||
- Материал раунда корректно идентифицирован: код задачи по-прежнему
|
||||
отсутствует (только публикация документа r2 в диффе `9fe7f88c..HEAD`),
|
||||
так что вся оценка — снова чисто по тексту ТЗ и по уже существующему коду
|
||||
соседних (не-скоуповых) модулей, которые контракт называет.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Не запускал `npm run typecheck`/`npm test`/`npm run build`,
|
||||
`node scripts/check-docs.mjs`, смоки, `golden:verify`, инварианты модели —
|
||||
кода задачи не существует ни на материале r1/r2, ни на текущем `HEAD`
|
||||
(`19edda83`): `git branch -a` не находит ветку `issue/676-*`, `git diff
|
||||
9fe7f88c..HEAD` содержит только документ ревью r2 и индекс. Дифф для этих
|
||||
гейтов не существует, они относятся к этапу код-ревью, который наступит
|
||||
после реализации.
|
||||
- Не перечитывал заново построчно против кода разделы, не тронутые дельтой
|
||||
r2→r3 (К1–К7 кроме ветки `self`, УХ, модель данных, i18n, план автотестов
|
||||
кроме AC8, риски, откат, release-артефакты) — они уже дважды проверены
|
||||
(r1 по коду, r2 текстуально против r1) и текстуально идентичны в текущем
|
||||
теле issue; см. «Унаследовано из r2».
|
||||
- Не проверял заново достижимость `self` через реальный UI (перенос/слияние
|
||||
помещений) — для снятия находки r2 было достаточно того, что модель
|
||||
(`stairs.ts:84`) не отвергает такие данные и канон (`STAIRS.md:21-23`)
|
||||
документирует состояние как поддерживаемое; глубже не уходил, как и в r2.
|
||||
- Не проверял #663/#669 по существу (смежные задачи, не в скоупе).
|
||||
|
||||
## Вердикт
|
||||
|
||||
Вердикт: зелёный · заход r3 · блокирующих циклов 2/4 · High: 0 · Medium: 0
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `19edda83e35e` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `4963bc95c5187a923844c4e6ab5ae387a0af5094`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 4963bc95c518
|
||||
```
|
||||
- Тело issue: `72bccdffa1d7cdfdd71c8c8ee5d1cd66f64b6aba7db2003b718c0af2f2292183`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user