From fc835cb97d57993aafabedf981aa55446d014644 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:18:39 +0000 Subject: [PATCH] docs: review document for #727 Issue: #727 User-Visible: no --- docs/reviews/INDEX.md | 3 +- docs/reviews/SPEC-REVIEW-727-r2.md | 168 +++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 docs/reviews/SPEC-REVIEW-727-r2.md diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index ba954d7b..1f8bead4 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,6 +1,6 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 218, issue: 109. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 219, issue: 109. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. | Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы | |---|---|---|---|---:|---:|---|---| @@ -8,6 +8,7 @@ | #732 | [CODE-REVIEW-732-r1.md](CODE-REVIEW-732-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — | | #728 | [SPEC-REVIEW-728-r1.md](SPEC-REVIEW-728-r1.md) | spec · r1 | 🟡 жёлтый | 1 | 0 | 1. АС3/К3: заявленное различение причин validate-red и conflict «на текстах из констант…; 2. АС8: заявленное доказательство правки process-metrics.yml (fetch-depth: 0, timeout-m… | `wait-verdict.mjs` `review-doc-guard.mjs` `scripts/wait-verdict.mjs` `.github/workflows/_process.yml` `_process.yml` `_process-metrics.yml` `test/process-metrics.test.mjs` | | #727 | [SPEC-REVIEW-727-r1.md](SPEC-REVIEW-727-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 1 | К7/AC7: архивирование ночного документа с базой-стабильным-тегом не имеет ни одного про… | `scripts/reviews-archive.mjs` | +| #727 | [SPEC-REVIEW-727-r2.md](SPEC-REVIEW-727-r2.md) | spec · r2 | 🟢 зелёный | 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 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-727-r2.md b/docs/reviews/SPEC-REVIEW-727-r2.md new file mode 100644 index 00000000..c74766c6 --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-727-r2.md @@ -0,0 +1,168 @@ +# SPEC-REVIEW-727-r2 + +Issue: #727 · этап: spec · трек: ask · заход: r2 · блокирующих циклов израсходовано (после этого раунда): 1/4 + +## Скоуп + +#727 — первая из двух независимых частей, выделенных из #707 п.3: ночное +пакетное ship-ревью на `dev` и переиспользование его результата в гейте беты +(`ship-review.mjs check`). Контракт не изменился с r1: К1 (патч-набор по +`git patch-id --stable`), К2 (ночной режим `tag=nightly`, имя документа +`SHIP-REVIEW-<база>-dev-.md`), К3 (`shipCoverage`: +`clean`/`high`/`stale`/`none`), К4 (гейт `check` по покрытию), К5 (дельта +беты), К6 (job в `_nightly.yml`), К7 (индекс и архив узнают ночное имя), К8 +(комментарий в задачу при High), К9 (канон). Красная ночь — отдельный issue E, +не входит. Продуктового кода нет, `User-Visible: no`, трек `ask` обоснован +(см. r1 и подтверждение ниже). + +Этот раунд — правка автора по единственной находке r1 (Medium, К7/АС7): К7 +переписан, в АС7 добавлены четыре конкретных примера вход→выход. Комментарий +автора 2026-10-01T00:13:45Z («ТЗ исправлено по ревью r1 ... Возвращаю на +ревью ТЗ») и пометка в ТЗ («Правка по ревью r1 сверена с `a49f7095`: файлы, +которые называет ТЗ, между этими коммитами не менялись») задают материал +раунда. Разбор — по дельте (§2.10): объём сопоставим с одной находкой, +ребейза, смены контракта или новой подсистемы нет — сокращаю объём разбора, +не строгость. + +## Как проверялось + +1. **Закрытие находки r1** — построчное сравнение текста К7/АС7 r1 (квоты в + `docs/reviews/SPEC-REVIEW-727-r1.md`) с текущим телом issue + текст + комментария автора, описывающий правку. +2. **Проверка новой логики по коду на материале ревью** (`HEAD` рабочей копии + `a49f7095ce77def25cc1ec4d48b390ec62d84bfd`, совпадает с материалом, названным + в задаче): прочитан целиком `scripts/reviews-archive.mjs` (`archivePlan`, + `compareStable`, `stableTagsThrough`), `scripts/reviews-index.mjs` + (`parseDocName`, `SHIP_DOC_NAME`), `test/ship-review.test.mjs` (тест #696, + строка 79-93) — каждый новый технический пример АС7 (а/б/в/г) проверен на + реализуемость существующими примитивами. +3. **Локальность дельты**: `git diff 40607aa37f13..HEAD --stat` и точечный + `git diff` по файлам, которые называет ТЗ (`scripts/ship-review.mjs`, + `scripts/reviews-index.mjs`, `scripts/reviews-archive.mjs`, + `.github/workflows/_nightly.yml`, `.github/workflows/_ship-review.yml`, + `.github/workflows/ship-review.yml`, `test/ship-review.test.mjs`, + `test/nightly-workflow.test.mjs`, `test/process-digests.test.mjs`, + `PROCESS.md`, `docs/process/REVIEWER.md`) — пусто: материал r1 не устарел. +4. Сверка текущего §11.7 PROCESS.md с формулировкой «публичного контракта» в + обосновании трека `ask`. +5. Гейты: `npx tsc --noEmit` (узел не содержит `node_modules`, зависимости на + этапе spec не ставились — #696, ожидаемо и не блокирует), мутант и + `entry-cost` проверены точечным чтением/запуском (ниже). + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| Medium (К7/АС7): правило «база — стабильный тег → первая архивируемая линия новее базы» не реализуемо точным совпадением `archivePlan`, и АС7 не даёт для этой ветки ни одного примера вход→выход | К7 переписан: явно разделены две ветки архивации (база-бета — точное совпадение, как сегодня; база-стабильный тег — «наименьшая архивируемая линия строго новее базы», `compareStable`, названа как новая логика). АС7 получил четыре конкретных примера (а: база-бета → `v1.79.0`; б: `[v1.78.0, v1.79.0]`, база `v1.78.0` → `v1.79.0`; в: `[v1.78.0, v1.78.1, v1.79.0]` → `v1.78.1`, ближайшая, не последняя; г: линии новее нет → `kept` с новой причиной) | Тело issue #727, раздел «Контракт поведения» → К7 (три подпункта: база-бета / база-стабильный тег / подходящей линии нет); таблица «Критерии приёмки» → АС7 (все 4 примера); раздел «Граничные случаи» (окно между релизом и бетой) и «Чем краснеет» (два новых отрицательных случая, явно привязанных к АС7 б/г) | + +Проверка покрытия по существующему коду: +- `compareStable` (`scripts/reviews-archive.mjs:46-50`) и `stableTagsThrough` (`:53-57`) уже существуют и реализуют именно сравнение, которое нужно для «наименьшая линия строго новее базы» — К7 корректно называет существующий примитив, а не выдумывает его. +- Сегодняшняя ветка `stage === 'ship'` (`scripts/reviews-archive.mjs:91-97`) действительно ищет точное совпадение (`tags.has(line)`) и не умеет искать «следующий по порядку» тег — ровно тот пробел, который r1 называл находкой; К7 теперь явно описывает его как новую логику, а не как уже работающую. +- Пример (б) и (в) оба реализуемы одной и той же операцией: `ordered.filter(l => compareStable(l.tag, base) > 0)[0]` (где `ordered` — уже отсортированный по возрастанию массив строк кода) — даёт «ближайшую, не последнюю» линию без дополнительных допущений. +- Пример (а) — существующая ветка, не меняется; тест `#696` (`test/ship-review.test.mjs:78-93`) продолжает работать как сегодня, АС7 это прямо фиксирует («`deepEqual` теста `#696` не меняется») — проверено построчным чтением теста, сигнатура `assert.deepEqual(parseDocName('SHIP-REVIEW-v1.79.0-beta.1.md'), { stage: 'ship', issue: null, round: null, suffix: null, tag: 'v1.79.0-beta.1' })` не содержит поля `nightly` — реализация обязана добавлять `nightly: true` только условно (для ночных имён), что соответствует формулировке АС7 («`nightly: true`» называется только для нового примера, не для старого) и не противоречит незыблемости старого теста. + +Находка закрыта полно: ветка, для которой АС7 не имел примера, теперь имеет все четыре требуемых случая (положительный×3 с различием «одна линия / несколько линий / ближайшая vs последняя», отрицательный), и реализуемость каждого подтверждена существующими примитивами, а не только декларацией. + +## Унаследовано из r1 + +Без повторной проверки принято всё, что r1 зафиксировал в разделе «Что +проверено и корректно» (`docs/reviews/SPEC-REVIEW-727-r1.md`, материал — +`origin/dev` `40607aa37f13819c9db37a392a1d99f30382b3c0`), поскольку дельта его +не касается и диапазон `40607aa3..a49f7095` не трогает ни один из файлов, +которые называет ТЗ (проверено `git diff --stat` в этом раунде, см. «Как +проверялось» п.3): + +- существование и сигнатуры `readCandidateHistory`, `issueTrailers`, + `shipReviewDocPath`, `isShipIssue`, `specSection`, `shipIssuesInRange`, + `renderShipBrief`, `anchorBlock`, `parseAnchorBlock`, `shipReviewProblems`, + `readShipDoc`; +- `RELEASE_TAG_RE`, текущий машинный блок документа беты и его поля; +- реальность тега `v1.79.0-beta.1`, документа `SHIP-REVIEW-v1.79.0-beta.1.md`, + коммита `dca0fd28` с трейлерами `Issue:`/`Release:`; +- `SHIP_DOC_NAME`/`parseDocName` сегодня не знают ночной суффикс; +- содержимое `_nightly.yml` (job `dispatch`, ожидание до 3 минут, токен + `github.token`), входы и права тонких файлов `ship-review.yml`; +- `HP_PROCESS_TOKEN` как существующий секрет публикации; +- мутант `ship-review-ignores-merge-marker` (`scripts/mutation-registry.mjs`), + команда `node scripts/entry-cost.mjs --check`; +- существование `test/process-digests.test.mjs`, `test/ship-review.test.mjs`, + `test/nightly-workflow.test.mjs`; +- обязательные разделы §7.1 присутствуют и в правильном порядке; +- обоснование трека `ask` (сложность/риск >3, публичный контракт §11.7). + +Точечно переподтверждено в этом раунде (не просто унаследовано): §11.7 +PROCESS.md прочитан заново (строки 1555-1583) — формулировка «документ обязан +лежать в кандидате или в `dev`, покрывать их все и не нести High» совпадает +дословно с тем, что обоснование трека `ask` называет «сегодняшним» правилом. + +## Что проверено и корректно (этот раунд) + +- К7/АС7 — полностью, см. «Закрытие раунда r1» выше. +- «Принято предположительно» — пункт 7 (новый): «Линия ночного документа со + стабильной базой — ближайшая архивируемая линия новее базы, а не линия по + трейлерам его задач» — корректно резюмирует именно то решение, что описано + в К7, не вводит противоречия с остальными 6 пунктами (не изменились). +- «Чем краснеет» — два новых отрицательных случая («ночной документ со + стабильной базой не уходит в каталог самой базы (АС7 б)», «без более новой + линии остаётся на месте (АС7 г)») точно соответствуют новым примерам АС7, не + дублируют и не противоречат трём прежним пунктам. +- «Затронутые файлы» — уточнение «(`archivePlan`: новая ветка для ночного + документа со стабильной базой)» верно называет функцию, которую правка + действительно трогает (проверено чтением `scripts/reviews-archive.mjs`, не + исполнением — продуктового кода задачи ещё нет). +- Материал не устарел: файлы ТЗ не менялись между `40607aa3` и `a49f7095` + (гейт «материал ревью не запушен/не устарел» выполнен). + +## Чего не проверял + +- Гейты (`npx tsc --noEmit`, `npm test`, `npm run build`) не прогонял по + существу — `node_modules` не установлены (зависимости на этапе spec не + ставятся, #696), а задача не меняет ни одного файла репозитория на этом + этапе: показывать «зелёный»/«красный» тестов, которых ещё нет, не на чем. + Обязательны на `S7-code-review`. +- Не проверял, что `ordered.filter(...)` (конкретная реализация «ближайшей + линии новее базы», которую я предложил как пример реализуемости) — + единственно возможная или будущая реализация автора; это право + реализатора, спецификация фиксирует только вход/выход АС7. +- Golden/смоки/бэкенд-pytest/инварианты модели — не относится: задача класса A + не содержит, геометрии и визуала не касается. +- Не проверял повторно всё, что уже подтверждено в r1 (список — раздел + «Унаследовано из r1»); точечно перепроверено только §11.7 PROCESS.md. +- Не проверял реальный прогон `git patch-id --stable` и `workflow_dispatch` + между workflow-файлами — та же причина, что в r1 (документированное + поведение инструментов, не специфика этого кода); дельта этого раунда их не + касается. + +## Вердикт + +Единственная находка r1 (Medium, К7/АС7) закрыта: правило архивации для +ночного документа со стабильной базой теперь описано отдельной веткой с +названным существующим примитивом (`compareStable`), и АС7 содержит четыре +конкретных примера вход→выход, включая отрицательный случай — реализуемость +каждого подтверждена чтением существующего кода, а не только текстом ТЗ. +Новых находок в дельте нет. Материал не устарел (файлы ТЗ не менялись между +`40607aa3` и `a49f7095`). Трек `ask` обоснован с r1 без изменений. + +**Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0** + +## Материал раунда + +- Этап: spec. Материал — тело issue #727 на момент комментария Matysh + 2026-10-01T00:13:45Z («ТЗ исправлено по ревью r1 ... Возвращаю на ревью + ТЗ»). +- Кода/ветки продукта не существует (инфраструктурная задача до реализации); + факты сверены с рабочей копией на `HEAD` = `a49f7095ce77def25cc1ec4d48b390ec62d84bfd`. + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `a49f7095ce77` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `b65ac0114507ee69bdb435b2ba9f006de09b4e26` + ``` + git log --all --format='%H %T' | grep b65ac0114507 + ``` +- Тело issue: `8ce2942ca915bc938c8c5b4a720bb71d5a06d18c13db0692ee802f6a55662b7a` +- Вердикт конвейера: `green` · High 0