From 5fbb9339c6cf54d1881a8b21414c0aa28f7f3845 Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 6 Sep 2026 14:21:11 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20spec=20#473=20=E2=80=94=20=D1=81=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=D1=80=D0=B8=D0=B9,=20=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B8,=20=D0=B4=D0=BE=D0=BA=D0=B0=D0=B7=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=BE=20AC7,=20=D1=84?= =?UTF-8?q?=D0=BB=D0=B0=D0=B3=D0=B8=20=D0=B1=D0=B5=D0=BD=D1=87=D0=BC=D0=B0?= =?UTF-8?q?=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Visible: no Issue: #473 --- .../specs/473-iso-perf-witnesses-and-smoke.md | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/docs/specs/473-iso-perf-witnesses-and-smoke.md b/docs/specs/473-iso-perf-witnesses-and-smoke.md index 03c7d24c..5e2068d0 100644 --- a/docs/specs/473-iso-perf-witnesses-and-smoke.md +++ b/docs/specs/473-iso-perf-witnesses-and-smoke.md @@ -26,6 +26,23 @@ LRU-кэш размещений с подписью, кэш по идентич Два дефекта одного класса: горячий код без свидетелей и гейт, который есть, но не там, где нужен. +## 1.1. Сценарий + +Персона — автор задачи, трогающей путь отрисовки (`src/iso-*`, `src/live-*`, +`houseplan-card.ts`), и ревьюер этой задачи. Автор пушит ветку; Validate +запускается сам. Ревьюер читает вердикт Validate на SHA как подтверждение +дешёвых гейтов и тратит бюджет раунда на чтение кода. + +## 1.2. Что человек увидит до и после + +До: регрессия первого кадра в 6,5 раза невидима до предрелизного полного +бенчмарка; ревью проходит зелёным; исправление идёт под тегом по §11.4. + +После: на первом же пуше ветки, задевшей `src/iso-*`, job `performance_smoke` +краснеет с абсолютным потолком профиля — «первый кадр 9 870 мс при потолке +3 500» — и автор видит это до того, как ревью началось. Для веток, не +трогающих отрисовку, ничего не меняется: те же два glow-профиля, то же время. + ## 2. Скоуп 1. Свидетели на четыре механизма перф-дельты (§4) — через них проходит и @@ -71,9 +88,12 @@ LRU-кэш размещений с подписью, кэш по идентич `src/houseplan-card.ts` — добавляется `large-house-interaction-v1`. Классификацию делает `changes` (существующий job) двумя новыми выходами -`perf_iso` и `perf_interaction` по тем же `has(...)`-шаблонам. Профили идут с -`--variants=60 --samples=3 --warmups=1 --absolute-only` и **своими -smoke-бюджетами** `budgets-isometric-smoke.json`, `budgets-interaction-smoke.json` +`perf_iso` и `perf_interaction` по тем же `has(...)`-шаблонам. Профили идут +через `demo/benchmark_large_house.mjs` с `--samples=3 --warmups=1` +(`--variants` — флаг только `benchmark_glow.mjs`, у `benchmark_large_house` +его нет: `demo/benchmark_large_house.mjs:17-18` принимает `samples`, +`warmups`, `target-root`, `profile`, `output`), сравнение — +`benchmark:compare --absolute-only` и **свои smoke-бюджеты** `budgets-isometric-smoke.json`, `budgets-interaction-smoke.json` (`minimumSamples: 3`, потолки — `hardMaxMs` из полных профилей). Регрессионные коэффициенты в смоке не участвуют: сравнивать не с чем, абсолютный потолок достаточен — 9 870 мс против 3 500 он ловит с одного образца. @@ -100,7 +120,22 @@ smoke-бюджетами** `budgets-isometric-smoke.json`, `budgets-interaction- | AC4 | Smoke-бюджеты новых профилей валидны для `benchmark:compare --absolute-only` и повторяют `hardMaxMs` полных | unit: чтение обоих файлов, сравнение потолков | | AC5 | Ключ `reuse` для `performance_smoke` различает наборы профилей | контрактный тест на YAML | | AC6 | Воспроизведение: на дереве `de215578` изометрический smoke-бюджет краснеет по первому кадру | замер один раз при реализации, результат в issue с командой | -| AC7 | На текущем `dev` оба новых профиля укладываются в потолки за 3 образца | прогон в CI этой ветки | +| AC7 | На текущем `dev` оба новых профиля укладываются в smoke-потолки за 3 образца | вручную при реализации, как AC6: команды и числа в issue. Дифф этой задачи не задевает продуктовых путей, поэтому её собственный Validate новые профили не запустит, а `workflow_dispatch` у `validate.yml` нет | +| AC8 | Диффозависимость доказана на самом workflow: контрактный тест подставляет в `changes` дифф из `src/iso-x.ts` и ожидает `perf_iso=true`, из `src/live-x.ts` — `perf_interaction=true`, из `docs/x.md` — оба `false` | unit на функцию классификации, вынесенную из inline-shell в `scripts/classify-changes.mjs` (или на извлечённые `has(...)`-шаблоны) | + +## 7.1. UX, модель данных, i18n + +Не применимо: продуктовый код, конфиг, хранилище и словари не меняются; +пользователь ничего не увидит. Единственная поверхность — CI. + +## 7.2. Риски и меры + +| Риск | Мера | +|---|---| +| Изометрический профиль на 3 образцах удлиняет `performance_smoke` за 20-минутный лимит job | замер при реализации (AC7); при превышении лимит поднимается в этой же задаче с числом | +| Абсолютный smoke-потолок на 3 образцах шумит на общем раннере и красит честные ветки | потолки берутся из `hardMaxMs` полных профилей — это «в разы», а не «на проценты»; регрессионные коэффициенты в смок сознательно не входят | +| Свидетель AABB недостижим существующей фикстурой (перекрытие вместо касания) | фикстура касания добавляется, отрицательный прогон обязателен до заявления мутанта (правило после #426) | +| Ключ `reuse` без набора профилей засчитает glow-only результат прогону с изометрией | AC5, контрактный тест | ## 8. Release-артефакты @@ -113,7 +148,8 @@ smoke-бюджетами** `budgets-isometric-smoke.json`, `budgets-interaction- - `test/iso-scene-render.test.mjs`, `test/iso-overlays.test.mjs` — гарды и AC2; - `.github/workflows/validate.yml` — выходы `changes`, условные шаги смока, ключ `reuse`; - `demo/performance/budgets-isometric-smoke.json`, `budgets-interaction-smoke.json` — новые; -- `test/validate-workflow.test.mjs` — AC3, AC5; `test/performance-budget.test.mjs` — AC4; +- `test/validate-workflow.test.mjs` — AC3, AC5, AC8; `test/performance-budget.test.mjs` — AC4; +- `scripts/classify-changes.mjs` — если `has(...)`-шаблоны `changes` выносятся из inline-shell ради AC8; - `PROCESS.md` §8. ## 10. Принятые предположения