Files
houseplan-card/docs/reviews/SPEC-REVIEW-492-r2.md
T
2026-09-08 21:55:07 +00:00

159 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPEC-REVIEW-492-r2
Issue: #492 «CI: проверять точный кандидат интеграции и полный набор зависимостей selection/reuse»
Этап: ТЗ на ревью (PROCESS.md §2.4). Трек: полный — ТЗ в
`docs/specs/492-exact-candidate-and-input-manifest.md`.
Заход: r2 · блокирующих циклов израсходовано 1 из 4.
## Скоуп
Предыдущий раунд (r1) прошёл на коммите `941c7cff` (материал ревью, ветка
`issue/492-exact-candidate-and-input-manifest`) и получил жёлтый вердикт с
одной находкой Medium в скоупе задачи: AC6 не назвал способ доказательства
(PROCESS.md §2.5). SHA базы r1 в самом тексте вердикта на issue не назван —
там процитирован только `ea6061e9` (SHA аудита, источник «Проблемы» ТЗ), а
не SHA проверенного дерева ТЗ; SHA ревью восстановлен из раздела «Материал
раунда» документа `SPEC-REVIEW-492-r1.md` (коммит `941c7cff`, дерево
`b9b9b1a2`), который для этого и существует (#414). Отмечаю как процесс-
наблюдение, не как находку по существу этого раунда — механизм привязки
сработал, вердикт этого раунда явно называет свой SHA (`8c1b1728`).
Правка после r1 — один коммит `8c1b1728` («docs: AC6 gets its negative
probe»), диф: 2 строки в одном файле,
`docs/specs/492-exact-candidate-and-input-manifest.md` (§8.1 и AC6 в §10).
Ни ребейза на ушедший вперёд `dev`, ни смены контракта поведения, ни новой
подсистемы — делта локальна и целиком укладывается в единственную находку
r1. Разбор сужен до этой делты; всё остальное наследуется из r1 (раздел
ниже).
## Как проверялось
- `git diff 941c7cff..8c1b1728 -- docs/specs/492-exact-candidate-and-input-manifest.md`
— единственное изменение: в §8.1 к списку представителей добавлено
предложение «**Обратная проба (AC6):** представитель
`src/houseplan-card.ts` — ключ `backend` **не** меняется и
`checksAffectedBy` **не** содержит `backend`; тест в
`test/gate-reuse.test.mjs` и `test/classify-changes.test.mjs`…»; в §10
формулировка AC6 дополнена придаточным «доказано обратной пробой §8.1
(правка `src/houseplan-card.ts` не меняет ключ `backend` и не
классифицируется как `backend`)».
- Проверено закрытие находки r1 по существу, а не по факту правки строки:
требование PROCESS.md §2.5 — назвать способ доказательства для
защитного/отрицательного утверждения. Теперь AC6 называет: (а) конкретный
файл-представитель (`src/houseplan-card.ts`, реально лежит в `src/**`,
подходящий представитель категории `source`, которую AC6 и отрицает для
`backend`), (б) ожидаемый результат в двух измерениях — не меняется ключ
реюза И не входит в `checksAffectedBy`, (в) конкретные тестовые файлы.
Это устраняет ровно сценарий отказа, названный в r1: «финальный коммит
AC6 сводится к удалению строки без теста — регресс не поймает ни один
автотест».
- Проверена согласованность добавленного текста с остальным ТЗ:
`test/gate-reuse.test.mjs` и `test/classify-changes.test.mjs` уже
числятся в §12 «Затронутые файлы» как существующие (не новые) файлы —
добавление обратной пробы не требует правки §12, расхождения нет. Оба
файла существуют в дереве (`test/gate-reuse.test.mjs`,
`test/classify-changes.test.mjs`), значит тест добавляется в реальные
файлы, а не в несуществующий путь.
- Перепроверена только формулировка AC6 в §10 — остальные AC1–AC5, AC7–AC10
делтой не задеты, повторно не разбирались (см. «Унаследовано из r1»).
- Дешёвые гейты — зелёного Validate на `8c1b1728` нет, прогнал сам:
`npx tsc --noEmit` — чисто, без ошибок; `npm test` — 2275 тестов, 2274
pass, 1 skipped (уже пропущенный ранее, не новый), 0 fail; `npm run
build` — успешно (`tsc --noEmit && rollup -c`, `dist` собран за 18.4с).
`node scripts/check-docs.mjs` не прогонял — диф не трогает `src/**`
(только `docs/specs/**`), условие прогона явно не выполнено.
`git status` после build — рабочее дерево чистое (`dist` в `.gitignore`),
побочных изменений нет.
- Тяжёлые/специфичные гейты (`golden`, смоки, backend pytest, инварианты
модели, performance) не прогонялись — диф не трогает `src/**`,
`custom_components/**`, геометрию/`layout`/толщину/`open_spans`, они
нерелевантны и на r1 были нерелевантны по той же причине.
## Находки
Нет. Делта закрывает единственную находку r1 полностью, новых находок в
изменённых 2 строках не обнаружено.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium (в скоупе): AC6 не называет способ доказательства — защитное утверждение «`backend` не зависит от `src/**`» не привязано ни к одному пункту §8, регресс (случайный возврат `sourceFingerprint` в ключ `backend`) не поймает ни один автотест | В §8.1 добавлена «Обратная проба (AC6)»: представитель `src/houseplan-card.ts`, двойное ожидание (ключ `backend` не меняется + `checksAffectedBy` не содержит `backend`), названы тестовые файлы `test/gate-reuse.test.mjs` и `test/classify-changes.test.mjs`; формулировка AC6 в §10 дополнена ссылкой на эту пробу | `docs/specs/492-exact-candidate-and-input-manifest.md`, коммит `8c1b1728`, строки §8.1 (список представителей) и §10 (пункт AC6); `git diff 941c7cff..8c1b1728` — единственный диф раунда |
## Унаследовано из r1
Без повторной проверки в этом раунде принято всё содержание
`docs/reviews/SPEC-REVIEW-492-r1.md` (документ ревью r1, база — коммит
`941c7cff`), кроме пункта AC6, разобранного заново выше:
- Скоуп и класс задачи: infra/P1/tech-debt, маршрутизация через S-метки
без файлов класса A — прецедент #472/#475/#481 подтверждён в r1 прямым
запросом к issue-метаданным.
- Все пять утверждений раздела «Проблема» (§1 ТЗ) — проверены чтением кода
на `ea6061e9` в r1, ни одно не оказалось домыслом.
- Двусторонняя связь issue ↔ ТЗ ↔ `docs/specs/README.md`.
- Полнота обязательных разделов §7.1 PROCESS.md (сценарий, до/после,
проблема, скоуп/не-скоуп, контракт, UX/модель данных/i18n — явно «не
затрагиваются», критерии приёмки, риски, откат, release-артефакты).
- Внутренняя согласованность §5.1 (категории manifest) с §8.1 (представители)
и §13/§8.5 (список из шести мутантов протокола).
- AC1–AC5, AC7–AC10 — каждый однозначен и привязан к конкретному пункту §8
как способу доказательства; делта их не касалась.
- §4 (точный кандидат слияния), §6 (замыкание входов гарда), §7 (ночной
прогон), §9 (откат) — оценены в r1 как корректно устраняющие
подтверждённые дефекты, без пробелов.
- §13 «Принятые предположения» — только технические решения, помечены как
свободно изменяемые; продуктовых вопросов владельцу нет и не должно
быть (задача не имеет пользовательской поверхности в смысле
`docs/SCOPE.md`).
- Выбор полного трека (не `small`) — верен, четыре поверхности протокола
CI одновременно.
## Что проверено и корректно
- Единственная находка r1 закрыта по существу (не косметически): способ
доказательства AC6 теперь явный, конкретный и указывает на реальные
тестовые файлы, уже числящиеся в §12.
- Делта не вносит противоречий с остальным текстом ТЗ (§12, §5.1, другие
AC не затронуты и не разъехались с новой формулировкой).
- Дешёвые гейты на `8c1b1728` зелёные: typecheck, полный набор `npm test`
(2274/2275, 1 плановый skip), `npm run build`.
## Чего не проверял
- AC1–AC5, AC7–AC10 и разделы §1–§7, §9, §13 — не переразбирал, делта их
не касается; унаследовано из r1 (раздел выше).
- Реализацию по существу — на этапе ТЗ её нет, diff — только
`docs/specs/**` (класс C).
- Тяжёлые/специфичные гейты (`golden`, `smoke`, backend pytest, инварианты
модели, performance-профили) — diff не трогает `src/**`,
`custom_components/**` или геометрию/толщину/`layout`/`open_spans`,
нерелевантны этапу и типу изменений.
- `node scripts/check-docs.mjs` — diff не трогает `src/**`, условие
прогона не выполнено.
- Точный пересчёт «10 из 35» гардов (§1 п.4 ТЗ) — уже отмечено как не
пересчитанное построчно в r1, делта этого числа не касается.
## Вердикт
Зелёный. High: 0, Medium: 0. Единственная находка r1 закрыта делтой
`8c1b1728` по существу.
---
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/492-exact-candidate-and-input-manifest`, коммит `8c1b1728fc10` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `64ce76085c6ceee7e01d1a0d072f67490a542e9e`
```
git log --all --format='%H %T' | grep 64ce76085c6c
```
- ТЗ `docs/specs/492-exact-candidate-and-input-manifest.md`, блоб `4292bb38834882bb26425be67e995a06fed747e7`
```
git log --all --find-object=4292bb38834882bb26425be67e995a06fed747e7 -- docs/specs/492-exact-candidate-and-input-manifest.md
```