13 KiB
02 — Техническое задание (ТЗ)
Work Item: ORCH-066 Стадия: analysis → (вход для architecture) Автор: Analyst
ТЗ фиксирует ТРЕБУЕМОЕ ПОВЕДЕНИЕ и затронутые точки кода. Конкретную архитектуру резолвера (точные имена ключей/функций) финализирует архитектор в ADR. Ниже — опорный контракт, согласованный с бизнес-запросом Owner.
1. Задействованные модули src/
| Модуль | Роль в задаче |
|---|---|
src/plane_sync.py |
Ядро изменений (слой B): реестр логических статусов (_DEFAULT_STATES), _PLANE_NAME_TO_KEY, маппинг стадия→статус (_STAGE_TO_STATE_KEY, STAGE_VISIBILITY_STATE), хелперы set_issue_*. |
src/webhooks/plane.py |
Маршрутизация входящего статуса (handle_issue_updated): To Analyse → handle_status_start (старт или resume). |
src/stage_engine.py |
Точки ручной простановки статуса: analyst-flow (Analysis/Needs Input/In Review), Phase A (Awaiting Deploy), Phase B (Deploying), Phase C → Monitoring after Deploy, post-deploy monitor → Done/Blocked. |
src/reconciler.py |
F-2 запрос статусов (To Analyse в список), Guard 2 skip-list (активные ожидания). |
src/stages.py |
НЕ менять (инвариант слоя A). Используется только для чтения переходов. |
src/config.py |
(При необходимости) kill-switch для новой статусной модели — на усмотрение архитектора (см. §6). |
2. Изменения статусной модели (слой B)
2.1. Реестр логических статусов (src/plane_sync.py)
Ввести новые логические ключи и их имена в _PLANE_NAME_TO_KEY:
| Логический ключ | Plane name | Назначение |
|---|---|---|
to_analyse |
To Analyse |
Вход-триггер (старт + resume аналитика). |
analysis |
Analysis |
Индикация стадии analysis (орк). |
code_review |
Code-Review |
Индикация стадии review (орк). Заменяет review. |
awaiting_deploy |
Awaiting Deploy |
Phase A approval-pending (орк). |
deploying |
Deploying |
Phase B прод-деплой идёт (орк). |
monitoring |
Monitoring after Deploy |
Phase C / post-deploy окно (орк). |
Сохранить существующие: backlog, todo, in_progress (backward-compat), needs_input,
in_review, blocked, done, cancelled, architecture, development, testing,
approved, rejected. Cancelled уже присутствует в _PLANE_NAME_TO_KEY.
2.2. Fail-closed резолюция (КРИТИЧНО — BR-12)
get_project_states() после резолва по API делает setdefault(k, v) из _DEFAULT_STATES.
Чтобы отсутствие нового статуса в проекте (enduro / Plane down / частичная конфигурация)
не ломало конвейер, новые логические ключи в _DEFAULT_STATES должны
алиаситься на существующие UUID (degrade-to-current):
| Новый ключ | Default-алиас (UUID) | Деградированное поведение |
|---|---|---|
to_analyse |
= in_progress |
enduro/старый проект: In Progress по-прежнему триггерит старт/resume. |
analysis |
= in_progress |
analysis показывается как In Progress (как сейчас). |
code_review |
= review |
review показывается как Review (как сейчас). |
awaiting_deploy |
= in_review |
Phase A показывается как In Review (как сейчас). |
deploying |
= in_progress |
Phase B показывается как In Progress (как сейчас). |
monitoring |
= done |
Phase C показывается как Done (как сейчас); монитор затем держит Done / флипает Blocked. |
Эффект: если оператор НЕ создал новый статус — система работает строго как до ORCH-066 (никаких падений, никаких 404 от Plane PATCH). Если создал — резолвится по имени и используется новый UUID. Это ровно паттерн ORCH-059 AC-7.
2.3. Маппинг стадия → статус
src/plane_sync.py:
_STAGE_TO_STATE_KEY:analysis→analysis(былоin_progress);review→code_review(былоreview).deployостаётся (управляется Phase A/B/C напрямую, не черезupdate_issue_state).created/architecture/development/testing/done— без изменений.STAGE_VISIBILITY_STATE:review→code_review(былоreview). Добавитьanalysis→analysis, если индикация analysis ставится черезset_issue_stage_state(решает архитектор; альтернатива — отдельный хелперset_issue_analysis).- Сохранить совместимость
STAGE_TO_STATE/PLANE_STATESалиасов (импортируются тестами).
2.4. Точки простановки статуса
| Место (файл:симв.) | Сейчас | Должно стать |
|---|---|---|
webhooks/plane.py handle_issue_updated |
new_state == in_progress → handle_status_start |
new_state == to_analyse (с fail-closed: при алиасе совпадает с in_progress) → handle_status_start |
webhooks/plane.py start_pipeline (старт) |
статус остаётся In Progress |
при старте/enqueue analyst орк ставит Analysis |
webhooks/plane.py handle_status_start (resume из Needs Input) |
relaunch на In Progress-триггере |
relaunch на To Analyse-триггере; при relaunch орк ставит Analysis. Fork «старт vs resume» (по get_task_by_plane_id + has_active_job_for_task) — сохранить как есть. |
stage_engine.py _handle_analysis_approved_flow (artifacts ready) |
set_issue_in_review |
оставить In Review (BR-9: In Review только за approve-pending конвейера) ✔ без изменений |
stage_engine.py _handle_analysis_approved_flow (questions) |
set_issue_needs_input |
без изменений (BR-10) |
stage_engine.py _handle_self_deploy_phase_a |
set_issue_in_review |
Awaiting Deploy (set_issue_awaiting_deploy или аналог) |
stage_engine.py _handle_self_deploy_phase_b |
(статус не меняет) | Deploying |
stage_engine.py advance deploy → done (terminal-sync, строка ~338) |
set_issue_done для всех |
self-hosting: Monitoring after Deploy (перед/вместо арма монитора); не-self: Done как сейчас |
stage_engine.py run_post_deploy_monitor (HEALTHY, окно закрыто) |
пишет лог + коммент, статус Plane НЕ трогает (остаётся Done) | Done (явно) |
stage_engine.py run_post_deploy_monitor (DEGRADED) |
пишет лог + alert | Blocked |
Замечание по terminal-sync (важно для архитектора): сейчас
advance_stageнаnext_stage == "done"вызываетset_issue_doneбезусловно (строка ~338), затем армит post-deploy monitor для self-hosting (~361). Нужно развести: для репо, гдеpost_deploy.post_deploy_applies(repo)истинно (self-hosting) — ставитьMonitoring after DeployвместоDone, и переложить простановкуDone/Blockedна финал монитора (run_post_deploy_monitor). Для прочих репо —Doneкак сейчас.
2.5. Новые хелперы src/plane_sync.py
Добавить тонкие обёртки по образцу set_issue_in_review (резолв per-project UUID +
_set_issue_state_direct), never-raise при отсутствии issue:
set_issue_analysis(work_item_id, project_id=None)set_issue_code_review(...)(или черезset_issue_stage_state("review"))set_issue_awaiting_deploy(...)set_issue_deploying(...)set_issue_monitoring(...)
(Точный набор/именование — на усмотрение архитектора; контракт: per-project резолв + fail-closed.)
3. Изменения reconciler (src/reconciler.py)
- F-2
_reconcile_plane_project: добавитьto_analyseв список запрашиваемых статусов (list_issues_by_state([... , to_analyse])) и в_reconcile_plane_issueмаршрутизироватьnew_state == to_analyse→handle_status_start(старт приtask is None, resume при существующем task без active-job — логика уже вhandle_status_start). Сохранить обработкуapproved/rejected. При fail-closed алиасеto_analyse==in_progressповедение не дублируется (один и тот же UUID). - Guard 2
_is_blocked_or_needs_input(F-1 skip): расширить skip-множество активными ожиданиями —awaiting_deploy,deploying,monitoring— чтобы реконсилер НЕ «оживлял» их как зависшие (BR-13). Имя метода/семантику можно обобщить («human-or-active-wait»), флагreconcile_skip_blocked_enabledпродолжает управлять этим networked-чеком.
Примечание: F-1 и так не тронет Phase A (
check_deploy_statusred → silent), Deploying (active finalizer job), Monitoring (стадияdone). Guard 2 — явная defense-in-depth по требованию Owner.
4. Изменения API / эндпоинтов
Нет новых HTTP-эндпоинтов. GET /queue / GET /status — без изменений контракта
(статусы Plane там не отражаются). Изменения только во внешней индикации Plane (PATCH
issue state — существующий механизм).
5. Изменения схемы БД
Нет. tasks не хранит Plane-статус (источник истины — стадия в БД + Plane API).
Миграции не требуются.
6. Требования к новым QG checks
Нет. QG_CHECKS не расширяется. Статусы — индикация, не управление (канон:
машинные вердикты читаются из YAML-frontmatter артефактов, не из Plane-статуса).
Опционально (на усмотрение архитектора): единый kill-switch новой статусной модели
(env-флаг) для безопасного раската, по образцу staging_infra_tolerance_enabled /
reconcile_skip_blocked_enabled. Не обязателен, т.к. fail-closed алиасинг (§2.2) уже даёт
backward-compatible деградацию.
7. Артефакты pipeline, создаваемые/обновляемые
06-adr/ADR-001-plane-status-model.md— архитектор (решение по резолверу, алиасингу, разводке terminal-sync).07-infra-requirements.md— архитектор (список Plane-статусов для ручного создания оператором + Plane API инструкция).- Документация (golden source, тот же PR):
CLAUDE.md(секция статусной модели),docs/architecture/README.md(секция статусов рядом с ORCH-036/ORCH-021),CHANGELOG.md.
8. Инварианты (проверяемые)
src/stages.pySTAGE_TRANSITIONS— байт-в-байт без изменений.QG_CHECKS,check_deploy_status/_parse_deploy_status, exit-коды хука, merge-gate, схема БД,Confirm Deploy, механизмNeeds Input— без изменений.- Все новые
set_issue_*/ резолв — never-raise (Plane down ⇒ degrade, не crash). - Поведение enduro (не-self) и его терминальный
Done— без регресса.