Files
orchestrator/docs/work-items/ORCH-076/02-trz.md

125 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`, семантика
вердиктов, fallback `worktree→origin/main`, трёх-полевой контракт tester (ORCH-047),
токен-логика BLOCKED/FAILED — без изменений.
- **Нулевая регрессия enduro (NFR-4):** для не-self-hosting репо поведение 1:1; условные гейты
(ORCH-35/43/58) не затрагиваются по существу.
- **Полный регресс `tests/` зелёный** перед мержем.
- **self-hosting:** не перезапускать прод-контейнер вручную; деплой через штатный путь;
первый боевой `autoDeploy` (наблюдение — за стадией deploy).