architect(ET): auto-commit from architect run_id=778
All checks were successful
CI / test (push) Successful in 1m13s

This commit is contained in:
2026-06-17 12:55:28 +03:00
parent 432da2c4ed
commit 1fcbe06df5
4 changed files with 397 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
---
work_item: ORCH-120
stage: architecture
author_agent: architect
status: proposed
created_at: 2026-06-17
model_used: claude-opus-4-8
---
# ADR-0053: Поток «открытые вопросы аналитика → Needs Input» (приоритет + пауза + resume)
Сквозной (cross-cutting) ADR. Детальное решение задачи —
`docs/work-items/ORCH-120/06-adr/ADR-001-analyst-open-questions-needs-input.md`.
Статус: **Proposed** · Дата: 2026-06-17 · Источник: **ORCH-120** (bug → escalate full-cycle)
## Контекст
Конвейер обязывает аналитика выпустить 4 файла (`01-brd`/`02-trz`/`03-acceptance-criteria`/
`04-test-plan.yaml`), иначе exit-гейт `analysis` не пройдёт. При неоднозначном бизнес-запросе
(классика — `Description: TBD`) у аналитика нет рабочего канала уточнения → он **фабрикует**
требования. Механизм «вопросы → Needs Input» в `_handle_analysis_approved_flow`
(`src/stage_engine.py`) **существует, но мёртв** из-за четырёх смежных дефектов: контракт не
доведён до промпта; ветка `files_ok` имеет приоритет над веткой вопросов; Needs Input клинит
serial-gate репо (ORCH-088); нет гигиены устаревшего `01-questions.md`.
Поток пересекает несколько подсистем, поэтому фиксируется сквозным ADR (анти-археология ORCH-078:
блок `_handle_analysis_approved_flow` несёт 3+ маркера — ORCH-066/088/089/124):
- **ORCH-066** — Needs Input принадлежит **только** аналитику (слой B индикации ≠ слой A стадий).
- **ORCH-088** — per-repo serial-gate: «активная задача» по `tasks.stage NOT IN ('done','cancelled')`.
- **ORCH-124** (adr-0051) — ортогональная ось «пауза» (`tasks.paused_at`): исключает задачу из
«активного» предиката, **не** обходя оси `task_deps`/`repo_freeze`/терминал.
- **ORCH-089** — autoApprove (человеческий BRD-гейт по лейблу) в той же ветке `files_ok`.
## Решение
**Активировать мёртвый путь четырьмя согласованными изменениями** — аддитивно, под kill-switch,
скоуп self-hosting, never-raise:
1. **Контракт промпта + канон артефакта.** `.openclaw/agents/analyst.md` документирует канал
«блокирующие вопросы → `01-questions.md`, НЕ фабриковать deliverables»; `01-questions.md`
стандартизирован как **сигнальный** when-applicable артефакт (скелет `docs/_templates/` +
строка манифеста `PIPELINE_DOCS.md`) — **не** machine-verdict (гейтом не парсится, BR-6).
2. **Приоритет «вопросы активны» > «файлы готовы».** В `_handle_analysis_approved_flow` предикат
активных вопросов проверяется **до** ветки `files_ok` → блокирующие вопросы надёжно достигают
Needs Input даже при частичных/сфабрикованных deliverables.
3. **Авто-park через ось «пауза» ORCH-124.** Переход в Needs Input вызывает `db.set_task_paused`
→ задача исключается из «активного» предиката serial-gate → следующая задача репо входит в
`analysis`, пока первая ждёт человека (не клинит FIFO неопределённо долго).
4. **Resume + unpark.** `handle_status_start` (analysis-resume) снимает паузу (`clear_task_paused`)
и перезапускает аналитика; relaunch-guard ORCH-090 (только `analysis`) не ослаблен.
**Устаревание `01-questions.md` (детерминированно, offline):** freshness-gated supersede по mtime —
вопросы «активны», пока пакет неполон ИЛИ `01-questions.md` не старше всех 4 deliverables; полный
свежий пакет supersedeит старый файл (выбор механизма и отвергнутые альтернативы — ADR-001 DQ-2).
## Инварианты (нормативно)
- **Поток — pre-gate-ветка движка, НЕ Quality Gate.** `STAGE_TRANSITIONS` / реестр и имена
`QG_CHECKS` / семантика `check_analysis_complete`/`check_analysis_approved` / machine-verdict-ключи
/ схемы существующих таблиц — **байт-в-байт не тронуты**.
- **Без схемы БД:** переиспользуется `tasks.paused_at` (ORCH-124); новых таблиц/колонок нет.
- **ORCH-066 не расширяется:** Needs Input остаётся **только** у аналитика.
- **ORCH-124 не регрессирует:** пауза ортогональна — оси `task_deps`/`repo_freeze`/терминал
`{done,cancelled}` `paused_at` **не читают**; анти-stale-base ORCH-088 цел (нормальная задача
`paused_at IS NULL` держит гейт; свежесть базы на resume — существующими механизмами).
- **Self-hosting-безопасность:** поток только меняет Plane-статус/паузу/коммент и читает worktree —
не деплоит, не рестартит прод-контейнер, не пушит в `main`, не трогает detached-процессы.
- **never-raise / обратимость:** все врезки изолированы и деградируют к прежнему поведению;
3 флага (`analyst_questions_gate_enabled` / `analyst_questions_gate_repos` /
`analyst_needs_input_autopause_enabled`) с безопасными дефолтами → off/out-of-scope = байт-в-байт
как до ORCH-120 (enduro не затронут).
## Последствия
Конвейер перестаёт строить решения поверх домыслов; serial-gate не клинит на задаче, ждущей
человека (поддержка автономного пакетного прогона ORCH-088); аналитик получает легитимный канал
уточнения. Цена — узкое связывание индикации с осью планировщика при авто-park (смягчено флагом +
узким триггером + never-raise) и зависимость supersede от mtime (смягчено: полный прогон всегда
пишет свежие deliverables + контракт промпта). Детали, альтернативы и риски —
`docs/work-items/ORCH-120/06-adr/ADR-001-analyst-open-questions-needs-input.md`,
`docs/work-items/ORCH-120/10-tech-risks.md`.