architect(ET): auto-commit from architect run_id=362
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
# ADR-001: Источник Plane-статуса для live-карточки и кликабельный номер задачи
|
||||
|
||||
- **Статус:** Proposed
|
||||
- **Дата:** 2026-06-08
|
||||
- **Задача:** ORCH-067
|
||||
- **Слой:** B (индикация), НЕ слой A (машина стадий) — см. CLAUDE.md / ORCH-066
|
||||
- **Связи:** ORCH-066 (статусная модель Plane, `_PLANE_NAME_TO_KEY` / `_STAGE_TO_STATE_KEY`),
|
||||
ORCH-042 (live-tracker, режимы `edit`/`bump`), ORCH-017 (`_build_plane_issue_link`,
|
||||
`plane_web_url`/`plane_workspace_slug`, loopback-guard), ORCH-059 (Confirm Deploy),
|
||||
ORCH-060 (`fetch_issue_state`), ORCH-010 (`get_project_states` per-project + кэш),
|
||||
adr-0001 (реестр проектов), adr-0010 (post-deploy monitor).
|
||||
|
||||
## Контекст
|
||||
|
||||
ТЗ ORCH-067 (`02-trz.md`) фиксирует объём изменений; данный ADR закрывает развилки,
|
||||
явно отданные архитектору метками `[ARCH]`:
|
||||
|
||||
1. **Источник «истинного» Plane-статуса для веток, не выводимых из `tasks.stage`**
|
||||
(Needs Input, Blocked, Rejected, Cancelled, Deploying, Monitoring after Deploy),
|
||||
при **запрете менять схему БД** (нельзя добавить колонку-флаг). TZ §2.2 предлагает
|
||||
два варианта: (а) best-effort чтение живого Plane-статуса с fail-safe;
|
||||
(б) только stage-выводимые статусы.
|
||||
2. **Способ доступа к `plane_issue_id`/`project_id`** в каждой точке `send_telegram`,
|
||||
где есть только `work_item_id` (требование 4), оставаясь fail-safe.
|
||||
3. Смена дефолта `tracker_mode` (`edit` → `bump`) для общего инстанса.
|
||||
|
||||
### Ключевая находка анализа (определяет развилку 1)
|
||||
|
||||
Когда аналитик задаёт вопросы, `stage_engine.start_pipeline` при наличии
|
||||
`01-questions.md` вызывает `set_issue_needs_input(work_item_id)` (Plane → Needs Input),
|
||||
но **DB-стадия остаётся `analysis`**, а BRD-часы (`brd_review_started_at`) **не
|
||||
запускаются** (они стартуют позже, в `notify_approve_requested`, когда BRD готов).
|
||||
Следовательно состояния **`Analysis` (аналитик работает)** и **`❓ Needs Input`
|
||||
(аналитик ждёт ответа)** **неразличимы** по offline-данным БД (`stage` + brd-clock).
|
||||
Единственный авторитетный источник этого различия — **живой Plane-статус**, который
|
||||
оркестратор сам выставил через `set_issue_needs_input`.
|
||||
|
||||
То же касается `Deploying` / `Monitoring after Deploy`: на стадии `deploy`/`done`
|
||||
конкретная фаза self-deploy видна только в Plane (ORCH-059/ORCH-066), не в `tasks.stage`.
|
||||
|
||||
Вывод: чисто-offline вариант (б) **не покрывает обязательный по DoD `❓ Needs Input`**
|
||||
(AC-8). Нужен гибрид.
|
||||
|
||||
## Решение
|
||||
|
||||
### Р-1. Гибрид: offline-first ядро + best-effort live-overlay
|
||||
|
||||
Статус карточки строится в два слоя; **offline-ядро авторитетно и всегда работает без
|
||||
сети**, live-overlay лишь дорисовывает ветки, неотличимые offline.
|
||||
|
||||
**Слой 1 — чистая offline-функция `plane_status_label(task_row) -> str`** в
|
||||
`src/notifications.py`. Детерминированная, **никогда не бросает**, **никогда не ходит в
|
||||
сеть**. Маппинг (имена статусов — финальные из ORCH-066 `_PLANE_NAME_TO_KEY`):
|
||||
|
||||
| Источник (DB) | Метка карточки |
|
||||
|---|---|
|
||||
| `stage == "created"` | `To Analyse` |
|
||||
| `stage == "analysis"`, brd-clock не запущен | `Analysis` |
|
||||
| `stage == "analysis"`, `brd_review_started_at` есть, `brd_review_ended_at` пуст | `⏸️ In Review — ожидание согласования BRD` |
|
||||
| `stage == "architecture"` | `Architecture` |
|
||||
| `stage == "development"` | `Development` |
|
||||
| `stage == "review"` | `Code-Review` |
|
||||
| `stage == "testing"` | `Testing` |
|
||||
| `stage == "deploy"` | `⏸️ Awaiting Deploy — ожидание Confirm Deploy` |
|
||||
| `stage == "done"` | `Done` |
|
||||
| неизвестный/битый `stage` | дефолт: `html`-безопасная строка по `stage` (или `To Analyse`) |
|
||||
|
||||
Этого слоя достаточно для **`⏸️ In Review`** и **`⏸️ Awaiting Deploy`** — оба
|
||||
обязательны по DoD и **работают без сети** (AC-7, AC-8). `In Review` выводится
|
||||
исключительно из brd-clock.
|
||||
|
||||
**Слой 2 — best-effort live-overlay** `_live_plane_branch_override(repo, plane_issue_id,
|
||||
base_label) -> str` для веток, неразличимых offline: **Needs Input, Blocked, Rejected,
|
||||
Cancelled, Deploying, Monitoring after Deploy**. Алгоритм:
|
||||
|
||||
1. Резолв `project_id` по `repo` (`get_project_by_repo(repo).plane_project_id`).
|
||||
2. `live_uuid = fetch_issue_state(plane_issue_id, project_id)` (ORCH-060) — **с коротким
|
||||
таймаутом** (см. Р-4), не дефолтным 10s.
|
||||
3. Сопоставление `live_uuid` с **конкретными** UUID веток из
|
||||
`get_project_states(project_id)` (кэш ORCH-010): `needs_input`, `blocked`,
|
||||
`cancelled`, `rejected`, `deploying`, `monitoring`.
|
||||
4. Override применяется **только** если `live_uuid` совпал с одним из этих ключей.
|
||||
Иначе возвращается `base_label` (offline-метка).
|
||||
|
||||
**Прецеденс (порядок приоритета):**
|
||||
1. Если offline-ядро дало **`⏸️ In Review`** (brd-clock) — overlay **не вызывается**:
|
||||
brd-clock авторитетнее возможно-устаревшего Plane-чтения для In Review.
|
||||
2. Иначе `base_label` = offline-метка, затем применяется overlay (если включён и удался).
|
||||
|
||||
**Анти-false-positive на enduro (важно):** на enduro-trails ключи `deploying`/
|
||||
`monitoring` алиасят UUID `in_progress`/`done` (`_STATE_ALIAS_FALLBACK`), поэтому прямое
|
||||
сравнение UUID дало бы ложный `Deploying` для любой `in_progress`-задачи. Поэтому для
|
||||
`deploying`/`monitoring` override применяется **только если** их UUID в
|
||||
`get_project_states` **отличается** от UUID базового ключа (т.е. проект реально завёл
|
||||
отдельный статус — это ORCH, не enduro). Ключи `needs_input/blocked/cancelled/rejected`
|
||||
имеют отдельные UUID и на enduro, и на ORCH (`_DEFAULT_STATES`), поэтому различимы всегда.
|
||||
|
||||
### Р-2. Fail-safe и невлияние на конвейер (overlay)
|
||||
|
||||
- `_live_plane_branch_override` обёрнут в `try/except` и **никогда не бросает**; любая
|
||||
ошибка/таймаут/нет сети/нет данных → возвращается `base_label`. Это удовлетворяет
|
||||
«без сети не падать» и AC-9 (рендер карточки никогда не падает).
|
||||
- Нет `plane_issue_id` / нет `project_id` / нет креды → overlay не вызывается, метка =
|
||||
offline-ядро.
|
||||
- **Kill-switch:** новый флаг конфигурации `tracker_live_status: bool = True`
|
||||
(env `ORCH_TRACKER_LIVE_STATUS`). При `False` overlay полностью отключён (никаких
|
||||
сетевых чтений в рендере) — карточка деградирует на offline-ядро. Это аварийный
|
||||
тумблер и страховка от регресса для не-ORCH проектов. **Дефолт `True`**, иначе
|
||||
обязательный по DoD `Needs Input` не отобразится из коробки.
|
||||
|
||||
### Р-3. Кэш live-статуса (защита hot-path)
|
||||
|
||||
`render_task_tracker` вызывается на КАЖДОМ обновлении трекера (старт/финиш агента,
|
||||
переход стадии), а в режиме `bump` — с delete+send каждый раз. Чтобы серия быстрых
|
||||
перерисовок не била по Plane:
|
||||
|
||||
- Добавить **TTL-кэш per-issue** для `live_uuid` (ключ — `plane_issue_id`, TTL
|
||||
`tracker_live_status_ttl_s: int = 60`). По образцу `_STATES_CACHE` в `plane_sync.py`.
|
||||
- На промахе кэша — один `fetch_issue_state` с коротким таймаутом; результат кладётся в
|
||||
кэш. На любой ошибке кэш не портится, возвращается offline-метка.
|
||||
|
||||
Это ограничивает сетевую нагрузку overlay ~одним GET в `TTL` на задачу.
|
||||
|
||||
### Р-4. Короткий таймаут live-чтения в рендере
|
||||
|
||||
`fetch_issue_state` (ORCH-060) хардкодит `timeout=10`. Для пути рендера это слишком
|
||||
долго (рендер синхронный, в линии переходов общего конвейера). Решение: добавить в
|
||||
`fetch_issue_state` **необязательный параметр `timeout`** (дефолт прежний `10` —
|
||||
обратная совместимость для reconciler), а overlay вызывает его с
|
||||
`settings.tracker_live_status_timeout_s` (дефолт **3** с). Поведение/сигнатуры
|
||||
существующих вызовов не меняются.
|
||||
|
||||
### Р-5. Единый хелпер кликабельного номера `plane_issue_link`
|
||||
|
||||
Добавить в `src/notifications.py`:
|
||||
|
||||
```python
|
||||
def plane_issue_link(work_item_id, plane_issue_id=None, project_id=None, repo=None) -> str:
|
||||
"""HTML с кликабельным номером (<a href=...>ORCH-NNN</a>) или html.escape(work_item_id).
|
||||
Никогда не падает."""
|
||||
```
|
||||
|
||||
- Переиспользовать логику и guard'ы `_build_plane_issue_link` (ORCH-017), **разнеся**
|
||||
«текст ссылки = номер задачи» и «текст ссылки = `✅ Задача в Plane`», чтобы не
|
||||
дублировать резолв проекта и loopback-guard. Рекомендуется выделить приватный
|
||||
`_plane_issue_url(repo, plane_issue_id, project_id) -> str | None` (сборка URL +
|
||||
loopback/workspace/project guard), который зовут оба: `plane_issue_link` (текст =
|
||||
номер) и `_build_plane_issue_link` (текст = «✅ Задача в Plane»).
|
||||
- База URL: `plane_web_url` → fallback `plane_api_url`; loopback → «нет web URL»
|
||||
(`_is_loopback_base`).
|
||||
- `project_id`: явный аргумент → иначе резолв по `repo`.
|
||||
- URL: `{web_base}/{workspace}/projects/{project_id}/issues/{plane_issue_id}/`.
|
||||
- Текст = `html.escape(work_item_id)`; `href` = `html.escape(url, quote=True)`.
|
||||
- **Fail-safe:** не хватает любого из (web_base/не-loopback, workspace, project_id,
|
||||
plane_issue_id) → вернуть `html.escape(work_item_id)` (номер без ссылки). Никогда не
|
||||
бросает (AC-11, AC-12).
|
||||
|
||||
### Р-6. Доступ к `plane_issue_id`/`project_id` в точках уведомлений (требование 4)
|
||||
|
||||
В большинстве точек `send_telegram` доступен только `work_item_id`. Решение —
|
||||
тонкая fail-safe обёртка по образцу `_get_task_link_fields`:
|
||||
|
||||
```python
|
||||
def link_for(work_item_id, task_id=None) -> str:
|
||||
"""По work_item_id (или task_id) достать repo+plane_issue_id из БД и вернуть
|
||||
plane_issue_link(...). На любой нехватке данных -> html.escape(work_item_id)."""
|
||||
```
|
||||
|
||||
- Если у точки есть `task_id` — читать `(repo, plane_issue_id)` напрямую из `tasks` по
|
||||
`id`. Если только `work_item_id` — `SELECT repo, plane_issue_id FROM tasks WHERE
|
||||
work_item_id=? ORDER BY id DESC LIMIT 1` (как в `_resolve_project_id`).
|
||||
- Везде, где данных нет — деградация на `html.escape(work_item_id)`, без падения.
|
||||
- Применить во всех точках из TZ §3.3 (`notify_approve_requested`, `notify_error`,
|
||||
`stage_engine`, `launcher`, `merge_gate`, `job_reaper`, `security_gate`, `reconciler`,
|
||||
`main`) — **только там, где упоминается номер задачи**.
|
||||
|
||||
### Р-7. `tracker_mode` дефолт → `bump`
|
||||
|
||||
`src/config.py`: `tracker_mode: str = "edit"` → `"bump"`. Инвариант «одна карточка на
|
||||
задачу» сохранён в обоих режимах (код `update_task_tracker` не меняется по сути).
|
||||
`edit` остаётся доступен через `ORCH_TRACKER_MODE=edit`. Транзиентный фейл `send` не
|
||||
обнуляет `tracker_message_id` (инвариант уже в коде — сохранить).
|
||||
|
||||
### Р-8. Чего НЕ делаем (границы)
|
||||
|
||||
- НЕ менять схему БД, `STAGE_TRANSITIONS`, Quality Gates, транспорт
|
||||
`send_telegram`/`edit_telegram`/`delete_telegram`, `disable_notification`-семантику.
|
||||
- НЕ менять поведение агентов/конвейера. Слой B (индикация) не управляет слоем A.
|
||||
- НЕ добавлять блокирующих сетевых ожиданий в линию переходов сверх одного короткого
|
||||
best-effort GET с кэшем (Р-3/Р-4).
|
||||
- НЕ создавать глобальный (сквозной) ADR: изменение локально для `notifications.py` +
|
||||
один config-дефолт, не вводит новую стадию/QG/компонент. Достаточно per-work-item ADR.
|
||||
|
||||
## Последствия
|
||||
|
||||
**Плюсы**
|
||||
- Обязательные по DoD `⏸️ In Review`, `⏸️ Awaiting Deploy` работают **без сети**
|
||||
(детерминированно, тестируемо offline — AC-6/AC-7).
|
||||
- `❓ Needs Input` (и Blocked/Rejected/Cancelled/Deploying/Monitoring) отражаются через
|
||||
авторитетный источник — живой Plane-статус, который иначе невосстановим из БД.
|
||||
- Единый хелпер ссылки убирает дублирование резолва проекта/loopback-guard (ORCH-017).
|
||||
- Kill-switch + кэш + короткий таймаут ограничивают риск для общего инстанса.
|
||||
|
||||
**Минусы / ограничения**
|
||||
- Overlay добавляет ≤1 короткий GET (3 с таймаут) на задачу в `TTL=60s` в путь рендера.
|
||||
Митигировано кэшем, таймаутом и kill-switch.
|
||||
- При недоступном Plane ветки `Needs Input`/`Blocked`/… деградируют на offline-метку
|
||||
(`Analysis`/stage). Это осознанный, безопасный компромисс (рендер важнее точности
|
||||
ветки; конвейер не блокируется).
|
||||
- На частично сконфигурированном проекте без отдельных статусов `Deploying`/`Monitoring`
|
||||
эти ветки не показываются (alias-guard) — корректная деградация, не баг.
|
||||
|
||||
**Риски** — см. `10-tech-risks.md`.
|
||||
|
||||
## Альтернативы (отклонены)
|
||||
|
||||
- **Только offline (вариант б TZ).** Отклонён: не отличает `Needs Input` от `Analysis`
|
||||
→ не покрывает обязательный AC-8.
|
||||
- **Чтение `01-questions.md` из worktree как offline-сигнал Needs Input.** Отклонён:
|
||||
хрупко (резолв пути worktree из `notifications.py`, файл может пережить ответ,
|
||||
гонки) — менее надёжно, чем авторитетный Plane-статус.
|
||||
- **Добавить DB-колонку-флаг для ветки.** Запрещено TZ (без изменения схемы).
|
||||
- **Асинхронный фон/демон для подтяжки статуса.** Избыточно для слоя индикации; кэш +
|
||||
короткий таймаут дешевле и проще, без нового компонента.
|
||||
46
docs/work-items/ORCH-067/07-infra-requirements.md
Normal file
46
docs/work-items/ORCH-067/07-infra-requirements.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Инфраструктурные требования — ORCH-067
|
||||
|
||||
Топология не меняется (никаких новых контейнеров/портов/сервисов). Изменения —
|
||||
**только конфигурация/env** и обязательный staging-гейт (self-hosting).
|
||||
|
||||
## 1. Изменения конфигурации (`src/config.py`)
|
||||
|
||||
| Поле | env | Старое | Новое | Назначение |
|
||||
|---|---|---|---|---|
|
||||
| `tracker_mode` | `ORCH_TRACKER_MODE` | `"edit"` | `"bump"` (дефолт) | Карточка падает вниз ленты при обновлении (ADR-001 Р-7). `edit` доступен через env. |
|
||||
| `tracker_live_status` | `ORCH_TRACKER_LIVE_STATUS` | — (нет) | `True` (дефолт) | Kill-switch live-overlay Plane-статуса (ADR-001 Р-2). `0/false` → только offline-метки, без сетевых чтений в рендере. |
|
||||
| `tracker_live_status_ttl_s` | `ORCH_TRACKER_LIVE_STATUS_TTL_S` | — | `60` | TTL per-issue кэша live-статуса (ADR-001 Р-3). |
|
||||
| `tracker_live_status_timeout_s` | `ORCH_TRACKER_LIVE_STATUS_TIMEOUT_S` | — | `3` | Короткий таймаут live-чтения в рендере (ADR-001 Р-4). |
|
||||
|
||||
Уже существующие (не менять, использовать): `plane_web_url`
|
||||
(`ORCH_PLANE_WEB_URL`, прод — `https://plane.mva154.duckdns.org`),
|
||||
`plane_workspace_slug` (прод — `ag_proj`), `plane_api_url`.
|
||||
|
||||
## 2. `.env` / `.env.example`
|
||||
|
||||
- Обновить `.env.example`: добавить `ORCH_TRACKER_MODE`, `ORCH_PLANE_WEB_URL`,
|
||||
`ORCH_TRACKER_LIVE_STATUS*` с дефолтами и комментариями (канон настроек —
|
||||
`.env.example`, реальные секреты не коммитить).
|
||||
- На прод-хосте допустимо явно выставить `ORCH_TRACKER_MODE=bump` как страховку, но код
|
||||
обязан работать «из коробки» и без env.
|
||||
- `ORCH_PLANE_WEB_URL` должен быть задан на проде (иначе номер задачи деградирует на
|
||||
текст без ссылки — fail-safe, не падение).
|
||||
|
||||
## 3. Self-hosting (обязательно)
|
||||
|
||||
- **НЕ перезапускать / не ронять** прод-контейнер `orchestrator` (8500) в рамках задачи —
|
||||
общий инстанс/БД с enduro-trails.
|
||||
- Обязательная страховка через `deploy-staging` (8501, изолированная БД) **до** прод-деплоя.
|
||||
На staging проверить:
|
||||
- режим `bump`: одна карточка на задачу, падает вниз, тихо (без звука), без дублей;
|
||||
- статус-строка: `⏸️ In Review`, `⏸️ Awaiting Deploy`, `❓ Needs Input` отображаются;
|
||||
- кликабельный номер ведёт на страницу Plane;
|
||||
- **нет регресса для enduro-trails** (карточка без новых статусов деградирует корректно).
|
||||
- Прод-деплой орка — только переводом задачи на стадии `deploy` в статус
|
||||
**«Confirm Deploy»** (ORCH-059), не `Approved`.
|
||||
|
||||
## 4. Сетевые требования
|
||||
|
||||
- Live-overlay требует доступности Plane API (`plane_api_url`) из контейнера — он уже
|
||||
есть (используется plane_sync). Недоступность Plane → graceful degrade на offline-метку,
|
||||
конвейер не блокируется (короткий таймаут + kill-switch).
|
||||
35
docs/work-items/ORCH-067/08-data-requirements.md
Normal file
35
docs/work-items/ORCH-067/08-data-requirements.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Требования к данным — ORCH-067
|
||||
|
||||
## Изменения схемы БД: НЕТ
|
||||
|
||||
`STAGE_TRANSITIONS`, таблицы и колонки `tasks`/`agent_runs` **не меняются**. Это жёсткое
|
||||
ограничение TZ §6 и предпосылка ADR-001 (запрет колонки-флага для веток статуса).
|
||||
|
||||
## Читаемые колонки `tasks` (существующие)
|
||||
|
||||
| Колонка | Использование в ORCH-067 |
|
||||
|---|---|
|
||||
| `id` | Ключ задачи. |
|
||||
| `work_item_id` | Текст номера (`ORCH-NNN`) + ключ резолва в `link_for`. |
|
||||
| `title` | Заголовок карточки (`html.escape`). |
|
||||
| `stage` | Offline-маппинг Plane-статуса (ADR-001 Р-1, слой 1). |
|
||||
| `brd_review_started_at`, `brd_review_ended_at` | Различение `Analysis` ↔ `⏸️ In Review` (offline, без сети). |
|
||||
| `repo` | Резолв `project_id` (`get_project_by_repo`) для ссылки и live-overlay. |
|
||||
| `plane_issue_id` (UUID) | `issue_id` в URL Plane + аргумент `fetch_issue_state` (live-overlay). |
|
||||
| `created_at`, `updated_at` | Тоталы времени в done-строке (без изменений). |
|
||||
|
||||
`render_task_tracker` **расширяет существующий `SELECT`** по `tasks`, добавляя `repo` и
|
||||
`plane_issue_id` к уже выбираемым полям. Схему это не трогает — колонки уже есть.
|
||||
|
||||
## Кэш в памяти (не БД)
|
||||
|
||||
Per-issue TTL-кэш live-статуса (ключ `plane_issue_id`, TTL
|
||||
`tracker_live_status_ttl_s=60`, ADR-001 Р-3) — **in-memory**, по образцу `_STATES_CACHE`
|
||||
в `plane_sync.py`. Не персистится, переживание рестарта не требуется (best-effort
|
||||
индикация). Очистка при рестарте — допустима.
|
||||
|
||||
## Источник имён статусов
|
||||
|
||||
Имена и логические ключи статусов берутся из существующих структур `src/plane_sync.py`
|
||||
(`_PLANE_NAME_TO_KEY`, `get_project_states`, `_DEFAULT_STATES`), вводимых ORCH-066.
|
||||
Новых статусов/ключей ORCH-067 **не добавляет**.
|
||||
21
docs/work-items/ORCH-067/10-tech-risks.md
Normal file
21
docs/work-items/ORCH-067/10-tech-risks.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Технические риски — ORCH-067
|
||||
|
||||
| # | Риск | Вероятность / Влияние | Митигация (ADR-001) | Остаточный риск |
|
||||
|---|---|---|---|---|
|
||||
| R-1 | **Регресс enduro-trails** при смене дефолта `tracker_mode` → `bump` (другое поведение карточки для всех проектов). | Сред / Сред | Инвариант «одна карточка на задачу» сохранён; `edit` доступен через env; проверка на staging + тесты нерегресса (AC-16). | Низкий |
|
||||
| R-2 | **Поломка HTML-разметки** неэкранированным `title`/причиной → сообщение с `parse_mode=HTML` не доставится. | Сред / Сред | Обязательный `html.escape` для всего пользовательского текста; `href` через `html.escape(url, quote=True)`; тест с `<b>`/`&` (AC-14). | Низкий |
|
||||
| R-3 | **Latency в hot-path конвейера**: live-overlay добавляет сетевой GET в синхронный рендер, вызываемый на каждом переходе/в bump. | Сред / Сред | Короткий таймаут 3 с (Р-4) + per-issue TTL-кэш 60 с (Р-3) + kill-switch `ORCH_TRACKER_LIVE_STATUS=0` (Р-2). ≤1 GET на задачу за TTL. | Низкий |
|
||||
| R-4 | **Рендер карточки падает** на битых данных/недоступном Plane. | Низк / Выс | `plane_status_label` чистая и never-raise; overlay в `try/except` → degrade на offline-метку; `render_task_tracker` уже never-raise (AC-9). | Очень низкий |
|
||||
| R-5 | **Ложный `Deploying`/`Monitoring` на enduro** (их UUID алиасит `in_progress`/`done`). | Сред / Низк | Override этих веток только если UUID статуса ≠ UUID базового ключа в `get_project_states` (Р-1, anti-false-positive). | Очень низкий |
|
||||
| R-6 | **Устаревший Plane-статус из кэша** показывает неактуальную ветку (например, `Needs Input` после ответа). | Сред / Низк | TTL 60 с самозаживает; offline-ядро авторитетно для In Review (brd-clock не оверрайдится). Индикация, не управление — расхождение косметическое. | Низкий |
|
||||
| R-7 | **Транзиентный фейл `send` плодит дубли / обнуляет указатель** в bump. | Низк / Сред | Инвариант уже в коде (`set_tracker_message_id` только при `new_mid is not None`); не менять; тест AC-3. | Низкий |
|
||||
| R-8 | **Self-hosting**: деплой орка ломает общий инстанс (enduro + ORCH, общая БД/очередь). | Низк / Выс | Обязательный staging-гейт (8501) до прода; прод-контейнер не ронять в задаче; прод-деплой только через «Confirm Deploy». | Низкий |
|
||||
| R-9 | **Пропущенная точка** уведомления с сырым номером (требование 4 — много call-sites). | Сред / Низк | Единый `link_for`/`plane_issue_link`; чек-лист точек из TZ §3.3; reviewer проверяет покрытие (AC-13). | Низкий |
|
||||
| R-10 | **Рассинхрон имён статусов** с ORCH-066, если та не в проде на момент разработки. | Низк / Низк | Имена берутся из `_PLANE_NAME_TO_KEY` (golden source); делать после прода ORCH-066 (BRD §6). | Низкий |
|
||||
|
||||
## Сводно
|
||||
|
||||
Все остаточные риски — низкие/очень низкие после митигаций. Главные защитные контуры:
|
||||
(1) offline-ядро статуса не требует сети и детерминировано; (2) live-overlay полностью
|
||||
best-effort с таймаутом+кэшем+kill-switch; (3) обязательный staging-гейт перед прод-деплоем
|
||||
общего инстанса (self-hosting).
|
||||
Reference in New Issue
Block a user