diff --git a/docs/reviews/SPEC-REVIEW-492-r2.md b/docs/reviews/SPEC-REVIEW-492-r2.md new file mode 100644 index 00000000..d33b45c5 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-492-r2.md @@ -0,0 +1,158 @@ +# 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` по существу. + +--- + +--- + + + +## Материал раунда + +- Ветка: `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 + ```