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

18 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used, escalate
work_item stage author_agent status created_at model_used escalate
ORCH-120 analysis analyst ready-for-review 2026-06-17 claude-opus-4-8 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-601-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 (заполняет архитектор).