--- type: review work_item_id: ORCH-076 verdict: APPROVED version: 1 --- # Review ORCH-076 — ORCH-52c: единый frontmatter-контракт + спека handoff ## Summary Изменение реализует слой 2 эпика ORCH-52: `src/frontmatter.py` превращён из single-key reader'а в полный машинный контракт (reader + writer + валидатор схемы + единый парс-примитив), а дублированное чтение YAML-frontmatter в пяти вердикт-парсерах сведено к одной точке (`parse_frontmatter`). Дополнительно создана формальная спека handoff (`docs/_standards/HANDOFF_PROTOCOL.md`). Реализация **полностью соответствует ТЗ и ADR-001/adr-0020**: унифицирован только МЕХАНИЗМ парсинга (D2), семантика вердиктов, token-логика, приоритет негативного токена, fallback `worktree→origin/main` и трёх-полевой контракт tester (ORCH-047) сохранены 1:1. Валидатор warning-only по умолчанию, hard-fail только под kill-switch `frontmatter_validation_strict` (дефолт `False`) — критично для self-hosting (задача не self-block'ится). Весь модуль never-raise. `STAGE_TRANSITIONS` и состав `QG_CHECKS` не тронуты (подтверждено TC-16). Проверка по осям: - **Соответствие ТЗ:** FR-1…FR-6 реализованы (writer, валидатор, полночтение, единый контракт вердиктов, BC старых доков, спека handoff). API/БД не тронуты (TRZ §4–§5). ✓ - **Соответствие AC:** AC-1…AC-7 выполнены (см. ниже). ✓ - **Соответствие ADR:** D1–D5 реализованы как спроектировано (функции в leaf-модуле, unify-механизм-не-семантику, warning-only validator, спека handoff, без API/БД). ✓ - **Качество кода:** docstrings на всех публичных функциях; never-raise контракт выдержан (broad-except + лог + безопасный возврат); leaf-модуль без проектных импортов (cycle-free). - **Тесты:** содержательные, покрывают writer/round-trip/валидатор/strict/never-raise/reader (`test_frontmatter.py`), семантику пяти гейтов + BC + origin/main fallback (`test_qg_verdicts.py`), security-гейт (`test_security_gate.py`), инварианты реестра (`test_stages_invariants.py`). Полный регресс **1212 passed**. Проверка AC: - **AC-1** (reader+writer+валидатор, unit-tested): ✓ `read_frontmatter_value` (BC), `render/write_frontmatter`, `validate_schema` с 6 полями `REQUIRED_FIELDS`; TC-01…TC-07. - **AC-2** (спека handoff в `docs/_standards/`, согласована): ✓ покрывает все стадии `created`→`done`, набор документов/ключей/гейтов 1:1 с `PIPELINE_DOCS.md` §2–§3; `PIPELINE_DOCS.md` обновлён ссылкой + отметкой реализации (§5–§6). - **AC-3** (единый контракт вердиктов): ✓ все 5 (`check_reviewer_verdict`, `_parse_tests_verdict`, `_parse_deploy_status`, `_parse_staging_status`, `parse_security_status`) делегируют `parse_frontmatter`; ad-hoc блоки удалены. - **AC-4** (BC старых доков + регресс зелёный): ✓ TC-13/TC-14 для старых доков без схемы; 1212 tests green. - **AC-5** (never-raise + warning-only + kill-switch): ✓ TC-05 (битый ввод), `maybe_warn_schema` инертен при дефолте, `frontmatter_validation_strict` в `config.py`. - **AC-6** (`STAGE_TRANSITIONS`/`QG_CHECKS` неизменны, семантика 1:1): ✓ TC-16; вердикт-логика не тронута. - **AC-7** (документация): ✓ см. раздел «Документация». ## Findings ### P0 — Blocker - Нет. ### P1 — Must fix - Нет. ### P2 — Should fix - Нет. ### P3 — Nice-to-have - [ ] `_parse_tests_verdict` (`src/qg/checks.py`): для редкого случая «валидный YAML, но не mapping» во frontmatter старая ветка возвращала reason `"Malformed YAML frontmatter in test report (not a mapping)"`, новая реализация маршрутизирует этот ввод в путь пустых данных → reason `"No machine-readable verdict/status/result in test report frontmatter"`. **Boolean-вердикт идентичен (`False` в обоих случаях) → семантика и STAGE_TRANSITIONS не затронуты (AC-6 соблюдён).** Расхождение только в reason-строке (лог/коммент). ADR D2 заявляет «reason-строки 1:1» — здесь незначительное отклонение в крайне редком кейсе. Можно при желании добавить явную ветку для паритета, но это не обязательно. - [ ] `parse_security_status` (`src/security_gate.py`) не вызывает `maybe_warn_schema`, тогда как 4 из 5 вердикт-парсеров его вызывают. Поскольку warning инертен (не влияет на вердикт), это чисто косметическая несогласованность наблюдаемости. Для единообразия можно добавить вызов. ## Документация Обновлено в том же PR (golden source синхронен с кодом, правило CLAUDE.md №2/№6): - `CLAUDE.md` — блок про единый frontmatter-контракт в «Конвенциях». - `docs/architecture/README.md` — «Канон гейтов» (единый контракт), компонент frontmatter, ссылки на спеку handoff и adr-0020. - `docs/_standards/HANDOFF_PROTOCOL.md` — **создан** (спека handoff, все стадии, обязательная схема `REQUIRED_FIELDS`). - `docs/_standards/PIPELINE_DOCS.md` — обновлён (слой 2 реализован, §5–§6 + ссылки). - `CHANGELOG.md` — детальная запись `[Unreleased]`. - ADR: per-work-item `docs/work-items/ORCH-076/06-adr/ADR-001-frontmatter-contract.md` + сквозной `docs/architecture/adr/adr-0020-frontmatter-contract.md`; индекс `docs/architecture/adr/README.md` обновлён (adr-0018/0019/0020, max=0020). Документация полная и согласованная — претензий нет.