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:
ddadminandClaude Opus 4.8 committed 2026-06-14 17:50:11 +03:00
1 parent 41a7c042a2
commit 7b95e0f5cb
3 files changed
+278

No files matched your search

@@ -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-а и число кругов ревью;
- как формализовать порог «большое исправление требует второго круга».