mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 20:29:00 +00:00
@@ -1,10 +1,11 @@
|
||||
# Индекс ревью
|
||||
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 242, issue: 120. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 243, issue: 121. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
|
||||
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|
||||
|---|---|---|---|---:|---:|---|---|
|
||||
| бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — |
|
||||
| #744 | [SPEC-REVIEW-744-r1.md](SPEC-REVIEW-744-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #742 | [SPEC-REVIEW-742-r1.md](SPEC-REVIEW-742-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | устаревшее число в AC6 (не блокирует) | `src/houseplan-card.ts` `test/core-file-budget.test.mjs` |
|
||||
| #741 | [CODE-REVIEW-741-r1.md](CODE-REVIEW-741-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #740 | [SPEC-REVIEW-740-r1.md](SPEC-REVIEW-740-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | устаревший номер строки в «Проблема», п.2 | `src/stairs-view.ts` `src/stairs-editor.ts` `stairs-view.ts` `stairs-editor.ts` `stairs.ts` `large-house.mjs` `matrix.mjs` |
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
# SPEC-REVIEW-744-r1
|
||||
|
||||
Issue: #744 — «Производительность: кэш чистого пола сбрасывается любой правкой конфига»
|
||||
Этап: spec (PROCESS.md §2.4) · Трек: ask (§5, критерий «перф») · Заход: r1 · блокирующих циклов 0/4
|
||||
Материал: тело issue #744 (раздел `## ТЗ`), сверено с кодом на `origin/dev` `8b7725ac` (SHA, на который ссылается сам автор) и с рабочей копией `5a49c8c3` — расхождений в затронутых файлах между этими SHA нет (единственный коммит между ними — несвязанный тест луны).
|
||||
Route: fix (трек уже `ask`, переквалификация не применяется).
|
||||
|
||||
## Скоуп
|
||||
|
||||
Задача меняет ключи и инвалидацию четырёх структурных геометрических кэшей
|
||||
этажа (`_physicalBodiesCache`, `_wallUnionGeometry`/`_wallUnionPool`,
|
||||
`_innerRoomContour`/`_innerContourCache`, `cleanFloorForRoom`/`_cleanFloorCache`):
|
||||
сегодня ключ несёт глобальный `_cfgEpoch`, из-за чего правка одного этажа
|
||||
«остужает» кэши всех остальных. Цель — ключ на отпечаток содержимого записи
|
||||
конкретного этажа, без потери инвалидации при правках, которые законно трогают
|
||||
несколько этажей (лестницы, общие стены). Служит J1/J6 docs/SCOPE.md — отзывчивость
|
||||
переключения этажей и честность редакторского цикла; видимых новых функций нет.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Ревью ТЗ на этом этапе не включает выполнение гейтов (код не писался) — проверялась
|
||||
только состоятельность документа: обязательные разделы §7.1, однозначность и
|
||||
доказуемость каждого AC, и — так как расследование опирается на построчные
|
||||
ссылки на код — сверка каждой процитированной строки с реальным деревом,
|
||||
а не с заявлением автора.
|
||||
|
||||
Построчно сверено чтением (не исполнением) с текущим деревом:
|
||||
|
||||
| Утверждение ТЗ | Файл:строка в ТЗ | Проверено |
|
||||
|---|---|---|
|
||||
| `roomKey`/ключ чистого пола, LRU 600 | `src/clean-floor.ts:32–33,64` | совпадает дословно |
|
||||
| Ключ оболочки стен, пул LRU 8 | `src/houseplan-card.ts:8755,8777` | совпадает (`:8755`, `lruWrite(... 8)` на той же строке диапазона) |
|
||||
| Ключ внутренних контуров, LRU 600 | `:8806` | совпадает |
|
||||
| Ключ физических тел, «одна запись» | `:9462–9463` | совпадает — это действительно единственный слот, не `Map`; автор сам это отмечает («одна запись») |
|
||||
| `_saveConfig` поднимает эпоху, комментарий «every mutation path ends here» | `:7634–7637` | совпадает (функция с 7634, `_cfgEpoch++` на 7635) |
|
||||
| Замена `_serverCfg` поднимает эпоху кроме geometry-preserving исключения | `:4019–4025` | совпадает |
|
||||
| `StairsEditor.write` поднимает эпоху и чистит `_cleanFloorCache` целиком | `src/stairs-editor.ts:149–156` | совпадает (`clear()` действительно без учёта этажа — текущий баг подтверждён) |
|
||||
| `contentFingerprint` существует, уже используется для `_model` | `src/visual-continuity.ts:439`, `houseplan-card.ts:3817` | совпадает |
|
||||
| `cacheSnapshot` считает `wallUnion` как 0/1, не считает `innerContour` вовсе | `demo/benchmark_large_house.mjs:163–172` | совпадает — подтверждает «слепоту» свидетеля #735, на которую опирается AC3 |
|
||||
| Потолок `src/houseplan-card.ts` — 12896 строк, запас к моменту ТЗ — 4 | `test/core-file-budget.test.mjs:52` | совпадает: файл сейчас 12892 строки |
|
||||
| Явные полные сбросы при откате и восстановлении геометрии остаются | `src/houseplan-editor-runtime.ts:1474–1477, 1688–1691` | совпадает |
|
||||
| Фикстуры-прецеденты для нового смока (`physicalize`, партиции/колонна) | `demo/smoke_space_switch_transitions.mjs:55–66`, `demo/smoke_space_card.mjs:18–34` | совпадает по смыслу и содержимому |
|
||||
| `performance.yml` можно запустить вручную (`workflow_dispatch`) для AC4 | `.github/workflows/performance.yml:15` | совпадает |
|
||||
|
||||
Ни одно утверждение о текущем поведении кода не разошлось с деревом. Это
|
||||
резко снижает риск «ТЗ описывает код, которого нет».
|
||||
|
||||
## Находки
|
||||
|
||||
Находок High и Medium нет.
|
||||
|
||||
Low (снято с записью, не требует правки): раздел «План автотестов» даёт явную
|
||||
красную причину для AC1, AC2а, AC2б, но не называет отдельный красный случай
|
||||
для AC2в (поведение во время resize-превью). Это не защитный AC в смысле §2.7
|
||||
(не валидация/гард, а утверждение о неизменности поведения, которое уже
|
||||
корректно на dev), и на стадии ТЗ отдельная строка «чем краснеет» для него не
|
||||
обязательна — но на код-ревью пустое место здесь не должно остаться пустым по
|
||||
умолчанию, если тест действительно нечувствителен к ошибке в превью-ветке.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- Обязательные разделы §7.1 присутствуют все: сценарий (две персоны из
|
||||
`docs/SCOPE.md` — админ-десктоп, домочадцы-киоск), что человек увидит
|
||||
до/после (одной фразой, без терминов реализации), проблема (5 нумерованных
|
||||
пунктов с кодовыми ссылками), скоуп и не-скоуп (с явной мотивировкой каждого
|
||||
исключения), контракт поведения К1–К5, UX/данные/i18n/touch (сжато,
|
||||
обоснованно — новых элементов нет), критерии приёмки AC1–AC5 с колонками
|
||||
«Доказательство» и «Oracle», план автотестов, риски, откат,
|
||||
release-артефакты (текст changelog RU+EN уже написан).
|
||||
- Каждый AC однозначен и проверяем конкретным механизмом: AC1/AC2 — новый
|
||||
смок с названным сценарием воздействия и named oracle (независимая карточка,
|
||||
построенная с нуля на том же конфиге — классический oracle против «кэш
|
||||
соврал»); AC3 — правка полей бенчмарка плюс существующий сторож диапазона;
|
||||
AC4 — реальный perf-workflow плюс локальный зонд тем же методом, что в «Итоге
|
||||
исследования»; AC5 — перечисленные гейты и два конкретных мутанта с
|
||||
названными guard AC.
|
||||
- Защитный AC (К1 «правка другого этажа не остужает этот», К2 «устаревший
|
||||
кадр не отдаётся») доказывается по правилам §2.7 уже на стадии ТЗ: для
|
||||
AC1 назван красный случай на текущем коде (эпоха в ключе), для AC2а —
|
||||
названный мутант без отпечатка содержимого, для AC2б — красный случай на
|
||||
текущем коде (`StairsEditor.write` чистит чужой кэш). Пустых строк в этой
|
||||
части нет.
|
||||
- Главный риск задачи («устаревший кадр» — неполный ключ отдаст старую
|
||||
геометрию) назван автором явно и закрыт мерой (ключ — отпечаток всей записи
|
||||
этажа «по построению», плюс независимый oracle AC2а) — это ровно то дерево
|
||||
рассуждений, которого требует правка кэша на горячем пути.
|
||||
- «Принято предположительно» — пять технических решений, явно помеченных как
|
||||
не-продуктовые и подлежащие пересмотру ревьюером без эскалации владельцу;
|
||||
каждое обосновано (трейд-офф полнота/скорость ключа, выбор четырёх кэшей на
|
||||
основе замера, отказ от `StairsEditor.write` чистки по данным замера, смок
|
||||
вместо новой метрики бенчмарка — экономия на правке `budgets-*.json`,
|
||||
отдельный модуль ключа — из-за строкового бюджета). Технических споров,
|
||||
которые требовали бы вердикта вместо решения автора, не нашлось.
|
||||
- Раздел «Вопросы владельцу» — пусто, с явным обоснованием («видимое изменение
|
||||
одно, расширение на четыре кэша — техническое средство без отдельного
|
||||
видимого эффекта»); никакого технического вопроса, спрятанного под видом
|
||||
вопроса владельцу, в тексте нет — весь список открытых решений находится в
|
||||
«Принято предположительно», а не вынесен наружу.
|
||||
- Трейлер `User-Visible: yes` обоснован (один наблюдаемый эффект —
|
||||
отзывчивость переключения этажей после правки) и текст changelog уже
|
||||
подготовлен на русском и английском в самой ТЗ — на коммите кода потребуется
|
||||
перенести его в оба `docs/CHANGELOG*.md`, это уже учтено в «Затронутые файлы».
|
||||
- Трек `ask` обоснован по критерию §5 «перф»: горячий путь переключения этажа,
|
||||
задействованный предыдущими перф-правками (#694/#725/#740), риск неверного
|
||||
кадра, а не просто медленного — ТЗ сама называет этот критерий, совпадает с
|
||||
меткой `track:ask` на issue.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Исполнение гейтов (`tsc`, `npm test`, `npm run build`, golden, perf) — кода
|
||||
ещё нет, этап spec их не требует.
|
||||
- Прогон `smoke-select`, мутационных якорей или perf-workflow — неприменимо до
|
||||
реализации.
|
||||
- Фактическую корректность числовых замеров из «Итога исследования» (607 мс,
|
||||
3 % вклад чистого пола и т. п.) — они явно помечены автором как локальная
|
||||
диагностика, а не доказательство (это доказывает только будущий AC4), и
|
||||
ревью ТЗ не требует их перепроверки.
|
||||
- Состояние соседней задачи #742 (на неё ссылается пункт 5 «Принято
|
||||
предположительно» про запас строк) — не часть материала этого ревью; если к
|
||||
моменту кода запас бюджета будет другим, это всплывёт на гейте
|
||||
`core-file-budget`, а не здесь.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. Документ ТЗ полон, построчные ссылки на код проверены и совпадают,
|
||||
AC однозначны и снабжены доказательством и oracle, защитные AC доказаны по
|
||||
правилам §2.7 уже на этой стадии, открытых продуктовых вопросов нет. High: 0,
|
||||
Medium: 0.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `5a49c8c32df9` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `436061a24c6d0fb33f9cc036606d03922b5476a9`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 436061a24c6d
|
||||
```
|
||||
- Тело issue: `9dec80eead95ea0cbc014364d7ed09eaef1f7f45b7e2c70f97f1a95c586ac465`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
Reference in New Issue
Block a user