# BRD — ORCH-046: pass reviewer/tester findings text to developer (not just link)

Work Item ID: ORCH-046
Stage: analysis
Author: analyst
Date: 2026-06-06

## 1. Контекст и проблема

Оркестратор при заворотах задачи деву (откат на `development`) формирует
описание задачи (`task_desc`), которое попадает в `.task-dev.md` запускаемого
агента-разработчика. Сейчас в двух ветках отката этот текст содержит **только
ссылку на файл-артефакт**, без сути замечаний:

- **Reviewer → REQUEST_CHANGES** (`src/stage_engine.py`, ветка
  `_handle_qg_failure_rollbacks`, ~стр. 419): `task_desc` =
  `"…Fix findings in docs/work-items/<id>/12-review.md"`.
- **Tester → FAIL** (`check_tests_passed`, ~стр. 455): `task_desc` =
  `"…Fix failures described in docs/work-items/<id>/13-test-report.md"`.

В результате developer-агент получает инструкцию «иди читай файл». Ключевые
претензии (P0/P1 у ревьюера, причина падения у тестера) часто проскакивают —
агент не открывает файл целиком или теряет фокус, повторяет ту же ошибку, и
задача снова заворачивается. Это «испорченный телефон»: расход циклов retry
(`MAX_DEVELOPER_RETRIES = 3`), деньги на токены, простой конвейера.

## 2. Бизнес-цель

Убрать «испорченный телефон» между reviewer/tester и developer при заворотах:
встраивать **дословный текст ключевых замечаний** прямо в `task_desc`, чтобы
developer-агент видел суть претензий сразу, а не только ссылку.

Это снижает число повторных заворотов и расход retry-бюджета на одну задачу.

## 3. Объём (вариант A — выбран Славой 06.06)

Минимальное, низкорисковое изменение **ядра** (`stage_engine`), которое:

1. Извлекает из `12-review.md` блок findings и выносит **must-fix (P0/P1)
   дословно** в `task_desc` при reviewer REQUEST_CHANGES.
2. Извлекает из `13-test-report.md` причину FAIL (reason из гейта + релевантный
   фрагмент тела отчёта) в `task_desc` при tester FAIL.
3. Во всех случаях **сохраняет ссылку на полный файл** как дополнительный
   контекст («полный контекст — см. файл»).
4. Извлечение выполняется новым отдельным хелпером-парсером
   (`src/review_parse.py`), который **никогда не бросает исключение**: при
   отсутствующем/битом файле возвращает пустой результат, и вызывающий код
   делает graceful fallback на прежнюю ссылку-строку.

## 4. Что НЕ входит в объём (out of scope)

- НЕ трогать гейты `check_*` (в т. ч. ORCH-45 `check_ci_green`,
  ORCH-47 `_parse_tests_verdict`) — они в проде, поведение неизменно.
- НЕ трогать реестр `QG_CHECKS`.
- НЕ менять сигнатуры публичных функций (`advance_stage`, `_run_qg`,
  `check_*`).
- НЕ менять webhook-пути.
- НЕ менять retry-счётчик (`_developer_retry_count`, `MAX_DEVELOPER_RETRIES`)
  и rollback-логику (последовательность `update_task_stage` →
  `notify_stage_change` → `plane_notify_stage` → enqueue) — поведение
  идентично.
- НЕ менять формат Plane-комментариев (`build_status_comment`).

## 5. Заинтересованные стороны

- **Owner (Слава)** — заказчик, выбрал вариант A.
- **Developer-агенты** — потребители `task_desc`: получают суть замечаний.
- **Конвейер всех проектов** (self-hosting) — выигрывает за счёт меньшего
  числа заворотов.

## 6. Ограничения и риски (self-hosting)

- Правка ядра `stage_engine` — компонент крутится в продакшене и обслуживает
  все проекты из общего инстанса/БД/очереди. Любая регрессия в формировании
  `task_desc` или (тем более) исключение в `advance_stage` останавливает
  конвейер всех проектов → **парсер обязан быть полностью graceful**.
- Обязателен прогон `deploy-staging` (8501) перед прод-деплоем.
- Это правка ядра → требуется ADR (per-work-item).

## 7. Критерий успеха (бизнес)

- При заворотах в `.task-dev.md` есть дословный текст ключевых замечаний
  (P0/P1 ревьюера; reason+фрагмент тестера) плюс ссылка на полный файл.
- Парсер устойчив к битым/отсутствующим артефактам (graceful fallback на
  старую ссылку-строку).
- Существующие тесты зелёные; поведение retry/rollback не изменилось.
