13 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-119 | analysis | analyst | ready-for-review | 2026-06-17 | claude-opus-4-8 |
01 — BRD / Bug-report: ORCH-119 — 00-business-request.md всегда TBD, теряется source-backed контекст запроса
Work Item: ORCH-119 · Repo: orchestrator · Стадия: analysis · Трек: Bug (укороченный маршрут, пропуск стадии architecture)
🐞 Багфикс-трек (ORCH-019). Облегчённый пакет (bug-report + обязательный регресс-тест), но все 4 файла analysis (гейт
check_analysis_completeне меняется). Экономия — в пропуске стадииarchitecture, не в числе файлов.Эскалация в full-cycle рассмотрена и отклонена. Дефект — контейнерный data-flow + рендеринг, чинится точным зеркалированием уже существующего прецедента
tasks.title(персист при создании задачи → чтение в_materialize_deferred_branch). Нет нового компонента, нового QG, политического решения или визуального артефакта → ADR/макет не требуется. Если разработчик в ходе фикса упрётся в архитектурное решение (напр. иной механизм персиста, влияющий на схему/контракты) — снять трек:POST /bug-fast-track/escalate?work_item=ORCH-119и пометить здесьescalate: full-cycle.
1. Бизнес-контекст и проблема
Симптом (наблюдаемое)
Для каждой созданной задачи файл docs/work-items/<id>/00-business-request.md генерируется
с телом раздела «Description» равным буквальному TBD. Реальный текст запроса (описание Plane-issue,
обогащённое из Plane API) не попадает в персистентный артефакт. Пример — сам этот work item:
# Business Request: BUG: 00-business-request.md is always TBD, losing source-backed request context
Work Item ID: ORCH-119
## Description
TBD
Последствие (бизнес-боль)
00-business-request.md — точка входа конвейера и источник для analyst (вход стадии analysis,
см. PIPELINE_DOCS.md §2). Когда тело всегда TBD:
- source-backed контекст запроса теряется из durable-артефакта репозитория (остаётся только эфемерно
в
task_contentanalyst-job'а и в Plane); - последующее чтение work item «глазами» (reviewer, человек, ретроспектива, петля уроков) видит пустой бизнес-запрос — невозможно сверить, ту ли задачу решал конвейер;
- на self-hosting (
orchestrator) задача почти всегда идёт отложенным срезом ветки (serial gate, ORCH-088), где контекст теряется безвозвратно (см. §3, причина B).
Причина симптома (установленный факт, по коду)
src/webhooks/plane.py::_create_initial_docs (строка ~925) хардкодит тело:
content = f"# Business Request: {name}\n\nWork Item ID: {work_item_id}\n\n## Description\n\nTBD\n"
Функция принимает только (repo, branch, work_item_id, name) — description ей не передаётся,
хотя у вызывающего start_pipeline оно есть в области видимости и уже используется для analyst-job
(task_desc, строка ~725: Description:\n{description}). То есть данные есть, но в артефакт не
доходят.
Локализация (куда смотреть разработчику) — два пути создания
Путь A — прямой (serial_gate не применим к репо):
start_pipeline (src/webhooks/plane.py) имеет description (строки ~518; обогащается из Plane API,
~539–551) → зовёт _create_initial_docs(repo, branch, work_item_id, name) (строка ~710) без
description. Достаточно дотянуть аргумент.
Путь B — отложенный (критичный для self-hosting) (serial_gate_applies(repo) → для orchestrator):
start_pipeline не создаёт ветку/доки (ORCH-088, анти-stale-base); срез релоцирован в
src/agents/launcher.py::_materialize_deferred_branch (строки ~514–538), который вызывает то же
_create_initial_docs, располагая только title из строки tasks (description нигде не
персистится). Установленный факт схемы: таблица tasks не имеет колонки description; title
персистится через _ensure_column (src/db.py:125) и читается в _spawn/_materialize_deferred_branch
именно так. ⇒ Чтобы путь B рендерил описание, description надо сохранить durable при создании
задачи (зеркало tasks.title).
Предусловие истинности данных (установленный факт)
QG-0 (_qg0_errors, src/webhooks/plane.py:490) отклоняет создание при description короче 20
символов (строка ~500). ⇒ любая задача, дошедшая до _create_initial_docs, гарантированно имеет
непустое осмысленное описание — терять его тем более недопустимо. Защитный fallback на случай
пустого описания всё равно предусмотреть (NFR-2).
2. Объём (scope)
В объёме
- Рендер фактического
description(предпочтительноdescription_stripped, plain-text) в раздел «Description» файла00-business-request.md— на обоих путях (A прямой, B отложенный). - Durable-персист
descriptionпри создании задачи (зеркалоtasks.title), чтобы путь B имел доступ к нему на момент claim. - Защитный fallback при отсутствии/пустом описании (без падения).
- Обязательный регресс-тест (красный до фикса, зелёный после).
Вне объёма
- Изменение
STAGE_TRANSITIONS/QG_CHECKS/check_*/ machine-verdict-ключей / семантики гейтов. - Изменение поведения serial-gate / отложенного среза ветки ORCH-088 (только дополнить данными, не менять момент/условие среза).
- Ретро-генерация
00-business-request.mdдля уже существующих задач (только новые создания). - Переформатирование/обогащение структуры самого
00-business-request.mdсверх вставки описания (заголовки/название источника остаются как есть). - Любая запись в Plane (артефакт пишется только в Gitea-ветку, как сейчас).
3. Заинтересованные стороны
- Заказчик/оператор — получает читаемый durable бизнес-запрос вместо
TBD. - Агент analyst и reviewer — могут сверять решённое с запросом по репозиторию.
- Петля уроков / ретроспектива (ORCH-098) — корректный контекст в артефакте.
- Приёмку результата выполняет конвейер (reviewer + Quality Gates), не аналитик.
4. Бизнес-требования (BR)
- BR-1 — Раздел «Description» в
00-business-request.mdсодержит фактический текст запроса (из Plane-issue, как он используется для analyst-job'а), а не литералTBD, для вновь создаваемых задач. - BR-2 — Поведение одинаково на обоих путях создания: прямом (A) и отложенном срезе ветки (B,
self-hosting/serial-gate). Путь B — приоритетный сценарий (доминирует на
orchestrator). - BR-3 — При отсутствующем/пустом описании артефакт создаётся с явным безопасным fallback- маркером (напр. «описание отсутствует в источнике»), без падения создания задачи.
- BR-4 — Сохранён состав/имена артефактов: создаётся ровно
00-business-request.mdпо тому же пути; downstream-конвейер (analyst и далее) не затронут.
5. Нефункциональные требования (NFR)
- NFR-1 (обратная совместимость / never-break) — изменение аддитивно: создание задачи никогда
не должно падать из-за нового рендера/персиста. Любая ошибка обогащения → деградация на безопасное
значение (fallback-маркер), а не отказ создания. Идемпотентность
_create_initial_docs(422 = уже существует → no-op) сохранена. - NFR-2 (целостность данных) — описание рендерится как есть (plain-text
description_stripped), без обрезки/искажения; многострочный текст сохраняется.00-business-request.md— информационный док (гейтом не парсится), поэтому markdown-спецсимволы в описании безопасны для гейтов. - NFR-3 (инварианты ORCH-088) — момент и условие отложенного среза ветки не меняются; описание
лишь дополнительно переносится через durable-хранилище (зеркало
tasks.title), анти-stale-base логика цела. - NFR-4 (self-hosting-безопасность) — фикс не деплоит/не рестартит прод, не трогает
main, не добавляет сетевых вызовов в горячийclaim_next_job.
6. Допущения и ограничения
description/description_strippedдоступны вstart_pipelineи достаточны как источник (уже используются для analyst-job). Plane-обогащение (ORCH «name_missing/desc_missing» блок) остаётся единственным источником описания — новых сетевых обращений не вводим.- QG-0 гарантирует ≥20 символов описания для прошедших задач (см. §1) — нормальный путь всегда имеет реальный текст.
- Персист описания следует установленному прецеденту
tasks.title(аддитивная колонка через_ensure_column); это не новое архитектурное решение.
7. Критерии успеха
Новые задачи получают 00-business-request.md с реальным описанием на обоих путях; обязательный
регресс-тест красный до фикса и зелёный после; полный pytest tests/ -q зелёный. Детальные PASS/FAIL
— 03-acceptance-criteria.md.
8. Риски
- Путь B забыт (чинят только прямой путь A) → на self-hosting баг остаётся. Митигируется обязательным integration-тестом пути B (TC-03).
- Регресс схемы/создания задачи при добавлении персиста → митигируется аддитивным
_ensure_columnи тестом обратной совместимости (TC-05). Детальные тех-риски архитектором не выпускаются (bug-track).