Files
2026-10-01 08:57:19 +00:00

17 KiB
Raw Permalink Blame History

CODE-REVIEW-729-r1

Материал раунда: git log --oneline origin/dev..HEAD / git diff origin/dev...HEAD на SHA 0e44f8a69f01c94b15b1ef48b411f5081b8e686d (ветка issue/729-spec-draft, один коммит поверх dev@7ff2b5ae). Трек: ask · заход r1 · блокирующих циклов 0/4 · маршрут вердикта: fix.

Скоуп

Issue #729 (выделено из #707) вводит одно явное исключение из правила №1: локальный, непушимый черновик кода класса A на track:ask, пока задача стоит в S4-spec-review, принимается правилом 10 (checkCommitEraStatuses, scripts/process-gate.mjs), если:

  1. коммит несёт ровно один трейлер Spec-Draft: sha256:<64 hex>;
  2. трек на момент написания (authorDate) — ask;
  3. эпоха S4-spec-review, в которой написан коммит, закрыта S5-ready;
  4. трейлер равен хешу «Тело issue» зелёного (High 0) SPEC-REVIEW-<NN>-r* этой эпохи, прочитанного из git (вершина диапазона или origin/dev).

Пакет задачи (scripts/task-packet.mjs) печатает новый раздел «Черновик (#729)»: в S4 — право вести черновик и готовую строку трейлера; в S5/S6 — какое ревью ТЗ зелёное и изменилось ли тело после него. Канон (PROCESS.md §11.8 и ссылки на него из §1, §2.4–2.6, §3 п.1, §7.2, §9, §10.2, §12), docs/process/AUTHOR.md, docs/process/REVIEWER.md, AGENTS.md и test/process-digests.test.mjs обновлены синхронно. _process.yml не менялся — так и было заявлено в ТЗ (не-скоуп).

Изменённые файлы (все входят в заявленный в ТЗ список «Затронутые файлы», новых — нет): AGENTS.md, PROCESS.md, docs/process/AUTHOR.md, docs/process/REVIEWER.md, scripts/process-gate.mjs, scripts/task-packet.mjs, test/pre-push-gate.test.mjs, test/process-digests.test.mjs, test/process-gate.test.mjs, test/task-packet.test.mjs.

Коммит несёт Issue: #729 и User-Visible: no; изменение не видно продуктовым пользователям House Plan (процесс разработки, не продукт из docs/SCOPE.md), changelog корректно не тронут.

Как проверялось

Дешёвые гейты на этом SHA подтверждены зелёным Validate (ссылка в промпте) — tsc/npm test/npm run build+bundle-policy не перегонялись. Дополнительно к этому прогнано:

Гейт Команда Результат
Целевые юниты диффа node --test test/process-gate.test.mjs test/task-packet.test.mjs test/process-digests.test.mjs test/pre-push-gate.test.mjs 89/89 pass (совпадает с заявленным автором числом)
Монолит-якоря (не регрессия) node --test test/monolith-text-anchors.test.mjs 2/2 pass
Мутации (реестр, без новых запусков) node scripts/mutation-gate.mjs --check 4 предупреждения — совпадает с dev, новых не добавилось
Бюджет чтения node scripts/entry-cost.mjs --check author 5367/12000, reviewer 4750/9000 — совпадает с хендоффом
Процессный гейт на себя node scripts/process-gate.mjs --range origin/dev..HEAD чисто, 0 нарушений
Трек/маршрут node scripts/process-track.mjs stage --stage=code --labels=track:ask,S7-code-review ... track=ask, route_note → route: fix
Мутационная проверка AC «чем краснеет» (ручная, не из реестра) временно if (false) вместо сравнения хешей в judgeDraft, затем откат 4 теста AC1/AC2/AC4 красные — подтверждает, что тест на сверку хеша умеет падать

Прочитаны построчно: весь диапазон scripts/process-gate.mjs (новые функции trackAt, draftEpoch, greenSpecReviewOf, judgeDraft, gitSpecReviewReader, правка checkCommitEraStatuses), весь диапазон scripts/task-packet.mjs (rightsFor, latestGreenSpecReview, specDraftState, buildPacket, renderPacket, collectInputs), полные диффы PROCESS.md §11.8 и правок к §1/§2.4–2.6/§3/§7.2/§9/§10.2/§12, AUTHOR.md, REVIEWER.md, AGENTS.md, test/process-digests.test.mjs, test/pre-push-gate.test.mjs. Проверена полнота HOOK_FILES (test/pre-push-gate.test.mjs) прямым чтением import-блоков review-doc-guard.mjs, process-track.mjs, change-risk.mjs, review-result-gate.mjs — список действительно покрывает новое дерево импортов process-gate.mjs.

Прочитано, но не исполнено: сопоставление ТЗ (АК1–АК10, тело issue #729) с кодом — построчно, без отдельного прогона (доказательство — тесты автора, воспроизведённые выше).

AC → доказательство

AC Что Чем доказан Чем краснеет
AC1 Черновик принят/отклонён по трейлеру test/process-gate.test.mjs «#729 AC1», прогнан ручная мутация сравнения хешей в judgeDraft красит тест (см. таблицу гейтов)
AC2 Границы эпохи и раунда «#729 AC2», прогнан тест сам содержит отрицательные случаи (эпоха закрыта S3/S6, не закрыта, timeline без allowed)
AC3 Трек на момент записи и формат трейлера «#729 AC3», прогнан формат проверен 4 негативными значениями трейлера в самом тесте
AC4 Сопоставление с зелёным документом своей эпохи «#729 AC4», прогнан негативные случаи (yellow, High 1, без «Тело issue», вне окна, более старый раунд) — в тесте
AC5 Совместимость с #738 — без читателя исключение выключено «#729 AC5», прогнан тест сравнивает plain === strip(c) на 8 сценариях и напрямую дергает warn/fail-ветки
AC6 Чтение документов из git + CLI «#729 AC6» (reader) и «#729 AC6» (CLI), оба прогнаны на временном git-репозитории с заглушкой gh тест проверяет оба кода выхода (0/1) и текст находки на 4 сценариях (rebased/fromDev/stale/unproven)
AC7 Один источник хеша «#729 AC7» в обоих файлах теста, прогнаны тест читает _process.yml и проверяет тождество функций issueBodyDigest
AC8 Пакет задачи «#729 AC8» ×2 в test/task-packet.test.mjs, прогнаны негативные случаи (track:show, blocked, review-4, устаревшее тело) — в тесте
AC9 Канон и конспекты test/process-digests.test.mjs, прогнан целиком новые ключевые правила и привязка к заголовку ### 11.8 проверены assert'ами на реальный текст файлов
AC10 Гейт gate:small, mutation-gate --check, entry-cost --check воспроизведены выше якоря task-packet-* и packet-infra-track-ignores-show-default не сдвинуты (сверено diff'ом mutation-registry.mjs — пусто)

Все десять AC — защитные по характеру (гейт либо принимает, либо отказывает коммит), и у каждого в таблице есть непустой третий столбец — требование §2.7/REVIEWER.md выполнено.

Находки

Нет High. Нет Medium. Нет Low.

Читал реализацию на предмет типичных мест ошибок в такой логике (границы эпохи, порядок проверок «находка одна — по первой невыполненной», ленивое чтение git, инъекция specReviews, согласованность issueBodyDigest между тремя модулями, нормализация \r\n) — расхождений с ТЗ не нашёл. Отклонения от ТЗ, о которых автор написал в хендоффе (правка фикстуры test/pre-push-gate.test.mjs, предупреждение «трейлер вне S4» только с читателем, кэш документов по задаче, trailer: null в --json при запрещённом черновике) — все мелкие технические решения в объявленном скоупе «реализатору на выбор» (ТЗ, «Принято предположительно», пп. 6, 9, 10), находок не образуют.

Побочные дефекты, найденные при реализации и правомерно вынесенные в отдельные issue (не чинятся в этой задаче, не TODO в этом документе): #752 (process-metrics), #748 п.1 (устаревшая строка пакета для S3), #751 п.4 (метрика черновиков), плюс названные в хендоффе кандидаты (формат Spec-Draft в commit-msg, вывод HOOK_FILES из дерева импортов) — по заявлению автора заведены или добавлены как кандидаты; это корректный путь по §12 («Оставили в тексте ревью» не считается закрытием), ревью их не заводит повторно.

Что проверено и корректно

  • Правило 10 (judgeDraft) проверяет условия строго в порядке ТЗ (К3 п.2: формат → трек → эпоха → документ → хеш), «находка одна — по первой невыполненной» выполнено буквально (return fail(...) на первой же).
  • draftEpoch корректно учитывает reconcile (#555): шагает назад по непрерывной серии S4-spec-review в уже отфильтрованном списке статусных событий, не путает начало эпохи с повторной постановкой метки.
  • trackAt на коммите без трековых событий возвращает ask — соответствует §5.1 («продуктовая задача без метки трека — ask»), совпадает с trackFromLabels([]).
  • gitSpecReviewReader ленив (ни одного вызова git, пока правило 10 не спросит документы чернового коммита) и кэширован по issue — подтверждено тестом AC5 (reader.reads) и AC6.
  • issueBodyDigest — действительно одна функция на гейт, пакет и конвейер: scripts/task-packet.mjs реэкспортирует её же из review-doc-guard.mjs (не копию), scripts/process-gate.mjs импортирует оттуда же якоря anchorIssueBodyFrom/anchorVerdictFrom. «Одно число — один источник» (§8) выполнено: хеш тела issue виден в трейлере коммита, в пакете задачи и в документе ревью — везде один источник.
  • test/pre-push-gate.test.mjs HOOK_FILES расширен корректно и полно: прямой разбор import-блоков показал, что список покрывает всё новое транзитивное дерево зависимостей process-gate.mjs без пропусков.
  • Без инъекции specReviews (или если в диапазоне нет чернового коммита) поведение и тексты находок побайтово равны #738 — проверено тестом AC5 и чтением кода (ветки if (specReviews ...) вокруг каждого нового куска).
  • User-Visible: no обоснован: изменение процесса разработки, не продукта из docs/SCOPE.md; changelog не нужен и не тронут.
  • Коммит несёт трейлеры Issue: #729/User-Visible: no корректно; сам этот коммит не является черновиком (Spec-Draft на нём не требуется — он сделан после S5, что подтверждает хендофф «Взял: ... по зелёному ревью ТЗ»).

Чего не проверял

  • Полный npm run gate:small, npx tsc --noEmit, npm run build с полной сверкой трёх копий бандла — не перегонял: зелёный Validate на этом SHA уже подтверждён (ссылка в промпте), диффа в dist/, src/, custom_components/, demo/golden/baselines/ нет (проверено git diff --stat — пусто).
  • Браузерные смоки, golden:verify, pytest tests_backend, npm run invariants, performance-профили — не прогонял и не выбирал по smoke-select.mjs: изменение не трогает ни один из путей, которые эти гейты проверяют (нет файлов src/**, custom_components/**/*.py, геометрии или рендера в диффе); ни один AC их не требует.
  • Реальный прогон сценария «живой» ревью ТЗ → черновик → гейт на настоящем GitHub issue (end-to-end через CI) — не воспроизводил; AC6 покрывает CLI с заглушкой gh на временном git-репозитории, этого достаточно для доказательства логики гейта, но не для проверки, что реальный gh api .../timeline отдаёт точно тот формат событий, который ожидает trackAt/statusEvents (риск уже назван автором в разделе «Риски» хендоффа и в самом ТЗ, п. «Часы автора отстают от GitHub»).
  • Не проверял исполнением фактическое поведение _process.yml (шаг «Взять SHA материала», публикация SPEC-REVIEW) — по ТЗ этот файл не менялся (не-скоуп), а материал ревью кода не включает ревью ТЗ.

Вердикт

Все 10 AC доказаны автотестами, тесты воспроизведены и умеют падать (одна мутация проверена вручную дополнительно к имеющимся негативным случаям внутри тестов). Реализация соответствует контракту ТЗ буквально — К1–К5 покрыты файл-в-файл. High/Medium не найдено. Побочные находки корректно вынесены в отдельные issue, а не оставлены как TODO.

Зелёный.


Материал раунда

  • Ветка: issue/729-spec-draft, коммит 0e44f8a69f01 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: c7dc00f61e25ed2b0dae9d0ed9dea6275d3510a9
    git log --all --format='%H %T' | grep c7dc00f61e25
    
  • Тело issue: 94cd1bca3f851c8c9d9fc64b3b6227fb2fd3dac9f47715053a95dd133ae40bed
  • Вердикт конвейера: green · High 0 · маршрут fix