diff --git a/memory/2026-06-06.md b/memory/2026-06-06.md new file mode 100644 index 0000000..568ddb0 --- /dev/null +++ b/memory/2026-06-06.md @@ -0,0 +1,15 @@ +# 2026-06-06 + +## ORCH-46 запущен конвейером (вариант A) — 04:06 UTC +- Слава выбрал **вариант A** («вклеить findings», минимальный), велел сделать **автономно** (вести до конца как ORCH-47, дёргать только если упрётся в его решение). +- ТЗ: `tasks/orchestrator/DEV_TASK_ORCH-046.md` (3 варианта дизайна, выбран A). Описание варианта A залито в Plane ORCH-46 (заголовок укорочен 120→77 символов под QG-0). +- **Суть A:** в `src/stage_engine.py` встраивать ТЕКСТ замечаний в task_desc деву (не только ссылку): + - reviewer REQUEST_CHANGES (~стр.419): парсить `## Findings` из 12-review.md → вынуть P0/P1 дословно + - tester FAIL (~стр.455): вынуть reason + фрагмент 13-test-report.md + - новый хелпер-парсер (graceful, never raise, fallback на ссылку) +- НЕ трогать: гейты check_* (ORCH-45/47), QG-реестр, retry/rollback-логику, webhook-пути. +- **task 37**, ветка `feature/ORCH-046-stage-engine-pass-reviewer-tes`, analyst run 139. +- **ПЛАН (автономно):** дать конвейеру пройти analyst→arch→dev→review→testing→deploy-staging. + - Это правка ЯДРА → следить внимательнее. На BRD-апруве задача встанет ждать Approved Славы (by design) — НЕ забыть, что на BRD нужен человек. + - Возможные затыки: (1) BRD-апрув ждёт Славу; (2) staging B6 isolation FAIL (как у ORCH-47 — не блокер кода, но даст FAILED на deploy-staging); (3) если петля dev↔review — теперь должна быть короче, т.к. фикс про передачу findings. + - Финал: ручной merge + ребилд прода (build образа + рестарт + claude-auth check) — по накатанному из LESSONS_2026-06-05.md. diff --git a/tasks/orchestrator/DEV_TASK_ORCH-046.md b/tasks/orchestrator/DEV_TASK_ORCH-046.md new file mode 100644 index 0000000..a19ddeb --- /dev/null +++ b/tasks/orchestrator/DEV_TASK_ORCH-046.md @@ -0,0 +1,97 @@ +# ТЗ / черновик ADR — ORCH-46: «Испорченный телефон» при заворотах агентам + +> Статус: **ЧЕРНОВИК на согласование Славе.** Перед запуском конвейером Слава выбирает +> вариант дизайна (см. §3) и подтверждает scope. ORCH-46 лезет в **ядро** (`stage_engine.py`), +> поэтому ADR обязателен. + +## 1. Проблема (факты из кода, проверено 06.06) + +Когда задачу возвращают на доработку, орк формирует деву `task_desc` (→ `.task-dev.md`), и в +нём — **только ссылка на файл, без сути замечаний**. Дословно из `src/stage_engine.py`: + +- **Reviewer REQUEST_CHANGES** (стр. ~419): + `"...Note: REQUEST_CHANGES from reviewer (attempt N/3). Fix findings in docs/work-items//12-review.md"` +- **Tester FAIL** (стр. ~455): + `"...Note: Tests FAILED. Fix failures described in docs/work-items//13-test-report.md"` + +Три корневые беды (ровно они убивали автономность ORCH-17): + +1. **Испорченный телефон.** Деву дают ссылку «иди читай файл», а не текст претензий. Ключевую + мысль (напр. governance: «не трогай shared-гейт») легко проскочить. +2. **Противоречивые сигналы.** Tester шлёт «Tests FAILED, чини тесты» (толкает лезть в тест-код + → в т.ч. в shared-гейт), reviewer шлёт «не трогай gate». Два противоположных приказа в разных + кругах, дев видит только последний. +3. **Нет памяти между кругами.** Каждый developer-запуск — чистый агент (`agent_runs` лишь + считает количество). Дев не знает, на чём уже погорел в прошлых кругах → повторяет ошибку. + +## 2. Что есть для решения (разведано) + +- **`12-review.md`** содержит структурированный блок `## Findings` с уровнями + `### P0 — Blocker / P1 — Must fix / P2 — Should fix / P3 — Nice-to-have` + frontmatter + `verdict:`. → findings машиночитаемы, можно извлечь P0/P1/P2. +- **`13-test-report.md`** содержит frontmatter `result:`/`verdict:`/`status:` + тело с описанием + падений. → можно извлечь причину FAIL. +- **`agent_runs`** (БД) — по `task_id`+`agent` считаются круги; туда же можно писать краткий + «след» каждого заворота (что требовалось, к какому агенту относилось). +- Передача в агента: `enqueue_job(agent, repo, task_desc, task_id)` → launcher пишет `task_desc` + в `.task-dev.md`. Менять формат `task_desc` достаточно, чтобы донести больше. + +## 3. ВАРИАНТЫ ДИЗАЙНА (выбрать один — решение Славы) + +### Вариант A — «Вклеить findings» (минимальный, низкий риск) ⭐ рекомендую как старт +- В `task_desc` при заворотах **встраивать ТЕКСТ замечаний**, а не только ссылку. + - Reviewer: распарсить `## Findings` из `12-review.md`, вынуть P0/P1 (must-fix) дословно в + `task_desc`. Ссылку на файл оставить как «полный контекст». + - Tester: вынуть причину FAIL (reason + ключевые строки тела `13-test-report.md`). +- Плюсы: бьёт прямо в беду №1 (испорченный телефон), правка локальная (формирование строки + + парсер-хелпер), легко тестируется. Минусы: не решает №2/№3 полностью. + +### Вариант B — A + «память кругов» (средний) +- Всё из A, плюс: в `agent_runs` (или отдельную мини-таблицу `dev_round_notes`) писать краткий + след каждого заворота: круг N, агент-источник (reviewer/tester), суть требования. При новом + запуске дева вклеивать в `task_desc` блок «История прошлых кругов: на чём уже погорел / чего + НЕ делать». Бьёт по беде №3. +- Плюсы: дев перестаёт повторять ошибки. Минусы: миграция БД/новая таблица, чуть сложнее. + +### Вариант C — A + B + «склейка противоречий» (полный, выше риск) +- Всё из A+B, плюс: если в истории есть конфликт сигналов (reviewer «не трогай X» vs tester + «почини тесты, связанные с X»), орк **склеивает** их в одно непротиворечивое ТЗ с явным + приоритетом (governance reviewer > tester по умолчанию; правило вынести в конфиг/ADR). +- Плюсы: убивает все три беды. Минусы: эвристика склейки сложна, риск ложной логики, больше + тестов, заметнее правка ядра. + +> **Моя рекомендация:** делать **A сейчас** (быстрая большая отдача, низкий риск ядра), B и C — +> отдельными инкрементами после обкатки A на реальных заворотах. Но финальное слово — за Славой. + +## 4. Scope (для выбранного варианта — заполнить после решения) +- Файлы: `src/stage_engine.py` (формирование task_desc в 2-3 ветках), новый хелпер-парсер + (напр. `src/review_parse.py`: `extract_review_findings(path) -> str`, + `extract_test_failures(path) -> str`), тесты, ADR, CHANGELOG. +- (Вариант B/C доп.: миграция БД / `src/db.py`.) +- **НЕ трогать:** сами гейты `check_*` (ORCH-45/47 уже в проде), QG-реестр, сигнатуры + публичных функций, webhook-пути (заворот идёт launcher-путём, finished_agent задан). + +## 5. Acceptance Criteria (вариант A) +- AC-1: при reviewer REQUEST_CHANGES `.task-dev.md` содержит ДОСЛОВНЫЙ текст P0/P1 findings из + `12-review.md` (не только ссылку). +- AC-2: при tester FAIL `.task-dev.md` содержит причину падения (reason + релевантный фрагмент + `13-test-report.md`). +- AC-3: ссылка на полный файл сохранена как доп. контекст. +- AC-4: парсер устойчив к отсутствию/битому файлу (graceful: fallback на старую ссылку-строку, + никогда не падает — по образцу `_parse_tests_verdict`, который «never raise»). +- AC-5: существующие тесты `stage_engine`/`test_qg` зелёные; добавлены юнит-тесты парсера + (findings есть / пусто / битый YAML / только P3). +- AC-6: retry-счётчик и rollback-логика НЕ изменены по поведению. + +## 6. Команды проверки +- В контейнере: `python -m pytest tests/test_qg.py tests/test_stage_engine*.py -q`. +- Ручной снапшот task_desc: смоделировать заворот и проверить содержимое `.task-dev.md`. + +## 7. Грабли (из опыта 05.06 — обязательно учесть) +- Запуск через конвейер: заголовок задачи ≤80 символов (QG-0), иначе Blocked. +- Деплой после мержа: `/app` запечён в образ → нужен `docker compose build orchestrator` + + рестарт + проверка claude-auth (`HOME=/home/slin claude.exe --print`, timeout 90с). +- Gitea API: заголовок `Authorization: token `; heredoc через ssh+docker + глотает вывод → скрипт+base64+docker cp. +- Это правка ЯДРА (stage_engine) — на staging обязателен честный прогон; помнить про B6/ORCH-48 + (staging-реестр пока видит прод-проекты — не блокер, но при E2E учитывать).