11 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-120 | analysis | analyst | ready-for-review | 2026-06-17 | claude-opus-4-8 |
02 — ТЗ (TRZ): ORCH-120 — Открытые вопросы аналитика → Needs Input
Work Item: ORCH-120 · Repo: orchestrator · Стадия: analysis
ТЗ описывает конкретные изменения к реализации, выведенные из BRD и фактического кода. Архитектурное обоснование (выбор механизма приоритета, авто-park vs operator-park, способ устаревания
01-questions.md) — задача архитектора (06-adr/). Открытые проектные вопросы — BRD §6 (DQ-1…DQ-4).
1. Сводка изменения
Активировать и достроить уже существующий, но мёртвый путь «аналитик задаёт блокирующие вопросы →
задача в Needs Input». Четыре связанных изменения: (1) контракт промпта аналитика +
канон артефакта 01-questions.md; (2) приоритет ветки вопросов над веткой «файлы готовы» в
_handle_analysis_approved_flow; (3) неблокирование serial-gate через ось «пауза» ORCH-124;
(4) гигиена устаревания 01-questions.md на resume-петле. STAGE_TRANSITIONS, реестр QG_CHECKS,
семантика и имена check_*, machine-verdict-ключи, схема существующих таблиц — не меняются.
2. Задействованные модули / пути
| Путь | Действие |
|---|---|
.openclaw/agents/analyst.md |
изменить — добавить контракт «блокирующие вопросы → 01-questions.md, не фабриковать deliverables» (в <task> + <deliverables> + поведение на resume); сохранить канон 52d (5 секций, 6 полей frontmatter). |
docs/_templates/01-questions.md |
создать — скелет артефакта открытых вопросов (формат: контекст / список блокирующих вопросов с вариантами / что разблокирует анализ). |
docs/_standards/PIPELINE_DOCS.md |
изменить — строка манифеста §2 для 01-questions.md (владелец analyst, категория when-applicable, стадия analysis, «механизм: ветка Needs Input в _handle_analysis_approved_flow», machine-key — «нет, сигнальный»). |
src/stage_engine.py |
изменить — _handle_analysis_approved_flow: правило приоритета (вопросы активны → Needs Input до/вместо files_ok, см. DQ-3); опц. вызов park (DQ-1); гигиена устаревания (DQ-2). Всё never-raise. |
src/webhooks/plane.py |
изменить (точечно) — handle_status_start (analysis-resume ветка, стр. 317–381): при перезапуске аналитика снять паузу (clear_task_paused/POST эквивалент), чтобы re-enqueued job был claimable. |
src/db.py |
переиспользовать — set_task_paused / clear_task_paused / is_task_paused (ORCH-124, уже есть; новых колонок НЕ вводить). |
src/serial_gate.py |
не менять кодом — ось «пауза» уже исключает paused_at NOT NULL (ORCH-124); ORCH-120 лишь корректно её триггерит. |
src/config.py |
изменить — добавить kill-switch(и) нового поведения (напр. analyst_questions_gate_enabled, опц. analyst_needs_input_autopause_enabled), env ORCH_*, безопасные дефолты. |
src/main.py |
возможно — наблюдаемость в блоке GET /queue (если потребуется доп. поле); pause/resume эндпоинты ORCH-124 переиспользуются как есть. |
Точный набор правок в
src/**финализирует архитектор (DQ-1…DQ-3). TRZ фиксирует наблюдаемый контракт, а не конкретную реализацию ветвления.
3. Функциональные требования
FR-1 — Контракт промпта аналитика (BR-1, BR-6)
.openclaw/agents/analyst.md явно описывает: при блокирующей неоднозначности бизнес-запроса
аналитик пишет docs/work-items/<plane-id>/01-questions.md (через Write tool) со списком конкретных
блокирующих вопросов и не выпускает сфабрикованные 4 deliverables. Указывается поведение на
перезапуске: прочитать свежие комментарии-ответы в Plane, снять/не переписывать устаревшие вопросы,
выпустить полный пакет. Промпт остаётся в каноне 52d (5 секций, 6 полей schema, без model:).
FR-2 — Приоритет «вопросы активны» (BR-2)
В _handle_analysis_approved_flow наличие активных блокирующих вопросов (01-questions.md,
с учётом supersede-правила DQ-2) ведёт к set_issue_needs_input(...) + комментарий + Telegram +
result.note = "analysis-needs-input" независимо от того, присутствуют ли на диске 4 файла.
Сейчас ветка files_ok (стр. 711) делает return до проверки вопросов (стр. 769) — порядок/предикат
исправляется так, что вопросы имеют приоритет. Happy-path (нет вопросов, 4 файла) → In Review
(analysis-in-review) без изменений.
FR-3 — Неблокирование serial-gate (BR-3, NFR-3)
Переход в Needs Input приводит к тому, что задача исключается из «активного» предиката serial-gate
(ORCH-088), чтобы следующая задача orchestrator могла войти в analysis. Механизм — ось «пауза»
ORCH-124: paused_at NOT NULL уже исключается в build_claim_clause/repo_has_active_task/
_per_repo_snapshot. Авто-park vs operator-park — DQ-1. Терминал {done,cancelled} и оси
task_deps/freeze не читают paused_at — пауза их не обходит (инвариант ORCH-124 цел).
FR-4 — Resume + unpark (BR-4)
handle_status_start (analysis-ветка) при перезапуске аналитика после ответа заказчика снимает паузу
(clear_task_paused), чтобы re-enqueued analyst-job был claimable (совместно с фиксом ORCH-126 о
stale run_id/pid). Существующий relaunch-guard ORCH-090 (relaunch только для analysis) — не
ослабляется.
FR-5 — Гигиена устаревания 01-questions.md (BR-4)
Перезапущенный аналитик, выпустивший полный валидный пакет (4 файла) без свежих блокирующих
вопросов, приводит к In Review, а не к повторному Needs Input. Реализация supersede — DQ-2
(детерминированно, offline, без сетевого Plane).
FR-6 — Обратимость / kill-switch (BR-5)
Новое поведение под kill-switch с безопасным дефолтом: при отсутствии 01-questions.md и выключенном
под-флаге поток Needs Input/паузы — байт-в-байт как до ORCH-120. Скоуп — self-hosting
(orchestrator); enduro не затронут.
4. Изменения API
Нет новых эндпоинтов. Переиспользуются существующие POST /serial-gate/pause и
POST /serial-gate/resume (ORCH-124, src/main.py:396/442) как операторский путь park/unpark (если
архитектор выберет operator-park, DQ-1). При авто-park вызывается db.set_task_paused напрямую из
движка. Блок serial_gate в GET /queue уже отдаёт paused — возможно дополнение полем-причиной.
5. Изменения схемы БД
Нет. Колонка tasks.paused_at уже введена ORCH-124 (src/db.py:160, _ensure_column). Новых
таблиц/колонок/индексов ORCH-120 не вводит.
6. Требования к новым/изменённым QG checks
Нет. 01-questions.md — сигнальный артефакт, не machine-verdict-док; гейтом не парсится.
check_analysis_complete / check_analysis_approved / _parse_* — байт-в-байт. Поток вопросов
остаётся pre-gate-веткой движка (_handle_analysis_approved_flow), как и был.
7. Совместимость / регресс
- Обратная совместимость: при отсутствии
01-questions.mdветвление_handle_analysis_approved_flowи serial-gate работают как прежде (NFR-2). Стадии ≠analysis— не трогаются. - Kill-switch: новое поведение (приоритет вопросов / авто-park) выключаемо → откат байт-в-байт
(FR-6/BR-5). Область — self-hosting
orchestrator. - Инварианты: ORCH-066 (Needs Input только у аналитика) — не расширяется; ORCH-088/124 (анти-stale-base,
терминал/freeze/deps оси) — не регрессируют (NFR-3); never-raise (NFR-1); self-hosting-безопасность
(NFR-4: без прод-рестарта/
main-push). - Полный регресс
pytest tests/остаётся зелёным; обязательный новый регресс-тест (TC-01) красный до фикса и зелёный после. - Трассировка маркеров (ORCH-078): правки в
_handle_analysis_approved_flow/serial_gate/plane.pyсверяются с ADR ORCH-066 / ORCH-088 / ORCH-124 перед изменением (не сломать инварианты).