5.6 KiB
5.6 KiB
adr-0020: Единый frontmatter-контракт + спека handoff (reader/writer/валидатор)
Статус: Accepted · Дата: 2026-06-09 · Источник: ORCH-076 (ORCH-52c)
Детально: docs/work-items/ORCH-076/06-adr/ADR-001-frontmatter-contract.md
Контекст
Слой 1 эпика ORCH-52 (ORCH-075/52b) дал описательный стандарт документов
(docs/_standards/PIPELINE_DOCS.md), явно отложив машинную проверку на ORCH-52c. В коде:
src/frontmatter.py — только single-key reader (never-raise), а ~10-строчный блок парсинга
YAML-frontmatter продублирован в 5 вердикт-парсерах (check_reviewer_verdict,
_parse_tests_verdict, _parse_deploy_status, _parse_staging_status, parse_security_status)
- в
_strip_frontmatter/extract_security_findings. Единого контракта чтения, writer'а, схемы и формальной спеки handoff — нет. Эти парсеры читают вердикты на гейтах self-hosting инструмента, обслуживающего прод других проектов из общего инстанса → любой регресс = стоп конвейера всех проектов.
Решение
src/frontmatter.py→ полный frontmatter-контракт (функции в существующем leaf-модуле, контракт never-raise): сохранённыйread_frontmatter_value(без изменений) + единый парс-примитивparse_frontmatter(content) -> FrontmatterParse(единственная точка YAML-логики, структура различает no-block / malformed / yaml-error / data) +render_/ write_frontmatter(writer) +validate_schema(обязательная схемаwork_item, stage, author_agent, status, created_at, model_used) +strip_frontmatter.- Унифицируется механизм парсинга, НЕ семантика. Все 5 вердикт-парсеров читают YAML через
parse_frontmatter; token-наборы, upper-casing, приоритет негативного токена, 3-полевой контракт tester'а (ORCH-047), fallbackworktree→origin/main— 1:1. Сигнатуры иtuple[bool, str]— неизменны. Reason-строки переносятся дословно. - Валидатор не hard-fail по умолчанию. Флаг
frontmatter_validation_strict(envORCH_FRONTMATTER_VALIDATION_STRICT, дефолтFalse): default — warning/лог, вне вердикт-пути гейтов (нулевая регрессия); hard-fail — зарезервированный strict-режим (включение — с ORCH-52d). Иначе ORCH-52c заблокировала бы собственный деплой. - Формальная спека handoff
docs/_standards/HANDOFF_PROTOCOL.md— «стадия → обязательный выход» (документы + frontmatter-ключи), согласована 1:1 сPIPELINE_DOCS.md§2–§3; источник истины — код.PIPELINE_DOCS.mdобновляется ссылкой + отметкой о реализации машинного слоя. - Без изменений
STAGE_TRANSITIONS, составаQG_CHECKS, API, схемы БД.
Альтернативы
- Общий «умный» verdict-резолвер (поле+токены для всех гейтов) — отклонён: различия token-логики → риск тонкого регресса на гейте при self-hosting. Унифицируем только парс YAML.
- Класс/новый пакет — отклонён: состояния нет, лишний blast radius.
- Hard-fail валидатор по умолчанию — отклонён (NFR-3: self-block собственного деплоя).
- Сторонняя
python-frontmatter— отклонена: лишняя зависимость ради ~30 строк.
Последствия
- + Конец дублирования/рассинхрона парсинга; writer+валидатор+схема готовы к ORCH-52d; спека handoff закрывает пробел контракта стадий.
- + Нулевая регрессия по построению: семантика и reason-строки 1:1, валидатор инертен при дефолте, never-raise сохранён, enduro 1:1.
- − Унификация частичная (парс, не семантика); strict-режим «спящий» до ORCH-52d.
- Обратимость:
frontmatter_validation_strict=False⇒ прежнее поведение; перевод гейтов поведенчески инвариантен. - Риск: первый боевой
autoDeployорка (ORCH-089) — наблюдение за стадиейdeploy(docs/work-items/ORCH-076/10-tech-risks.md).
Связи
- Опирается: adr-0019 (pipeline-docs-standard, ORCH-075), ORCH-016 (reader), ORCH-047
(3-полевой tester), adr-0012 (security-гейт), adr-0018 (auto-label/
autoDeploy). - Готовит: ORCH-52d (эмиссия полной схемы агентами; возможное включение strict).