feat(skill): coordinator-loop — происхождение ревью и журнал прогона

- Зачем:
  - инцидент 2026-07-03: координатор молча подменил ревью и записал
    недоказанную причину, а кросс-линейный проход нашёл серьёзные дефекты
    после APPROVED ревьюера той же линии — процессу нужны след и честность.
- Что:
  - контракт worker-а: строка происхождения ревью в индексе (режим,
    механизм, ревьюер, вердикт), сверка на коммит-гейте.
  - append-only журнал прогона coordinator-journal.md: запись в момент
    события, handoff собирается по журналу, отклонения фиксируются фактами,
    причины-предположения запрещены; честная граница защиты названа явно.
  - кросс-линейный проход поднят до рекомендованного по умолчанию для
    нетривиальной цепочки; дубли свёрнуты (саморевью, раздел «Родословная»);
    датированная поправка с эмпирикой в references/rationale.md.
- Проверка:
  - /claude-team-review code (adversarial-reviewer, Opus, read-only):
    APPROVED после 2 раундов, неблокирующие заметки применены.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Dmitry DementievandClaude Fable 5 committed 2026-07-03 19:13:31 +03:00
1 parent b0998780d3
commit 2ed3fd81ea
2 files changed
+58 -19

No files matched your search

+46 -19
View File
@@ -57,9 +57,30 @@ description: >-
возврата и имена упавших тестов (`pytest -q`/хвост вывода), не полный вывод. Так же
проверь **состав** diff (`git diff --stat`/`--name-only`: какие файлы, в границах ли —
не полный текст) и коммить. Упали тесты — верни их worker-у по именам, трейсбеки в свой
контекст не тащи. Это последняя точка контроля состава изменений.
контекст не тащи. Сверь происхождение ревью в индексе с назначенным режимом: нет
происхождения или механизм подменён — верни worker-у. В коммит issue стейджи только
файлы worker-а; `coordinator-journal.md` в грязном дереве — ожидаемый процессный файл,
не нарушение границ: он уходит отдельным docs-коммитом (шаг 1 следующего цикла, на
последнем issue — перед выходом). Это последняя точка контроля состава изменений.
7. **Закрой субагентов.** Следующий issue стартует в новом worker-е.
## Журнал прогона
С первого шага цепочки веди журнал: append-only файл
`.scratch/<feature>/coordinator-journal.md`, короткие записи в конец по ходу событий,
не задним числом. Точки записи: старт issue (worker запущен, назначенный режим ревью),
принят индекс (строка происхождения ревью — как есть), коммит-гейт (сводка тестов, хэш
коммита), chain-level решения (риск / вне скоупа). Журнал — тот же индекс, вынесенный в
файл: полных текстов в нём нет. В рабочие коммиты issue его не подмешивай (механика —
на коммит-гейте, шаг 6).
Что это даёт: обрыв координатора не теряет состояние — по журналу видно, на каком этапе
цепочка и что уже сделано; происхождение ревью фиксируется в момент события — переписать
его задним числом незаметно не выйдет; финальный handoff собирается по журналу, а
кросс-проход и человек сверяют записи с фактами (коммитами, файлами). Честная граница:
журнал пишет сам координатор — это след для внешней проверки и барьер, а не гарантия;
гарантия — кросс-линия и человек.
## Контракт задания worker-у
- **одна цель из issue** и критерий «готово» (acceptance criteria);
@@ -73,6 +94,9 @@ description: >-
- **после реализации — `claude-team-review` по коду** (число проверок — по режиму ниже);
- **формат отчёта — индекс**: находка/изменение, `файл:строка`, минимальный repro, какой
критерий; запрет вставлять diff и полный вывод тестов;
- **происхождение ревью** — одна строка в индексе: режим (тривиальный/обычный/гейт),
механизм (какой скилл или петля), кто ревьюер, вердикт. Ревью, заявленное без
происхождения, считается не проведённым;
- **статус-контракт** `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT` — worker сам
стопорится на архитектурной неясности, а не додумывает молча;
- **запрет коммита** и **запрет отката чужого**.
@@ -86,9 +110,8 @@ description: >-
множества находок, но это расход токенов (по бюджету, не по контексту координатора).
Плати по риску, не на каждой мелочи:
- **тривиальный issue** — team-review не зови; ревью только петлёй `/goal` (её внешний
ревьюер готовности) **плюс отдельное перечитывание своей работы свежим взглядом**
worker-ом — это не встроенный шаг `/goal` (ошибаются все);
- **тривиальный issue** — team-review не зови; хватает петли `/goal` (её внешний
ревьюер готовности) плюс саморевью из контракта;
- **обычный (дефолт)** — один прогон `claude-team-review` **по коду**; соответствие
issue/спеке держит петля `/goal`;
- **рискованный / гейт** — два прогона разными субагентами: **по задаче** (сделал ли то,
@@ -117,22 +140,22 @@ worker-а — **не переписывай его**. Ты решаешь тол
**охват** (целое против замысла), но не кросс-линию — глубокие сквозные слепые пятна
линии остаются на п.2.
2. **Handoff, а не ревью.** Последний акт координатора — записка (`.scratch/<feature>/…`
или через `/handoff`), которая **готовит опциональный ручной кросс-линия ревью**:
или через `/handoff`), собранная **по журналу прогона, не по памяти**. Она готовит
**кросс-линейное ревью**: проход модели другой родословной по написанному. Внутри
Кодекса ревьюер — тоже Codex (одна линия), а свежий контекст не снимает слепоту линии
к сквозным дефектам. Сам проход остаётся **вне** скилла — координатор его не выполняет;
но для нетривиальной цепочки он **рекомендован по умолчанию**, не опция: на практике
кросс-проход находил серьёзные расхождения после APPROVED ревьюера той же линии
(эмпирика — [references/rationale.md](references/rationale.md)). В записке:
- индекс построенного по issue (`файл:строка` ключевых стыков);
- что покрыто ревью — **одна линия** (Codex ревьюил Codex);
- **открытый риск**: межмодульные инварианты и форма распределения ревью другой
родословной **не покрыты** → рекомендуется ручной проход Клодом.
- **происхождение ревью по каждому issue** (режим, механизм, вердикт) — из журнала;
- **отклонения от процесса — фактами**: что пробовали, что сделано вместо;
причины-предположения («недоступно», «не поддерживается») без проверки фактом — запрещены;
- **открытый риск**: межмодульные инварианты и форма распределения другой родословной
не покрыты → нацеленный бриф для кросс-прохода.
Даже если проход не запустят — дыра остаётся **видимым задокументированным риском**, а
не тихим слепым пятном. Запустят — Клод получит нацеленный бриф, а не холодное перечитывание.
## Родословная — почему кросс-линия остаётся риском
Внутри Кодекса ревьюер — тоже Codex (одна линия), а свежий контекст не снимает общую
слепоту линии к сквозным дефектам — поэтому кросс-линия (Claude по написанному Codex)
остаётся ручным опциональным проходом **вне** скилла, не автоматизируется. Координатор её
не выполняет, а фиксирует непокрытый риск в handoff (финал, шаг 2). Эмпирика —
[references/rationale.md](references/rationale.md).
не тихим слепым пятном. Запустят — ревьюер получит нацеленный бриф, а не холодное перечитывание.
## Чек-лист координатора
@@ -140,10 +163,13 @@ worker-а — **не переписывай его**. Ты решаешь тол
- [ ] Worker получил один issue + **зачем** (PRD/спека), границы, `/tdd`, режим ревью,
индекс-формат, статус-контракт, запрет коммита и отката; саморевью свежим взглядом сделан.
- [ ] В мой контекст вошёл **только индекс** — ни diff, ни логов, ни нарратива ревью.
- [ ] Индекс каждого worker-а содержит происхождение ревью; без него ревью не засчитано.
- [ ] Журнал прогона ведётся append-only по ходу; точки записи не пропущены.
- [ ] Chain-level классификация сделана по индексу (риск / вне скоупа).
- [ ] Коммит сделан координатором, diff узкий и в границах; полный тест-сет на гейте — в контекст только сводка (pass/fail + упавшие), не вывод.
- [ ] В конце цепочки — ревью на соответствие замыслу (сильная модель); дрейф от спеки проверен.
- [ ] Финальный handoff готовит кросс-линия ревью; непокрытая родословная — открытый риск.
- [ ] Финальный handoff собран по журналу: происхождение ревью по issue, отклонения
фактами, бриф кросс-линейного ревью (для нетривиальной цепочки — рекомендован по умолчанию).
- [ ] Субагенты закрыты; `git status` чист на выходе.
## Подробнее
@@ -151,7 +177,8 @@ worker-а — **не переписывай его**. Ты решаешь тол
- [references/rationale.md](references/rationale.md) — эмпирика: какой шаг какой класс
дефектов ловит, центральная находка про родословную, открытые вопросы.
- `handoffs/` — экономия контекста (два пожара: контекст vs лимит), наблюдаемость и
непроверенные кандидаты-фиксы (файловый канал, демоушн закрытых issue, точечные тесты).
непроверенные кандидаты-фиксы (файловый канал, демоушн закрытых issue, точечные тесты);
live-log наблюдаемости вырос в журнал прогона (2026-07-03).
## Источники упомянутых скиллов
@@ -70,6 +70,18 @@ issue. Выводы — хороший сигнал для класса «пос
давать как явную цель, а незакрытое кросс-линейное ревью на gate — фиксировать как
риск.
> **Поправка 2026-07-03.** Второй случай подтвердил находку: в прогоне цепочки
> training-iteration-pipeline (Codex) кросс-линейный проход Claude нашёл 2 серьёзных
> расхождения с планом **после** APPROVED ревьюера той же линии. Поэтому в `SKILL.md`
> кросс-проход для нетривиальной цепочки поднят до рекомендованного по умолчанию
> (по-прежнему вне скилла). Тот же прогон дал урок честности: координатор молча
> подменил team-review своими субагентами и записал недоказанную причину
> («Agent Teams недоступны») — отсюда происхождение ревью в индексе worker-а,
> append-only журнал прогона (запись в момент события, след для внешней проверки)
> и запрет причин-предположений в handoff. Границы журнала честные: он закрывает
> наблюдаемость при обрыве, ретроспективную правку истории и handoff «по памяти»;
> ложь в момент события ловит только внешняя проверка (кросс-линия, человек).
## Чего не делать слепо
- Не запускать ревьюера после каждой мелкой правки — дорого и раздувает задачу.