From 5ce83feffaa7d09dc781b05ca6cb7e763a82c1a5 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:33:09 +0000 Subject: [PATCH] docs: review document for #726 Issue: #726 User-Visible: no --- docs/reviews/INDEX.md | 3 +- docs/reviews/SPEC-REVIEW-726-r1.md | 161 +++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 docs/reviews/SPEC-REVIEW-726-r1.md diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index 653f3313..ce5b565c 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,11 +1,12 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 214, issue: 106. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 215, issue: 107. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| | бета v1.79.0-beta.1 | [SHIP-REVIEW-v1.79.0-beta.1.md](SHIP-REVIEW-v1.79.0-beta.1.md) | пакетное ревью ship · — | ⚪ — | 0 | 0 | — | — | | #732 | [CODE-REVIEW-732-r1.md](CODE-REVIEW-732-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | +| #726 | [SPEC-REVIEW-726-r1.md](SPEC-REVIEW-726-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — | | #725 | [SPEC-REVIEW-725-r1.md](SPEC-REVIEW-725-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | устаревший номер строки в «Проблема» п.3 / «Не-скоуп» | `src/iso-scene-render.ts` `src/houseplan-card.ts` `houseplan-card.ts` `header-menu.ts` `iso-scene-render.ts` | | #724 | [CODE-REVIEW-724-r1.md](CODE-REVIEW-724-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #723 | [CODE-REVIEW-723-r1.md](CODE-REVIEW-723-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-726-r1.md b/docs/reviews/SPEC-REVIEW-726-r1.md new file mode 100644 index 00000000..d7261328 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-726-r1.md @@ -0,0 +1,161 @@ +# SPEC-REVIEW-726-r1 + +Issue: #726 «Процесс: выход из неудачного show — неверная классификация → ask без нового лимита» +Этап: spec (PROCESS.md §2.4) · Трек: ask · Заход: r1 · блокирующих циклов израсходовано 0 из 4 + +## Скоуп + +ТЗ (тело issue, раздел `## ТЗ`) меняет контракт конвейера ревью: + +- структурный вердикт модели получает поля `route` (`fix`|`reclassify`) и + `criterion`; +- на треке `show`, этапе `code`, не-зелёный вердикт с `route: reclassify` сам + переводит задачу в `track:ask`/`S3-spec` (если трек не подтверждён строкой + владельца) либо в `blocked`+вопрос владельцу (если подтверждён), вместо + прежнего единственного маршрута в `S6-in-progress`; +- бюджет циклов код-ревью становится общим на все треки задачи (до 4), и + вердикт, исчерпавший бюджет, сразу ставит `review-4`, не дожидаясь + следующего `S7`. + +Изменений класса A нет — это инфраструктура (файлы `scripts/process-track.mjs`, +`scripts/review-result-gate.mjs`, `scripts/review-doc-guard.mjs`, +`scripts/wait-verdict.mjs`, `.github/workflows/_process.yml`, `PROCESS.md`, +`docs/process/*`). Задача явно зависит от #707 (после его `S8`): часть +контракта (`cycleLimit(track)`, строка подтверждения владельца +«Трек: `` — решение владельца», один вызов `process-track.mjs` в шаге +трека, заметка ревьюеру show) вводит #707, а #726 только продолжает и +переиспользует её. + +## Как проверялось + +Дельты нет (r1, документов ревью на #726 в дереве ещё не было) — разбор +полный. Метод — не согласиться с автором, а перепроверить каждый факт из ТЗ +чтением текущего кода, а не поверить формулировке: + +- прочитаны `docs/SCOPE.md`, `AGENTS.md`, `docs/process/REVIEWER.md`, + PROCESS.md §2.4, §2.5, §4, §5, §7.1, §7.2, §10.4; +- тело issue #726 и его единственный комментарий («Оценка… трек ask…»); +- зависимость #707 — открыта её issue, сверены обещанные контракты + (`cycleLimit(track)`, строка `Трек: — решение владельца`, + `process-track.mjs`) на совпадение с тем, что #726 берёт как данность; +- каждая ссылка «`_process.yml:NNNN`» и утверждение о текущем поведении из + раздела «Проблема» ТЗ сверены построчным чтением `.github/workflows/_process.yml` + на HEAD `40607aa3` (факты в ТЗ сверены с `origin/dev` `108427dc` — дифф + `108427dc..40607aa3` не затрагивает ни один упомянутый в ТЗ файл, проверено + `git diff --stat`, разница пуста); +- прочитаны целиком `scripts/process-track.mjs`, `scripts/review-result-gate.mjs`, + значимые фрагменты `scripts/review-doc-guard.mjs` (`materialAnchorBlock`, + `anchorVerdictFrom`, `reusableGreenVerdict`), `scripts/status-label.mjs`, + `scripts/wait-verdict.mjs` (`PIPELINE_EVENTS`, `stateOf`) — проверено, что + структуры данных, которые ТЗ просит расширить, действительно в том виде, в + каком ТЗ их описывает; +- найден и прочитан мутант `process-label-step-combined-again` + (`scripts/mutation-registry.mjs:4085`) — AC9 требует, чтобы его якорь + (буквальный текст шага «Переставить метку») уцелел после правки К4; + подтверждено, что этот текст относится к шагу, который К4 не трогает + (К4 меняет «Решение по вердикту», не «Переставить метку»), то есть риск, + который называет AC9, реален и ровно там, где его называет ТЗ; +- проверено существование всех тестовых файлов, которые план автотестов + называет местом для новых кейсов (`test/process-track.test.mjs`, + `test/review-result-gate.test.mjs`, `test/review-doc-guard.test.mjs`, + `test/wait-verdict.test.mjs`, `test/process-digests.test.mjs`) и канона + (`docs/process/AUTHOR.md`, `docs/process/REVIEWER.md`) — все существуют, + ссылки не на фантомные файлы. + +## Находки + +Блокирующих (High) и находок в скоупе (Medium) нет. + +- **Low, снято ревьюером с записью.** К1 не уточняет, что происходит на + границе доверия, если `criterion` пришёл не строкой (число, объект): + явно описан только случай `route` вне словаря. На практике это не меняет + поведение — К2 уже относит любой `criterion`, не входящий в таблицу из + шести идентификаторов (в т.ч. нестроковый после сериализации), к ветке + «без критерия из таблицы → как `fix` с `note`», то есть система + сходится к безопасному исходу независимо от типа. Технический, не + продуктовый вопрос — решает реализатор; спецификацию менять не нужно. + +## Что проверено и корректно + +- Обязательные разделы §7.1 все на месте: сценарий, что человек увидит до/ + после, проблема, скоуп/не-скоуп, контракт поведения (К1–К6), раздел + UX/данные/i18n/миграция/perf/touch, критерии приёмки с доказательством, + план автотестов, риски, откат, release-артефакты. +- Продуктовые открытых вопросов владельцу нет — весь текст помечен как + решаемый технически («Принято предположительно», 6 пунктов) или закрыт + ссылкой на решение владельца из #707/#695/#696. Это ожидаемо для + инфраструктурной/процессной задачи: `docs/SCOPE.md` её не ограничивает + (задача не продуктовая, ни одной строки Core user jobs не касается — + `AGENTS.md` относит процессные изменения к отдельной ветке чтения, + минуя SCOPE.md). +- Таблица критериев К1 (`complexity`, `surfaces`, `migration`, `ux-contract`, + `perf-touch`, `undocumented`) — дословное соответствие шести пунктам + «Подсказка аналитику» §5 (PROCESS.md, шесть буллетов), без лишнего и без + пропуска. +- Таблица маршрутов К2 прогнана вручную по всем строкам AC3: `show`/`spent 1`/ + `fix` → `spentAfter=2 ≥ limit(show)=2` → `review-4` — сходится; тот же вход + с `reclassify` → `limitAfter=cycleLimit(ask)=4`, `spentAfter=2<4` — без + `review-4`, сходится; `ask`/`spent 3` → `spentAfter=4≥4` — сходится; `ask`/ + `spent 2` → `spentAfter=3<4` — сходится; зелёный вердикт бюджет не трогает + (§4, «зелёный цикла не образует») — сходится. +- AC6 (якорь): `anchorVerdictFrom` — `/Вердикт конвейера: `(green|yellow|red)` + · High (\d+)/` без `$`-якоря — подтверждено чтением + `scripts/review-doc-guard.mjs:516`, добавление хвоста + «· маршрут `reclassify` (критерий `undocumented`)» после существующего + текста не ломает этот regex: правка описана точно. +- Факты из раздела «Проблема» (схема `verdict/high/medium/summary` на + `_process.yml:1336`, безусловный перевод не-зелёного вердикта этапа `code` + в `S6-in-progress` на `:1764` независимо от причины, проверка + `spent -ge limit` только при входе в `S7` на `:288`) — все три + подтверждены построчным чтением тех же мест в текущем файле. +- Зависимость на #707 не голословна: контракт, который #726 заимствует + (`cycleLimit(track)`, формат строки владельца, единственный вызов + `process-track.mjs` в шаге трека), сверен с телом #707 (строки 106, 109, + 112) — совпадает дословно с тем, что #726 называет унаследованным. + #707 сейчас `S6-in-progress` (спека уже зелёная, код не смёржен) — #726 + корректно фиксирует это как «после `S8` #707», а не как готовую базу; + это дисциплинирует порядок работы, а не создаёт скрытую невыполнимость + ТЗ. +- Test targets существуют и не выдуманы (см. «Как проверялось»). + +## Чего не проверял + +- Гейты `npx tsc --noEmit`, `npm test`, `npm run build` не гонял: на этапе + spec зависимости и toolchain не ставятся (#696), задача правит только + ТЗ/процесс, продуктового кода нет. Материал для code-review ещё не + существует — «код» этой задачи появится только после `S5-ready`. +- Мутанты по диффу не запрашивались (по заголовку задачи) и не применимы: + диффа продуктового кода нет, весь диапазон АС проверяется unit-тестами + существующих скриптов, а не мутациями продукта. +- Не проверял реализацию (`reviewRoute`, обновлённые промпт/шаг `_process.yml`, + новые regex `wait-verdict.mjs`) — её ещё нет, ТЗ её не содержит, только + контракт. Проверено, что контракт для неё достаточен, чтобы писать тест + прежде кода (AC1–AC9 у каждого назван oracle и конкретный тестовый файл). +- Не проверял актуальность #707 после её собственного код-ревью (что там + не изменится `cycleLimit`/строка подтверждения до слияния) — это риск + следующего раунда, если #707 смёржится с отличным контрактом; ТЗ #726 + прямо предупреждает об этом рисках-разделе («Тело конвейера читается из + `dev` в момент события») и делает ревизию идемпотентной по смыслу + (откат — просто revert). +- Браузерные смоки, golden, performance, `pytest tests_backend` — не + применимы: задача не трогает `src/**`, демо, Python. + +## Вердикт + +Зелёный. ТЗ полно, каждый AC однозначен и назван способ доказательства, +факты о текущем поведении конвейера перепроверены чтением и подтвердились, +единственная находка — Low, снята ревьюером без правки спецификации. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `40607aa37f13` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `901e6cbd1964ef2dcd9a0e08e8ec01a5c47dcac7` + ``` + git log --all --format='%H %T' | grep 901e6cbd1964 + ``` +- Тело issue: `daf13164d67eb2612f80437127463957f152876d86adf9f60eda40d55848ef33` +- Вердикт конвейера: `green` · High 0