13 KiB
SPEC-REVIEW-728-r2 — «process-metrics: эффект процесса по трекам»
Issue: #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— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
b65ac0114507ee69bdb435b2ba9f006de09b4e26git log --all --format='%H %T' | grep b65ac0114507 - Тело issue:
b1610752e35e9640f33b40e054e4482a64098837a1564d41654fe796e145c6e8 - Вердикт конвейера:
green· High 0