From 619fd0c4ffac439c4687da720a602e1dd01979e0 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Wed, 10 Jun 2026 01:20:53 +0300 Subject: [PATCH] reviewer(ET): auto-commit from reviewer run_id=538 --- docs/work-items/ORCH-027/12-review.md | 125 +++++++++++++++----------- 1 file changed, 72 insertions(+), 53 deletions(-) diff --git a/docs/work-items/ORCH-027/12-review.md b/docs/work-items/ORCH-027/12-review.md index 458d28f..0ac77d7 100644 --- a/docs/work-items/ORCH-027/12-review.md +++ b/docs/work-items/ORCH-027/12-review.md @@ -1,29 +1,33 @@ --- -verdict: REQUEST_CHANGES +verdict: APPROVED work_item: ORCH-027 stage: review author_agent: reviewer -status: changes-requested +status: approved created_at: 2026-06-10 model_used: claude-opus-4-8 type: review work_item_id: ORCH-027 -version: 1 +version: 2 --- # Review ORCH-027 — Code coverage как гейт ## Summary -Сильная, дисциплинированная реализация детерминированного coverage-гейта по образцу +Дисциплинированная реализация детерминированного coverage-гейта строго по образцу security/merge/image-freshness под-гейтов. Соответствие ТЗ/ADR — полное; код качественный, -тесты содержательны (29/29 в `test_coverage_gate.py` зелёные, регресс реестров 89/89 зелёный); -документация обновлена исчерпывающе. **Блокирует приёмку ровно один дефект:** PR-коммит -**испортил соседнюю запись ORCH-095 в `CHANGELOG.md`** — тело абзаца продублировано -дословно (артефакт чужого work item повреждён). Это must-fix (дублирование в golden-source -доке + правка артефакта другой задачи, нарушение CLAUDE.md §3). Фикс тривиален. +тесты содержательны (`test_coverage_gate.py` — 30 тестов; **полный регресс `tests/ -q` +зелёный: 1466 passed**); документация обновлена исчерпывающе. -Проверено: 4 оси (ТЗ / ADR / качество кода / документация) + трассировка маркеров. +**Единственный прежний блокер закрыт.** Ревизия v1 выносила P1 за повреждённую (дословно +продублированную) запись ORCH-095 в `CHANGELOG.md` — коммит `75c33ab docs(changelog): repair +duplicated ORCH-095 entry body` устранил дубль: тело bullet ORCH-095 теперь присутствует ровно +один раз (`git revert occurrences on line 16: 1`), артефакт чужой задачи восстановлен. Новых +P0/P1 не выявлено. + +Проверено: 4 оси (ТЗ / ADR / качество кода / документация) + трассировка маркеров + полный +прогон тест-сьюта. ## Findings @@ -31,72 +35,87 @@ security/merge/image-freshness под-гейтов. Соответствие Т - (нет) ### P1 — Must fix -- [ ] **`CHANGELOG.md`: запись ORCH-095 повреждена — тело абзаца продублировано.** В строке 16 - bullet ORCH-095 заканчивается `…откат = `git revert`).` и затем **повторяет весь свой текст - заново** (`карточка задачи (src/notifications.py::render_task_tracker)… → карточка застывает… - откат = `git revert`).`). Это (а) **дублирование** в golden-source доке (severity P1 по рубрике - reviewer) и (б) **правка артефакта другой задачи** ORCH-095 (нарушение CLAUDE.md «Правила для - агентов §3 — никогда не править артефакты других этапов»; ORCH-027 при вставке своего блока - затёр/задублировал чужую запись). **Действие:** удалить дублирующую половину bullet ORCH-095 — - оставить ровно один экземпляр тела, заканчивающийся на первом `откат = `git revert`).`. Запись - ORCH-027 трогать не нужно — она корректна. +- (нет) — прежний P1 (дубль записи ORCH-095 в CHANGELOG) исправлен коммитом `75c33ab`. ### P2 — Should fix -- (нет) +- [ ] **Несоответствие формулировки ADR-001 D7 фактическому артефакту: 6-польная схема 52c + не эмитится.** `ADR-001-coverage-gate.md` D7 утверждает: «Артефакт несёт **аддитивно** + обязательную 6-польную схему 52c, не трогая `coverage_status:`». Фактически и генератор + (`coverage_gate.render_coverage_report`), и скелет `docs/_templates/18-coverage-report.md` + эмитят только `coverage_status`/`work_item` + coverage-поля; отсутствуют 5 из 6 полей схемы + 52c (`stage`/`author_agent`/`status`/`created_at`/`model_used`). **Почему не блокер:** (а) + TRZ §6 формулирует это условно («*Если* отчёт несёт обязательную 6-польную схему 52c — + добавить её аддитивно»), (б) валидация схемы warning-only по умолчанию + (`frontmatter_validation_strict=False`), (в) гейт-генерируемые артефакты (прецедент + `17-security-report.md`) исторически несут лишь свой machine-key — эпик 52c (ORCH-077) + скоупил схему на 6 агент-промптов, не на машинные отчёты. Машинный вердикт читается из + `coverage_status:` корректно, контракт не нарушен. **Действие (на усмотрение, не блокирует + приёмку):** привести формулировку D7 к факту (отчёт несёт `coverage_status:` + coverage-поля, + без полной 52c-схемы) ЛИБО добавить 5 полей в генератор+шаблон. ## Документация -**Статус: обновлена исчерпывающе** (golden source синхронизирован в том же PR, AC-10 PASS — с -оговоркой P1 выше по чистоте записи ORCH-095): +**Статус: обновлена исчерпывающе** (golden source синхронизирован в том же PR, AC-10 PASS): - `docs/architecture/README.md` — реестр `QG_CHECKS` дополнен `check_coverage_gate (ORCH-027)`; добавлен раздел «Coverage-гейт: защита от деградации покрытия» (точка/порядок, измерение, - чистая функция, baseline+ratchet, условность, артефакт/наблюдаемость). ✅ + чистая функция, baseline+ratchet, условность/fail-open, артефакт/наблюдаемость). ✅ - `docs/_standards/PIPELINE_DOCS.md` — диапазон доков `…18-coverage-report.md`; строка карты - `стадия→агент→документ→гейт→machine-key` и строка таблицы вердикт-парсеров. ✅ -- `docs/_templates/18-coverage-report.md` — скелет с frontmatter (`coverage_status:` + - measured/baseline/floor/policy/epsilon/delta) зарегистрирован. ✅ + `стадия→агент→документ→гейт→machine-key` + строка таблицы вердикт-парсеров + (`coverage_status:` → `check_coverage_gate`). ✅ +- `docs/_templates/18-coverage-report.md` — скелет с frontmatter зарегистрирован. ✅ - `docs/work-items/ORCH-027/06-adr/ADR-001-coverage-gate.md` (D1…D8) + сквозной `docs/architecture/adr/adr-0029-coverage-gate.md`. ✅ -- `CHANGELOG.md` — запись ORCH-027 детальная и корректная; **но** правка задела ORCH-095 (P1). ⚠️ +- `CHANGELOG.md` — детальная корректная запись ORCH-027; повреждение соседней записи ORCH-095 + устранено (v1-P1 закрыт). ✅ +- `CLAUDE.md` — паспортный блок «Гейт покрытия тестами (ORCH-027)» добавлен. ✅ - `.env.example` / `src/config.py` — флаги `ORCH_COVERAGE_*` задокументированы. ✅ - Маркеры `ORCH-027` проставлены в коде/доках (AC-10). ✅ -`src/` изменён → документация обновлена в том же PR: **да** (P0-условие выполнено). Остаточный -дефект — чистота соседней записи (P1), не отсутствие документации. +`src/` изменён → документация обновлена в том же PR: **да** (P0-условие выполнено). +**Обзорные доки (ORCH-079):** PR не закрывает ни один пункт `README.md` «Известные ограничения» +(coverage-деградация там не значилась) → обновление витрины не требуется, finding отсутствует. ## Оси проверки (детально) **1. Соответствие ТЗ (02-trz / 03-acceptance) — PASS.** AC-1 измерение инструментально (`measure_coverage` → `pytest --cov=src` → `totals.percent_covered`, `pytest-cov==5.0.0` в `requirements.txt`); AC-2 блокировка деградации + откат на `development` с -release merge-lease (`_handle_coverage_gate`, TC-13); AC-3 чистая функция `compute_coverage_verdict` -покрыта по всем режимам/границам/epsilon (TC-01…04, TC-10); AC-4 ratchet up-only + bootstrap + -per-repo изоляция + атомарный compare-and-set (TC-05/06, `db.ratchet_coverage_baseline`); AC-5 -kill-switch/scope/`applies` ПЕРВЫМ (TC-07/08); AC-6 fail-open дефолт / fail-closed по флагу -(TC-09); AC-7 never-raise + leaf + AST-проверка отсутствия деплой/force-push токенов (TC-10/12); -AC-8 контракты байт-в-байт, таблица аддитивна (TC-15); AC-9 вердикт только из frontmatter + -`GET /queue` блок + Telegram (TC-11/15). +release merge-lease (`_handle_coverage_gate`); AC-3 чистая функция `compute_coverage_verdict` +покрыта по всем режимам/границам/epsilon (TC-01…04); AC-4 ratchet up-only + bootstrap + per-repo +изоляция + атомарный compare-and-set `UPDATE … WHERE coverage <= ?` (`db.ratchet_coverage_baseline`); +AC-5 kill-switch/scope + `applies(repo)` ПЕРВЫМ (дорогой прогон только при `applies==True`) — +регресс зелёный, enduro не затронут; AC-6 fail-open дефолт / fail-closed по флагу; AC-7 never-raise ++ leaf (не импортирует `stage_engine`) + AST-проверка отсутствия деплой/force-push токенов; AC-8 +контракты `STAGE_TRANSITIONS`/`check_*`/вердикт-ключи байт-в-байт, таблица `coverage_baseline` +аддитивна; AC-9 вердикт только из frontmatter (`parse_coverage_status` через +`frontmatter.parse_frontmatter`) + `GET /queue` блок `coverage` + Telegram с кликабельным номером. -**2. Соответствие ADR (ADR-001 D1…D8 / adr-0029) — PASS.** +**2. Соответствие ADR (ADR-001 D1…D8 / adr-0029) — PASS** (с P2-оговоркой по тексту D7). Порядок под-гейтов `security → merge → coverage → image-freshness` реализован ровно как в D1 -(`stage_engine.py` строки 315→323→333→344); coverage ПОСЛЕ merge-gate (догнанный HEAD) и release -merge-lease при FAIL — соответствует D1/TR-2. Ratchet в choke-point `_handle_merge_verify` (D5), -БД-таблица `coverage_baseline` (D4), машинный вердикт/парсинг через `frontmatter.parse_frontmatter` -(D7), override `POST /coverage/baseline` (D8). Глобальные ADR (INV merge через Gitea API, не трогать -`main`/прод) не нарушены — leaf только мерит/читает/пишет/решает. +(врезка `_handle_coverage_gate` между merge-handling и ORCH-058 freshness в `advance_stage`); +coverage ПОСЛЕ merge-gate (догнанный HEAD) и `merge_gate.release_merge_lease` при FAIL — +соответствует D1/TR-2 (зеркало image-freshness rollback, в отличие от security — тот до захвата +lease). Ratchet в choke-point `_handle_merge_verify` (ребро `deploy→done`, D5), БД-таблица +`coverage_baseline` (D4), машинный вердикт/парсинг (D7), override `POST /coverage/baseline` (D8). +Глобальные ADR (INV-4 merge только через Gitea API; не трогать `main`/прод) не нарушены — leaf +только мерит/читает/пишет/решает. **3. Качество кода — PASS.** -Docstrings на всех публичных функциях; never-raise контракт выдержан последовательно; единый -frontmatter-контракт переиспользован (нет дублирования парс-логики); тесты содержательные, включают -реальный прогон pytest-cov на фикстур-репо (TC-14) и AST-инвариант self-hosting-безопасности (TC-12). -Нет утечек/security-дыр; измерение offline. Мелочь (не finding): чтение coverage-JSON независимо от -exit-code корректно прикрыто upstream-гейтами (`check_ci_green`/merge re-test) и явно объяснено в -коде. +Docstrings на всех публичных функциях; never-raise контракт выдержан последовательно (все +внешние границы обёрнуты, исключение не всплывает в `advance_stage`); единый frontmatter-контракт +переиспользован (нет дублирования парс-логики); тесты содержательные (режимы/границы/epsilon, +ratchet up-only + bootstrap + per-repo изоляция, fail-open/closed, never-raise, write/read-back +отчёта, self-hosting AST-инвариант, интеграция в `advance_stage` с откатом+release lease). +Фикс `sys.executable` вместо bare `python` (коммит `8cd7c20`) корректен — pytest-cov живёт в +интерпретаторе орка. Нет утечек/security-дыр; измерение offline. Замечание (не finding): +синхронный `pytest --cov` в hot-path `advance_stage` (тайм-аут `coverage_run_timeout_s=900`) +наследует established-паттерн merge-gate re-test/security-gate — нового класса риска не вводит. -**4. Документация — см. раздел «Документация» выше (P0-условие выполнено; P1 по чистоте ORCH-095).** +**4. Документация — см. раздел «Документация» выше (P0-условие выполнено; обзорные доки N/A).** -**Трассировка маркеров (TRACEABILITY):** правки рядом с маркерами `ORCH-022`/`ORCH-043`/`ORCH-058` -в `advance_stage` — аддитивная врезка между merge-gate и image-freshness, инварианты соседних -под-гейтов не сломаны (release-lease зеркалит image-freshness rollback). Единственное нарушение -трассировки/чужого артефакта — повреждённая запись ORCH-095 в CHANGELOG (P1 выше). +**Трассировка маркеров (TRACEABILITY).** Правки рядом с маркерами `ORCH-022`/`ORCH-043`/`ORCH-058` +в `advance_stage` — аддитивная врезка между merge-gate и image-freshness; инварианты соседних +под-гейтов не сломаны (release-lease зеркалит image-freshness rollback, merge через Gitea API +не тронут). Врезка в `_handle_merge_verify` (ORCH-071/073) — never-raise best-effort ratchet, +SHA-in-main choke-point не изменён. Чужие артефакты не повреждены (восстановлена запись ORCH-095).