---
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).

Документация полная и согласованная — претензий нет.
