mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 13:18:58 +00:00
@@ -0,0 +1,129 @@
|
||||
# CODE-REVIEW-692-r1
|
||||
|
||||
Материал раунда: `git log --oneline origin/dev..HEAD` = 1 коммит
|
||||
(`bb33626f3806fbde5ecdfb3e65e99669c99eae71`), ветка `issue/692-perf-first-stable`
|
||||
от `dev` @ `4c74e80a`. Заход r1, трек `track:show`, блокирующих циклов
|
||||
израсходовано 0 из 2.
|
||||
|
||||
## Скоуп
|
||||
|
||||
Инфраструктурная задача класса B: поднять `hardMaxMs` метрики
|
||||
`firstStableRenderMs` профиля `large-house-interaction-v1` с 3000 до 3400 мс
|
||||
(и в его smoke-двойнике), задокументировать обоснование в
|
||||
`demo/performance/README.md` и закрепить число тестом. Повод — находка ревью
|
||||
#689 (CODE-REVIEW-689-r1): бюджет краснел на 2.4 мс на честном Validate-прогоне
|
||||
из-за того, что уровень `firstStableRenderMs` вырос между линиями 1.77 и
|
||||
1.78.0, а не из-за кода #689. Задача обслуживает J6 (SCOPE.md: «Keep the plan
|
||||
true as the home evolves») косвенно — держит CI performance-гейт полезным
|
||||
(ловит регрессии), а не шумящим ложными красными.
|
||||
|
||||
Файлы диффа (4, все класса B):
|
||||
|
||||
| Файл | Изменение |
|
||||
|---|---|
|
||||
| `demo/performance/budgets-large-house-interaction.json` | `firstStableRenderMs.hardMaxMs` 3000 → 3400 |
|
||||
| `demo/performance/budgets-interaction-smoke.json` | то же число, синхронно (смок = полный профиль, #473 AC4) |
|
||||
| `demo/performance/README.md` | абзац с рядом замеров и обоснованием, по образцу существующего абзаца про `spaceSwitchMs` (#675) |
|
||||
| `test/performance-budget.test.mjs` | новый тест `#692`, закрепляющий число и точки ряда |
|
||||
|
||||
Файлов класса A нет (`src/**`, Python не тронуты) — подтверждено диффом.
|
||||
`User-Visible: no` в трейлере коммита корректен: изменение не меняет ничего,
|
||||
что видит пользователь карточки, только CI-гейт. Оба changelog поэтому
|
||||
не требуются и не тронуты — правильно.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
| Гейт | Прогнан | Результат |
|
||||
|---|---|---|
|
||||
| `typecheck` / `npm test` / `npm run build` + bundle-policy | нет, повторно | Validate на этом точном SHA `bb33626f` зелёный (run [36673058928](https://github.com/Matysh/houseplan-card/actions/runs/36673058928)) — дешёвые гейты подтверждены, перегонять не стал |
|
||||
| `node --test test/performance-budget.test.mjs` | да, локально | 15/15 зелёных, включая новый тест `#692` |
|
||||
| Тест `#692` умеет падать | да, проверено мутацией | `hardMaxMs` полного профиля вручную возвращён 3400 → 3000, тест `#692` красный (`not ok 11`, `testCodeFailure`); файл восстановлен, `git status` чист |
|
||||
| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | да | «Исполняемого frontend-диффа нет (`src/**/*.ts` не тронут)… смоки не выбираются — выбирать нечего» — браузерные смоки не нужны |
|
||||
| `golden:verify` | нет | метки `ci:golden` на issue нет, golden-баз не тронуто |
|
||||
| `pytest tests_backend` | нет | Python не тронут |
|
||||
| `npm run invariants` | нет | геометрия не тронута |
|
||||
| Свежий прогон `large-house-interaction-v1` (7 сэмплов) | нет | не требуется AC; авторитетный ряд — прогоны `performance.yml` (перечислены в оценке владельца и в README), не разовый повторный замер этой веткой, которая рантайм не меняет |
|
||||
| Мутанты в реестре | не гонял (и не должен) | track `show`: мутанты в разработке не гоняются ни на каком треке (#709); отсутствие прогона не находка |
|
||||
|
||||
Кросс-проверка «одно число — один источник» (§8): `firstStableRenderMs`
|
||||
встречается в других бюджетных файлах (`budgets.json`,
|
||||
`budgets-isometric-smoke.json`, `budgets-large-house-plan-snap.json`,
|
||||
`budgets-large-house-isometric.json`, `budgets-isometric-stage3-dense.json`),
|
||||
но это другие профили (default/plan-snap/isometric) с собственными
|
||||
потолками (3000/3500), не дубликаты значения `large-house-interaction-v1` —
|
||||
их не трогали и не должны были. Синхронизированы ровно два файла, которые и
|
||||
названы владельцем в оценке как «одно число».
|
||||
|
||||
## AC · чем доказан · чем краснеет
|
||||
|
||||
| AC | Чем доказан | Чем краснеет |
|
||||
|---|---|---|
|
||||
| AC1 — `hardMaxMs` = 3400 в обоих файлах (полный профиль и смок), коэффициент/допуск полного сравнения не ослаблены | `test/performance-budget.test.mjs:254-269`, прогнан локально, 15/15 | Проверено мутацией: ручной откат `hardMaxMs` на 3000 красит тест `#692` (`not ok`, см. таблицу выше); тест также проверяет `smoke.hardMaxMs === full.hardMaxMs`, `maxRegressionRatio === 0.3`, `noiseAllowanceMs === 250` — ослабление любого из них тоже красит соответствующий `assert.equal` |
|
||||
| AC2 — ряд и обоснование в README, тест закрепляет число и точки ряда | Прочитан текст README (строки 102–111): числа (2769.0, 2838.2, 2777.3, 2801.7, 2925.0, 2925.2, 3144.8, 3400) совпадают построчно с оценкой владельца в issue и с константами в тесте `#692`. Проверено чтением, не исполнением — README не исполняется | Тест `#692` пинит те же числа рядов (`level177`, `level178`, `worst`) отдельно от prose — рассинхрон README/теста не будет пойман автоматически, но это документационный AC, не защитный; риск низкий (числа скопированы дословно, сверены вручную) |
|
||||
|
||||
Оба AC выполнены. AC1 — защитный (лимит/потолок гейта), таблица заполнена
|
||||
результатом реального прогона мутации, третий столбец не пуст.
|
||||
|
||||
## Проверено и корректно
|
||||
|
||||
- Арифметика обоснования сходится: 3400 / 2925.2 (макс. уровня 1.78) ≈ 1.162
|
||||
→ «+16 %», 3400 / 3144.8 (худший прогон) ≈ 1.081 → «+8 %» — оба числа из
|
||||
текста issue/README подтверждены пересчётом.
|
||||
- Тест `#692` — не просто фиксация числа: он же проверяет полосу 15–20 % над
|
||||
уровнем 1.78 (`ceiling >= max(level178)*1.15` и `<= max(level178)*1.2`),
|
||||
то есть страхует от будущего чрезмерного расширения потолка тем же
|
||||
тестом, что фиксирует его сегодняшнее значение.
|
||||
- Формулировка в README и коммите продолжает точно тот же стиль и структуру
|
||||
доказательства, что и предыдущий прецедент того же файла — абзац про
|
||||
`spaceSwitchMs`/#675 (строки 113–124): уровень, шум раннера, запас, что
|
||||
ловит меньшие регрессии.
|
||||
- Трейлеры коммита корректны: `Issue: #692`, `User-Visible: no` (верно —
|
||||
поведение продукта не меняется), `Claude-Session` присутствует.
|
||||
- Рабочая копия после моей мутационной проверки восстановлена в исходное
|
||||
состояние (`git status --porcelain` пуст).
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Не гонял новый 7-сэмпловый прогон `large-house-interaction-v1` в CI —
|
||||
задача сознательно опирается на уже существующий авторитетный ряд
|
||||
`performance.yml` (перечислен владельцем в оценке), а не производит новое
|
||||
измерение; AC этого не требует.
|
||||
- Не гонял `golden:verify`, `pytest tests_backend`, `npm run invariants` —
|
||||
ни один не применим к этому диффу (нет golden-меток, Python, геометрии).
|
||||
- Не перегонял `tsc --noEmit` / `npm test` (полный) / `npm run build` —
|
||||
зелёный Validate на этом точном SHA (`bb33626f`, run 36673058928) уже их
|
||||
подтвердил.
|
||||
- Не запускал реестр мутантов — по правилам track `show` (#709) он не
|
||||
гоняется на этом этапе вообще; заменил его точечной ручной мутацией
|
||||
одного значения, чтобы лично убедиться, что новый тест умеет падать.
|
||||
- Не проверял шаг +4.5 % между линиями 1.77 и 1.78.0 по существу — задача
|
||||
явно выносит бисект за скоуп («Шаг… здесь не разбираю… если нужен бисект —
|
||||
отдельная задача»), и это соответствует объёму track `show` (до трёх AC).
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. High: 0, Medium: 0, Low: 0.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. AC1 и AC2 выполнены и доказаны — AC1 автотестом с подтверждённой
|
||||
способностью падать (проверено мутацией самим ревьюером), AC2 чтением с
|
||||
явной пометкой «проверено чтением, не исполнением». Дешёвые гейты подтверждены
|
||||
зелёным Validate на этом SHA, гейты по диффу (смоки, golden, pytest,
|
||||
инварианты) не применимы и это обосновано в разделе «Чего не проверял».
|
||||
Расхождений с `docs/SCOPE.md` или `docs/USER-GUIDE.ru.md` нет — видимого
|
||||
поведения нет вовсе.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/692-perf-first-stable`, коммит `bb33626f3806` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `0d4b3fe50cf39c6d21fae4dca3f1ce18db57fcf6`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 0d4b3fe50cf3
|
||||
```
|
||||
- Тело issue: `0450569e776cc3dadca6ebd0463bf615cf328185a6d8dfae9ca0af3acb4c062f`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user