Files
orchestrator/docs/_standards/HANDOFF_PROTOCOL.md
claude-bot 92961d1d32 refactor(frontmatter): unified frontmatter contract + handoff spec (ORCH-52c)
src/frontmatter.py grows from a single-key reader into the full machine
contract: reader (read_frontmatter_value, unchanged), one parse primitive
(parse_frontmatter), writer (render/write_frontmatter), schema validator
(validate_schema/REQUIRED_FIELDS, warning-only by default) and a shared
strip_frontmatter helper. The five verdict gates (check_reviewer_verdict,
_parse_tests_verdict, _parse_deploy_status, _parse_staging_status,
parse_security_status) now read through the single parse_frontmatter point
instead of duplicated ad-hoc YAML logic; review_parse._strip_frontmatter and
security_gate.extract_security_findings reuse the shared helper.

Strictly backward compatible + never-raise: STAGE_TRANSITIONS, the QG_CHECKS
composition, verdict semantics (incl. ORCH-047 three-field tester + negative
token priority), reason-strings and worktree->origin/main fallback are 1:1.
The schema validator never influences a gate verdict by default; hard-fail is
reserved behind the frontmatter_validation_strict kill-switch (default False).

New formal handoff spec docs/_standards/HANDOFF_PROTOCOL.md ("stage -> required
output" + required frontmatter schema), aligned 1:1 with PIPELINE_DOCS.md.

Tests: test_frontmatter.py (TC-01..07), test_qg_verdicts.py (TC-08..15),
test_security_gate.py (TC-12), test_stages_invariants.py (TC-16). Full
tests/ green (1212).

Refs: ORCH-076

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:14:30 +03:00

11 KiB
Raw Blame History

HANDOFF_PROTOCOL — формальный контракт handoff «стадия → обязательный выход»

Назначение. Нормативная спека: что КАЖДАЯ стадия конвейера обязана оставить на выходе — какие документы и какие frontmatter-ключи. Дополняет PIPELINE_DOCS.md (карта «документ → агент → стадия → гейт → machine-key») «вертикальным» срезом по стадиям и вводит обязательную frontmatter-схему для машинной проверки.

Статус истины (важно). Источник истины поведения — код: src/stages.py (STAGE_TRANSITIONS), src/qg/checks.py (QG_CHECKS / check_* / _parse_*), src/stage_engine.py (врезки под-гейтов). Машинный контракт чтения/записи/валидации frontmatter — src/frontmatter.py. Эта спека документирует; при расхождении первичен код (правило ORCH-075).

Введено задачей ORCH-076 (ORCH-52c — слой 2 эпика ORCH-52: машинный контракт). Слой 1 (ORCH-075/52b) дал описательный стандарт документов; ORCH-52c реализовала единый машинный frontmatter-контракт (reader + writer + валидатор) и свела чтение пяти вердиктов к одной точке парсинга. Сквозной ADR: adr-0020-frontmatter-contract.md; детально — ORCH-076/06-adr/ADR-001-frontmatter-contract.md.


1. Обязательная frontmatter-схема (машинный источник: frontmatter.REQUIRED_FIELDS)

Forward-looking аддитивная схема: набор полей, которые handoff-документ стадии должен нести в ведущем YAML-frontmatter. Машинный источник истины — кортеж src/frontmatter.py REQUIRED_FIELDS:

Поле Смысл
work_item ID задачи (ORCH-NNN / ET-NNN) — к какой задаче относится выход
stage стадия, на выходе которой написан документ (analysisdeploy)
author_agent роль-автор (analyst / architect / developer / reviewer / tester / deployer)
status человеко/машинно-читаемый статус выхода стадии
created_at дата создания артефакта (YYYY-MM-DD)
model_used модель агента, сгенерировавшего артефакт (claude-…)

Режим проверки (ORCH-52c, критично для self-hosting). Валидатор схемы frontmatter.validate_schema / maybe_warn_schema по умолчанию warning-only и никогда не влияет на boolean-вердикт ни одного гейта: отсутствие полей логируется (logger.warning), но не роняет конвейер и не заваливает гейт. Жёсткий режим (hard-fail) зарезервирован на будущее (ORCH-52d) и включается ТОЛЬКО kill-switch'ем frontmatter_validation_strict (env ORCH_FRONTMATTER_VALIDATION_STRICT, дефолт False). Схема аддитивна: старый документ-вердикт без этих полей читается гейтом ровно как раньше (см. §3).


2. Контракт handoff по стадиям

Категории документов — как в PIPELINE_DOCS.md §2: required (всегда), when-applicable (при наличии предмета: инфра / данные / security / post-deploy — отсутствие не нарушение). «Machine-verdict ключ» — поле, которое exit-гейт/под-гейт ребра читает ТОЛЬКО из frontmatter (никогда из прозы). Набор документов/ключей/гейтов согласован 1:1 с PIPELINE_DOCS.md §2§3.

Стадия (выход) Агент Обязательные документы на выходе Machine-verdict ключ (читает гейт ребра) Гейт ребра
created система (_create_initial_docs) / заказчик 00-business-request.md — (вход, не гейтится)
analysis analyst 01-brd.md, 02-trz.md, 03-acceptance-criteria.md, 04-test-plan.yaml — (гейт проверяет наличие файлов + Approved) check_analysis_approved
architecture architect 06-adr/ADR-NNN-<slug>.md (≥1); 07-infra-requirements.md, 08-data-requirements.md, 10-tech-risks.md (when-applicable/required-info) — (гейт проверяет наличие 06-adr/ ≥1 ИЛИ 07-…) check_architecture_done
development developer код + тесты в ветке (артефакт-док не пишется; гейт — зелёный CI) — (гейт читает CI-статус Gitea) check_ci_green
review reviewer 12-review.md verdict: (APPROVED | REQUEST_CHANGES) check_reviewer_verdict
testing tester 13-test-report.md result: / verdict: / status: (PASS | FAIL | BLOCKED; три равноранговых, ORCH-047) check_tests_passed
deploy-staging deployer 15-staging-log.md (required для self-hosting); 17-security-report.md (security-под-гейт, when-applicable) staging_status: (SUCCESS | FAILED); security_status: (PASS | FAIL) check_staging_status (ребро); под-гейты ребра deploy-staging→deploy: check_security_gatecheck_branch_mergeablecheck_staging_image_fresh
deploy deployer / deploy-finalizer 14-deploy-log.md deploy_status: (SUCCESS | FAILED) check_deploy_status
done — (терминал)
пост-done наблюдение post-deploy-monitor 16-post-deploy-log.md (when-applicable, ORCH-021) post_deploy_status: (HEALTHY | DEGRADED) — информационный, не гейт — (телеметрия петли уроков / наблюдаемость)

Примечания (нормативные)

  • Под-гейты ребра deploy-staging → deploy (check_security_gatecheck_branch_mergeablecheck_staging_image_fresh) — это врезки в advance_stage, а НЕ строки STAGE_TRANSITIONS. Их порядок и условность раската не меняются этой спекой.
  • 15-staging-log.md обязателен только для self-hosting репо (orchestrator); для прочих репо staging-гейт — N/A (ORCH-35), документ не требуется.
  • 16-post-deploy-log.md несёт post_deploy_status:, но это информационный ключ (телеметрия ORCH-8 / наблюдаемость), гейтом он НЕ парсится.
  • 09-… / 05-… / 11-… — зарезервированные/legacy номера; канон reviewer'а12-review.md.

3. Machine-verdict доки vs информационные (честный механизм проверки)

Полностью согласовано с PIPELINE_DOCS.md §3. Machine-verdict док — гейт читает ТОЛЬКО YAML-frontmatter (через единый frontmatter.parse_frontmatter), маппит ключ в вердикт; имя ключа чувствительно к регистру, значение парсер приводит к верхнему регистру.

Документ Machine-key Парсер Эффект вердикта
12-review.md verdict: check_reviewer_verdict APPROVED → дальше; REQUEST_CHANGES → откат на development
13-test-report.md result: / verdict: / status: _parse_tests_verdict PASS → дальше; FAIL/BLOCKED → откат (негативный токен авторитетен)
14-deploy-log.md deploy_status: _parse_deploy_status SUCCESSdone; FAILED → откат (БАГ-8)
15-staging-log.md staging_status: _parse_staging_status SUCCESS → дальше; FAILED → откат (self-hosting; иначе N/A)
17-security-report.md security_status: check_security_gateparse_security_status PASS → дальше; FAIL → откат

Информационные доки (гейтом НЕ парсятся): 00-business-request.md, 08-data-requirements.md, 10-tech-risks.md, 16-post-deploy-log.md.

Аддитивность схемы (§1). Документ-вердикт БЕЗ полей схемы из §1, но с вердикт-ключом, читается гейтом РОВНО как раньше: схема не участвует в вычислении вердикта при дефолтном frontmatter_validation_strict=False.


4. Единый машинный контракт — src/frontmatter.py

Все операции с frontmatter сведены в один leaf-модуль (never-raise):

  • read_frontmatter_value(path, key) -> str | None — single-key reader (контракт неизменен, BC).
  • parse_frontmatter(content) -> FrontmatterParseединственная точка парсинга YAML-frontmatter (data / has_block / malformed / yaml_error); пять вердикт-парсеров делегируют сюда.
  • parse_frontmatter_dict / read_frontmatter — ярлыки к распарсенному mapping.
  • render_frontmatter / write_frontmatter — writer (формат совместим с существующими парсерами).
  • validate_schema / REQUIRED_FIELDS / maybe_warn_schema — схема §1 (warning-only по умолчанию).
  • strip_frontmatter — общий хелпер тела (заменил дубли).
  • Kill-switch жёсткой валидации: config.frontmatter_validation_strict (env ORCH_FRONTMATTER_VALIDATION_STRICT, дефолт False).

Перед написанием номерного дока бери скелет из docs/_templates/ и не меняй имя machine-key frontmatter (регистр чувствителен — иначе гейт упадёт ложно).