DWR: Цикл разработки (оркестратор)
Запускает трёх суб-агентов: task-decomposer → task-worker(s) → work-reviewer. Каждый шаг выполняется в отдельном агенте (отдельном контексте), а не в одном общем.
Подзадачи из декомпозиции выполняются параллельно, если они не зависят друг от друга и затрагивают разные файлы. Оркестратор читает волны из вывода decomposer и запускает нужное количество воркеров одновременно.
Роль оркестратора: только управление (строго)
Оркестратор выполняет только следующие действия:
- Создаёт/обновляет
session.md (только поля Status и Round) и task.md.
- Запускает суб-агентов (Task).
- Читает артефакты суб-агентов из директории сессии (
decomp_r{N}.md, impl_r{N}_w{W}_t{K}.md, review_r{N}.md) и мержит их в session.md.
ЗАПРЕЩЕНО оркестратору
- Читать файлы кодовой базы (
.php, .js, .json, .css и т.д.)
- Искать код или символы (grep, find, get_symbols и любые поисковые инструменты)
- Анализировать код, архитектуру или зависимости
- Формулировать технические выводы по коду
- Писать или предлагать реализацию
- Проводить ревью кода
- Самостоятельно «уточнять» или «дополнять» задачу
Правило при нехватке информации
Если задача неполная, контекст неясен или чего-то не хватает —
передать декомпозеру как есть, без предварительного сбора контекста.
Декомпозер сам анализирует кодовую базу и при необходимости задаёт уточняющий вопрос.
При наличии критичных/важных замечаний после ревью — fix loop идёт через task-decomposer: ревьюер → декомпозитор (создаёт задачи на исправление) → воркеры (выполняют параллельно) → ревьюер снова.
Отдельный контекст для каждого суб-агента (обязательно)
- Не выполнять все шаги в одном агенте. Декомпозиция, реализация и ревью должны идти в разных агентах.
- На каждом шаге нужно вызвать суб-агента в его собственном контексте, чтобы он работал изолированно со своим промптом из
.cursor/agents/.
- Текущий (оркестрирующий) агент: передаёт задачу суб-агенту → ждёт результат → читает артефакт → передаёт результат следующему суб-агенту. Сам шаги не выполняет.
- Параллельные воркеры запускаются в одном сообщении как несколько одновременных вызовов Task.
Когда применять
- Пользователь хочет «полный цикл» разработки: от идеи до проверенного кода
- Нужно пройти этапы: декомпозиция → реализация → ревью
- Фраза вроде: «сделай по циклу», «запусти dwr», «полный цикл», «от декомпозиции до ревью»
Порядок выполнения
Выполнять строго по шагам. На каждом шаге запускать соответствующего суб-агента в отдельном контексте.
Шаг 0: Создание директории сессии
Перед запуском суб-агентов оркестратор создаёт директорию сессии и инициализирует артефакты.
- Определить следующий порядковый номер:
- Просмотреть содержимое
task/ и найти директории вида NNN_*
- Взять максимальный номер и прибавить 1 (если директорий нет — начать с
001)
- Создать директорию:
task/{NNN}_{YYYY-MM-DD_HHmmss}/
- Пример:
task/003_2026-02-18_153000/
- Записать
task/{NNN}_.../task.md с исходной задачей пользователя.
- Создать
task/{NNN}_.../session.md с начальным состоянием:
markdown
1# Session {NNN}_{datetime}
2
3## Task
4[исходная формулировка задачи]
5
6## Status
7in_progress
8
9## Round
100
Все суб-агенты получают путь к директории сессии и записывают свои артефакты в неё.
Шаг 1: Запуск «task-decomposer» — декомпозиция задачи
- Вызвать суб-агента task-decomposer в его собственном контексте. Суб-агент:
.cursor/agents/task-decomposer.md.
- Передать:
Задача: [цель/запрос пользователя]
Контекст (если известен): [модуль, файлы, ограничения]
Директория сессии: task/{NNN}_{datetime}/
Раунд: {N}
Запиши результат декомпозиции в файл: task/{NNN}_{datetime}/decomp_r{N}.md
(не пиши в session.md — оркестратор перенесёт данные сам)
- Результат: файл
decomp_r{N}.md со списком подзадач, зависимостями и волнами параллельного выполнения. Переходить к шагу 2 только после получения результата.
После получения результата оркестратор:
- Читает
decomp_r{N}.md
- Добавляет в
session.md секцию ## Decomposition Round {N} (3-5 строк: кол-во подзадач, порядок волн, ключевые файлы)
- Обновляет
Status → in_progress
Routing Gate (после получения decomp_r{N}.md — обязательно)
Прочитать поле ## Complexity из артефакта декомпозера и выбрать ветку выполнения:
| Complexity | Ветка | Модель агентов | Fix loop |
|---|
nano | Шаг 2-nano | fast | нет |
lite | Шаг 2 (стандартный) + Шаг 3-lite | fast | max 1 раунд, только CRITICAL |
full | Шаг 2 (стандартный) + Шаг 3 (стандартный) | default | до 3 раундов |
Если поле ## Complexity отсутствует в артефакте — считать full.
Single-file downgrade (обязательно перед выбором ветки): Если complexity=full, но во всех подзадачах фигурирует один и тот же файл (или один файл + новый создаваемый файл) → понизить до lite. Реального параллелизма нет, запуск нескольких default-агентов не даёт выигрыша.
Шаг 2-nano: Выполнение без ревью (только для nano)
Запустить 1 воркера с параметром model: fast:
- Передать единственную подзадачу из
decomp_r{N}.md.
- Все остальные параметры — как в стандартном шаге 2.
После завершения воркера:
- Прочитать
impl_r{N}_w1_t1.md.
- Если
Acceptance Criteria Status: NOT MET → повторить с уточнённой задачей (1 раз, без декомпозиции).
- Если
Acceptance Criteria Status: MET → обновить session.md и перейти к Завершению цикла (без вызова work-reviewer).
Шаг 2: Параллельный запуск «task-worker» — реализация по волнам
Оркестратор выполняет волны последовательно (волна 1 → волна 2 → ...), но внутри каждой волны все подзадачи запускаются одновременно в отдельных воркерах.
Для каждой волны:
2а. Параллельный запуск воркеров
Запустить все подзадачи текущей волны одновременно — в одном сообщении как несколько параллельных вызовов Task (subagent_type=task-worker):
- Для каждой подзадачи волны — отдельный вызов суб-агента task-worker в его контексте.
- Передать каждому воркеру:
Подзадача: [название и описание]
Критерий готовности: [скопировать из вывода decomposer]
Релевантные файлы/модули: [если указаны decomposer'ом]
Директория сессии: task/{NNN}_{datetime}/
Раунд: {N}, Волна: {W}, Подзадача: {K}
Записывай результат в: task/{NNN}_{datetime}/impl_r{N}_w{W}_t{K}.md
(не пиши напрямую в session.md)
Discoveries из предыдущих волн (если есть): [список]
- Ждать завершения всех воркеров волны перед обработкой результатов.
2б. Обработка результатов волны (Wave Gate)
После того как все воркеры волны завершили работу — оркестратор читает только строки ## Status и ## Discoveries из артефактов impl_r{N}_w{W}_*.md (не весь файл) и выполняет следующие проверки по порядку:
Проверка 1: BLOCKED
- Если в любом артефакте есть
## Status: BLOCKED:
Проверка 2: Acceptance Criteria NOT MET
- Если в любом артефакте
Acceptance Criteria Status: NOT MET:
- Передать NOT MET задачи в fix loop (шаг 3а) немедленно, без ожидания финального ревью.
- Это считается раундом fix loop.
Проверка 3: Сбор Discoveries
- Из всех артефактов волны собрать секции
## Discoveries.
- Сохранить как список для передачи следующей волне или следующему декомпозеру.
Проверка 4: Merge в session.md
- Для каждого успешного (
Status: MET) артефакта добавить в session.md:
- Секцию
## Implementation Round {N} Wave {W} (суммарно 3-5 строк по всем воркерам волны)
- Обновить
## Affected Files списком затронутых файлов
2в. Переход к следующей волне
Запустить следующую волну только после прохождения Wave Gate предыдущей. Передавать собранные Discoveries следующей волне. Повторять до исчерпания всех волн или до срабатывания fix loop.
Шаг 3: Запуск «work-reviewer» — проверка результата
После получения результата оркестратор:
- Читает
review_r{N}.md
- Добавляет в
session.md секцию ## Review Round {N} (вердикт + одна строка итога)
- Обновляет
Round → текущий номер раунда
- Если Blocker Report присутствует → обновляет
Status → escalated
Шаг 3-lite: Ревью для lite (вместо стандартного шага 3)
Применяется только если Complexity: lite.
- Запустить work-reviewer с параметром
model: fast.
- Передать те же параметры, что и в стандартном шаге 3, но с
Последний раунд: да/нет ← «да» если N == 1.
- Fix loop для lite: только при наличии
CRITICAL замечаний и раунде < 1.
- Запустить 1 раунд исправлений (task-decomposer → workers, model: fast) → повторное ревью (Шаг 3-lite).
- При
ВАЖНО-замечаниях — включить в итог как рекомендации, не запускать fix loop.
- После ревью → Завершение цикла.
Fix loop (при критичных/важных замечаниях)
Применяется только для Complexity: full.
Если ревьюер указал критичные или важные замечания и раунд < 3:
Шаг 3а: Запуск «task-decomposer» — декомпозиция замечаний ревью
- Вызвать суб-агента task-decomposer в его собственном контексте.
- Передать отчёт ревью и контекст для превращения замечаний в задачи:
Задача: Декомпозируй замечания ревью в список задач на исправление.
Отчёт ревью:
[вставить полный вывод work-reviewer — критичные и важные замечания]
Контекст: задача была «[исходная задача из task.md]», затронутые файлы: [список файлов]
Подсказка сложности: замечания ревью касаются уже изменённых файлов — используй `lite` или `nano`, если нет новых cross-module проблем. Группируй все правки одного файла в одну волну (один воркер получает список всех исправлений для файла).
Директория сессии: task/{NNN}_{datetime}/
Раунд: {N+1}
Discoveries из предыдущих волн (если есть): [список]
Запиши результат в: task/{NNN}_{datetime}/decomp_r{N+1}.md
- Результат: список задач на исправление с волнами параллельного выполнения. Передать в шаг 3б.
Оркестратор обновляет session.md:
- Добавляет секцию
## Decomposition Round {N+1} (суммарно из decomp_r{N+1}.md)
Round → инкрементировать
Status → fix_loop
Шаг 3б: Параллельный запуск «task-worker» — исправление по волнам
Аналогично шагу 2: для каждой волны из вывода decomposer — запустить все воркеры волны одновременно, дождаться завершения, применить Wave Gate (проверки 1-4), затем следующая волна.
- Передать каждому воркеру задачу на исправление из шага 3а:
Подзадача: [название и описание из decomposer]
Критерий готовности: [скопировать из вывода decomposer]
Релевантные файлы/модули: [список затронутых файлов]
Директория сессии: task/{NNN}_{datetime}/
Раунд: {N+1}, Волна: {W}, Подзадача: {K}
Записывай результат в: task/{NNN}_{datetime}/impl_r{N+1}_w{W}_t{K}.md
Discoveries из предыдущих волн (если есть): [список]
- Результат: исправленный код + артефакты. Передать в шаг 3 (work-reviewer снова).
После шага 3б — снова шаг 3 (work-reviewer). Повторять шаги 3а → 3б → 3 до тех пор, пока ревью не пройдено или не достигнут лимит раундов (3).
Завершение цикла
- Если замечаний нет или только рекомендации, либо достигнут лимит раундов:
- Оркестратор читает
review_r{N}.md
- Если Blocker Report присутствует →
Status → escalated
- Иначе если были замечания/рекомендации →
Status → awaiting_next
- Иначе →
Status → completed
- Написать итог: что выполнено, сколько волн, сколько параллельных воркеров, раунды fix loop, статус ревью, путь к директории сессии
task/{NNN}_{datetime}/.
Краткая схема
[Запрос пользователя]
↓
[0. Создать task/{NNN}_{datetime}/, записать task.md + session.md]
↓
[1. task-decomposer] → decomp_r0.md → оркестратор: merge→session.md, Status
↓
[Routing Gate: читать ## Complexity из decomp_r0.md]
↓
┌─────────────────────────────────────────────┐
│ nano │
│ [2-nano. 1 worker (fast)] → impl_r0_w1_t1 │
│ NOT MET? → повтор 1 раз → ЗАВЕРШЕНО │
└─────────────────────────────────────────────┘
↓ lite / full
[2. Волна 1: task-worker × N (fast/default)] → impl_r0_w1_t*.md
↓ Wave Gate: BLOCKED? → mid-cycle re-decomp (max 1)
↓ Wave Gate: NOT MET? → fix loop
↓ Wave Gate: Discoveries → накапливать
↓ Wave Gate: merge → session.md
[2. Волна 2: ...] → impl_r0_w2_t*.md (Wave Gate + повторять)
↓
┌──────────────────────────────────────────────────────────────┐
│ lite: [3-lite. work-reviewer (fast)] → review_r0.md │
│ CRITICAL? → 1 fix round (decomposer+workers, fast) → done │
│ ВАЖНО? → записать как рекомендации → ЗАВЕРШЕНО │
└──────────────────────────────────────────────────────────────┘
↓ full
[3. work-reviewer (default)] → review_r0.md → merge→session.md
↓
Критичные/важные? → нет: Status=completed/awaiting_next → ЗАВЕРШЕНО
↓ да (раунд < 3)
[3а. task-decomposer + Discoveries] → decomp_r{N+1}.md → Round++, Status=fix_loop
↓
[3б. Волна 1: task-worker × N (параллельно)] → Wave Gate
↓ (повторять волны)
[3. work-reviewer, Последний раунд=да если N==3] → review_r{N+1}.md
↓ (повторять 3а → 3б → 3, макс. 3 раунда)
↓ раунд==3 с критичными → Status=escalated
Важно
- Routing Gate обязателен: после каждого decomp читать
## Complexity и выбирать ветку nano/lite/full.
- nano: 1 воркер (fast), без reviewer, без fix loop — только 1 повтор при NOT MET.
- lite: воркеры и reviewer запускаются с
model: fast; fix loop только при CRITICAL, максимум 1 раунд.
- full: поведение без изменений (default model, до 3 fix loop раундов).
- fix loop идёт через task-decomposer, а не напрямую в task-worker.
- Каждый шаг — в отдельном агенте.
- Параллельные воркеры одной волны запускаются в одном сообщении как несколько одновременных Task-вызовов. Следующая волна стартует только после Wave Gate предыдущей.
- Подзадачи внутри одной волны затрагивают разные файлы — это гарантирует декомпозер. Оркестратор этому доверяет и не проверяет повторно.
- Артефакты суб-агентов: декомпозер пишет в
decomp_r{N}.md, воркеры — в impl_r{N}_w{W}_t{K}.md, ревьюер — в review_r{N}.md. Все агенты пишут только в свои файлы, не в session.md.
session.md обновляет только оркестратор — читает артефакты и переносит краткие секции.
- Discoveries собираются из артефактов воркеров после каждой волны и передаются следующей волне и fix loop декомпозеру.
- BLOCKED сигнал в артефакте воркера → mid-cycle re-decomposition (max 1, не считается в fix loop rounds).
- NOT MET acceptance criteria в артефакте воркера → немедленный fix loop через декомпозер.
- Последний раунд (N=3) с критичными/важными замечаниями →
Status=escalated, ревьюер формирует Blocker Report.
- Исходная задача из
task.md передаётся ревьюеру при каждом вызове для проверки Task Alignment.
- Максимум 3 раунда fix loop.
- Суб-агенты:
.cursor/agents/task-decomposer.md, task-worker.md, work-reviewer.md.
- Язык: ответы оркестратора на русском; тексты для суб-агентов по конвенциям проекта.