docs: review document for #812

Issue: #812
User-Visible: no
This commit is contained in:
claude[bot]
2026-10-07 05:58:14 +00:00
parent a106b71762
commit 42960896d4
2 changed files with 204 additions and 1 deletions
+2 -1
View File
@@ -1,6 +1,6 @@
# Индекс ревью
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 339, issue: 171. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 340, issue: 172. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|---|---|---|---|---:|---:|---|---|
@@ -8,6 +8,7 @@
| бета v1.80.0-beta.1 | [SHIP-REVIEW-v1.80.0-beta.1.md](SHIP-REVIEW-v1.80.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — |
| бета v1.79.0-beta.2 | [SHIP-REVIEW-v1.79.0-beta.2.md](SHIP-REVIEW-v1.79.0-beta.2.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — |
| бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — |
| #812 | [SPEC-REVIEW-812-r1.md](SPEC-REVIEW-812-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | Нет — ни в скоупе, ни вне скоупа | `test/performance-budget.test.mjs` |
| #810 | [CODE-REVIEW-810-r1.md](CODE-REVIEW-810-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
| #809 | [CODE-REVIEW-809-r1.md](CODE-REVIEW-809-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
| #808 | [CODE-REVIEW-808-r1.md](CODE-REVIEW-808-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
+202
View File
@@ -0,0 +1,202 @@
# SPEC-REVIEW-812-r1
Issue: #812 — «Надёжность проверок: граф входов CI, регрессионные свидетели и
perf-харнесс»
Этап: spec (PROCESS.md §2.4) · Трек: ask (§5) · Заход: r1 · блокирующих
циклов 0/4
Материал: тело issue #812, раздел `## ТЗ` (редакция на момент ревью) плюс три
комментария того же issue («Оценка», «Взял», «Сделано» — автор ТЗ, трек и
хендофф в S4-spec-review). Продуктовый код в этой задаче не писался и не
требуется на этапе spec; ветка реализации не создавалась.
Route: fix (зафиксирован промптом конвейера, #726).
## Скоуп
Инфраструктурная задача (класс B: `scripts/**`, `demo/**`, `test/**`,
`docs/TESTING.md`), обслуживающая надёжность J1–J7 `docs/SCOPE.md`
опосредованно — через доверие к тестам, которые эти job'ы защищают, а не
напрямую. Объединяет 10 находок (F7–F10, F15, F16, F23 частично, F24, F26,
F28) из `findings-2026-10-06.md` в десять AC. Обычный infra-маршрут пропускает
ТЗ («В разработке — реализация» сразу после аналитики, §1), но владелец прямо
поручил полный маршрут с независимым ревью ТЗ для всех четырёх задач волны
(#811/#812/#813/#814) — это явно названное исключение, не самовольное
расширение процесса, и ревью ТЗ принимает этот маршрут как данность, не
переоценивая решение владельца.
Границы с соседними задачами волны поименованы и непротиворечивы: F15
реализуется только здесь, #813 запускает свои space-card smoke отдельно,
#811 — конвейер/browser inventory, #814 — продуктовая геометрия (F23
продуктовая часть явно исключена сюда же словом «вне этой задачи»). `src/**`,
Python-интеграция, UI/UX, численные performance-бюджеты/golden-эталоны,
политика CI reuse и server URL из F10.2 — явный не-скоуп.
## Как проверялось
Ревью ТЗ не включает выполнение гейтов: это этап spec, зависимости и Chromium
не ставились (#696), «Verified» без кода — норма до S5. Прочитаны
`docs/SCOPE.md` → `AGENTS.md` → `docs/process/REVIEWER.md` → PROCESS.md
§2.3–2.5, §7.1, §4, §7.2; канонического документа подсистемы для этой задачи
нет (инфраструктура теста/CI не входит в список `AGENTS.md` «Read this
first» — это не продуктовая поверхность), поэтому утверждения о поведении
сверялись напрямую с исходниками затронутых скриптов и тестов.
Технические утверждения ТЗ проверены чтением кода, не исполнением (способ
проверки назван для каждого пункта ниже):
- **AC1** (стрип комментариев теряет импорт / добавляет ложный). Прочитан
`stripComments`/`referencesOf` (`scripts/check-inputs.mjs:186–241`):
regex `\/\*[\s\S]*?\*\//g` и `(^|[^:'"\`\\])\/\/[^\n]*` — наивный
построчный/посимвольный стриппер без учёта строковых литералов; строка с
`/*` внутри строкового литерала или `//` внутри шаблонной строки
действительно может съесть реальный `import` на следующей строке.
Утверждение подтверждено чтением, не выдумано.
- **AC2** (data-only узел не обходится кодовым ребром). Прочитана `closure()`
(`scripts/check-inputs.mjs:265–301`): строка 290 добавляет `ref` в `seen`
сразу при встрече как `data`-ссылки, минуя очередь `queue`; если тот же файл
позже встречается как `code`-ссылка из другого файла, строка 287
(`if (!seen.has(ref)) queue.push(ref)`) не поставит его в очередь — узел
никогда не читается и не парсится на собственные зависимости. Баг
порядко-зависим именно так, как описывает AC2 («обходится независимо от
порядка корней и рёбер»). Подтверждено чтением.
- **AC3** (четыре разных `importClosure`). Найдены все четыре копии:
`test/process-track.test.mjs:706`, `test/publish-push-refusal.test.mjs:53`,
`test/rebase-generated.test.mjs:53`, `test/ship-review.test.mjs:470` — у
каждой свой regex импорта (например, только статический
`import...from` без `require`/side-effect import у части копий).
Утверждение о расхождении механизмов подтверждено построчным сравнением.
- **AC4** (наследование shell, причины conflict/validate-red, `unknown`).
`test/helpers/workflow-step.mjs:10–15` уже документирует приоритет
step→job→workflow→default; `test/process-metrics.test.mjs:277–335`
показывает существующую классификацию `conflict`/`validate-red`/`unknown`
как рабочий контракт, который AC4 расширяет, а не изобретает. AC4 — самый
составной пункт таблицы (связывает F7 и часть F10), но оба подпункта имеют
общий способ проверки («Unit и Linux-исполнение действительных шагов с fake
gh»), и разделение на два AC не изменило бы проверяемость — не нахожу это
основанием для находки, Low не завожу.
- **AC5** (space-render смок-селектор). `НЕОПРЕДЕЛЁННОСТЬ`/`unproven` —
реальные термины `scripts/smoke-select.mjs:308,399–400`, не изобретение
автора ТЗ.
- **AC7** (`--warmups=0` → 1). `demo/benchmark_large_house.mjs:25`:
`Math.max(0, Math.min(5, Number(valueArg('warmups')) || 1))` — классический
JS-баг «`0 || 1` = 1». Воспроизведено чтением буквально, без домысливания.
- **AC8** (backdrop вне switchCycle-семьи). `test/performance-budget.test.mjs`
`SWITCH_CYCLE_FAMILIES.isometric.files` (строка ~381) перечисляет три файла
бюджетов, но не `budgets-large-house-isometric-backdrop.json`, хотя у него
тот же `hardMaxMs: 1550` (`demo/performance/budgets-large-house-isometric-
backdrop.json:13`) — расхождение между кодом и ТЗ-описанием не найдено,
AC8 корректно описывает существующий пробел.
- **AC9** (неограниченный рост epoch/stack). Диагностика `_cfgEpoch` — вне
`src/**`? Проверено по скоупу: `demo/benchmark_large_house.mjs` упомянут как
затрагиваемый файл («сохраняет все epoch stack traces... boot-вывод
использует только первые восемь»), т.е. изменение остаётся в harness, не в
продуктовом коде — согласуется с не-скоупом «продуктовая геометрия вне этой
задачи» (F23).
Дубликаты проверены ссылками на #766/#793/#774/#770/#809 — все пять
закрытые/предшествующие, не повторно открываемые задачи; самостоятельно не
искал дополнительных совпадений сверх названных, это разумный предел для
ревью ТЗ.
## Находки
### High
Нет.
### Medium
Нет — ни в скоупе, ни вне скоупа.
### Low
Нет находок, которые стоило бы заводить: единственный кандидат — чуть
расплывчатая формулировка способа доказательства AC8 («Budget unit плюс
сверка документации с workflow») — рассмотрен выше и снят как не требующий
правки: `test/performance-budget.test.mjs` уже содержит рабочий паттерн
«бюджет-файл × assert.equal» (см. `SWITCH_CYCLE_FAMILIES`), которому
реализация AC8 естественно последует; редакционная точность формулировки не
блокирует реализуемость или проверяемость AC.
## Что проверено и корректно
- Обязательные разделы §7.1 присутствуют и по существу: сценарий — отдельный
раздел с персоной (автор изменения/CI/ревьюер) и поверхностью; «что человек
увидит» — отдельной фразой без терминов реализации («пользовательский
интерфейс Home Assistant не меняется», до/после — доверие к зелёной
проверке); проблема, скоуп и не-скоуп, контракт поведения, UX/данные/
миграция/i18n (объединены одним разделом — корректно для чисто
инфраструктурной задачи без пользовательских поверхностей), критерии
приёмки AC1–AC10 с доказательством в каждой строке, план автотестов, риски,
откат и release-артефакты (объединены) — все на месте.
- Каждый AC снабжён способом доказательства **и** красным случаем
(«чем краснеет») в одной ячейке таблицы — это с запасом покрывает защитный-
AC требование §2.7, хотя оно формально адресовано код-ревью, а не этому
этапу.
- DoR-пункты (§2.5) закрыты по существу, не всегда отдельной строкой:
i18n — явное «нет» (новых ключей нет); touch — явное «не меняется»; миграция
— явное «не меняется»; откат — explicit; release-артефакты — explicit
`User-Visible: no`, changelog не требуется; производительность — не названа
отдельной фразой-штампом, но содержательно закрыта многократно («изменения
численных performance-бюджетов... вне работы», «полный performance/golden
не нужен для принятия неизменных бюджетов», `src/**` вне скоупа, AC9 прямо
ограничивает рост диагностики, а не меняет продуктовую геометрию) — тот же
стандарт принятия, что применялся ранее к implicit-«нет» для touch в
SPEC-REVIEW-806-r1.
- Каждое проверяемое техническое утверждение ТЗ (F7–F9, F15, F24, F26 выше)
сверено построчно с реальным кодом — расхождений не найдено; это ТЗ не
описывает воображаемое поведение.
- Продуктовых вопросов владельцу нет, и это обоснованно: все нетривиальные
технические решения (расположение общего scanner/closure-хелпера, выбор
сохранить первые восемь epoch-записей) явно помечены «принято
предположительно, поменять свободно» — корректное использование правила
«то, чего пользователь не наблюдает, решают агенты» (§7.1); ни одного
продуктового по сути вопроса, ошибочно не заданного, не нашёл.
- Трек `ask` обоснован самим текстом (явное поручение владельца на полный
маршрут для всей волны, несколько поверхностей и риск 6/10) и подтверждён
контекстом прогона (`Трек: ask (PROCESS.md §5)` уже зафиксирован).
- Границы между этой и тремя соседними задачами волны (#811/#813/#814)
названы явно и без пересечения ответственности.
## Чего не проверял
- Исполнение гейтов (`gate:small`, Linux workflow tests, `smoke_radar_setup.mjs`,
performance-contract) — продуктового/тестового кода для этой задачи ещё нет,
этап spec исполнения не требует; упомянутые в ТЗ прогоны («42 passed, 1
skipped») — свидетельства автора на этапе аналитики, не материал этого
ревью, и не принимались как замена собственной проверки: каждое затронутое
утверждение (AC1, AC2, AC3, AC7, AC8) перепроверено чтением кода заново,
самостоятельно.
- AC6 (radar-смок, два primary-жеста, координаты/направление, Cancel) — только
чтением: не проверял, действительно ли `demo/smoke_radar_setup.mjs` в
текущем виде не доказывает координаты установки (F16), это браузерный
сценарий, не читаемый статически с той же уверенностью, что AC1–AC3/AC7–AC9;
на этапе spec это и не требуется, но код-ревью должен исполнить, а не
принять на слово.
- AC10 (документация F28) — не сверял исходный прогон #809 и версии окружения
повторно, доверился ссылке на предыдущее ревью, названной в тексте.
- Будущую реализацию общего `importClosure`/scanner-механизма и его влияние на
время выполнения тестов — вне ТЗ-ревью, это инженерное решение реализации.
## Вердикт
Зелёный. ТЗ полно по разделам §7.1, каждый AC однозначен и снабжён способом
доказательства и красным случаем, каждое проверяемое техническое утверждение
сверено с кодом и подтвердилось, DoR §2.5 закрыт по существу (включая
производительность — через совокупность явных ограничений не-скоупа, а не
отдельной фразой-штампом), продуктовых вопросов нет и не пропущено ни одного.
High: 0, Medium: 0.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `dev`, коммит `a106b717621a` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `e33c8365dc06eaa9167f1c479f6dff350d3094cf`
```
git log --all --format='%H %T' | grep e33c8365dc06
```
- Тело issue: `74b22b52501ac013caed95264d543317f0429f595059333ce18db15ede9f0dde`
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
<!-- hp:usage input_tokens=4033 output_tokens=25729 cache_creation_input_tokens=84967 cache_read_input_tokens=1800029 num_turns=37 -->