docs: update plans

This commit is contained in:
2026-09-26 20:29:58 +05:00
parent 6a44a3d018
commit 7bca9f3a3a
4 changed files with 59 additions and 83 deletions
+15 -74
View File
@@ -1,10 +1,11 @@
# План: линтеры, тесты и качество кодовой базы # План: линтеры, тесты и качество кодовой базы
> Статус: **draft — Q0–Q5 и Q6a–Q6f.5 готовы к ревью; Q7 — следующий этап**. > Статус: **draft — Q0–Q5 и Q6a–Q6f.5, Q7a–Q7e готовы; остался Q8**.
> >
> Источник: `docs/backlog.md`, аудит конфигурации `web/`, e2e-тестов и > Источник: `docs/backlog.md`, аудит конфигурации `web/`, e2e-тестов и
> инфраструктурных скриптов. Q0–Q5 и Q6a–Q6f.5 выполнены; Q7–Q8 выполняются > инфраструктурных скриптов. Q0–Q5, Q6a–Q6f.5 и Q7a–Q7e выполнены; остался Q8.
> отдельными атомарными шагами. > Решения, важные за пределами плана, живут в `docs/quality-gates.md`,
> `docs/testing-strategy.md` и `AGENTS.md`.
> >
> Цель: сделать качество кодовой базы воспроизводимым, убрать ложную «зелёность» > Цель: сделать качество кодовой базы воспроизводимым, убрать ложную «зелёность»
> проверок, стабилизировать тестовые контракты и только после этого расширять > проверок, стабилизировать тестовые контракты и только после этого расширять
@@ -112,8 +113,8 @@ pnpm --dir web test:e2e
- Добавить отдельный workflow для pull request: typecheck, unit, rule-тесты, - Добавить отдельный workflow для pull request: typecheck, unit, rule-тесты,
lint, format и build. lint, format и build.
- E2E сначала запускать отдельным job; сделать его blocking после закрытия - E2E сначала запускать отдельным job; сделать его blocking после закрытия
известных ошибок и стабилизации baseline. Решение отложено: условия matrix известных ошибок и стабилизации baseline. Условия перехода и текущая политика
пересматриваются после Q6f.3, см. раздел 7 «Отложенное решение». описаны в `docs/quality-gates.md`, раздел «Политика e2e в CI».
**Готово, когда:** одна команда воспроизводит все быстрые проверки, а deploy не **Готово, когда:** одна команда воспроизводит все быстрые проверки, а deploy не
может пройти при type/unit/lint/build-ошибке. может пройти при type/unit/lint/build-ошибке.
@@ -355,36 +356,16 @@ Firefox и WebKit для browser-critical спецификаций и mobile Chr
- Порог functions самый слабый (74.31% против 91.77%): добавление инструмента с - Порог functions самый слабый (74.31% против 91.77%): добавление инструмента с
непокрытым `run` быстрее всего опускает именно его. Это ожидаемо, порог держит непокрытым `run` быстрее всего опускает именно его. Это ожидаемо, порог держит
запас. запас.
- DOM-тесты `SchemaToolView`/controls не начаты: браузерные модули исключены из - DOM-тесты `SchemaToolView`/controls сознательно не начаты: node-Vitest не
coverage сознательно, а их перенос в scope — отдельное решение вместе с visual имеет DOM, а e2e уже покрывает поведение. Задача живёт в `docs/backlog.md`.
snapshots, см. Q6f.5.
Не применять один одинаковый smoke-сценарий к image-, text-, generator- и Не применять один одинаковый smoke-сценарий к image-, text-, generator- и
file-result-инструментам. file-result-инструментам.
#### Q6f.5. Visual snapshots — решение отложено #### Q6f.5. Visual snapshots
**Статус:** сознательно не делаем. Это решение, а не долг. **Статус:** решено не делать. Обоснование, чем закрыта потребность сейчас и при
каком условии стоит вернуться — в `docs/testing-strategy.md`, раздел 8.
- Механика: `toHaveScreenshot` сравнивает отрендеренную страницу с PNG-baseline,
закоммиченным в `web/e2e/<spec>-snapshots/`. Эталон — картинка из прошлого
коммита, а не замысел дизайнера; обновление идёт через `--update-snapshots` и
ревью картинок.
- Почему отложено:
- визуальный язык сейчас активно меняется, поэтому каждый дизайн-PR
превращается в перегенерацию и ревью картинок, а соблазн обновить снапшот не
глядя появляется постоянно;
- baseline привязан к платформе (ОС, шрифты, особенности рендеринга): снимок с
Windows не совпадёт на `ubuntu-latest`, значит эталоны должны рождаться на
Linux, а локальные прогоны будут постоянно расходиться;
- при матрице из четырёх проектов плюс тема и viewport число файлов Baseline
растёт нелинейно.
- Что закрывает потребность сейчас: e2e-поведение (276 тестов), `lint:tokens` и
token audit, i18n-гейт, ручной чеклист `docs/checklist-manual-testing.md`. Не
закрыто только «элемент визуально наехал» — это ловится чеклистом и ревью.
- Условие возврата: визуальный язык стабилен, изменения редкие, ручной чеклист
перестал справляться. Тогда первым идёт `/kit` в двух темах, а эталоны
генерируются на Linux (docker-образ Playwright или отдельный CI-job).
### Q7. Укрепление lint-инфраструктуры ### Q7. Укрепление lint-инфраструктуры
@@ -403,8 +384,7 @@ file-result-инструментам.
- Шкалы остались неполными намеренно (`duration-s/l` без `m`, `space-text` без - Шкалы остались неполными намеренно (`duration-s/l` без `m`, `space-text` без
`s`): мёртвый элемент шкалы хуже, чем «дырявая» шкала, а вернуть его можно `s`): мёртвый элемент шкалы хуже, чем «дырявая» шкала, а вернуть его можно
вместе с потребителем. вместе с потребителем.
- Второй пункт («после очистки решить, должен ли unused audit быть - Режим unused-аудита решён в Q7d: он остаётся предупреждением.
fail-режимом») остаётся открытым: сам audit пока только сообщает.
#### Q7b. Тесты token audit и PostCSS HCT-плагина #### Q7b. Тесты token audit и PostCSS HCT-плагина
@@ -494,12 +474,6 @@ file-result-инструментам.
`Unresolved var() references` и код выхода 1; `app.css` восстановлен байт в `Unresolved var() references` и код выхода 1; `app.css` восстановлен байт в
байт. байт.
#### Q7f. Оставшиеся направления
- Новые правила подключать только после fixtures, `test:rules` и baseline.
- Если в коде появится чтение токенов из JS, `collectUsedTokens` придётся
расширить — иначе unused-аудит начнёт считать используемые токены пылью.
### Q8. Новые автоматические правила ### Q8. Новые автоматические правила
**Оценка:** L. **Зависимости:** Q4, Q7. **Оценка:** L. **Зависимости:** Q4, Q7.
@@ -631,39 +605,6 @@ checklist. `README.md` в корне остаётся кратким обзор
Каждый PR должен быть атомарным и небольшим; не объединять `SchemaPreview` Каждый PR должен быть атомарным и небольшим; не объединять `SchemaPreview`
refactor, новые i18n-правила и исправление продуктовых багов в одну работу. refactor, новые i18n-правила и исправление продуктовых багов в одну работу.
## 6. Отдельные направления и что не начинать автоматически Продуктовые направления, которые план не начинает (платформа PWA/API/WASM,
plural-формы, batch/архивы, region-инструменты), живут в `docs/backlog.md` и
- полноценный browser/visual/coverage matrix; `docs/roadmap.md`; границы этого плана — в разделе 1.
- полноценная PWA/API/WASM-платформа;
- `SchemaPreview` state/view-model refactor;
- plural-формы до модели словаря;
- универсальный линтер одинаковых комментариев;
- batch/архивы, region-инструменты и остальные продуктовые волны из backlog.
## 7. Решения, которые нужно принять на ревью
- Какие executor/worker/fallback сценарии войдут в первый Q6 coverage PR?
- Нужны ли browser/mobile matrix и visual snapshots до coverage thresholds?
Решено: matrix — Q6f.3, coverage — Q6f.4, visual snapshots отложены с
обоснованием в Q6f.5.
- Какие unused design tokens можно удалить, а какие должны остаться? Решено в
Q7a: удалены все четыре, audit чист.
- Какие browser/e2e проверки должны быть обязательными для PR, а какие —
отдельным ночным прогоном?
### Отложенное решение: условия matrix и blocking e2e
Окончательное решение про `e2e` в CI принимается **не сейчас**, а после
пересмотра условий тестов. К этому моменту нужно вернуться и решить одним шагом:
1. Пересмотреть условия matrix: какие спецификации обязаны идти в
`browserContractTests` и `mobileTests`, нужен ли `png-fixtures` вне Chromium
и что делать с engine-специфичными расхождениями декодеров.
2. Накопить стабильные прогоны `e2e` на раннере (сейчас ориентир — 276 тестов,
~3 мин на job) без падений по таймингу.
3. Только после этого решать, делать ли `e2e` blocking, и если да — снимать
`continue-on-error`, иначе общий conclusion прогона останется зелёным при
красном `e2e` (проверено на run `36225579363`).
До этого решения `e2e` остаётся non-blocking baseline, а его фактический статус
проверяется по отдельному job, а не по conclusion прогона.
+19
View File
@@ -150,6 +150,25 @@ Browser matrix стоит около трёх минут, поэтому её д
Полный прогон локально на 1 воркере — заметно дольше (~7 мин), и именно поэтому Полный прогон локально на 1 воркере — заметно дольше (~7 мин), и именно поэтому
локальные правила нагрузки описаны в `docs/agent-workflow.md`. локальные правила нагрузки описаны в `docs/agent-workflow.md`.
## Политика e2e в CI
Текущее состояние: `e2e` — non-blocking baseline, запускается на каждом пуше в
`main` и на каждом PR целиком (все четыре проекта matrix). Ночного разделения
нет: при стоимости job около трёх минут оно не окупается, поэтому новые
browser-critical спецификации просто добавляются в `browserContractTests`.
`e2e` станет blocking, когда выполнятся три условия:
1. Условия matrix пересмотрены: решено, какие спецификации обязаны идти в
`browserContractTests` и `mobileTests`, нужен ли `png-fixtures` вне Chromium
и что делать с engine-специфичными расхождениями декодеров.
2. Накопились стабильные прогоны на раннере без падений по таймингу.
3. Вместе с `continue-on-error` снимается и сам trick с общим conclusion: иначе
зелёный прогон при красном `e2e` останется возможен.
Пока условия не выполнены, `e2e` остаётся non-blocking, а его статус читается по
отдельному job.
## Локальная диагностика ## Локальная диагностика
При медленном полном прогоне сначала запускай минимальную команду из таблицы, а При медленном полном прогоне сначала запускай минимальную команду из таблицы, а
+21 -5
View File
@@ -156,8 +156,24 @@ non-blocking E2E не считается заменой локальному smo
тесты падают без ошибок. Локальный matrix поэтому медленный, но не нагружает тесты падают без ошибок. Локальный matrix поэтому медленный, но не нагружает
компьютер. компьютер.
- Локальный baseline: 276 тестов, 276 passed, 0 skipped, 0 failed. - Локальный baseline: 276 тестов, 276 passed, 0 skipped, 0 failed.
- Visual snapshots сознательно не используются: baseline платформенный, а - Coverage ограничена `src/lib` и не включает браузерные модули — см. раздел 4.
визуальный язык сейчас активно меняется. Причина и условие возврата — в
`docs/plan-codebase-quality.md` (Q6f.5). ## 8. Visual snapshots
- Visual snapshots и coverage thresholds вынесены в
`docs/plan-codebase-quality.md` (Q6f.4, Q6f.5). Сознательно не используются. `toHaveScreenshot` сравнивает страницу с
PNG-baseline из прошлого коммита, а не с замыслом дизайна, поэтому:
- визуальный язык в активной работе означает перегенерацию и ревью картинок в
каждом дизайн-изменяющем PR;
- baseline привязан к платформе (ОС, шрифты, рендеринг): снимок с Windows не
совпадёт на `ubuntu-latest`, и baseline должны рождаться на Linux;
- четыре проекта matrix плюс тема и viewport дают нелинейный рост числа файлов.
Потребность закрывают e2e-поведение, `lint:tokens` с token audit, i18n-гейт и
ручной чеклист `docs/checklist-manual-testing.md`; «элемент визуально наехал»
ловится чеклистом и ревью.
Возвращаться к snapshots стоит, когда визуальный язык стабилизируется, изменения
станут редкими, а чеклист перестанет справляться. Тогда первым идёт `/kit` в
двух темах, а baseline генерируются на Linux (docker-образ Playwright или
отдельный CI-job).
+4 -4
View File
@@ -139,10 +139,10 @@
— fallback легален без определения. Провал (exit 1), потому что несуществующий — fallback легален без определения. Провал (exit 1), потому что несуществующий
токен молча роняет объявление. токен молча роняет объявление.
- **Неиспользуемые токены**: выводится **варнинг** (определены, но нигде не - **Неиспользуемые токены**: выводится **варнинг** (определены, но нигде не
используются) — выход он не меняет. Решение оставить это неблокирующим используются) — выход он не меняет. Проверка видит только ссылки `var(--x)`,
зафиксировано в `docs/plan-codebase-quality.md` (Q7d): правило «новый токен — поэтому чтение токена из JS (`getPropertyValue`) она не учтёт; решение
вместе с потребителем» живёт в `AGENTS.md`. Провалами (exit 1) считаются оставить проверку неблокирующей зафиксировано в `docs/quality-gates.md`.
parity, hct-авторство и резолв `var()`. Провалами (exit 1) считаются parity, hct-авторство и резолв `var()`.
## Тесты кастомных линт-правил ## Тесты кастомных линт-правил