From 153fa7a680d4324214bd3c8892fc4a63a4d18c99 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:19:58 +0000 Subject: [PATCH] docs: review document for #728 Issue: #728 User-Visible: no --- docs/reviews/INDEX.md | 3 +- docs/reviews/SPEC-REVIEW-728-r2.md | 139 +++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 docs/reviews/SPEC-REVIEW-728-r2.md diff --git a/docs/reviews/INDEX.md b/docs/reviews/INDEX.md index 1f8bead4..91e7a4f2 100644 --- a/docs/reviews/INDEX.md +++ b/docs/reviews/INDEX.md @@ -1,12 +1,13 @@ # Индекс ревью -Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 219, issue: 109. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`. +Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 220, issue: 109. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). 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 | — | — | | #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` | +| #728 | [SPEC-REVIEW-728-r2.md](SPEC-REVIEW-728-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — | | #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 | — | — | diff --git a/docs/reviews/SPEC-REVIEW-728-r2.md b/docs/reviews/SPEC-REVIEW-728-r2.md new file mode 100644 index 00000000..8586912c --- /dev/null +++ b/docs/reviews/SPEC-REVIEW-728-r2.md @@ -0,0 +1,139 @@ +# SPEC-REVIEW-728-r2 — «process-metrics: эффект процесса по трекам» + +Issue: [#728](https://github.com/Matysh/houseplan-card/issues/728) +Этап: spec · трек `ask` +Заход: r2 (второй; блокирующих циклов израсходовано 1 из 4) + +## Вердикт + +**Зелёный.** High: 0. Medium в скоупе: 0. Medium вне скоупа: 0. Low: 0. + +## Скоуп разбора + +Повторный раунд — объём по дельте (§2.10). Дельта — комментарий автора +`2026-10-01T00:15:18Z` и правка тела issue, которую он описывает, между +материалом r1 (тело issue на момент вердикта r1, SHA кода `40607aa3`/ +`a49f7095` — между ними правок не было) и текущим телом issue (прочитано +целиком заново, 20747 байт). Автор сам перечисляет изменённые разделы: +К3/АС3 (новые регэкспы различения причин), «Не-скоуп» (явный отказ от +отдельных констант в конвейере), граничный случай #705, «Затронутые файлы», +«Чем краснеет», «Принято предположительно» п.4 — и отдельно АС8 (новый тест +вместо ссылки на несуществующую проверку). + +Дельта локальна: два пункта ТЗ (К3/АС3, АС8), оба — прямой ответ на находки +r1, новых подсистем/контрактов не вводит. Разбор ограничен этими двумя AC; +остальное (К1, К2, К4–К8, АС1, АС2, АС4–АС7, АС9, обоснование трека, +обязательные разделы §7.1) унаследовано из r1 без повторной проверки — +таблица ниже. + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| **High.** АС3/К3: `validate-red` и `conflict` заявлены различимыми «на текстах из констант `wait-verdict.mjs`», а единственная константа `PIPELINE_EVENTS` сливает оба случая в один `kind: 'conflict'`. | Формулировка «константа различает» снята. Введены два **новых**, явно не заимствованных у `wait-verdict.mjs` регэкспа прямо в тексте ТЗ: `NOT_RUN_VALIDATE_RE = /^\*\*Ревью не запускалось:\*\* Validate(?: с мутантами)? на материале /m` и `NOT_RUN_CONFLICT_RE = /^\*\*Ревью не запускалось:\*\* ветка \S+ не ребейзится на /m`, которые должны жить в `process-metrics.mjs`, а не в `wait-verdict.mjs`. Формулировка «импорт, не копия» для этой пары снята и в К3, и в «Рисках»: защита переопределена как контрактный тест АС3 на самих шаблонах `_process.yml`. | Тело issue, раздел «К3. Возвраты», абзацы «**`validate-red` и `conflict` такой константы не имеют**» и далее; АС3 в таблице критериев приёмки; «Риски», второй пункт, подпункт про `validate-red`/`conflict`. Проверено чтением `.github/workflows/_process.yml`: оба регэкспа корректно и однозначно матчат реальные строки `:708` (`ветка \`$BRANCH\` не ребейзится на`) и `:850` (`Validate` / `Validate с мутантами` `на материале`); `grep -rn '\*\*Ревью не запускалось:\*\*'` по всему дереву даёт ровно два попадания — ровно столько, сколько требует оракул АС3 («шаблонов должно быть ровно два»). | +| **Medium (в скоупе).** АС8 ссылается на тест `#637 workflow: еженедельный запуск читает только…` как на доказательство `fetch-depth: 0`/`timeout-minutes: 30`, а этот тест таких полей не проверяет. | Ссылка на `#637` для этих двух полей снята. АС8 переписан: новый тест `#728 workflow: полная история и потолок 30 минут`, который читает `_process-metrics.yml` и явно проверяет `timeout-minutes: 30` у job `metrics`, `fetch-depth: 0` у шага checkout и отсутствие другой строки `fetch-depth:` в файле. То же продублировано в К8 и в «Чем краснеет» («`fetch-depth: 1` или `timeout-minutes: 15` в `_process-metrics.yml` (AC8)»). | Тело issue, АС8 в таблице критериев, К8 последний пункт, «План автотестов» → «Чем краснеет». Проверено чтением `.github/workflows/_process-metrics.yml` (текущий HEAD): ровно один `fetch-depth:` во всём файле (значение `1`), `timeout-minutes: 15` у job `metrics` — то есть новый тест на сегодняшнем файле действительно красный, как и заявляет ТЗ, и однозначен (нет второго `fetch-depth:`, с которым тест мог бы спутаться). | + +## Унаследовано из r1 + +Без повторной проверки, по документу `docs/reviews/SPEC-REVIEW-728-r1.md` +(материал того раунда: тело issue на момент вердикта r1, код `HEAD = +40607aa37f13819c9db37a392a1d99f30382b3c0`, ветка `dev`; между ним и кодом +материала этого раунда — `a49f7095` — ни один файл, который называет ТЗ, не +менялся, см. ниже): + +- Обязательные разделы §7.1 — полный комплект, подтверждён и в r1, и в + текущем теле (список разделов не сократился правкой). +- Обоснование трека `ask` по §5 («ожидаемое поведение не зафиксировано» + + «сложность > 3», задача — только класс B). +- К1, К2, К4, К5, К6, К7, К8 (кроме последнего пункта К8 про + `fetch-depth`/`timeout-minutes`, который относится к закрытой находке + Medium и перепроверен выше) и соответствующие АС1, АС2, АС4, АС5, АС6, + АС7, АС9. +- Имена jobs конвейера (`guard`/`prepare`/`model`/`integrate`) в К5 — сверены + с `.github/workflows/_process.yml`. +- Формат машинного блока `ship-review.mjs` (`anchorBlock`/`parseAnchorBlock`) + для АС4. +- Арифметика примера АС2 (фикстура часов, сумма отрезков = `lead`). +- Приём «unit + временный git-репозиторий» для АС7 (`test/process-track. + test.mjs`, `mkdtempSync` + `git init`). +- Дата `TRACKS_CUTOVER = '2026-09-28'`, сверенная с PROCESS.md §5 (#695). +- Отсутствие продуктовых вопросов владельцу (чисто инфраструктурный, + read-only отчёт). + +## Находки + +Нет. Обе находки r1 закрыты по существу (таблица выше), новых AC дельта не +вносит и не задевает. + +## Что проверено и корректно + +- Делта локальна и полностью отвечает находкам r1: автор не расширил и не + сократил скоуп задачи, не ввёл новых продуктовых решений — только + техническое уточнение различения причин возврата и доказательства АС8. +- Новые регэкспы `NOT_RUN_VALIDATE_RE`/`NOT_RUN_CONFLICT_RE` корректно и + однозначно разбирают оба реальных текста конвейера (`_process.yml:708` и + `:850`), включая оба значения `$kind` (`Validate` и `Validate с + мутантами`) — проверено построчным сопоставлением regex с исходным + bash/YAML-текстом, а не на веру. +- Граничный случай #705 (`merge-candidate.mjs`, `commentFor('push-refused- + workflow', …)`) по-прежнему даёт `unknown`: его текст — `**Ревью не + запускалось: кандидат меняет workflow-файл…**` — жирность закрывается + **после** двоеточия, а не перед ним, поэтому литерал `**Ревью не + запускалось:**` (с закрытием жирного сразу после двоеточия), на который + опираются оба новых регэкспа и старый `PIPELINE_EVENTS`, не матчит эту + строку ни при каком раскладе — заявление ТЗ подтверждено чтением кода. +- Тест АС8 на сегодняшнем `_process-metrics.yml` действительно падает + (`fetch-depth: 1`, `timeout-minutes: 15`), и ровно один `fetch-depth:` во + всём файле — конструкция «другой строки `fetch-depth:` в файле нет» + однозначна, двусмысленности в разборе YAML не будет. +- Материал этого раунда (код) совпадает с материалом, на который ссылается + сам автор в правке («Правка по ревью r1 сверена с `a49f7095`») и с HEAD + рабочей копии. + +## Чего не проверял + +- Не запускал `npm run gate:small`, `tsc --noEmit`, `npm test`, `npm run + build` — кода для #728 ещё нет (ветка `issue/728-*` не существует ни + локально, ни на remote), это этап ТЗ, а не код-ревью; гонять гейты не над + чем, как и в r1. +- Не проверял живьём `npx tsc --noEmit`/`npm run build` на самом `a49f7095` + для целей этой задачи — он не содержит кода #728, сверка с этим SHA имеет + смысл только для материала код-ревью, которого здесь нет. +- Не проверял реальные данные GitHub Actions/issues (`fetchSnapshot`, + `gh api`) — АС1–АС8 рассчитаны на unit-фикстуры; живой прогон назван в + плане тестов как наблюдение после слияния, не как AC (без изменений + относительно r1). +- Не проверял предположение, что между 108427dc/40607aa3 и `a49f7095` + изменился состав файлов, важных для ТЗ, кроме как `git log --oneline` по + перечисленному в «Затронутые файлы» списку — тем же способом, что и в r1; + результат — пусто, правок нет. +- Не оценивал заново все восемь AC целиком — только два, которые задевает + дельта (АС3, АС8); остальные унаследованы из r1 (раздел выше) согласно + §2.10: дельта локальна, не ребейз на ушедший вперёд `dev`, не смена + контракта и не новая подсистема. + +## Материал раунда + +Issue #728, тело на момент вынесения вердикта r2 (раздел `## ТЗ`), хэш тела +`sha256:709fab2bbde11d68c5082a0534f271a38e39a8bf1ec6c228ab42a92e0c2c55ac`. +Ветки `issue/728-*` не существует — задача всё ещё не входила в реализацию. +Код читан с `HEAD = a49f7095ce77def25cc1ec4d48b390ec62d84bfd` (ветка `dev`), +дерево `b65ac0114507ee69bdb435b2ba9f006de09b4e26`; ТЗ само ссылается на этот +же коммит («Правка по ревью r1 сверена с `a49f7095`»), совпадает с рабочей +копией. + +--- + +--- + + + +## Материал раунда + +- Ветка: `dev`, коммит `a49f7095ce77` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `b65ac0114507ee69bdb435b2ba9f006de09b4e26` + ``` + git log --all --format='%H %T' | grep b65ac0114507 + ``` +- Тело issue: `b1610752e35e9640f33b40e054e4482a64098837a1564d41654fe796e145c6e8` +- Вердикт конвейера: `green` · High 0