Files
2026-09-30 23:33:09 +00:00

13 KiB
Raw Permalink Blame History

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), строка подтверждения владельца «Трек: <x> — решение владельца», один вызов 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), строка Трек: <x> — решение владельца, 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