Files
2026-10-01 00:19:58 +00:00

13 KiB
Raw Permalink Blame History

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 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: b65ac0114507ee69bdb435b2ba9f006de09b4e26
    git log --all --format='%H %T' | grep b65ac0114507
    
  • Тело issue: b1610752e35e9640f33b40e054e4482a64098837a1564d41654fe796e145c6e8
  • Вердикт конвейера: green · High 0