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