analyst(ET): auto-commit from analyst run_id=339
This commit is contained in:
110
docs/work-items/ORCH-066/01-brd.md
Normal file
110
docs/work-items/ORCH-066/01-brd.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# 01 — Business Requirements Document (BRD)
|
||||
|
||||
**Work Item:** ORCH-066
|
||||
**Заголовок:** [высокий] Статусная модель Plane: осмысленные статусы этапов
|
||||
**Стадия:** analysis
|
||||
**Автор:** Analyst
|
||||
**Дата:** 2026-06-07
|
||||
|
||||
---
|
||||
|
||||
## 1. Контекст и проблема
|
||||
|
||||
Статусная модель Plane оркестратора имеет **семантические перегрузки**: один и тот
|
||||
же Plane-статус используется для несовместимых смыслов, из-за чего:
|
||||
|
||||
- оператор не понимает, на каком реально этапе стоит задача (доска нечитаема);
|
||||
- повышается риск ошибки оператора (например, неверный ручной перевод статуса);
|
||||
- `In Progress` одновременно означает «человек запускает конвейер», «идёт анализ»,
|
||||
«идёт прод-деплой» и «возврат из Needs Input» — четыре разных смысла на одном статусе.
|
||||
|
||||
Уже частично исправлено: ORCH-059 ввёл отдельный статус для подтверждения деплоя
|
||||
(`Confirm Deploy`), разгрузив перегруженный `Approved`. ORCH-066 завершает наведение
|
||||
порядка по **утверждённой Owner** статусной модели.
|
||||
|
||||
### Два слоя (критично различать)
|
||||
|
||||
| Слой | Что это | Источник | Трогаем? |
|
||||
|------|---------|----------|----------|
|
||||
| **A** | `STAGE_TRANSITIONS` — внутренняя машина стадий (`created→analysis→…→done`) | `src/stages.py` | **НЕТ (инвариант)** |
|
||||
| **B** | Plane-статусы — индикация на доске | `src/plane_sync.py` + точки в `src/stage_engine.py` / `src/webhooks/plane.py` | **ДА** |
|
||||
|
||||
ORCH-066 меняет **только слой B** и точки, где код вручную проставляет Plane-статусы.
|
||||
|
||||
---
|
||||
|
||||
## 2. Целевая статусная модель (решение Owner)
|
||||
|
||||
```
|
||||
Backlog → Todo → [To Analyse] → Analysis → [In Review → Approved] → Architecture →
|
||||
Development → Code-Review → Testing → Awaiting Deploy → [Confirm Deploy] → Deploying →
|
||||
Monitoring after Deploy → Done
|
||||
```
|
||||
|
||||
- `[...]` = **действие человека** (вход-триггер).
|
||||
- Остальное ставит **орк** (индикация).
|
||||
|
||||
### Ветки (нелинейные исходы)
|
||||
- **Rejected** — откат на предыдущую стадию (человек).
|
||||
- **Needs Input** — ТОЛЬКО аналитик (НЕ расширять на других агентов).
|
||||
- **Blocked** — затык / фейл деплоя / деградация прода.
|
||||
- **Cancelled** — человек решил не делать задачу (валидный выход из In Review).
|
||||
|
||||
---
|
||||
|
||||
## 3. Бизнес-требования
|
||||
|
||||
| ID | Требование | Приоритет |
|
||||
|----|------------|-----------|
|
||||
| **BR-1** | Каждый этап конвейера показывается на доске Plane осмысленным статусом (To Analyse / Analysis / Code-Review / Awaiting Deploy / Deploying / Monitoring after Deploy). | Must |
|
||||
| **BR-2** | `To Analyse` — единый человеческий вход: (а) старт нового конвейера, (б) resume/relaunch аналитика при возврате из Needs Input. Заменяет роль `In Progress` как входа-триггера. | Must |
|
||||
| **BR-3** | Стадия `analysis` индицируется отдельным статусом `Analysis` (орк ставит при старте/relaunch аналитика), а не `In Progress`. | Must |
|
||||
| **BR-4** | Стадия `review` индицируется Plane-статусом `Code-Review` (переименование `Review`). | Must |
|
||||
| **BR-5** | Self-deploy Phase A (approval-pending) ставит `Awaiting Deploy` вместо `In Review`. | Must |
|
||||
| **BR-6** | Self-deploy Phase B (старт прод-деплоя) ставит `Deploying`. | Must |
|
||||
| **BR-7** | Self-deploy Phase C (health-OK финализация) ставит `Monitoring after Deploy` (НЕ `Done` сразу). | Must |
|
||||
| **BR-8** | Post-deploy monitor (ORCH-021): чистое закрытие окна (HEALTHY) → `Done`; UNHEALTHY/деградация → `Blocked`. | Must |
|
||||
| **BR-9** | `In Review` разгрузить: оставить ТОЛЬКО за approve-pending артефактов конвейера (BRD/ревью). Выходы: `Approved` (вперёд), `Rejected` (откат), `Cancelled` (человек отменил). | Must |
|
||||
| **BR-10** | `Needs Input` — БЕЗ ИЗМЕНЕНИЙ. Остаётся только у аналитика (`01-questions.md` → `set_issue_needs_input`). Механизм не трогать. | Must |
|
||||
| **BR-11** | Возврат аналитика из Needs Input выполняется через `To Analyse` (а НЕ через `In Progress`). Логика fork «старт vs resume» (по наличию task + active-job) сохраняется. | Must (грабли R1) |
|
||||
| **BR-12** | **Fail-closed:** отсутствие нового статуса в проекте (enduro / Plane API down / fallback `_DEFAULT_STATES`) НЕ приводит к падению; поведение остаётся backward-compatible (паттерн ORCH-059 AC-7). | Must |
|
||||
| **BR-13** | Reconciler не «оживляет» активные ожидания (`Awaiting Deploy` / `Deploying` / `Monitoring after Deploy`) как зависшие задачи (Guard 2 skip-list). | Must |
|
||||
| **BR-14** | Документация (golden source) обновлена в том же PR: `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md`, ADR per-work-item. | Must |
|
||||
|
||||
---
|
||||
|
||||
## 4. Границы (Out of Scope / НЕ трогать)
|
||||
|
||||
- `STAGE_TRANSITIONS` (`src/stages.py`) — машина стадий, инвариант.
|
||||
- `QG_CHECKS`, `check_deploy_status`, exit-коды хука (0/1/2), merge-gate, схема БД.
|
||||
- `Confirm Deploy` (уже работает, ORCH-059).
|
||||
- Механизм `Needs Input` (analyst-only) — не расширять, не менять.
|
||||
- Поведение прод-деплоя **не-self** репозиториев (enduro-trails): для них терминальный
|
||||
переход остаётся `deploy → Done` как сейчас (Monitoring after Deploy не применяется —
|
||||
post-deploy monitor армится только для self-hosting).
|
||||
- Автоматический approve / авто-rollback self-hosting (ORCH-54 / ORCH-021 политика
|
||||
ALERT_ONLY) — не меняется.
|
||||
|
||||
---
|
||||
|
||||
## 5. Инфра-предусловие (вне кода, делает оператор)
|
||||
|
||||
Новые Plane-статусы в проекте **ORCH** создаёт оператор через Plane API **ДО** эксплуатации:
|
||||
`To Analyse`, `Analysis`, `Code-Review`, `Awaiting Deploy`, `Deploying`,
|
||||
`Monitoring after Deploy` (`Confirm Deploy` уже есть).
|
||||
|
||||
Резолвер (`_PLANE_NAME_TO_KEY` + `get_project_states`) подхватывает их **по имени** с
|
||||
**fail-closed fallback** на `_DEFAULT_STATES` (см. BR-12). Документируется в
|
||||
`07-infra-requirements.md` (создаёт архитектор) и в `docs/operations/`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Definition of Done
|
||||
|
||||
- Plane показывает осмысленные статусы на каждом этапе.
|
||||
- Возврат аналитика из Needs Input работает через `To Analyse`.
|
||||
- Phase A → `Awaiting Deploy`, Phase B → `Deploying`, Phase C → `Monitoring after Deploy`,
|
||||
окно HEALTHY → `Done`, фейл → `Blocked`.
|
||||
- `STAGE_TRANSITIONS` не изменён.
|
||||
- `pytest tests/ -q` — зелёный. Fail-closed покрыт тестами.
|
||||
- Документация обновлена.
|
||||
178
docs/work-items/ORCH-066/02-trz.md
Normal file
178
docs/work-items/ORCH-066/02-trz.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# 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_status` red → 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.py` `STAGE_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` — без регресса.
|
||||
71
docs/work-items/ORCH-066/03-acceptance-criteria.md
Normal file
71
docs/work-items/ORCH-066/03-acceptance-criteria.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 03 — Критерии приёмки (Acceptance Criteria)
|
||||
|
||||
**Work Item:** ORCH-066
|
||||
|
||||
Каждый критерий — чёткое условие PASS/FAIL. Покрытие тестами — см. `04-test-plan.yaml`.
|
||||
|
||||
---
|
||||
|
||||
## Группа A — Вход и стадия анализа
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-1** | `To Analyse` запускает конвейер | Перевод issue без task в `To Analyse` → `handle_status_start` → `start_pipeline` (создаётся task, ветка, enqueue analyst). | Не запускается / запускается на другом статусе. |
|
||||
| **AC-2** | `To Analyse` делает resume аналитика из Needs Input | Существующий task без active-job + перевод в `To Analyse` → relaunch агента текущей стадии (analyst читает свежие комменты). Fork «старт vs resume» определяется по `get_task_by_plane_id` + `has_active_job_for_task` (как раньше). | Создаётся второй task / двойной запуск / resume не происходит. |
|
||||
| **AC-3** | Стадия `analysis` индицируется статусом `Analysis` | При старте/relaunch аналитика орк ставит `Analysis`. | Остаётся `In Progress` (при наличии статуса `Analysis` в проекте). |
|
||||
| **AC-4** | Busy-guard сохранён | `To Analyse` при существующем active-job для task → НЕ relaunch (no double launch). | Двойной запуск агента. |
|
||||
|
||||
## Группа B — Code-Review
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-5** | Стадия `review` индицируется `Code-Review` | Вход в стадию `review` → Plane-статус `Code-Review`. | Остаётся `Review` (при наличии нового статуса). |
|
||||
|
||||
## Группа C — Self-deploy фазы
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-6** | Phase A → `Awaiting Deploy` | `_handle_self_deploy_phase_a` ставит `Awaiting Deploy` (не `In Review`). | Ставит `In Review` (при наличии нового статуса). |
|
||||
| **AC-7** | Phase B → `Deploying` | `_handle_self_deploy_phase_b` при успешном `initiate_deploy` ставит `Deploying`. | Статус не меняется / иной. |
|
||||
| **AC-8** | Phase C → `Monitoring after Deploy` (self) | Финализатор SUCCESS для self-hosting → статус `Monitoring after Deploy`, НЕ `Done` сразу. | Ставит `Done` немедленно (для self-hosting). |
|
||||
| **AC-9** | Не-self deploy → `Done` без регресса | Для не-self репо (`post_deploy_applies==False`) терминальный `deploy → done` ставит `Done` как сейчас. | Не-self репо получает `Monitoring after Deploy` / иной регресс. |
|
||||
|
||||
## Группа D — Post-deploy monitor
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-10** | Чистое окно → `Done` | `run_post_deploy_monitor` HEALTHY + окно исчерпано → статус `Done`. | Остаётся `Monitoring after Deploy` / иной. |
|
||||
| **AC-11** | Деградация → `Blocked` | `run_post_deploy_monitor` DEGRADED → статус `Blocked` (+ существующий ALERT_ONLY для self). | Остаётся в Monitoring / ставит Done. |
|
||||
| **AC-12** | Self-hosting монитор не рестартит прод | Тик НИКОГДА не рестартит/откатывает прод-контейнер (ORCH-021 BR-5 сохранён). | Тик трогает прод-контейнер. |
|
||||
|
||||
## Группа E — In Review / Needs Input / ветки
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-13** | `In Review` только за approve-pending конвейера | `In Review` ставится лишь для approve артефактов (analyst BRD/ревью), не для Phase A. | Phase A / иные стадии ставят `In Review`. |
|
||||
| **AC-14** | `Needs Input` без изменений | Поведение `set_issue_needs_input` (analyst `01-questions.md`) идентично прежнему; не расширено на других агентов. | Механизм изменён / расширен. |
|
||||
| **AC-15** | `Cancelled` — валидный выход из In Review без действий конвейера | Перевод в `Cancelled` → орк не выполняет advance/rollback (индикация, не управление). | Орк совершает действие конвейера на `Cancelled`. |
|
||||
|
||||
## Группа F — Fail-closed (КРИТИЧНО)
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-16** | Отсутствие нового статуса не ломает конвейер | Проект без новых статусов (enduro/частичный/Plane down) → `get_project_states` отдаёт default-алиасы; все `set_issue_*`/триггеры работают backward-compatible, без исключений и без 404 PATCH. | Падение / необработанное исключение / зависание задачи. |
|
||||
| **AC-17** | enduro `In Progress` по-прежнему стартует конвейер | Через `to_analyse`-алиас (= `in_progress` UUID) перевод enduro-issue в `In Progress` запускает старт/resume. | enduro-старт сломан. |
|
||||
| **AC-18** | Резолв по имени | При наличии статуса в проекте по `name` (`_PLANE_NAME_TO_KEY`) используется его UUID, а не default-алиас. | Используется неверный UUID. |
|
||||
|
||||
## Группа G — Reconciler
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-19** | F-2 реконсилирует `To Analyse` | `_reconcile_plane_project` запрашивает `to_analyse` и маршрутизирует к `handle_status_start` (старт/resume при потерянном webhook). | `To Analyse`-старты не реконсилируются. |
|
||||
| **AC-20** | Guard 2 skip активных ожиданий | Задачи в `Awaiting Deploy` / `Deploying` / `Monitoring after Deploy` НЕ «оживляются» F-1 как зависшие. | Реконсилер advance'ит активное ожидание. |
|
||||
|
||||
## Группа H — Инварианты и документация
|
||||
|
||||
| ID | Критерий | PASS | FAIL |
|
||||
|----|----------|------|------|
|
||||
| **AC-21** | `STAGE_TRANSITIONS` не изменён | `src/stages.py` `STAGE_TRANSITIONS` идентичен (diff пуст). | Любое изменение слоя A. |
|
||||
| **AC-22** | Реестры/контракты не изменены | `QG_CHECKS`, `check_deploy_status`, exit-коды хука, merge-gate, схема БД, `Confirm Deploy` — без изменений. | Любое изменение перечисленного. |
|
||||
| **AC-23** | Тесты зелёные | `pytest tests/ -q` проходит полностью; новые fail-closed тесты присутствуют и зелёные. | Любой красный тест. |
|
||||
| **AC-24** | Документация обновлена (golden source) | `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md` обновлены; заведён `06-adr/ADR-001-*`. | Любой из артефактов не обновлён. |
|
||||
184
docs/work-items/ORCH-066/04-test-plan.yaml
Normal file
184
docs/work-items/ORCH-066/04-test-plan.yaml
Normal file
@@ -0,0 +1,184 @@
|
||||
work_item: ORCH-066
|
||||
description: >
|
||||
Тест-план статусной модели Plane (слой B). Покрывает осмысленные статусы этапов,
|
||||
возврат аналитика через To Analyse, фазы self-deploy, post-deploy monitor,
|
||||
fail-closed деградацию и reconciler. Слой A (STAGE_TRANSITIONS) проверяется на
|
||||
неизменность. Все тесты — pytest; Plane API мокается (httpx), как в существующих
|
||||
tests/test_plane_*.py / tests/test_orch10_states.py.
|
||||
|
||||
tests:
|
||||
# --- Группа A: вход и стадия анализа ---
|
||||
- id: TC-01
|
||||
type: unit
|
||||
description: "To Analyse без существующего task -> handle_status_start -> start_pipeline (старт конвейера)."
|
||||
module: tests/test_status_trigger.py
|
||||
covers: [AC-1]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-02
|
||||
type: integration
|
||||
description: "To Analyse при существующем task без active-job -> relaunch агента стадии (resume из Needs Input), новый task НЕ создаётся."
|
||||
module: tests/test_plane_to_analyse_resume.py
|
||||
covers: [AC-2, BR-11]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-03
|
||||
type: unit
|
||||
description: "Старт/relaunch аналитика ставит Plane-статус Analysis (а не In Progress) при наличии статуса в проекте."
|
||||
module: tests/test_plane_status_model.py
|
||||
covers: [AC-3]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-04
|
||||
type: unit
|
||||
description: "To Analyse при существующем task с active-job -> НЕ relaunch (busy-guard)."
|
||||
module: tests/test_plane_to_analyse_resume.py
|
||||
covers: [AC-4]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа B: Code-Review ---
|
||||
- id: TC-05
|
||||
type: unit
|
||||
description: "Вход в стадию review -> Plane-статус Code-Review (маппинг _STAGE_TO_STATE_KEY / STAGE_VISIBILITY_STATE)."
|
||||
module: tests/test_plane_status_model.py
|
||||
covers: [AC-5]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа C: self-deploy фазы ---
|
||||
- id: TC-06
|
||||
type: unit
|
||||
description: "_handle_self_deploy_phase_a ставит Awaiting Deploy (не In Review)."
|
||||
module: tests/test_deploy_approve.py
|
||||
covers: [AC-6, AC-13]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-07
|
||||
type: unit
|
||||
description: "_handle_self_deploy_phase_b при успешном initiate_deploy ставит Deploying."
|
||||
module: tests/test_deploy_approve.py
|
||||
covers: [AC-7]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-08
|
||||
type: integration
|
||||
description: "Phase C (finalizer SUCCESS) для self-hosting ставит Monitoring after Deploy, НЕ Done; армит post-deploy monitor."
|
||||
module: tests/test_deploy_terminal_sync.py
|
||||
covers: [AC-8]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-09
|
||||
type: integration
|
||||
description: "Не-self репо: deploy->done ставит Done (без регресса, Monitoring не применяется)."
|
||||
module: tests/test_deploy_terminal_sync.py
|
||||
covers: [AC-9]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа D: post-deploy monitor ---
|
||||
- id: TC-10
|
||||
type: unit
|
||||
description: "run_post_deploy_monitor HEALTHY + окно исчерпано -> Plane-статус Done."
|
||||
module: tests/test_post_deploy.py
|
||||
covers: [AC-10]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-11
|
||||
type: unit
|
||||
description: "run_post_deploy_monitor DEGRADED -> Plane-статус Blocked (+ ALERT_ONLY для self)."
|
||||
module: tests/test_post_deploy.py
|
||||
covers: [AC-11]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-12
|
||||
type: unit
|
||||
description: "Self-hosting тик НЕ рестартит/не откатывает прод-контейнер (ORCH-021 BR-5 сохранён)."
|
||||
module: tests/test_post_deploy.py
|
||||
covers: [AC-12]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа E: In Review / Needs Input / Cancelled ---
|
||||
- id: TC-13
|
||||
type: unit
|
||||
description: "In Review ставится только за approve-pending конвейера (analyst BRD ready), не Phase A."
|
||||
module: tests/test_analyst_status_only_regression.py
|
||||
covers: [AC-13]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-14
|
||||
type: unit
|
||||
description: "set_issue_needs_input (analyst 01-questions.md) поведение идентично прежнему; не расширено на других агентов."
|
||||
module: tests/test_plane_status_model.py
|
||||
covers: [AC-14, BR-10]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-15
|
||||
type: unit
|
||||
description: "Перевод в Cancelled -> handle_issue_updated не выполняет advance/rollback (индикация, не управление)."
|
||||
module: tests/test_plane_webhook.py
|
||||
covers: [AC-15]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа F: fail-closed (критично) ---
|
||||
- id: TC-16
|
||||
type: unit
|
||||
description: "Проект без новых статусов: get_project_states отдаёт default-алиасы (to_analyse=in_progress, code_review=review, awaiting_deploy=in_review, monitoring=done); исключений нет."
|
||||
module: tests/test_plane_status_failclosed.py
|
||||
covers: [AC-16, BR-12]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-17
|
||||
type: unit
|
||||
description: "Plane API down -> get_project_states fallback на _DEFAULT_STATES; set_issue_* never-raise."
|
||||
module: tests/test_plane_status_failclosed.py
|
||||
covers: [AC-16]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-18
|
||||
type: integration
|
||||
description: "enduro In Progress по-прежнему стартует конвейер через to_analyse-алиас."
|
||||
module: tests/test_plane_status_failclosed.py
|
||||
covers: [AC-17]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-19
|
||||
type: unit
|
||||
description: "Резолв по имени: при наличии статуса в проекте используется его UUID, а не default-алиас."
|
||||
module: tests/test_orch10_states.py
|
||||
covers: [AC-18]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа G: reconciler ---
|
||||
- id: TC-20
|
||||
type: integration
|
||||
description: "F-2 _reconcile_plane_project запрашивает to_analyse и маршрутизирует к handle_status_start (потерянный webhook старта/resume)."
|
||||
module: tests/test_reconciler_plane.py
|
||||
covers: [AC-19]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-21
|
||||
type: unit
|
||||
description: "Guard 2: задачи в Awaiting Deploy / Deploying / Monitoring after Deploy НЕ оживляются F-1 как зависшие."
|
||||
module: tests/test_reconciler.py
|
||||
covers: [AC-20, BR-13]
|
||||
expected: PASS
|
||||
|
||||
# --- Группа H: инварианты ---
|
||||
- id: TC-22
|
||||
type: unit
|
||||
description: "STAGE_TRANSITIONS не изменён (явная проверка ключей/значений слоя A)."
|
||||
module: tests/test_plane_status_model.py
|
||||
covers: [AC-21]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-23
|
||||
type: unit
|
||||
description: "QG_CHECKS реестр и check_deploy_status контракты не изменены."
|
||||
module: tests/test_plane_status_model.py
|
||||
covers: [AC-22]
|
||||
expected: PASS
|
||||
|
||||
- id: TC-24
|
||||
type: integration
|
||||
description: "Полный прогон pytest tests/ -q зелёный (регрессия)."
|
||||
module: tests/
|
||||
covers: [AC-23]
|
||||
expected: PASS
|
||||
Reference in New Issue
Block a user