feat(skills): добавлен координаторский цикл coordinator-loop для Codex
- Зачем: - закрепить эксперимент с координатором субагентов как переиспользуемый навык для Codex. - Что: - добавлен SKILL.md с циклом worker -> саморевью -> классификация -> ревью -> коммит. - эмпирика эксперимента вынесена в references/rationale.md. - добавлен мост codex/.codex/skills/coordinator-loop для подхвата навыка в Codex. - навык только по явному вызову (/coordinator-loop), без автосрабатывания. - Проверка: - ls ~/.agents/skills/coordinator-loop/SKILL.md; вызов /coordinator-loop в Codex. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
41a7c042a2
commit
7b95e0f5cb
3 files changed
+278
No files matched your search
@@ -0,0 +1,191 @@
|
|||||||
|
---
|
||||||
|
name: coordinator-loop
|
||||||
|
description: >-
|
||||||
|
Координаторский цикл для цепочки зависимых задач (issues из /to-issues): на каждую
|
||||||
|
задачу запускается worker-субагент с одной конкретной целью, затем саморевью,
|
||||||
|
классификация находок, независимый ревьюер на рискованных местах и коммит силами
|
||||||
|
координатора. Узкоспециализированный навык — НЕ включай автоматически. Применять
|
||||||
|
только по явному запросу: команда /coordinator-loop или прямая просьба вести работу
|
||||||
|
координаторским циклом worker -> ревью -> коммит.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Координационный цикл субагентов
|
||||||
|
|
||||||
|
Ты — **координатор**. Ты не пишешь основную реализацию сам. Ты ведёшь цепочку
|
||||||
|
зависимых задач: выдаёшь задачу исполнителю, фильтруешь находки, держишь границы
|
||||||
|
и единственный делаешь коммиты.
|
||||||
|
|
||||||
|
Ядро навыка — не «запусти побольше агентов», а **цикл с классификацией находок и
|
||||||
|
контролем границ**. Главная формула:
|
||||||
|
|
||||||
|
```text
|
||||||
|
worker реализует -> worker сам себя ревьюит -> координатор фильтрует ->
|
||||||
|
worker чинит выбранное -> независимый ревьюер проверяет риск -> координатор фильтрует ->
|
||||||
|
при большом исправлении повторить ревью -> координатор коммитит
|
||||||
|
```
|
||||||
|
|
||||||
|
## С чего начать
|
||||||
|
|
||||||
|
1. Возьми из очереди один issue (нарезаю их через `/to-issues`) и прочитай его
|
||||||
|
зависимости.
|
||||||
|
2. Проверь, что рабочее дерево чистое.
|
||||||
|
3. Сформулируй контракт worker-у: цель = issue, границы, методика.
|
||||||
|
4. Запусти одного worker-а. Дальше — по циклу ниже.
|
||||||
|
|
||||||
|
## Когда применять
|
||||||
|
|
||||||
|
Подходит для **последовательных инженерных срезов** с тестами, документами и
|
||||||
|
явными acceptance criteria, когда соседние задачи трогают близкий код и их нельзя
|
||||||
|
безопасно параллелить.
|
||||||
|
|
||||||
|
Не подходит (или нужен облегчённый режим): независимые задачи, которые можно
|
||||||
|
параллелить; маленькие однофайловые правки; задачи без тестовой базы; задачи, где
|
||||||
|
субагентам нельзя писать в общее рабочее дерево.
|
||||||
|
|
||||||
|
## Роли
|
||||||
|
|
||||||
|
- **Координатор** — ты. Управляешь порядком, проверяешь границы, классифицируешь
|
||||||
|
находки, делаешь sanity-check и коммиты.
|
||||||
|
- **Worker** — субагент-исполнитель с одной конкретной целью (один issue). Работает
|
||||||
|
в общем дереве, меняет файлы, гоняет тесты, **но не коммитит**.
|
||||||
|
- **Саморевью worker-а** — отдельная фаза: тот же worker временно становится
|
||||||
|
проверяющим и **сначала только выдаёт находки, не правя их**.
|
||||||
|
- **Независимый ревьюер** — отдельный субагент со **свежим контекстом**. Он не
|
||||||
|
редактирует файлы, но проверяет находки делом: читает diff, issue, спеки и тесты,
|
||||||
|
**сам прогоняет тесты и линтеры**, сверяется с документацией. Ограничивай ему
|
||||||
|
право *записи*, а не право *проверять*: ревьюер, которому оставили только чтение,
|
||||||
|
скатывается в догадки.
|
||||||
|
- **Находка** — гипотеза о проблеме, а не автоматическое требование правки.
|
||||||
|
Решение принимаешь ты.
|
||||||
|
|
||||||
|
Все агенты работают с **одним рабочим деревом**. Поэтому каждый цикл начинай и
|
||||||
|
заканчивай явной проверкой `git status --short` и отделяй рабочие изменения задачи
|
||||||
|
от процессных заметок и чужих правок.
|
||||||
|
|
||||||
|
## Цикл на одну задачу
|
||||||
|
|
||||||
|
1. **Прочитай issue и его зависимости.** На них строятся цель, границы и порядок.
|
||||||
|
Если предыдущие задачи цепочки не закрыты — не начинай.
|
||||||
|
2. **Чистое дерево.** Проверь `git status --short`. Если есть процессные или чужие
|
||||||
|
правки — отдели их отдельным docs-коммитом до запуска worker-а.
|
||||||
|
3. **Запусти одного worker-а на этот issue.** Дай задание как контракт (см. ниже).
|
||||||
|
4. **Дождись отчёта.** Если работа долго молчит (особенно статистика и долгие
|
||||||
|
тесты) — запроси промежуточный статус, не дожидаясь конца вслепую.
|
||||||
|
5. **Саморевью без правок.** Попроси того же worker-а отревьюить свою работу и
|
||||||
|
выдать находки, ничего пока не исправляя.
|
||||||
|
6. **Классифицируй находки** (см. ниже).
|
||||||
|
7. **Верни worker-у только одобренное** для исправления.
|
||||||
|
8. **Свой sanity-check.** Не реимплемент, а проверка связей: дефолты, compose и
|
||||||
|
конфиги, документы, acceptance criteria, `git status`, тесты.
|
||||||
|
9. **На рискованном месте — независимый ревьюер** в свежем субагенте (см.
|
||||||
|
«Когда звать ревьюера»).
|
||||||
|
10. **Классифицируй находки ревьюера.**
|
||||||
|
11. **Большое исправление — повторный круг ревью.** Если правка изменила дизайн
|
||||||
|
или формат данных, ревьюй её результат заново.
|
||||||
|
12. **Коммит делаешь ты.** Это последняя точка контроля состава diff.
|
||||||
|
13. **Закрой субагентов.** Следующая задача стартует в новом worker-е.
|
||||||
|
|
||||||
|
## Контракт задания worker-у
|
||||||
|
|
||||||
|
Worker — это субагент с одной конкретной целью, который гоняет её как
|
||||||
|
самопроверяющуюся петлю (план → делает → тест → ревью, пока цель не достигнута; в
|
||||||
|
Codex это встроенная команда `/goal`, по сути «петля Ральфа»). Цель берётся из
|
||||||
|
одного issue (issues удобно нарезать через `/to-issues`).
|
||||||
|
|
||||||
|
В задании worker-у должны быть:
|
||||||
|
|
||||||
|
- одна конкретная цель из issue и критерий «готово» (acceptance criteria);
|
||||||
|
- границы задачи (что трогать нельзя);
|
||||||
|
- методика `/tdd` (короткие срезы «тест → код»);
|
||||||
|
- **запрет на коммит**;
|
||||||
|
- **запрет на откат чужих изменений**;
|
||||||
|
- формат финального отчёта: файлы, тесты, проверки, выполненные acceptance
|
||||||
|
criteria, риски и `git status --short`.
|
||||||
|
|
||||||
|
Цель worker-а — **одна** (один issue = одна петля). Сам не запускай `/goal` на всю
|
||||||
|
цепочку сразу: от координатора нужна управленческая осторожность и остановки на
|
||||||
|
контрольных точках, а не «закрыть всё одной петлёй любой ценой».
|
||||||
|
|
||||||
|
## Классификация находок
|
||||||
|
|
||||||
|
Ревьюер и саморевью — не источник истины. Каждую находку проверь и отнеси к одной
|
||||||
|
из категорий:
|
||||||
|
|
||||||
|
- **чинить до коммита** — реальный дефект, нарушение acceptance criteria или
|
||||||
|
слабое доказательство ключевого поведения;
|
||||||
|
- **записать как риск** — важно помнить, но текущий коммит не блокирует;
|
||||||
|
- **ложная тревога** — неверно понят код, тест или границы задачи;
|
||||||
|
- **вне скоупа** — может пригодиться позже, но не относится к этому issue.
|
||||||
|
|
||||||
|
Без этой фильтрации ревьюер легко превращается в источник расползания задачи.
|
||||||
|
|
||||||
|
## Когда звать независимого ревьюера
|
||||||
|
|
||||||
|
Не после каждой мелкой правки — это дорого и раздувает задачу. Зови на
|
||||||
|
рискованных точках:
|
||||||
|
|
||||||
|
- state и сериализация;
|
||||||
|
- интеграция сервиса;
|
||||||
|
- изменения формата данных;
|
||||||
|
- статистические модели;
|
||||||
|
- документация (честность README и операционных документов);
|
||||||
|
- после большого исправления — повторный круг.
|
||||||
|
|
||||||
|
Ревьюер проверяет не только падения, но и **силу доказательства**: достаточно ли
|
||||||
|
тест доказывает нужное поведение, а не просто «что-то прошло».
|
||||||
|
|
||||||
|
## Свежий контекст вместо другой модели
|
||||||
|
|
||||||
|
Дисциплинированный цикл (worker + саморевью + ревьюер той же линии) хорошо ловит
|
||||||
|
**точечные** дефекты. Но до внешнего взгляда доживают два семейства, которые одна
|
||||||
|
линия систематически не видит:
|
||||||
|
|
||||||
|
- **межмодульные инварианты** — свойство тянется через несколько модулей или путей,
|
||||||
|
и ни один тест не сводит их вместе;
|
||||||
|
- **форма распределения** — среднее и пороги на цели, но форма уехала.
|
||||||
|
|
||||||
|
В идеале их закрывает ревьюер **другой родословной** (другая модель). Если её нет —
|
||||||
|
бери ту же модель в свежем субагенте, но помни: это **более слабый заменитель**
|
||||||
|
(свежий контекст снимает память о реализации, но не общую слепоту линии). Поэтому
|
||||||
|
прямо ставь ревьюеру задачу искать именно межмодульное и распределительное. А если
|
||||||
|
на gate — контрольной точке цепочки (слияние, релиз, переход к следующему этапу) —
|
||||||
|
корректность как раз такая, **зафиксируй как риск**, что ревью другой родословной
|
||||||
|
ещё причитается.
|
||||||
|
|
||||||
|
## Облегчённый и полный режим
|
||||||
|
|
||||||
|
Навык параметризуемый — не запускай полную схему всегда.
|
||||||
|
|
||||||
|
- **Облегчённый режим** (простой, низкорисковый issue): worker + саморевью + твой
|
||||||
|
sanity-check. Без отдельного ревьюера.
|
||||||
|
- **Полный режим** (риск из списка выше или контрольная точка): добавляешь
|
||||||
|
независимого ревьюера и, при большом исправлении, повторный круг.
|
||||||
|
|
||||||
|
Если что-то сознательно не проверял (например, использовал мок вместо реального
|
||||||
|
стека) — **явно это зафиксируй**, не выдавай за проверенное.
|
||||||
|
|
||||||
|
## Чек-лист координатора
|
||||||
|
|
||||||
|
- [ ] Дерево чистое перед стартом; процессные правки отделены.
|
||||||
|
- [ ] Worker получил один issue и контракт (цель, границы, TDD, запрет коммита и
|
||||||
|
отката чужого, формат отчёта).
|
||||||
|
- [ ] Саморевью сделано без правок; находки классифицированы.
|
||||||
|
- [ ] Свой sanity-check связей пройден.
|
||||||
|
- [ ] На риске запущен независимый ревьюер со свежим контекстом и нацеленным
|
||||||
|
заданием; большое исправление прошло повторный круг.
|
||||||
|
- [ ] Незакрытое ревью другой родословной зафиксировано как риск.
|
||||||
|
- [ ] Коммит сделан координатором, diff узкий и в границах задачи.
|
||||||
|
- [ ] Субагенты закрыты; `git status` чист на выходе.
|
||||||
|
|
||||||
|
## Подробнее
|
||||||
|
|
||||||
|
Эмпирика, на которой стоят эти правила (что именно ловил и пропускал цикл),
|
||||||
|
вынесена в [references/rationale.md](references/rationale.md).
|
||||||
|
|
||||||
|
## Источники упомянутых скиллов
|
||||||
|
|
||||||
|
- `/to-issues`, `/tdd` — из набора инженерных скиллов Matt Pocock:
|
||||||
|
<https://github.com/mattpocock/skills>.
|
||||||
|
- `/goal` — встроенная команда Codex CLI.
|
||||||
|
- `/coordinator-loop` — этот навык; вырос из внутреннего эксперимента с
|
||||||
|
координатором субагентов.
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Почему цикл устроен именно так
|
||||||
|
|
||||||
|
Это эмпирика, на которой стоят правила в `SKILL.md`. Читать не обязательно перед
|
||||||
|
каждым запуском — нужна, когда хочешь понять, какому классу дефектов какой шаг
|
||||||
|
противостоит, или решить спорный случай.
|
||||||
|
|
||||||
|
Источник — эксперимент на цепочке из трёх зависимых задач генератора кликстрима
|
||||||
|
(калибровка интенсивности, state версии 2 и рестарт, интеграция сервиса). Задачи
|
||||||
|
меняли близкий код, поэтому шли строго последовательно, по одному worker-у на
|
||||||
|
issue. Выводы — хороший сигнал для класса «последовательные инженерные срезы с
|
||||||
|
тестами и acceptance criteria», но не универсальная истина: один репозиторий, один
|
||||||
|
домен, три задачи.
|
||||||
|
|
||||||
|
## Что какой шаг ловит
|
||||||
|
|
||||||
|
- **Саморевью worker-а** хорошо ловит локальные несостыковки своей же реализации:
|
||||||
|
забытый старый дефолт, слишком широкий тест, устаревшие числа в конфиге,
|
||||||
|
двусмысленный README. У worker-а уже есть подробный контекст, поэтому он дёшево
|
||||||
|
находит такие вещи — но только если запретить ему править на первом шаге и
|
||||||
|
попросить сначала выдать находки.
|
||||||
|
- **Sanity-check координатора** добавляет то, что саморевью структурно не видит:
|
||||||
|
связи между дефолтами, обычным запуском, документами и acceptance criteria.
|
||||||
|
Пример из эксперимента: новый базовый поток конфликтовал со старым нижним
|
||||||
|
пределом числа событий на тик — каждая настройка по отдельности «корректна», а
|
||||||
|
вместе ломали критерий интенсивности.
|
||||||
|
- **Отдельный ревьюер** ловит то, что не видит ни worker, ни его саморевью:
|
||||||
|
падение на битом сохранённом состоянии, которое проходит первичную загрузку;
|
||||||
|
слишком большой снимок состояния (мегабайты вместо компактного); слабый
|
||||||
|
интеграционный тест, который формально проходит, но не доказывает уход от
|
||||||
|
старой плоской модели.
|
||||||
|
- **Повторный круг ревью после большого исправления.** Когда правка по находке
|
||||||
|
меняет дизайн или формат данных, она сама нуждается в ревью. В эксперименте
|
||||||
|
переделка компактного состояния закрыла старый дефект и тут же внесла рядом
|
||||||
|
новый — его поймал именно второй круг.
|
||||||
|
|
||||||
|
## Центральная находка про родословную
|
||||||
|
|
||||||
|
Главную гипотезу эксперимента проверяло отложенное ревью **моделью другой
|
||||||
|
родословной** — той, что вела дизайн и спеки, а не той, что писала код.
|
||||||
|
|
||||||
|
Прогноз, что цикл пропустит ссылочную целостность при восстановлении состояния, **не
|
||||||
|
оправдался**: этот точечный дефект цикл поймал сам (саморевью и отдельный ревьюер
|
||||||
|
независимо нашли «битое состояние проходит загрузку, но роняет восстановление», и в
|
||||||
|
коммит легли обёртка и регрессионный тест).
|
||||||
|
|
||||||
|
А до внешнего взгляда дожили дефекты **не точечные, а сквозные**:
|
||||||
|
|
||||||
|
- **Расхождение живого и восстановленного путей.** Живой визит и восстановленный
|
||||||
|
после рестарта брали атрибуты из разных источников и по-разному генерировали
|
||||||
|
идентификаторы событий. Инвариант «один визит — однородный контекст» нарушался на
|
||||||
|
стыке двух путей, который ни один тест не сводил вместе.
|
||||||
|
- **Форма распределения длины визита.** Среднее и конверсия — на цели, воронка
|
||||||
|
монотонна (тесты это подтверждали), но форма уехала от эталона: спайк на коротких
|
||||||
|
визитах, заметная доля срезов о верхний потолок, медиана у нижней границы тестовой
|
||||||
|
полосы. Тесты пинили средние и пороги, но не форму.
|
||||||
|
|
||||||
|
Отсюда уточнение: ценнее всего ревьюер **другой родословной**, и именно там, где
|
||||||
|
свойство (а) тянется через несколько модулей или путей, либо (б) корректность
|
||||||
|
распределительная (форма, а не одно среднее). Для точечных дефектов на входе
|
||||||
|
хватает саморевью и отдельного ревьюера той же линии.
|
||||||
|
|
||||||
|
Поэтому в `SKILL.md` независимый ревьюер по умолчанию — свежий субагент той же
|
||||||
|
модели, но с честной оговоркой: свежий контекст снимает память о реализации, а не
|
||||||
|
общую слепоту линии. Эти два семейства (межмодульное и распределительное) ему надо
|
||||||
|
давать как явную цель, а незакрытое кросс-линейное ревью на gate — фиксировать как
|
||||||
|
риск.
|
||||||
|
|
||||||
|
## Чего не делать слепо
|
||||||
|
|
||||||
|
- Не запускать ревьюера после каждой мелкой правки — дорого и раздувает задачу.
|
||||||
|
- Не принимать все находки за правду — каждую классифицировать.
|
||||||
|
- Не давать координатору верхнеуровневый `/goal` на всю цепочку — нужна
|
||||||
|
управленческая осторожность, а не достижение цели любой ценой.
|
||||||
|
- Не смешивать процессные и handoff-заметки с рабочими коммитами задач.
|
||||||
|
- Не требовать реальный внешний стек на каждом шаге, если acceptance criteria
|
||||||
|
допускают мок, — но явно фиксировать, что именно осталось непроверенным.
|
||||||
|
|
||||||
|
## Открытые вопросы
|
||||||
|
|
||||||
|
Эксперимент оставил нерешённым:
|
||||||
|
|
||||||
|
- как заранее понять, что задаче нужен отдельный ревьюер, а не только саморевью;
|
||||||
|
- стоит ли заранее обязывать worker-а к промежуточным отчётам на статистике и
|
||||||
|
долгих тестах;
|
||||||
|
- нужно ли явно ограничивать бюджет worker-а и число кругов ревью;
|
||||||
|
- как формализовать порог «большое исправление требует второго круга».
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../agents/.agents/skills/coordinator-loop
|
||||||
Reference in new issue
Block a user