208 lines
21 KiB
Markdown
208 lines
21 KiB
Markdown
---
|
||
work_item: ORCH-019
|
||
stage: analysis
|
||
author_agent: analyst
|
||
status: ready-for-review
|
||
created_at: 2026-06-10
|
||
model_used: claude-opus-4-8
|
||
---
|
||
|
||
# 02 — ТЗ (TRZ): ORCH-019 — Режим багфиксинга (упрощённый/дешёвый трек для багов)
|
||
|
||
Work Item: **ORCH-019** · Repo: **orchestrator** · Стадия: analysis
|
||
|
||
> ТЗ описывает **что** должно измениться и **где** (модули/контракты/артефакты), выведенное из BRD
|
||
> и фактического кода. **Как** (точная схема: где именно ветвить маршрут, хранить ли тип задачи в
|
||
> БД, отдельный leaf-модуль или расширение `labels.py`) — решает архитектор в `06-adr/`. ТЗ
|
||
> фиксирует требования и границы, архитектурное решение не предлагает.
|
||
|
||
> ⚠️ **Корневой инвариант (NFR-1 BRD):** срезается ТОЛЬКО аналитика/архитектура. Любой Quality Gate,
|
||
> exit-код deploy-хука, под-гейт безопасности/покрытия — байт-в-байт прежние.
|
||
|
||
---
|
||
|
||
## 1. Сводка изменения
|
||
Ввести **опциональный багфикс-трек**: задача, помеченная в Plane меткой `Bug`, проходит конвейер по
|
||
**укороченному маршруту** — пропускается стадия `architecture` и тяжёлая аналитика (полный
|
||
BRD/TRZ/AC/ADR заменяются минимальным bug-report + обязательным планом регресс-теста). Все
|
||
Quality Gate'ы (CI/review/tester/staging/deploy + под-гейты security/merge/coverage/image-freshness)
|
||
исполняются **без изменений**. Распознавание бага и маршрут — аддитивно, под kill-switch, с областью
|
||
репо, never-raise, fail-safe → полный цикл. `STAGE_TRANSITIONS` и реестр `QG_CHECKS` структурно не
|
||
меняются.
|
||
|
||
---
|
||
|
||
## 2. Задействованные модули / пути
|
||
|
||
| Путь | Роль в задаче | Характер изменения |
|
||
|------|---------------|--------------------|
|
||
| `src/labels.py` | аппарат чтения метки Plane (ORCH-089: `has_label`, `*_applies`) | переиспользовать; **добавить** `is_bug_task(work_item_id, project_id) -> bool` + `bug_fast_track_applies(repo) -> bool` (по образцу `auto_approve_applies`), либо вынести в новый leaf `src/bug_fast_track.py` (never-raise) — выбор архитектора |
|
||
| `src/plane_sync.py` | `fetch_issue_labels` / `get_project_labels` / `_normalize_label` | **без изменений** — переиспользуются для чтения метки `Bug` (источник истины — Plane API) |
|
||
| `src/webhooks/plane.py` | `start_pipeline` (создаёт task-row со стадией `"analysis"`, режет ветку `_create_gitea_branch`), `handle_status_start`, `handle_issue_updated` | **ключевая врезка:** перед `create_task_atomic(...)` определить тип задачи и (при багфикс-треке) пометить задачу багом / задать укороченный маршрут. Внешний контракт вебхука Plane не меняется |
|
||
| `src/stages.py` | `STAGE_TRANSITIONS`, `get_next_stage` | **структура `STAGE_TRANSITIONS` не меняется** (новых стадий нет). Требование: маршрут багфикса = `analysis → development` (пропуск `architecture`). Механизм (условный `get_next_stage` по типу задачи / bug-mode-флаг на task) — архитектору |
|
||
| `src/stage_engine.py` | `advance_stage`, `_run_qg`, `_handle_analysis_approved_flow`, откаты | `advance_stage` уже маршрутизирует через `get_next_stage` (не зашивает порядок) → при условной маршрутизации правка точечная. Гейты диспетчеризуются как раньше |
|
||
| `src/db.py` | `create_task_atomic(plane_id, work_item_id, repo, branch, stage, title)`, схема `tasks`, `claim_next_job` | если архитектор решит хранить «тип=bug» в БД — **аддитивная идемпотентная** колонка (`_ensure_column`, напр. `tasks.track TEXT DEFAULT 'full'`); горячий `claim_next_job` **не** должен ходить в сеть (NFR-4) |
|
||
| `src/config.py` | флаги фичи | новые: `bug_fast_track_enabled`, `bug_fast_track_label`, `bug_fast_track_repos` (CSV) + helper `applies(repo)` по образцу `auto_label_*` / `serial_gate_*` |
|
||
| `src/qg/checks.py` | реестр `QG_CHECKS` и `check_*` | **без изменений** (инвариант NFR-1) |
|
||
| `src/serial_gate.py`, `src/coverage_gate.py`, `src/merge_gate.py` | композиция | **без изменений**; проверить совместимость (NFR-7) интеграционным тестом |
|
||
| `src/main.py` | `GET /queue` | **аддитивный** read-only блок `bug_fast_track` (флаг/область/счётчики/метрика экономии) |
|
||
| `src/notifications.py` | live-карточка | опционально — отметка «🐞 багфикс-трек» в карточке (never-raise) |
|
||
| `.openclaw/agents/analyst.md` | промпт мини-аналитика | при багфикс-треке выдавать **облегчённый** пакет (bug-report + регресс-тест-план), не полный BRD/TRZ/AC. Канон промптов 52d не нарушать |
|
||
| `.openclaw/agents/reviewer.md` | ось контроля | добавить ось «багфикс без регресс-теста → REQUEST_CHANGES» (BR-4) — нормативно-описательно, не машинный гейт |
|
||
|
||
---
|
||
|
||
## 3. Функциональные требования
|
||
|
||
### FR-1 — Классификация задачи как «баг» (BR-1)
|
||
- Багфикс-трек активируется, если issue несёт метку Plane с именем `bug_fast_track_label`
|
||
(дефолт `Bug`), прочитанную через `labels.has_label(work_item_id, label, project_id)` (ORCH-089:
|
||
`fetch_issue_labels` + `get_project_labels`, нормализация `_normalize_label`, TTL-кэш).
|
||
- **Источник истины — Plane API**, не payload вебхука (поле `type` в payload отсутствует).
|
||
- Чтение метки допускается **только** в `start_pipeline` (момент старта, сетевой вызов приемлем,
|
||
как ORCH-089) — **не** в горячем `claim_next_job` (NFR-4).
|
||
- `applies(repo)` (локальный, без сети) проверяется **первым**; `has_label` (сеть) — только при
|
||
`applies==True` → при выключенном флаге нулевой сетевой оверхед (образец ORCH-089).
|
||
|
||
### FR-2 — Укороченный маршрут (BR-2)
|
||
- Для багфикс-задачи маршрут конвейера: `analysis(lite) → development → review → testing →
|
||
deploy-staging → deploy → done`, т.е. **пропускается стадия `architecture`** (и её exit-гейт
|
||
`check_architecture_done` / требование `06-adr/`).
|
||
- `STAGE_TRANSITIONS` **не изменяется структурно**. Требуемый инвариант результата: при выходе
|
||
багфикс-задачи из `analysis` следующая стадия = `development` (а не `architecture`); для
|
||
не-багфикс задач — прежняя `architecture`. Конкретный механизм (условный `get_next_stage(stage,
|
||
task)` / bug-mode-флаг на task / точка входа сразу в `development`) — решение архитектора.
|
||
- Тяжёлая аналитика облегчается: на багфикс-треке обязательны лишь `01-brd.md` (короткий
|
||
bug-report: симптом, шаги воспроизведения, локализация, причина) и `04-test-plan.yaml` (план
|
||
регресс-теста). Полные `02-trz.md`/`03-acceptance-criteria.md` и `06-adr/` — **не обязательны**.
|
||
(Совместимость с `check_analysis_complete`, требующим `01/02/03/04` — см. FR-6.)
|
||
|
||
### FR-3 — Гейты качества сохраняются полностью (BR-3, корневой инвариант)
|
||
- На багфикс-треке исполняются **без изменений**: `check_ci_green` (development→review),
|
||
`check_reviewer_verdict` (review→testing, `12-review.md`), `check_tests_passed` (testing→
|
||
deploy-staging, `13-test-report.md`), `check_staging_status`, `check_deploy_status`, под-гейты
|
||
ребра `deploy-staging→deploy` (security ORCH-022 → merge ORCH-043 → coverage ORCH-027 →
|
||
image-freshness ORCH-058) и merge-verify ребра `deploy→done` (ORCH-071/073).
|
||
- Ни один `check_*`, его сигнатура, вердикт-ключ или порядок под-гейтов **не меняется**.
|
||
|
||
### FR-4 — Обязательный регресс-тест (BR-4)
|
||
- Багфикс **обязан** содержать новый/изменённый тест, воспроизводящий дефект (красный до фикса,
|
||
зелёный после). Требование закрепляется: (а) в `04-test-plan.yaml` багфикса как обязательный TC;
|
||
(б) reviewer-осью (`.openclaw/agents/reviewer.md`): «исправление кода без теста-фиксатора →
|
||
finding ≥P1 / REQUEST_CHANGES»; (в) усиливается coverage-гейтом ORCH-027 (структурно ловит «код
|
||
без тестов»). Это требование, не новый машинный гейт.
|
||
|
||
### FR-5 — Эскалация в полный цикл (BR-5)
|
||
- Багфикс-задача должна иметь путь возврата в полный цикл, если баг оказался сложным/архитектурным
|
||
или визуальным (нужен макет — связка ORCH-12/14, прецедент ET-9). Минимум v1: ручная эскалация
|
||
(оператор снимает метку `Bug` / переводит стадию) **и/или** решение мини-аналитика «баг сложный →
|
||
не фаст-трекать» (тогда задача идёт штатным маршрутом с `architecture`). Конкретный механизм и
|
||
его автоматизация — архитектору; v1 не обязан включать LLM-авто-триаж сложности.
|
||
|
||
### FR-6 — Fail-safe → полный цикл (BR-6, NFR-3)
|
||
- При `bug_fast_track_enabled=False`, неприменимом репо, ошибке/таймауте/неоднозначности чтения
|
||
метки (`has_label` → False / `None`-labels), отсутствии метки `Bug` в проекте — задача идёт
|
||
**полным** циклом (точка входа `analysis`, маршрут с `architecture`). never-raise: ошибка логики
|
||
не роняет `start_pipeline`/вебхук.
|
||
- **Совместимость с `check_analysis_complete`** (требует наличие `01/02/03/04`): при облегчённом
|
||
пакете багфикса гейт не должен ложно блокировать. Варианты (архитектору): мини-аналитик всё равно
|
||
эмитит заглушки `02/03` ИЛИ гейт `check_analysis_approved` на багфикс-треке учитывает облегчённый
|
||
набор. Требование: **не ослабить** проверку для не-баг задач и **не заблокировать ложно** баг.
|
||
|
||
### FR-7 — Наблюдаемость стоимости (BR-7)
|
||
- Факт «задача на багфикс-треке» и метрика экономии видны: (а) аддитивный блок `bug_fast_track` в
|
||
`GET /queue` (флаг/область + счётчик задач на треке + агрегат сэкономленных стадий/agent-runs);
|
||
(б) лог-строка на решение о маршруте; (в) опц. отметка в Telegram-карточке. Метрика «во сколько
|
||
дешевле» считается из существующей телеметрии `agent_runs` (Σ токены/время багфикс-трека vs
|
||
средний полный цикл) — без новой тяжёлой инфраструктуры.
|
||
|
||
---
|
||
|
||
## 4. Изменения API
|
||
|
||
### 4.1. Новые публичные endpoint'ы
|
||
- **Не требуются обязательно.** (Эскалация и классификация идут через Plane-метки/статусы, не через
|
||
новый HTTP-эндпоинт. Если архитектор вводит админ-эндпоинт принудительной (де)классификации —
|
||
описать в ADR и обновить таблицу API в README.)
|
||
|
||
### 4.2. Изменяемые endpoint'ы
|
||
- `GET /queue` — **аддитивно** добавляется блок `bug_fast_track` (read-only, never-raise) по образцу
|
||
блоков `serial_gate` / `auto_labels` / `coverage`: `enabled`, `repos`, `label`, перечень/счётчик
|
||
задач на багфикс-треке, агрегатная метрика экономии. Существующие ключи `GET /queue` не меняются.
|
||
|
||
### 4.3. Webhook-обработчики
|
||
- `start_pipeline` (`webhooks/plane.py`): добавляется ветвление «issue имеет метку `Bug` и
|
||
`applies(repo)` → багфикс-трек (пометить задачу / задать укороченный вход-маршрут)». Внешний
|
||
контракт вебхука Plane не меняется.
|
||
|
||
---
|
||
|
||
## 5. Изменения схемы БД
|
||
> Только **аддитивные, идемпотентные** миграции (общая прод-БД; enduro не трогать).
|
||
|
||
- **Опционально (выбор архитектора):** если тип задачи нужно знать после старта (для маршрутизации
|
||
в `advance_stage`/`get_next_stage` и для метрики), ввести аддитивную колонку
|
||
`tasks.track TEXT DEFAULT 'full'` (значения `full` | `bug`) через `_ensure_column` (паттерн
|
||
`tasks.cancelled_at` ORCH-090). Тогда горячий `claim_next_job` читает тип из БД, **не** из сети
|
||
(NFR-4). Альтернатива без колонки (вывести тип повторным чтением метки) допустима, но повторный
|
||
сетевой вызов в горячем пути запрещён (NFR-4) → колонка предпочтительнее.
|
||
- **Существующие** `tasks`-контракт (прочие колонки), `jobs`, `job_deps`, `agent_runs`,
|
||
`coverage_baseline`, `repo_freeze` — **без изменений**.
|
||
|
||
---
|
||
|
||
## 6. Требования к новым/изменённым QG checks
|
||
- **Новых QG-проверок не вводить; ни один `check_*` не менять семантически** (NFR-1). Маршрутизация
|
||
багфикса — свойство планировщика/точки входа, **не** Quality Gate.
|
||
- Единственная допустимая тонкая правка — обеспечить, чтобы exit-гейт стадии `analysis`
|
||
(`check_analysis_approved` / helper `check_analysis_complete`) **не блокировал ложно** облегчённый
|
||
багфикс-пакет, **не ослабляя** проверку для полного цикла (FR-6). Если для этого требуется правка
|
||
`check_*` — она должна сохранить вердикт-семантику для не-баг задач байт-в-байт.
|
||
|
||
---
|
||
|
||
## 7. Совместимость / регресс
|
||
- **Kill-switch** `bug_fast_track_enabled` (env `ORCH_BUG_FAST_TRACK_ENABLED`); `False` → точка входа
|
||
и маршрут строго прежние (`analysis → architecture → …`), нулевая регрессия (NFR-2).
|
||
- **Область репо** `bug_fast_track_repos` (CSV; пусто → рекомендуется self-hosting + явно
|
||
разрешённые проекты, где есть метка `Bug` — решение об области по умолчанию фиксирует архитектор).
|
||
- **`applies(repo)` первым** (локально, без сети) → выключенный флаг = нулевой сетевой оверхед,
|
||
enduro не затронут.
|
||
- **Композиция (NFR-7):** не конфликтует с serial-gate (ORCH-088: багфикс-задача — обычная задача
|
||
репо, учитывается в serial-очереди), auto-label (ORCH-089: `autoApprove`/`autoDeploy` работают и
|
||
на багфикс-треке), coverage-gate (ORCH-027: союзник BR-4), merge-gate (ORCH-043).
|
||
- **never-raise / fail-safe** (NFR-3): ошибка классификации/маршрута → полный цикл, не падение.
|
||
- **Self-hosting** (NFR-6): механизм не рестартит/не роняет прод, не пушит/force-push в `main`.
|
||
- **Маркеры трассировки** (CLAUDE.md §9): новые инварианты помечаются `ORCH-019`; правка
|
||
маркированного кода (ORCH-088/089/027) — со сверкой их `06-adr/`.
|
||
|
||
---
|
||
|
||
## 8. Артефакты pipeline (создать/обновить в ТОМ ЖЕ PR)
|
||
- `docs/work-items/ORCH-019/06-adr/ADR-001-<slug>.md` — решение (механизм маршрута, хранение типа,
|
||
совместимость с `check_analysis_complete`, область по умолчанию, механизм эскалации).
|
||
- `docs/architecture/README.md` — новый раздел «Багфикс-трек (ORCH-019)» + блок `bug_fast_track` в
|
||
описании `GET /queue`; при новой колонке — раздел «База данных».
|
||
- `CLAUDE.md` — краткий абзац о багфикс-режиме (правила для агентов / конвейер).
|
||
- `CHANGELOG.md` — запись `feat:`.
|
||
- `.openclaw/agents/analyst.md` / `reviewer.md` — облегчённый пакет багфикса + reviewer-ось
|
||
регресс-теста (канон 52d не нарушать).
|
||
- При новой колонке — `docs/work-items/ORCH-019/08-data-requirements.md` (заполняет архитектор).
|
||
|
||
---
|
||
|
||
## 9. Открытые вопросы для архитектора (не блокируют анализ)
|
||
- OQ-1: Механизм пропуска `architecture` — условный `get_next_stage(stage, task)`, bug-mode-флаг на
|
||
task, или прямой вход багфикса сразу в `development` с сохранённым мини-bug-report? (Влияет на
|
||
§3 `stages.py`/`stage_engine.py` и на `check_analysis_complete`.)
|
||
- OQ-2: Хранить ли тип задачи в БД (`tasks.track`) vs выводить из метки. Рекоменд. — колонка
|
||
(NFR-4 запрещает сеть в горячем claim).
|
||
- OQ-3: Сохранять ли мини-стадию `analysis(lite)` (рекоменд., ради регресс-теста и трассируемости)
|
||
или допустить чистый hotfix `→ development` (вне дефолта). См. BRD §6.
|
||
- OQ-4: Механизм эскалации (BR-5) — только ручной (снять метку/сменить стадию) или авто-сигнал
|
||
мини-аналитика «баг сложный → полный цикл».
|
||
- OQ-5: Область по умолчанию (пустой CSV) — self-hosting only vs все репо с меткой `Bug`.
|
||
- OQ-6: Совместимость с `check_analysis_approved`/`check_analysis_complete` на облегчённом пакете
|
||
(FR-6) — заглушки `02/03` vs условный учёт гейтом.
|
||
</content>
|