diff --git a/docs/reviews/SPEC-REVIEW-421-r2.md b/docs/reviews/SPEC-REVIEW-421-r2.md new file mode 100644 index 00000000..19e23f9f --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-421-r2.md @@ -0,0 +1,150 @@ +# SPEC-REVIEW-421-r2 + +- Issue: https://github.com/Matysh/houseplan-card/issues/421 +- Этап: `S4-spec-review` (ревью ТЗ, PROCESS.md §2.4) +- Материал: `docs/specs/421-negative-test-proofs.md` на коммите `fac1f884` + (ветка `origin/issue/421-negative-test-proofs`). +- Заход: r2. Разбор — по дельте (PROCESS.md §2.9, issue #214): предыдущая + находка была текстовой (отсутствие разделов §7.1), правка — тоже текстовая, + AC и Контракт не менялись. + +## Скоуп раунда + +r1 (SHA `c409ec6a`, документ `docs/reviews/SPEC-REVIEW-421-r1.md`) дал жёлтый +вердикт с единственной находкой Medium в скоупе: в ТЗ отсутствовали +обязательные по §7.1 разделы «Сценарий», «Что человек увидит до и после», +«UX»; «Модель данных и миграция» была не выделена отдельным заголовком. +Автор («ТЗ обновлено после ревью r1», 2026-09-02T17:04:15Z) заявил правку без +изменения AC и технического контракта, коммит `fac1f884`. + +Дельта этого раунда — `git diff c409ec6a..fac1f884 -- docs/specs/421-negative-test-proofs.md`: +четыре добавленных раздела («Сценарий», «Что человек увидит до и после», +«UX», «Модель данных и миграция»), вставленных в существующие места +документа. Ни одна строка «Контракт», «Критерии приёмки», «Скоуп/Не-скоуп» +или «План отрицательной проверки» не тронута — подтверждено самим diff +(hunks затрагивают только окрестности вставок, существующие разделы видны в +контексте без изменений). + +Дельта локальна: новая подсистема не затронута, поведенческий контракт не +менялся, объём правки (4 коротких раздела) несопоставим с объёмом исходной +задачи. Полный разбор ТЗ заново не требуется — переразбирается только +закрытие находки r1 и факт-чек нового текста. + +## Как проверялось + +1. Получен вердикт r1 и его SHA — из комментария в issue (короткий вердикт + SHA не называет — сверено с полным документом + `docs/reviews/SPEC-REVIEW-421-r1.md`, где раздел «Материал раунда» прямо + называет `c409ec6a`; расхождения между коротким комментарием и документом + нет, просто короткий комментарий не обязан дублировать SHA). +2. `git diff c409ec6a..fac1f884 -- docs/specs/421-negative-test-proofs.md` — + построчный разбор дельты (см. «Закрытие раунда r1» ниже). +3. Прочитан ТЗ целиком на текущем SHA `fac1f884`, чтобы убедиться, что новые + разделы синтаксически и по смыслу встали на место, названное r1 (не + просто заголовки-заглушки). +4. Факт-чек нового текста против кода, а не только против issue: раздел + «Модель данных и миграция» утверждает, что поле `lastWriteWasFingerprintOnly` + уже действует в проде — проверено чтением `scripts/docs-accept.mjs:157` + (`{ ...(previous || {}), lastWriteWasFingerprintOnly: true }`), утверждение + точное, это не новая догадка, выданная за факт. +5. Проверено, что новый текст не вводит утверждений о поведении, не + зафиксированных ни в одном документе и не помеченных как предположение — + не найдено; все новые фразы — перефразировка уже существующих разделов + («Проблема», «Контракт», «Не-скоуп») под нужным заголовком. + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| Medium: нет раздела «Сценарий» | Добавлен раздел «Сценарий» — явно называет наблюдателя (разработчик, меняющий одну из трёх подсистем) и момент наблюдения (запуск объявленной проверки) | `docs/specs/421-negative-test-proofs.md:9-18` | +| Medium: нет раздела «Что человек увидит до и после» | Добавлен раздел с явными «До:» / «После:», отвечающий, что видимого продуктового различия нет, эффект косвенный (регрессии ловятся до релиза) | `docs/specs/421-negative-test-proofs.md:20-29` | +| Medium: нет раздела «UX» | Добавлен раздел «UX», явно перечисляющий отсутствие новых экранов/сообщений/настроек и то, что desktop/touch/kiosk/ARIA не затронуты | `docs/specs/421-negative-test-proofs.md:87-92` | +| Medium: «Модель данных и миграция» не выделена отдельно | Добавлен отдельный раздел с этим заголовком, называющий единственный затронутый артефакт (`docs/images/screenshots.json.acceptance`) и что миграция не нужна | `docs/specs/421-negative-test-proofs.md:186-196` | + +Все четыре пункта одной находки закрыты именно так, как их описал r1 в «Что +чинит находку» (сценарий = разработчик, UX = «нет UI-поверхности», данные = +поле `lastWriteWasFingerprintOnly`) — правка не подменяет замечание +формальными заголовками без содержания. + +## Унаследовано из r1 + +Без повторной проверки в этом раунде, так как дельта их не касается: +документ `docs/reviews/SPEC-REVIEW-421-r1.md`, SHA `c409ec6a`. + +- Фактическая точность описания трёх разрывов доказательности (idempotent + `discard` в `websocket_api.py:2242-2247`; раздельные `roundTripLivePages()` + в `reportPageErrors()`/`finish()`, `demo/serve.mjs:98-99` vs `108-113`; + инлайновая сборка `acceptance` в `docs-accept.mjs:150-159` на момент r1) — + подтверждена чтением production-кода в r1, дельта эти файлы не трогает. +- Однозначность и доказуемость AC1–AC9 — контракт и AC не менялись. +- Реализуемость плана на существующей инфраструктуре + (`backend-test-guard.mjs`, `demo/guard/`, параметризуемый + `_prune_support_previews(rt, now)`) — код инфраструктуры дельтой не + затронут. +- Корректность «Скоуп»/«Не-скоуп», «Риски», «План отрицательной проверки», + «Откат», «Release-артефакты» — не менялись. +- Снятый в r1 Low (формулировка каденции browser-пробы в «Производительность») + — раздел «Производительность» не менялся, решение остаётся в силе. +- Выбор полного трека вместо `small` (обоснование «нарушен критерий одной + поверхности») — не пересматривался, не затронут дельтой. + +## Находки + +Нет. Дельта закрывает единственную находку r1 без побочных эффектов; новых +разрывов доказательности, недоказанных допущений или продуктовых вопросов не +внесено. + +## Что проверено и корректно + +- Все четыре добавленных раздела стоят под требуемыми §7.1 заголовками и + содержат конкретный ответ, а не общую фразу без содержания. +- Новый текст не расширяет и не сужает ни один AC, не меняет «Контракт», + «Скоуп»/«Не-скоуп» — сверено построчно по diff. +- Утверждение о поле `lastWriteWasFingerprintOnly` как об уже действующем — + фактически верно (подтверждено чтением кода, не только текста ТЗ). +- ТЗ на этом SHA закрывает все обязательные разделы DoR §2.5, применимые к + этапу spec-review: AC пронумерованы и у каждого назван способ доказательства, + файлы перечислены, i18n/миграция/touch/производительность/откат/ + release-артефакты названы явно (в т.ч. явным «нет» там, где нет эффекта), + открытых продуктовых вопросов не осталось. + +## Чего не проверял + +- Гейты `typecheck`/`npm test`/`npm run build` — неприменимо, как и в r1: на + этом SHA есть только текст ТЗ, реализации ещё нет; это предмет + код-ревью следующего этапа. +- Повторное чтение `custom_components/houseplan/websocket_api.py`, + `demo/serve.mjs`, `scripts/docs-accept.mjs`, `scripts/mutation-gate.mjs` — + не требовалось: дельта r1→r2 не касается технического контракта, эти + файлы и их сверка с ТЗ унаследованы из r1 (см. выше). +- `docs/SCOPE.md`-обоснование задачи как техдолга без прямой строки Core user + jobs — не пересматривалось повторно; framing принят в r1 неявно (не + вызвал находки) и не является предметом правки этого раунда. + +## Материал раунда + +- Ветка: `origin/issue/421-negative-test-proofs` +- SHA: `fac1f884` +- Дельта: `git diff c409ec6a..fac1f884 -- docs/specs/421-negative-test-proofs.md` +- Предыдущий раунд: `docs/reviews/SPEC-REVIEW-421-r1.md`, SHA `c409ec6a` + +## Вердикт + +Зелёный. Единственная находка r1 закрыта точно так, как была описана +«что чинит находку»; новых находок дельта не создала. ТЗ готово к разработке. + +--- + + + +## Материал раунда + +- Ветка: `issue/421-negative-test-proofs`, коммит `fac1f8840ed1` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `b8775ea49c4263aeafdea84e92dfcc523a3d059c` + ``` + git log --all --format='%H %T' | grep b8775ea49c42 + ``` +- ТЗ `docs/specs/421-negative-test-proofs.md`, блоб `41cd21d1f105502a9c9a7464af0d4b199ae322c9` + ``` + git log --all --find-object=41cd21d1f105502a9c9a7464af0d4b199ae322c9 -- docs/specs/421-negative-test-proofs.md + ```