12 KiB
02 — ТЗ (TRZ): ORCH-076 — ORCH-52c: протокол handoff + frontmatter-контракт (writer/валидатор/схема)
Work Item: ORCH-076 · Repo: orchestrator · Стадия: analysis
ТЗ описывает конкретные изменения к реализации, выведенные из BRD и фактического кода. Архитектурное обоснование/решения (как именно структурировать модуль контракта вердиктов, точные сигнатуры) — задача архитектора (06-adr).
1. Сводка изменения
ORCH-52c превращает src/frontmatter.py из single-key reader в полный frontmatter-контракт
(reader + writer + валидатор обязательной схемы) и сводит разрознённое чтение вердиктов
гейтов к единому frontmatter-API, не меняя ни состав гейтов, ни семантику вердиктов.
Дополнительно создаётся формальная спека handoff в docs/_standards/, согласованная с
манифестом ORCH-52b (PIPELINE_DOCS.md). Всё строго обратно совместимо (старые доки читаются
как раньше), never-raise, валидатор не hard-fail по умолчанию (kill-switch).
2. Задействованные модули / пути
| Путь | Действие |
|---|---|
src/frontmatter.py |
изменить — добавить writer + валидатор + чтение всего frontmatter (multi-key/dict); reader read_frontmatter_value сохранить (контракт неизменен) |
src/qg/checks.py |
изменить — check_reviewer_verdict, _parse_tests_verdict, _parse_deploy_status, _parse_staging_status перевести на чтение через единый frontmatter-API (поведение/токены/семантика 1:1) |
src/security_gate.py |
изменить — parse_security_status читает security_status: через единый API (семантика 1:1) |
src/post_deploy.py |
изменить (по решению архитектора) — чтение post_deploy_status: через единый API (информационный, не гейт) |
src/review_parse.py |
возможно изменить — _strip_frontmatter может использовать общий хелпер; контракт «never raise → ""» сохранить |
src/config.py |
изменить — добавить kill-switch строгой валидации (напр. frontmatter_validation_strict: bool = False) |
docs/_standards/HANDOFF_PROTOCOL.md (имя — на усмотрение архитектора/стандарта) |
создать — формальная спека handoff «стадия → обязательный выход» |
docs/_standards/PIPELINE_DOCS.md |
изменить — связать со спекой handoff, отметить что ORCH-52c реализовала машинный контракт |
tests/test_frontmatter.py |
создать — unit на reader/writer/валидатор/round-trip |
tests/ (гейты) |
изменить/создать — анти-регресс тесты чтения вердиктов через новый API |
CLAUDE.md, docs/architecture/README.md, CHANGELOG.md, ADR |
изменить/создать — документация |
3. Функциональные требования
FR-1 — Writer frontmatter (BR-1)
В src/frontmatter.py добавить функцию записи: принимает данные frontmatter (mapping
ключ→значение) и тело документа, возвращает/записывает строку с каноничным ведущим
YAML-блоком ---\n…\n---\n<body>. Формат на 100% совместим с существующими парсерами
(split("---", 2) + yaml.safe_load). never-raise (NFR-2): ошибка сериализации/записи →
лог + безопасный результат, исключение наружу не выходит. Точная сигнатура (in-memory render
vs запись в файл, перезапись существующего frontmatter) — решение архитектора.
FR-2 — Валидатор обязательной схемы (BR-2, NFR-3)
В src/frontmatter.py добавить валидатор, проверяющий наличие обязательных полей схемы:
work_item, stage, author_agent, status, created_at, model_used. Возвращает
структурированный результат (список отсутствующих/невалидных полей + признак валидности).
Поведение по умолчанию — warning/лог, НЕ blocker (NFR-3): отсутствие полей не роняет
конвейер и не заваливает гейт. Жёсткость (hard-fail) включается ТОЛЬКО kill-switch'ем
frontmatter_validation_strict (дефолт False). never-raise.
FR-3 — Полночтение frontmatter / единый reader-API (BR-1, BR-4)
В src/frontmatter.py добавить чтение ВСЕГО frontmatter как mapping (а не только single-key),
поверх которого строится единый доступ к вердикт-полям. Существующий
read_frontmatter_value(path, key) сохраняется без изменения контракта (обратная
совместимость вызывающих — notifications.build_status_comment и т.п.). never-raise.
FR-4 — Единый контракт чтения вердиктов (BR-4, BR-5, NFR-1)
Пять гейтов-вердиктов читают свои стандартные поля через единый frontmatter-API:
| Гейт / парсер | Документ | Стандартное поле | Семантика (НЕИЗМЕННА) |
|---|---|---|---|
check_reviewer_verdict |
12-review.md |
verdict: |
APPROVED→дальше; REQUEST_CHANGES→откат на development |
_parse_tests_verdict |
13-test-report.md |
result: / verdict: / status: (3 равноранговых, ORCH-047) |
PASS→дальше; FAIL/BLOCKED→откат; негативный токен авторитетен |
_parse_deploy_status |
14-deploy-log.md |
deploy_status: |
SUCCESS→done; FAILED→откат (БАГ-8) |
_parse_staging_status |
15-staging-log.md |
staging_status: |
SUCCESS→дальше; FAILED→откат (self-hosting; иначе N/A) |
parse_security_status |
17-security-report.md |
security_status: |
PASS→дальше; FAIL→откат |
Требование: только механизм чтения унифицируется (одна точка парсинга YAML-frontmatter);
наборы токенов (_TESTS_NEGATIVE_TOKENS/_TESTS_POSITIVE_TOKENS), приведение к верхнему
регистру, обработка «no frontmatter / bad YAML / missing key», fallback worktree → origin/main
для deploy/staging — сохраняются 1:1. Возврат каждого check_* — прежний tuple[bool, str].
FR-5 — Обратная совместимость старых доков (NFR-1, критично)
Документ-вердикт БЕЗ новых полей схемы (work_item/stage/author_agent/status/created_at/ model_used), но с вердикт-ключом (verdict:/result:/deploy_status:/…) ДОЛЖЕН читаться
гейтом ровно как сейчас. Новая схема — аддитивна; её отсутствие не влияет на чтение вердикта.
FR-6 — Спека handoff (BR-3)
Создать в docs/_standards/ формальную спеку «стадия → обязательный выход»: для каждой стадии
(created→analysis→architecture→development→review→testing→deploy-staging→deploy
→done) перечислить обязательные документы и обязательные frontmatter-ключи на выходе.
Согласовать с таблицей §2 PIPELINE_DOCS.md (тот же набор документов/ключей/гейтов), явно
указать «источник истины — код». Различать machine-verdict доки и информационные (как в
PIPELINE_DOCS.md §3).
4. Изменения API
Нет. HTTP-эндпоинты не добавляются/не меняются. (Опционально архитектор может предложить блок
наблюдаемости в GET /queue для счётчика валидации — НЕ требование данной задачи.)
5. Изменения схемы БД
Нет. Таблицы/миграции/индексы не затрагиваются. Контракт работает на файлах (YAML-frontmatter) и in-memory.
6. Требования к новым/изменённым QG checks
- Состав
QG_CHECKSНЕ изменяется (никаких новых/удалённых зарегистрированных гейтов) — AC-6 / правило CLAUDE.md. - Изменяется только внутренняя реализация чтения вердикта существующих
check_*/_parse_*(делегирование единому frontmatter-API). Сигнатуры и возвращаемые значения (tuple[bool,str]) — неизменны. - Новый kill-switch
frontmatter_validation_strict(config) управляет жёсткостью валидатора схемы; дефолтFalse(warning-only) → нулевая поведенческая регрессия.
7. Совместимость / регресс
- Обратная совместимость (NFR-1): старые доки-вердикты без новой схемы читаются как
раньше; контракт
read_frontmatter_valueнеизменен; формат writer'а совместим с существующими парсерами. - never-raise (NFR-2): writer/валидатор/единый reader не выбрасывают исключений в
конвейер (паттерн текущего
frontmatter.py). - kill-switch / обратимость (NFR-3, NFR-5):
frontmatter_validation_strict=False(дефолт) → валидация только логирует;True→ строгий режим (на будущее). Поведение деградирует к прежнему при дефолтном флаге. - Неизменность контрактов (AC-6):
STAGE_TRANSITIONS, составQG_CHECKS, семантика вердиктов, fallbackworktree→origin/main, трёх-полевой контракт tester (ORCH-047), токен-логика BLOCKED/FAILED — без изменений. - Нулевая регрессия enduro (NFR-4): для не-self-hosting репо поведение 1:1; условные гейты (ORCH-35/43/58) не затрагиваются по существу.
- Полный регресс
tests/зелёный перед мержем. - self-hosting: не перезапускать прод-контейнер вручную; деплой через штатный путь;
первый боевой
autoDeploy(наблюдение — за стадией deploy).