Files
orchestrator/docs/work-items/ORCH-120/01-brd.md
claude-bot 432da2c4ed
All checks were successful
CI / test (push) Successful in 1m13s
analyst(ET): auto-commit from analyst run_id=777
2026-06-17 12:45:52 +03:00

172 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
work_item: ORCH-120
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-17
model_used: claude-opus-4-8
escalate: full-cycle
---
# 01 — BRD (бизнес-требования): ORCH-120 — Открытые вопросы аналитика должны переводить задачу в Needs Input
Work Item: **ORCH-120** · Repo: **orchestrator** · Стадия: analysis
> ⚠️ **Эскалация в полный цикл (`escalate: full-cycle`).** Это формально баг (метка `BUG:` в
> заголовке), но фикс требует архитектурных решений (правило приоритета веток в
> `_handle_analysis_approved_flow`, интеграция с осью «пауза» ORCH-124, семантика устаревания
> `01-questions.md`, стандартизация нового pipeline-артефакта) — нужен ADR. Поэтому выпущен
> **полный** analysis-пакет (01/02/03/04), а не облегчённый bug-shaped. Оператор снимает багфикс-трек
> командой `POST /bug-fast-track/escalate?work_item=ORCH-120`, после чего задача идёт через стадию
> `architecture` (ADR-001 D5 ORCH-019). Открытые проектные вопросы для архитектора — §6 (DQ-1…DQ-4).
## 1. Бизнес-контекст и проблема
При запуске конвейера аналитик (`analyst`) получает бизнес-запрос и **обязан** выпустить 4 файла
(`01-brd` / `02-trz` / `03-acceptance-criteria` / `04-test-plan.yaml`), иначе exit-гейт стадии
`analysis` не пройдёт. Если бизнес-запрос неоднозначен или неполон (классический пример — тело
запроса `Description: TBD`), у аналитика **нет рабочего канала** запросить уточнения у заказчика: он
вынужден **домысливать** требования и всё равно сдать 4 файла. Сфабрикованный пакет уходит в
`In Review` / `architecture` — то есть весь конвейер строит решение поверх выдуманных требований.
**Парадокс:** механизм «вопросы → Needs Input» в движке **уже есть, но мёртв**. Код
`src/stage_engine.py::_handle_analysis_approved_flow` (стр. 769786) читает файл
`docs/work-items/<wid>/01-questions.md` и при его наличии вызывает `set_issue_needs_input(...)` +
комментарий в Plane + Telegram. Однако:
1. **Контракт не доведён до аналитика.** Промпт `.openclaw/agents/analyst.md` **нигде** не упоминает
`01-questions.md`: ни в `<deliverables>`, ни в `<task>`. Скелета `docs/_templates/01-questions.md`
нет, в манифесте `docs/_standards/PIPELINE_DOCS.md` артефакт не описан. Аналитик физически не
знает, что у него есть канал «задать блокирующий вопрос», поэтому домысливает.
2. **Ошибка приоритета веток.** В `_handle_analysis_approved_flow` ветка `files_ok` (все 4 файла на
месте — `check_analysis_complete`) проверяется **первой** и делает `return` (стр. 711767). Ветка
`01-questions.md` (стр. 769) достижима, только если 4 файла НЕ полны. Значит, если аналитик сдал и
неполный/заглушечный пакет, и `01-questions.md` — движок уйдёт в `In Review`, проигнорировав
блокирующие вопросы. «Есть вопросы» должно иметь приоритет над «файлы на месте».
3. **Needs-Input блокирует serial-gate репо.** Задача в Needs Input остаётся в стадии `analysis`
(Plane-статус — слой B индикации, ORCH-066, **не** меняет `tasks.stage`) и при этом
`paused_at IS NULL`. По правилу serial-gate (ORCH-088) такая «активная» задача держит FIFO репо
закрытым: пока заказчик не ответит (часы/дни), ни одна следующая задача `orchestrator` не войдёт в
`analysis`. ORCH-124 ввёл ортогональную ось «пауза» (`tasks.paused_at` + `POST /serial-gate/pause|
resume`) ровно для случая «приостановлено, но не блокирует» — Needs-Input обязан её использовать.
4. **Нет гигиены устаревшего `01-questions.md`.** После ответа заказчика `handle_status_start`
перезапускает аналитика (`src/webhooks/plane.py:317381`). Если перезапущенный аналитик теперь
выпускает полный валидный пакет, старый `01-questions.md` остаётся в ветке. Без правила
«устаревания» он либо игнорируется (если `files_ok` побеждает), либо вечно перезапускает Needs
Input (если вопросы получат приоритет). Нужно явное правило supersede.
Корень — **разрыв контракта между промптом аналитика и движком** плюс **3 смежных дефекта потока**
(приоритет, блокировка очереди, устаревание). ORCH-120 закрывает их как единый «правильный поток
Needs Input».
**Связь с предшественниками (контекст резюма из бэклога):** задача разморожена после корневых
фиксов **ORCH-124** (ось «пауза без блокировки» — необходимый фундамент для требования BR-3) и
**ORCH-126** (queued-job не застревает со stale `run_id`/`pid` — гарантирует, что перезапущенный
после ответа аналитик-job реально заберётся из очереди). Оба — предусловия, а не объём ORCH-120.
## 2. Объём (scope)
### В объёме
- **Контракт промпта аналитика:** `.openclaw/agents/analyst.md` явно документирует канал
«блокирующие открытые вопросы → пиши `01-questions.md`, НЕ фабрикуй 4 deliverables», с форматом и
правилом поведения на перезапуске (прочитать ответы, снять устаревшие вопросы).
- **Канон артефакта:** скелет `docs/_templates/01-questions.md` + строка в манифесте
`docs/_standards/PIPELINE_DOCS.md` (артефакт-сигнал Needs Input; **не** machine-verdict-док, гейтом
не парсится).
- **Приоритет веток в движке:** в `_handle_analysis_approved_flow` блокирующие открытые вопросы
получают корректный приоритет → задача с вопросами надёжно достигает Needs Input.
- **Неблокирование serial-gate:** переход в Needs Input не держит FIFO репо закрытым неопределённо
долго (интеграция с осью «пауза» ORCH-124).
- **Гигиена устаревания:** перезапущенный аналитик, выпустивший полный валидный пакет без свежих
вопросов, приводит к `In Review`, а не к повторному Needs Input.
- **Корректность resume-петли:** ответ заказчика → перезапуск аналитика → снятие паузы (unpark), job
забирается из очереди.
- **Обязательный регресс-тест** (красный до фикса, зелёный после) + анти-дрейф структурные тесты.
### Вне объёма
- **Расширение владения Needs Input на других агентов.** ORCH-066 BR-10 фиксирует: Needs Input —
только у аналитика. Механизм не расширяется на architect/developer/reviewer/tester/deployer.
- **Новые QG-проверки и новые рёбра `STAGE_TRANSITIONS`.** Поток вопросов — pre-gate-ветка движка,
не Quality Gate. `check_analysis_complete`/`check_analysis_approved` — байт-в-байт.
- **Изменение семантики самого гейта `analysis`** (4 файла по-прежнему обязательны для прохождения
exit-гейта `analysis → architecture`).
- **Авто-ответ на вопросы / LLM-триаж ответов заказчика.** Ответы читает человек/аналитик, а не
отдельный автомат.
- **Машинерия багфикс-трека (ORCH-019)** и любые изменения вне аналитической стадии.
## 3. Заинтересованные стороны
- **Заказчик / оператор (Слава)** — получает осмысленный запрос уточнений вместо выдуманных
требований; отвечает в Plane и возвращает задачу в работу.
- **Конвейер `orchestrator` (self-hosting)** — перестаёт строить решения поверх домыслов; serial-gate
репо не клинит на задаче, ждущей человека.
- **Аналитик-агент** — получает легитимный канал «не знаю — спрошу» вместо принуждения к фабрикации.
- **Другие проекты на общем инстансе (enduro-trails)** — не затронуты (нулевая регрессия при
отсутствии `01-questions.md` и вне self-hosting-области).
## 4. Бизнес-требования (BR)
- **BR-1** — Аналитик, столкнувшийся с **блокирующей** неоднозначностью бизнес-запроса, ОБЯЗАН иметь
документированный канал запроса уточнений (`01-questions.md`) и НЕ должен фабриковать 4 deliverables
«лишь бы пройти гейт». Промпт `.openclaw/agents/analyst.md` описывает этот канал.
- **BR-2** — Наличие блокирующих открытых вопросов переводит задачу в Plane-статус **Needs Input** и
**останавливает** продвижение по конвейеру (не `In Review`, не `architecture`), даже если на диске
присутствуют частичные/заглушечные deliverables. Приоритет «вопросы» > «файлы на месте».
- **BR-3** — Задача в Needs Input **не блокирует** per-repo serial-gate FIFO неопределённо долго:
следующая задача `orchestrator` может войти в `analysis`, пока первая ждёт ответа человека.
- **BR-4** — После ответа заказчика (возврат issue в рабочий статус) аналитик перезапускается, читает
ответы и выпускает пакет. Если пакет полон и валиден и свежих блокирующих вопросов нет → задача
переходит в `In Review` (устаревший `01-questions.md` не должен повторно ронять её в Needs Input).
- **BR-5** — Поведение **обратимо и выборочно**: при отсутствии `01-questions.md` и выключенных
под-флагах поток Needs Input/паузы — байт-в-байт как до ORCH-120 (нулевая регрессия для enduro и
для штатной задачи без вопросов).
- **BR-6** — `01-questions.md` стандартизирован как pipeline-артефакт (скелет в `docs/_templates/` +
строка манифеста `PIPELINE_DOCS.md`): он сигнальный, **не** machine-verdict (гейтом не парсится).
## 5. Нефункциональные требования (NFR)
- **NFR-1 (never-raise / fail-safe)** — Любая ошибка новой логики (чтение файла, park-вызов,
определение приоритета) НЕ роняет `advance_stage`/launcher и деградирует к безопасному прежнему
поведению (как существующие leaf'ы `serial_gate`/`labels`/`cancel`).
- **NFR-2 (обратная совместимость)** — Стадии, кроме `analysis`, и Needs-Input-владение (ORCH-066) —
не трогаются. `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / machine-verdict-ключи / семантика
exit-гейта `analysis` — байт-в-байт.
- **NFR-3 (инварианты serial-gate)** — Интеграция с паузой не регрессирует ORCH-088 (анти-stale-base:
отложенный срез ветки) и ORCH-124 (терминал `{done,cancelled}` и оси `task_deps`/`freeze`
не читают `paused_at`; пауза их не обходит).
- **NFR-4 (self-hosting-безопасность)** — Поток только меняет Plane-статус/паузу/комментарий и читает
worktree: не деплоит, не рестартит прод-контейнер, не пушит в `main`, не трогает detached-процессы.
- **NFR-5 (наблюдаемость)** — Переход в Needs Input и park/unpark логируются структурно; состояние
паузы видно в блоке `serial_gate` `GET /queue` (ORCH-124 уже отдаёт `paused`).
## 6. Допущения и ограничения
- **Допущение:** механизм чтения `01-questions.md` и `set_issue_needs_input` рабочие — задача в
основном **активирует и достраивает** существующий путь, а не строит его с нуля.
- **Допущение:** промпт `cat`-ается из worktree в момент запуска (ORCH-077 loading-model) → новый
контракт аналитика вступает в силу на следующем worktree от `main` без прод-рестарта.
- **Ограничение:** Plane-статус **Needs Input** должен существовать на доске проекта (ключ
`needs_input` уже в `plane_sync._DEFAULT_STATES`) — инфра-предусловие выполнено для ORCH.
- **Открытые проектные вопросы для архитектора (решить в `06-adr/`, НЕ в analysis):**
- **DQ-1** — Парковать задачу при Needs Input **автоматически** (`db.set_task_paused` в момент
перехода) или оставить park **операторским** (`POST /serial-gate/pause`)? Trade-off:
авто-park снимает риск стопора очереди (BR-3), но связывает индикацию (слой B) с осью планировщика.
- **DQ-2** — Механизм устаревания `01-questions.md` (BR-4): удалять файл при выпуске полного пакета /
приоритет по «вопросы свежее deliverables» (mtime/commit) / явный маркер «answered». Любой выбор
обязан быть детерминированным и не зависеть от сетевого Plane.
- **DQ-3** — Точное правило приоритета в `_handle_analysis_approved_flow`: проверять
`01-questions.md` ДО `files_ok`, либо ввести предикат «вопросы активны» с учётом DQ-2.
- **DQ-4** — Коллизия номера `01-questions.md` с `01-brd.md`. Движок читает именно `01-questions.md`
(`stage_engine.py:771`) — менять путь = код-изменение; стандарт документирует фактический путь.
- **Ограничение по флагам:** новое поведение (приоритет вопросов / авто-park) — под kill-switch с
безопасным дефолтом, чтобы откат был байт-в-байт (BR-5).
## 7. Критерии успеха
Аналитик при блокирующей неоднозначности пишет `01-questions.md`, задача надёжно переходит в Needs
Input, **не** блокирует serial-gate репо, после ответа заказчика возобновляется и выпускает корректный
пакет; при отсутствии вопросов — поведение прежнее. Детальные PASS/FAIL — `03-acceptance-criteria.md`.
## 8. Риски
- Связывание индикации (Plane-статус) с осью планировщика (пауза) при авто-park (DQ-1) — риск
непреднамеренного park; смягчение — kill-switch + явный лог.
- Устаревший `01-questions.md` зацикливает Needs Input (DQ-2) — смягчение детерминированным
supersede-правилом + регресс-тест BR-4.
- Регресс serial-gate (ORCH-088/124) при неаккуратной интеграции паузы — смягчение тестами NFR-3.
Детали и оценка — `10-tech-risks.md` (заполняет архитектор).