chore(skills): удалены устаревшие coordinator-loop и adversarial-review

- удалён каталог coordinator-loop, adversarial-review убран из .gitignore
- из claude-subagent-playbook убраны ссылки на оба скилла
- chief-of-staff и pr от Matt Pocock добавлены в .gitignore
- в AGENTS.md добавлено правило удаления устаревших скиллов

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dmitry DementievandClaude Opus 5.5 committed 2026-10-12 22:39:49 +02:00
1 parent 4d3edc09ee
commit d19239bf31
13 files changed
+9 -1716

No files matched your search

+4
View File
@@ -39,6 +39,10 @@ This repository contains personal dotfiles and configurations for a highly produ
### Adding/Updating Skills ### Adding/Updating Skills
1. Modify files in `agents/.agents/skills/`. 1. Modify files in `agents/.agents/skills/`.
2. Ensure symlinks in other tool directories are updated if new skills are added. 2. Ensure symlinks in other tool directories are updated if new skills are added.
3. Устаревшие скиллы время от времени удаляем. Убирай каталог целиком, а
вместе с ним ссылки из других скиллов и строку в `.gitignore`, если
скилл был внешним. Упоминания в архивах и handoff-записках — история,
их не трогаем.
## 📋 TODO ## 📋 TODO
+2 -1
View File
@@ -39,7 +39,8 @@ wait-what/
wizard/ wizard/
writing-for-agents/ writing-for-agents/
retro/ retro/
chief-of-staff/
pr/
# Skills, подключаемые в agents/ как внешние плагины (не версионируются здесь) # Skills, подключаемые в agents/ как внешние плагины (не версионируются здесь)
claude-team-review claude-team-review
adversarial-review
@@ -23,8 +23,7 @@ description: >-
**Не разворачивай конвейер на мелочь.** Косметика, один **Не разворачивай конвейер на мелочь.** Косметика, один
файл — сделай сам: накладные расходы процесса многократно превысят цену файл — сделай сам: накладные расходы процесса многократно превысят цену
работы. Очередь зависимых issue с автономным прогоном — работы.
это `/coordinator-loop`, не этот плейбук.
## Роли ## Роли
@@ -210,7 +209,7 @@ description: >-
уверенный вердикт одной (APPROVED без находок) не закрывает находки уверенный вердикт одной (APPROVED без находок) не закрывает находки
другой. другой.
Пофиндинговый триаж — у **исполнителя**, не у тебя (правило Пофиндинговый триаж — у **исполнителя**, не у тебя (правило
`/claude-team-review` и `/coordinator-loop`: судит тот, у кого контекст `/claude-team-review`: судит тот, у кого контекст
кода): перешли Codex индекс находок **дословно**, он чинит или кода): перешли Codex индекс находок **дословно**, он чинит или
**аргументированно отклоняет** — через контракт и тест, не голословно; **аргументированно отклоняет** — через контракт и тест, не голословно;
промпт починки — «закрой перечисленное, больше ничего не меняй». промпт починки — «закрой перечисленное, больше ничего не меняй».
@@ -256,7 +255,7 @@ description: >-
## Пользователь в петле ## Пользователь в петле
В отличие от `/coordinator-loop`, здесь пользователь рядом: на границах Здесь пользователь рядом: на границах
этапов давай в чат карту прогресса в 4–7 строк обычными словами этапов давай в чат карту прогресса в 4–7 строк обычными словами
(✅ сделано / ▶ идёт / ⬜ дальше); термины плейбука — только с (✅ сделано / ▶ идёт / ⬜ дальше); термины плейбука — только с
расшифровкой: телеграфные статусы в терминах этапов теряют пользователя. расшифровкой: телеграфные статусы в терминах этапов теряют пользователя.
@@ -295,13 +294,8 @@ teammate-субагентов — шум, а не событие: не докл
## Соседние скиллы ## Соседние скиллы
- `/coordinator-loop` — автономный цикл очереди issue на стороне Codex
(координатор в Codex, worker'ы — его субагенты). Выстрадан и отлажен;
словарь (индекс, свежие сессии, две ручки стоимости) — общий.
- `/claude-team-review` — ревью-петля, где лид сам чинит код (живёт - `/claude-team-review` — ревью-петля, где лид сам чинит код (живёт
отдельным репозиторием, в среде может быть не подключён). отдельным репозиторием, в среде может быть не подключён).
- `/adversarial-review` — разовое адверсарное ревью Кодексом (в среде
может быть не подключён).
- `codex-subagent-playbook` — близнец этого плейбука для координатора на - `codex-subagent-playbook` — близнец этого плейбука для координатора на
стороне Codex; скрыт от автовызова, зови по имени. стороне Codex; скрыт от автовызова, зови по имени.
- `/to-tickets` — разбиение на тикеты-срезы с рёбрами блокировок (этап 1); - `/to-tickets` — разбиение на тикеты-срезы с рёбрами блокировок (этап 1);
@@ -1,100 +0,0 @@
# coordinator-loop
Координаторский цикл: проводит готовые issues через subagent-worker по TDD, держит
границы задач, фильтрует находки и сам делает коммиты.
## Зачем
Когда подряд идёт несколько связанных кодовых срезов, писать их «одним потоком» —
значит терять границы задач и контроль над тем, что попало в коммит. Навык
разделяет роли: один subagent-worker делает **одну** issue по TDD и не коммитит, а
координатор проверяет, классифицирует находки и фиксирует результат. Навык узкий и
работает только по явному вызову (`/coordinator-loop`): он не проектирует, он
исполняет.
## Где в потоке
coordinator-loop — исполнительное звено в середине цепочки, а не вся цепочка:
```text
проектная документация (/brainstorm-with-docs | /grill-with-docs)
↓
узкие проверяемые issues (/to-issues)
↓
coordinator-loop каждый issue: worker (/goal + /tdd) + независимое ревью
(запускает координатор) → индекс → коммит координатора;
в финале — ревью на соответствие замыслу + handoff
↓
приёмка ручной кросс-линия ревью (обычно Claude) + проверка человеком
```
- **До скилла — проектирование.** Сначала выверенная верхнеуровневая документация
(`/brainstorm-with-docs` или `/grill-with-docs`): без неё issues не на чем
основывать. Затем `/to-issues` режет её на узкие задачи. Именно здесь
закладывается проверяемость результата (см. «Что получается»).
- **Скилл — исполнение.** Берёт **готовые** issues по одной и проводит каждую через
цикл worker (`/goal` + `/tdd`) → независимое ревью (ревьюеры-наблюдатели, запускает
координатор; триаж находок — в worker-е) → индекс → chain-level классификация →
коммит координатора. Контекст координатора держится на индексах, не на diff'ах.
В финале цепочки координатор прогоняет ревью на соответствие замыслу (целое против
исходной спеки, сильной моделью на усиленном уровне) и пишет handoff, готовящий
приёмку.
- **После скилла — приёмка.** Ревью другой модельной линией (Codex ревьюил Codex, так
что кросс-линия — обычно ручной проход Клодом) плюс проверка человеком. Скилл её не
автоматизирует — только передаёт эстафету с зафиксированным открытым риском.
## Что делает и чего не делает
Делает: ведёт по одному issue за раз, держит границы, фильтрует находки, коммитит.
Подробный цикл и роли — в [SKILL.md](SKILL.md).
Не делает:
- не создаёт проектную документацию и не принимает архитектурные решения — это
предыдущий этап;
- не нарезает issues — это `/to-issues`;
- не отвечает за проверяемость результата — она закладывается при проектировании;
- не делает финальную приёмку — это ревью другим агентом плюс человек;
- не готовит набор issues «пачкой» автоматически — пока не цель.
## Что получается
Результат прогона по одной issue — «пакет для проверки»:
- **отдельный коммит на каждую issue** с узким, в границах задачи, diff;
- **финальный отчёт worker-а**: какие файлы, какие тесты прогнаны, какие acceptance
criteria закрыты, риски, `git status`;
- **chain-level классификация** (риск / вне скоупа); per-finding триаж («реально /
ложно / чинить») делает worker по индексам ревьюеров.
Один issue = один проверяемый коммит плюс отчёт — так пост-цикловое ревью и ручная
проверка остаются посильными.
**Про проверяемость.** Прошлый прогон показал: если итог цепочки можно принять
только чтением diff, ручная проверка становится слишком дорогой. Лекарство — на
уровне проектирования: у всего набора issues должен быть **наблюдаемый конечный
результат** для приёмки (запись в Kafka-топик, строки в конкретной таблице, панель
дашборда, вывод команды). Это ответственность `/to-issues` и брейншторма, **не**
этого скилла. Координатор может отметить слабую проверяемость как **риск** и вернуть
сигнал на уровень выше, но сам критерий приёмки не выдумывает.
## Как вызвать
Только по явному запросу — навык узкий и не срабатывает сам:
```text
/coordinator-loop
```
## Статус и что дальше
Экспериментальный — прямое продолжение эксперимента с координатором субагентов,
будет дорабатываться. Открытые вопросы (когда нужен отдельный ревьюер, обязательные
промежуточные отчёты, бюджет worker-а) собраны в разделе «Открытые вопросы»
файла [references/rationale.md](references/rationale.md).
## Что читать рядом
- [SKILL.md](SKILL.md) — как координатор исполняет цикл (инструкция для агента).
- [references/rationale.md](references/rationale.md) — почему цикл устроен так:
эмпирика эксперимента, находка про ревьюера другой родословной, открытые вопросы.
@@ -1,382 +0,0 @@
---
name: coordinator-loop
disable-model-invocation: true
description: >-
Координаторский цикл по цепочке готовых issue: на каждый — worker-субагент по TDD
с независимым ревью, коммит делает координатор. Контекст координатора
держится чистым — в него входит только индекс находок, не diff. Рассчитан на
автономный прогон очереди issue без присмотра пользователя. Узкий навык, только
по явному вызову /coordinator-loop.
---
# Координационный цикл субагентов
Ты — **координатор**. Реализацию не пишешь, код ради верификации не читаешь
(точная граница чтения — в «Ролях»). Ты ведёшь цепочку
зависимых issue: даёшь worker-у задачу с контекстом, принимаешь от него **индекс**,
классифицируешь на уровне цепочки и единственный делаешь коммиты.
**Ведущее правило — работай по индексу, а не по полному тексту.** Всё, что попадает в
твой контекст, — это **индекс**: находка, `файл:строка`, какой критерий нарушен,
минимальный путь воспроизведения. Полного diff, вывода тестов и нарратива ревью в твоём
контексте быть не должно — их читают субагенты у себя, а тебе возвращают индекс.
Твоих собственных команд это тоже касается: шумный вывод гони в файл-лог, в контекст
бери код возврата и итоговые строки (механика — шаг 7).
Верификацию находок делает ревьюер, не ты. (Исключение — состав diff на коммит-гейте:
`git diff --stat`/`--name-only`, какие файлы и в границах ли; это не полный текст, см.
шаг 7.) Проверяй себя каждый цикл: *в мой контекст попал полный текст вместо индекса?
Если да — это баг процесса.* Так контекст не пухнет, не компактится и не начинает
косячить — это главная болезнь, которую навык лечит.
## Когда применять
Последовательные инженерные срезы с тестами и acceptance criteria, где соседние задачи
трогают близкий код и их нельзя безопасно параллелить. Вход цикла — **качественно
подготовленные issue**: цель, критерии готовности и границы уже сформулированы (обычно
это выход `/to-issues` после проработки замысла, например через `/brainstorm-with-docs`).
Мутный issue в цикл не брать: цикл не проясняет замысел, а превращается в дорогую машину
ревью-кругов — сначала прояснение и проработка замысла, потом цикл. Не подходит: независимые задачи
(параллель), однофайловые правки, задачи без тестовой базы. Если цепочка не подходит —
скажи об этом пользователю, а не тяни цикл силой.
## Контракт автономного прогона
Основной сценарий скилла: пользователь передаёт очередь подготовленных issue и уходит —
координатор ведёт конвейер сам, а не ждёт инструкций на каждом шаге.
**Вход** — что пользователь даёт при вызове:
- список issue и порядок (или правило зависимостей);
- где лежит «зачем» (PRD/спека), если это не очевидно из самих issue;
- ожидаемый финал, если он отличается от стандартного (см. «Финал цепочки»).
**Мандат**: весь цикл — worker, ревью, коммит-гейт, статусы, журнал, handoff —
координатор ведёт без уточняющих вопросов. Локальные коммиты рабочих срезов входят в
мандат по умолчанию; push, теги и всё, что уходит за пределы локального репозитория
или разрушает данные вне рабочего дерева, — только по явному поручению.
**Стоп-условия** — сводка, сами правила в своих разделах: чужие правки в дереве
(шаг 1); мутный или неготовый issue («Когда применять», шаг 2); спор, переживший
узкий усиленный гейт, и потолок кругов ревью (шаг 5); действие за пределами мандата.
Проверка, недоступная worker-у (стенд, docker, сеть), цепочку не останавливает:
worker сдаёт её как `DONE_WITH_CONCERNS` с готовой командой (статус-контракт);
доступную координатору проверку тот прогоняет сам — это часть коммит-гейта. Открытым
риском в handoff уходит только то, что не может проверить и координатор: ручная
приёмка человеком, недоступная отсюда внешняя среда.
**Выход** — по «Финалу цепочки»: чистое дерево, список коммитов, статусы issue,
handoff с открытыми рисками.
## Роли
- **Координатор** — ты. Порядок issue, богатый контракт, запуск ревьюеров, политика
кругов ревью, chain-level классификация по индексу, коммит-гейт, финальный handoff.
**Код ради верификации не читаешь** — это ревьюер; на коммит-гейте смотришь лишь
**состав** diff (не текст, см. шаг 7). Процессные и навигационные артефакты — файлы
issue и PRD, журнал, handoff, документация процесса — твоя зона: их читаешь и правишь
сам, запрет касается только кода ради верификации.
- **Worker** — субагент с одной целью (один issue). Гоняет `/goal` (петля
план→код→тест), меняет файлы, **не коммитит и не откатывает чужое**. Триажит находки
ревью: чинит или аргументированно отклоняет. Возвращает индекс + статус.
- **Ревьюер** — свежий субагент-**наблюдатель**, которого запускаешь **ты** (см.
«Контракт ревьюеру»): репозиторий и среду не меняет, но инструменты у него полные —
ограничение промптом, не урезанием субагента. Читает код сам, докладу worker-а не
верит, возвращает индекс находок. `claude-team-review` как механизм допустим только там, где его может
запустить **сам worker** (владелец правок): лид team-review чинит код сам, а второй
писатель в дереве недопустим — координатору team-review запускать нельзя.
**Факт среды Codex (проверено 2026-07-04 диагностом с `agent_type=worker`):** worker не
может запускать субагентов — `spawn_agent` недоступен, `tool_search` не находит ни
spawn, ни `claude-team-review`. Поэтому ревьюеров запускает координатор и пересылает
worker-у их индексы **дословно**, без своих интерпретаций. Не перепроверяй этот факт на
каждой цепочке — жечь токены; перепроверь только при сигнале обратного (например,
`tool_search` вдруг нашёл spawn).
**Всех субагентов — worker-а, ревьюеров, диагностов — запускай свежими сессиями, без
форка своей истории.** Контракт самодостаточен, правила и «зачем» лежат в репозитории
и issue — форк не нужен. А вреден он дважды: тащит твой контекст в субагента (расход
без пользы) и убивает «свежий взгляд» — ревьюер, унаследовавший твою историю, уже не
независим. Не трать циклы на попытки передать субагенту полный контекст — это против
дизайна, а не ограничение, которое надо обойти.
Свежая сессия — правило **запуска**, не запрет продолжения: уже запущенного субагента
между кругами **продолжай** (`send_input`), не пересоздавай. Worker-а — всегда: его
контекст по issue — актив. Ревьюера на rerun после точечных правок — тем же, узким
вопросом: «закрывают ли правки твои находки, не внесено ли нового рядом» — полный
обход заново не нужен. **Свежий ревьюер обязателен** там, где нужен незаинтересованный
взгляд: узкий гейт по спору, эскалация уровня, правки перекроили реализацию широко,
индекс прошлого ревьюера слаб или сомнителен. Серия полных обходов свежими xhigh-сессиями
на каждый rerun — сжигание бюджета, а не независимость (эмпирика 2026-07-04: пять
свежих кругов финального ревью).
## Цикл на одну задачу
1. **Чистое дерево.** `git status --short` до старта. Чужие правки — стоп, спроси
пользователя. Свои процессные — отдели docs-коммитом.
2. **Прочитай issue и зависимости.** Предыдущие в цепочке не закрыты — не начинай.
3. **Назначь режим ревью** по порогу риска (см. «Режимы ревью») и запиши в журнал;
если срез может задеть порог по ходу — задай условие эскалации (например, «worker
тронул state-схему → перевести в гейт»). Затем **контракт worker-у** (см. ниже) и
запусти **одного** worker-а — уровень мышления явно по
[references/effort-levels.md](references/effort-levels.md), в журнал вместе с режимом.
4. **Дождись индекса.** Долго молчит — запроси промежуточный статус, не жди вслепую.
Пришло push-уведомление — сразу обрабатывай, не крути опрос по кругу.
5. **Ревью-гейт** (worker вернул `DONE`/`DONE_WITH_CONCERNS`; `BLOCKED` и
`NEEDS_CONTEXT` разбирай до ревью — гонять ревьюеров по незавершённой работе
бессмысленно). По назначенному режиму запусти ревьюеров; запуск и вердикт каждого
фиксируй в журнале в момент события. Индекс находок перешли worker-у **дословно**,
его триаж прими индексом же. Rerun после правок по гейт-находкам назначаешь **ты**,
автоматически — это не concern worker-а; узкий rerun — продолжением того же
ревьюера, свежий — по триггерам (см. «Роли»). **Круг** — одна итерация «прогон(ы) ревью →
триаж worker-а»; пара «по задаче + по коду» на гейте — один круг. Гейт закрыт, когда
все назначенные прогоны вернули `APPROVED`. Политика кругов (тождество находок между
кругами судит worker в триаже, не ты — по индексам оно не определяется):
- worker пометил **«спор»** (ревьюер снова поднял вопрос, уже аргументированно
отклонённый через контракт и тест) → не общий rerun, а **узкий гейт** по спорному
вопросу на усиленном уровне мышления;
- спор пережил и узкий усиленный гейт → стоп, решение человека;
- **третий круг на issue** — предупреди пользователя, не дожидаясь потолка: расход
растёт, причина (что именно не сходится). Это предупреждение, не вопрос: ответа
не жди, работу продолжай — жёсткая граница ниже;
- независимо от споров больше **четырёх** кругов ревью на issue → стоп, вынеси
человеку вопрос «дробить issue или принимать риск».
6. **Классифицируй по индексу — только chain-level** (см. «Классификация»).
7. **Коммит-гейт.** Прогони полный тест-сет **сам**: код возврата, который ты видел
своими глазами, — это и есть твоя проверка; прогон через субагента превращает гейт
обратно в чужой пересказ. Шумные команды гоняй через файл-лог
(`<команда> > /tmp/<лог> 2>&1`), в контекст возьми **только сводку**: код возврата
и итоговые строки (`tail`, имена упавших — `grep FAILED`). На «тихие» флаги вроде
`pytest -q` не полагайся: цель сборки может зашивать подробный вывод (эмпирика
2026-07-05: `make generator-test` с зашитым `pytest -v` высыпал в контекст
координатора полный список из 181 теста). Если сводки мало и вывод нужно
**интерпретировать** — лог сам не читай, спавни разборщика логов экономного уровня
([references/effort-levels.md](references/effort-levels.md)), он вернёт индекс. Так же
проверь **состав** diff (`git diff --stat`/`--name-only`: какие файлы, в границах ли —
не полный текст) и коммить. Упали тесты — верни их worker-у по именам, трейсбеки в свой
контекст не тащи. Сверь по журналу, что назначенный режим ревью выполнен: каждый
запуск и вердикт записаны в момент события; нет записи — ревью не проведено. В коммит
issue стейджи только файлы worker-а; файл issue и `coordinator-journal.md` —
процессные, не файлы worker-а: после коммита переведи в файле issue `Status: done`,
и оба уходят отдельным docs-коммитом (шаг 1 следующего цикла, на последнем issue —
перед выходом). Это последняя точка контроля состава изменений.
8. **Закрой субагентов.** Следующий issue стартует в новом worker-е.
## Журнал прогона
С первого шага цепочки веди журнал: append-only файл
`.scratch/<feature>/coordinator-journal.md`, короткие записи в конец по ходу событий,
не задним числом. Каждую запись начинай с времени `HH:MM` (дата — в заголовке дня;
время бери вызовом `date`, сама модель его не знает) — так по журналу восстанавливается
длительность этапов и границы issue. Точки записи: старт issue (worker запущен, его
уровень мышления, назначенный режим ревью), принят индекс worker-а, **запуск каждого
ревью** (механизм,
кто запускал, уровень мышления — **фактическое значение хоста** вроде `high`/`xhigh`,
не название яруса: «рабочий уровень» в журнале не проверяем, а `medium` вместо `high` —
видимое расхождение) и **его вердикт**, коммит-гейт (сводка тестов, хэш
коммита), chain-level решения (риск / вне скоупа). Происхождение ревью пишешь ты сам —
в момент запуска и в момент вердикта. Мельче этих точек (каждая команда, каждый
прочитанный файл) не пиши — метки времени не должны превратить журнал в спам. Журнал —
тот же индекс, вынесенный в файл: полных текстов в нём нет. В рабочие коммиты issue его
не подмешивай (механика — на коммит-гейте, шаг 7).
Что это даёт: обрыв координатора не теряет состояние — по журналу видно, на каком этапе
цепочка и что уже сделано; происхождение ревью фиксируется в момент события — переписать
его задним числом незаметно не выйдет; финальный handoff собирается по журналу, а
кросс-проход и человек сверяют записи с фактами (коммитами, файлами). Честная граница:
журнал пишет сам координатор — это след для внешней проверки и барьер, а не гарантия;
гарантия — кросс-линия и человек.
## Контракт задания worker-у
- **одна цель из issue** и критерий «готово» (acceptance criteria);
- **зачем**: ссылки на PRD/спеку/смежное. Без общего контекста worker триажит находки
вслепую; с ним — способен судить сам (это и делает верификацию на воркере надёжной);
- **границы** — что трогать нельзя;
- методика **`/tdd`** (короткие срезы тест→код); точечные тесты в петле;
- **саморевью свежим взглядом** перед сдачей (отдельно от петли `/goal`) — worker
критически перечитывает свою работу и правит очевидное. Базовый минимум даже без
независимого ревью: ошибаются все;
- **триаж находок ревью**: независимое ревью организует координатор и присылает индекс
находок; worker каждую находку чинит или **аргументированно отклоняет** — через
контракт и тест, не голословно. Вопрос, который ревьюер поднял снова после
аргументированного отклонения, worker помечает в своём индексе флагом **«спор»**
с отсылкой к прежнему обоснованию;
- **формат отчёта — индекс**: находка/изменение, `файл:строка`, минимальный repro, какой
критерий; запрет вставлять diff и полный вывод тестов;
- **статус-контракт** `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT` — worker сам
стопорится на архитектурной неясности, а не додумывает молча. `BLOCKED` — только про
саму работу; недоступная в среде worker-а стендовая проверка (docker, сеть, стенд) —
это `DONE_WITH_CONCERNS` с фактом («docker отсутствует: <вывод>») и **готовой
командой**, которую координатор прогонит сам (не прошла и у координатора — он
фиксирует в журнале, где и как проверка прошла фактически);
- **запрет коммита** и **запрет отката чужого**.
Цель worker-а — **одна** (один issue = одна петля). Не запускай `/goal` на всю цепочку
сразу: от координатора нужна остановка на контрольных точках, а не «закрыть всё любой ценой».
## Контракт ревьюеру
Симметричен контракту worker-а, короче:
- **наблюдатель с полными инструментами**: код читает сам, докладу worker-а не верит;
может запускать тесты, воспроизводить находки, смотреть документацию и сеть —
верификация требует инструментов. Ограничение — **промптом, не урезанием субагента**:
не менять репозиторий и среду (правки файлов, git-операции, установка пакетов —
нельзя), так в дереве нет второго писателя;
- **зачем**: те же ссылки на issue/PRD/спеку, что у worker-а, плюс фокус проверки
(по задаче или по коду); на гейте — явная цель по двум семействам, слепым для одной
линии: межмодульные инварианты и доменные инварианты данных (например, форма
распределений, если она важна проекту);
- **формат отчёта — индекс**: находка, `файл:строка`, какой критерий нарушен,
минимальный repro; вердикт одной строкой (`APPROVED` / `CHANGES_REQUESTED`); запрет
вставлять diff, полный вывод тестов и нарратив рассуждений;
- модель и уровень мышления задаёт координатор при запуске (см. «Режимы ревью»).
Готовый шаблон промпта — [references/reviewer-prompt.md](references/reviewer-prompt.md)
(адаптация из `claude-team-review`); скилл самодостаточен, внешних файлов не требует.
## Режимы ревью — рычаг стоимости
Две проверки **разными субагентами** — по задаче и по коду — ловят непересекающиеся
множества находок, но это расход токенов (бюджет; в твой контекст при этом идут только
индексы находок). Плати по риску, не на каждой мелочи:
- **тривиальный issue** — независимое ревью не зови; хватает петли `/goal` плюс
саморевью из контракта (в среде без вложенных субагентов внешняя проверка готовности
внутри `/goal` тоже недоступна — саморевью остаётся единственной проверкой, это
осознанная цена режима);
- **обычный (дефолт)** — один прогон независимого ревью **по коду**; соответствие
issue/спеке держит петля `/goal`;
- **рискованный / гейт** — два прогона разными субагентами: **по задаче** (сделал ли то,
что в issue/спеке) + **по коду** (тонкие баги, межмодульное).
Порог риска: state, версионирование и сериализация; формат данных; интеграция с внешним
сервисом — особенно разрушающие пути (синхронизация, удаление); защитные проверки, на
которые полагаются другие части системы, — всё, где ошибка означает «проверка молча
пропускает» (fail-open); статистические модели; честность документации; межмодульные
инварианты. Ниже порога: документация и учебные материалы, простая обвязка сборки,
локальные правки без новых инвариантов. (Калибровка по прогонам 2026-07-04/05: issue
с синхронизацией внешнего сервиса и fail-open проверками, пущенный обычным режимом,
собрал больше всех кругов — его класс надо было опознать на шаге 3.)
**Две ручки стоимости, не одна.** *Модель по роли* — какая модель на какой роли:
проверка по задаче тянет дешёвую, финальное chain-ревью требует сильную. *Уровень
мышления* — отдельная ось, глубина рассуждений той же модели. Три относительных уровня,
без привязки к именам: **экономный** (worker на обычном issue — реализацию с тестовой
сеткой страхуют рубежи ниже по течению; task-lens ревью, диагностика, разбор логов),
**рабочий** (любое code review — пропуск ревьюера не ловит никто, глубина важнее именно
здесь; worker на гейтовом issue), **усиленный** (эскалация споров по политике кругов,
межмодульные и доменные инварианты, финальное chain-ревью). Соответствие ролей конкретным моделям и уровням
хоста — датированная таблица [references/effort-levels.md](references/effort-levels.md);
в логике скилла имён нет, вышла новая модель — правится таблица, не правила. Уровень
выбирай по роли и классу issue из таблицы, дефолтного уровня «для всех» нет; вверх —
только по триггеру (шаг 5), не «на всякий случай». Хост без
управляемых уровней: эскалация вырождается в свежего субагента — слабее, но не пусто.
## Классификация находок
Per-finding триаж («реально / ложно / чинить») делает **worker** — у него контекст кода
и «зачем» из контракта; **не переписывай его**. Ты решаешь только **на уровне цепочки**,
читая индекс:
- **записать риском** — важно помнить, текущий коммит не блокирует (реестр рисков цепочки);
- **вне скоупа** — пригодится позже, отдать в следующий issue.
## Финал цепочки
Пока п.1–3 не выполнены, цепочка **не завершена** — и каждый твой отчёт пользователю
обязан явно это называть: статус («финальный гейт, не done») и остаток по пунктам.
Промежуточный статус, звучащий как финальный отчёт, — дефект коммуникации: пользователь
решит, что работа закончена, и уйдёт. Словарь статусов для отчётов: «финальный гейт,
не done: осталось …» → «done по coordinator-loop: handoff есть, дерево чистое,
субагенты закрыты»; открытые внешние риски (кросс-линия, ручная приёмка) перечисляй
и в done-отчёте. **APPROVED финального ревью — ещё не завершение цепочки.**
1. **Приведи документы до ревью.** Обнови PRD/трекер: сделанное — в сделанное, остаток
актуален, статусы issue переведены (шаг 7). Иначе финальное ревью предсказуемо найдёт
этот дрейф вместо настоящего.
2. **Ревью на соответствие замыслу** (рекомендуется для любой нетривиальной цепочки).
Один прогон субагента-ревьюера **сильной моделью на усиленном уровне** (обе ручки
вверх — см. «Режимы ревью»): читает **всю** реализацию против **исходной спеки/PRD**
и проверяет, не разъехалась ли поэтапная реализация с замыслом. Возвращает индекс.
Один прогон добавляет к общей стоимости немного, а ловит дрейф, который per-issue
срезы не видят — ни одно ревью отдельной задачи не сверяло целое с целым замыслом.
Rerun'ы финального ревью — по общему правилу продолжения: точечные правки проверяет
**тот же** ревьюер узким вопросом, свежая xhigh-сессия на каждый круг не нужна.
**Кто чинит находки финального ревью — по классу файла.** Процессные файлы
(`.scratch/<feature>/…`: остаток и статус PRD фичи, чекбоксы и статусы issue,
журнал) — чини сам: это твоя зона, п.1 и существует, чтобы таких находок не было
вовсе. Файлы проекта (код, docs/, уроки, дашборды) — **fixer-субагент** с коротким
worker-контрактом (цель — закрыть перечисленные находки, границы, запрет коммита;
уровень — экономный для док-дрейфа, рабочий для кода): правя проектный файл сам,
ты читаешь его полный текст и становишься вторым писателем — ломаешь оба своих
инварианта, даже если правка на две строки. Кодовая находка финала — фактически
мини-issue: после fixer-а — rerun ревью по общему правилу продолжения.
**Триаж находок финального ревью — у fixer-а**, тем же механизмом, что у worker-а:
богатый контракт («зачем», спека) даёт право судить; отклонение — аргументированное,
через контракт и тест; спор — по политике кругов (шаг 5). Финальный ревьюер
ошибается так же, как обычный, — «поправь всё перечисленное» без права возразить
превращает его находки в приказы.
Это Codex (одна линия): берёт **охват** (целое против замысла), но не кросс-линию —
глубокие сквозные слепые пятна линии остаются на п.3.
3. **Handoff — условие выхода, а не пожелание.** Для нетривиальной цепочки цикл не
считается завершённым без записки, собранной **по журналу прогона, не по памяти**.
Место и формат — по конвенции репозитория для handoff (AGENTS.md, ADR), если она
есть; иначе `.scratch/<feature>/…`. Записка готовит **кросс-линейное ревью**: проход
модели другой родословной по написанному. Внутри Кодекса ревьюер — тоже Codex (одна
линия), а свежий контекст не снимает слепоту линии к сквозным дефектам. Сам проход
остаётся **вне** скилла — координатор его не выполняет; но для нетривиальной цепочки
он **рекомендован по умолчанию**, не опция: на практике кросс-проход находил
серьёзные расхождения после APPROVED ревьюера той же линии (эмпирика —
[references/rationale.md](references/rationale.md)). В записке:
- индекс построенного по issue (`файл:строка` ключевых стыков);
- **происхождение ревью по каждому issue** (режим, механизм, кто запускал, уровень,
вердикт) — из журнала;
- **отклонения от процесса — фактами**: что пробовали, что сделано вместо;
причины-предположения («недоступно», «не поддерживается») без проверки фактом — запрещены;
- **открытый риск**: межмодульные и доменные инварианты другой родословной
не покрыты → нацеленный бриф для кросс-прохода.
Даже если проход не запустят — дыра остаётся **видимым задокументированным риском**, а
не тихим слепым пятном. Запустят — ревьюер получит нацеленный бриф, а не холодное перечитывание.
## Чек-лист координатора
- [ ] Дерево чистое перед стартом; чужие правки согласованы, процессные отделены.
- [ ] Worker получил один issue + **зачем** (PRD/спека), границы, `/tdd`, индекс-формат,
триаж находок ревью (с флагом «спор»), статус-контракт, запрет коммита и отката;
саморевью свежим взглядом сделан.
- [ ] В мой контекст вошёл **только индекс** — ни diff, ни логов, ни нарратива ревью.
- [ ] Ревью-гейт: индексы находок пересланы worker-у дословно; rerun назначал я;
политика кругов соблюдена (спор → узкий усиленный гейт; больше четырёх кругов →
человек).
- [ ] Происхождение каждого ревью (механизм, кто запускал, уровень, вердикт) записано
мной в журнал в момент события; нет записи — ревью не засчитано.
- [ ] Журнал ведётся append-only по ходу, каждая запись с меткой `HH:MM`; точки записи
не пропущены.
- [ ] Chain-level классификация сделана по индексу (риск / вне скоупа).
- [ ] Коммит сделан координатором, diff узкий и в границах; полный тест-сет на гейте
прогнал я сам, шумные команды — через файл-лог: в контекст только сводка
(pass/fail + упавшие), не вывод.
- [ ] Статусы закрытых issue переведены в `done` и ушли docs-коммитом вместе с журналом.
- [ ] PRD/трекер приведены **до** финального ревью; ревью на соответствие замыслу —
сильная модель на усиленном уровне; дрейф от спеки проверен.
- [ ] Финальный handoff собран по журналу и по конвенции репозитория: происхождение
ревью по issue, отклонения фактами, бриф кросс-линейного ревью. Для нетривиальной
цепочки без него из цикла не выходить.
- [ ] Субагенты закрыты; `git status` чист на выходе.
## Подробнее
- [references/rationale.md](references/rationale.md) — эмпирика: какой шаг какой класс
дефектов ловит, центральная находка про родословную, открытые вопросы.
- `handoffs/` — экономия контекста (два пожара: контекст vs лимит), наблюдаемость и
непроверенные кандидаты-фиксы (файловый канал, демоушн закрытых issue, точечные тесты);
live-log наблюдаемости вырос в журнал прогона (2026-07-03); топология ревью под Codex,
политика кругов и уровни мышления — по боевому прогону (2026-07-04).
## Источники упомянутых скиллов
- `/brainstorm-with-docs`, `/to-issues`, `/tdd`, `/claude-team-review` — инженерные
скиллы (набор Matt Pocock и внутренние).
- `/goal` — встроенная петля Codex (план→код→тест; её внешняя проверка готовности в
среде без вложенных субагентов недоступна).
@@ -1,272 +0,0 @@
# Handoff: экономия контекста в coordinator-loop
Дата: 2026-06-14 MSK
Статус: рабочая договорённость по итогам сессии проектирования. В `SKILL.md` ещё не внесена.
## Зачем этот handoff
Сохранить выводы сессии, пока свежие. Разбирались, почему навык `coordinator-loop`
(координатор + субагенты) при длинной цепочке задач переполняет контекст координатора и дорого
стоит по токенам. Это снимок для продолжения в новой сессии, а не готовая спецификация: часть
решений принята, часть осталась открытой — так и записано. Здесь сознательно «чуть больше
информации, чем нужно»: для handoff недобор хуже перебора.
## Где что лежит (чтобы следующая сессия всё нашла)
- **Навык, источник-правды (git):** `~/dotfiles/agents/.agents/skills/coordinator-loop/`
(`SKILL.md`, `README.md`, `references/rationale.md`, `handoffs/`). Этот handoff — здесь.
- **Развёрнутая копия навыка** (её читает Claude Code): `~/.claude/skills/coordinator-loop/`.
Правки вносить в dotfiles, потом разворачивать обычным способом.
- **Побратим:** `handoffs/2026-06-14-observability-design.md` (рядом) — проектирование файлового
канала `coordinator-runs/`. **Свести с этим handoff, см. раздел «Связь».**
- **Прогон, на котором всё замеряли:** репозиторий
`~/sources/clickstream-ch-kafka-superset-demo`, фичи `feature-data-generator` (8 задач) и
`generator-model-time-startup-history` (6 задач). Вёлся как `/coordinator-loop` под Codex.
- **Сырьё диагностики:** `~/.codex/logs_2.sqlite`, `~/.codex/sessions/2026/`,
`~/.codex/goals_1.sqlite`. Внимание: файлы Codex **нумерованные и ротируются** — к будущей
сессии этих именно логов может уже не быть. Поэтому ключевые числа вынесены в этот handoff
ниже, чтобы не зависеть от сырья.
- **Prior art:** obra:superpowers, навык `subagent-driven-development` —
<https://github.com/obra/superpowers/tree/main/skills/subagent-driven-development>
(`SKILL.md`, `implementer-prompt.md`, `spec-reviewer-prompt.md`,
`code-quality-reviewer-prompt.md`).
## Что болит
У координатора дважды заканчивался контекст (по разу на каждый из двух прогонов), и работа съела
почти весь 5-часовой лимит подписки (по логам — около 3 ч 45 мин на втором прогоне).
## Диагностика
Главный метод и главный урок: **логи — истина, самоотчёт модели — нет.** Codex на прямой вопрос
искренне назвал виновником многословные отчёты субагентов, пересекающие границу. Логи это
опровергли. Модель не видит свой токен-счёт и сочиняет правдоподобную, но неверную картину.
Спасло то, что полезли в логи, а не поверили рассказу. Разбор логов делал **отдельный субагент
на дешёвой модели** (Sonnet), чтобы не забивать контекст основного агента сырьём. Этот приём
стоит повторять.
### Два разных пожара (мы их сначала склеивали)
**Пожар A — контекст координатора.** Горел НЕ от отчётов на границе субагент→координатор: они
были компактны (в среднем 2,6 КБ, максимум 7,3 КБ, всего 112 КБ за 44 возврата; полных diff и
логов тестов в них не было). Горел от того, что происходило **внутри сессии самого
координатора**:
- координатор **сам читал полные diff'ы**, чтобы проверить находки, — 19 diff'ов крупнее 10 КБ,
суммарно 413 КБ, независимо от сводок воркеров;
- сессия ревьюера-апрувера раздулась до 947 КБ за 21 ход, и **42 из 44 ожиданий `wait_agent`
завершились таймаутом** (опрос по кругу при том, что push-уведомления приходили).
Пик контекста координатора: 199 307 токенов из окна 258 400 (77 %), одна компактизация.
**Пожар B — 5-часовой лимит** (отдельная от контекст-окна вещь — это суммарный расход токенов):
- **103 прогона полного тест-сета** (каждый ~40 КБ вывода, до 16 877 токенов за один) — главный
потребитель;
- `/goal`-петли воркеров по ~400K токенов на задачу (задачи 05 и 06; 30 и 23 минуты);
- 13 Docker-сборок и накладные расходы опроса.
### Процессные счётчики (прогон issues 02–06)
| Метрика | Значение |
|---|---|
| Обработано issues | 5 (02–06) |
| Воркеров запущено | 5 + 2 `/goal`-петли |
| Вызовов независимого ревьюера | 7 (4 explorer + 3 default) |
| Кругов ревью на задачу (среднее) | 1,4 |
| Кругов правок после ревью | ~2 на задачу |
| Прогонов полного тест-сета | 103 |
| Docker-сборок | 13 |
| Всего exec_command | 996 |
| Общая длительность прогона | ~3 ч 45 мин |
### Главные потребители (по убыванию)
1. Полный вывод тестов внутри воркеров — 103 вывода по ~40 КБ.
2. Повторное чтение diff'ов координатором — 19 outputs >10 КБ, 413 КБ.
3. Опросный цикл ревьюера-апрувера — 21 ход, сессия 947 КБ.
4. `/goal`-петли (issues 05 и 06) — ~400K токенов каждая.
5. Отчёты субагентов на границе — низкое влияние (среднее 2,6 КБ).
### Гипотезы и вердикты
| # | Гипотеза | Вердикт | Доказательство |
|---|---|---|---|
| H1 | контекст рос из-за отчётов субагентов | **опровергнута** | средний отчёт 2,6 КБ, max 7,3 КБ; diff и логи в них не входили |
| H2 | координатор перечитывал то, что воркер уже сообщил | **подтверждена** | 19 полных diff в сессии координатора, 413 КБ |
| H3 | компактизация теряла важное и его восстанавливали | частично | после компактизации координатор перечитывал статусы issue и git-историю |
| H4 | полный режим ревью применялся избыточно | частично, переосмыслена | дело не в самом ревью, а в polling-overhead: 42/44 таймаута, сессия 947 КБ |
| H5 | лимит съели `/goal` и тест-прогоны | частично | 103 полных ретеста — главное; `/goal` был только на 05–06 |
### Что Codex дал верно, несмотря на промах с локацией
Его интроспекция угадала **форму** балласта (материал, который должен был сжиматься после своего
момента) и продиктовала точные компактные форматы. Он перечислил, что таскал зря: полные выводы
тестов; полные diff'ы крупных файлов; полные отчёты ревьюеров (вместо классифицированных
находок); полные отчёты воркеров после приёмки issue; тексты уже закрытых issue; собственные
пользовательские апдейты («запускаю», «жду воркера»); полные build/compose/ClickHouse-логи;
длинные фрагменты спек после первичного чтения.
Ключевой ответ про классификацию находок: отчёта субагента **хватало для маршрутизации**
(blocker / риск / docs-мелочь / ложная тревога), но для финального решения «чинить или нет» по
**межмодульному инварианту** он **всё равно лез в код** — отчёт был индексом и аргументацией, а
не заменой чтения. Примеры мест, куда он шёл: `service.py:_is_startup_history_state`, порядок
записи manifest/state, путь восстановления state→manifest→state→live load→startup-marker→
fallback, SQL-воронка для доказательства. Вывод: лучший отчёт — это **индекс** (находка,
`файл:строка`, минимальный путь воспроизведения, какой критерий нарушен, что проверить в коде),
а не нарратив.
Про `wait_agent`: таймауты стояли 600000 мс (10 мин) для воркера/ревьюера, 900000 мс (15 мин)
для долгих стендовых задач, 180000 мс (3 мин) после запроса промежуточного статуса.
Push-уведомления (`<subagent_notification>`) приходили, но Codex им не доверял и ждал заново —
отсюда лишний опрос. Сам прописал лечение: на уведомление **сразу обрабатывать результат**, а не
запускать `wait_agent` повторно; после `spawn_agent` не делать длинный `wait_agent`, если есть
локальная работа; один разумный статус-таймер вместо polling-цикла.
## Prior art: obra:superpowers `subagent-driven-development`
Чужой навык глубоко проработан (в том числе по экономии токенов и выбору минимально достаточной
модели) и стоит на той же идее: оркестратор не делает работу сам, держит контекст чистым,
субагенты — «свежий контекст». По части ядра мы переизобретали его.
Как у них устроено: на задачу один эфемерный **implementer** → два последовательных ревьюера
(spec-review → quality-review) → фиксы → следующая задача. Задачи строго последовательны.
Implementer возвращает компактный статус `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT` +
изменённые файлы + итог тестов (без полного вывода). Spec-reviewer читает реальный код и не
доверяет докладу implementer'а. Модель выбирается по роли (дешёвая → стандартная → сильная).
**Берём оттуда:**
- **Ревьюер читает код сам и не верит докладу** — жёсткое правило, убивает Пожар A по построению
(координатор перестаёт быть верификатором).
- **Модель по роли.** Поправка под нас: наш implementer «толстый» (`/goal`), ему нужна сильная
модель; дешёвая выигрывает на субагенте-верификаторе простых находок, docs-проверках и
диагностике (разбор логов мы и сделали на Sonnet).
- **Статус-контракт воркера** `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT` — протокол
эскалации, которого у нас нет: воркер сам стопорится на архитектурной неясности.
- **Качественная стадия ревью** (хорош ли код, межмодульные инварианты).
**Не берём (сознательно другой выбор):**
- У superpowers **толстый план** (~2000 строк, почти реализация) + тонкий механический
implementer. У нас **тонкий issue** (acceptance criteria) + толстый `/goal`, который сам
додумывает реализацию и самопроверяется. Для учебного репозитория наш путь лучше: issue
читаемы менти, реальное решение живёт в петле, нет огромного плана.
- Их **спек-стадия ревью** у нас по большей части избыточна: «выполнили ли спеку» уже проверяет
петля `/goal`. Берём только качественную линзу.
> **Поправка 2026-07-02 (по опыту эксплуатации).** Отменено. На практике два лена ревью
> **разными субагентами** (task-lens «сделал ли то, что в issue/спеке» + code-lens «качество
> и межмодульное») находят **непересекающиеся** множества — и не так редко. Держим оба, но
> как **полный режим** (по порогу риска), а task-lens можно на дешёвой модели. См. раздел
> «Режимы ревью» в `SKILL.md`.
Вывод: `coordinator-loop` остаётся отдельным навыком (своя идентичность — цепочка issue из
`/to-issues`, гейт-классификация находок, владение коммитом). Заимствуем механику делегирования,
а не план-центричную философию.
## Решения сессии — с адресами правок в `SKILL.md`
**Принято (дёшево, метрически обосновано):**
1. **Координатор не читает diff ради проверки находки.** Чтение кода уходит ревьюеру-субагенту:
он читает код сам и возвращает только вердикт. Чинит Пожар A (413 КБ). Куда править:
- «Цикл на одну задачу», **шаг 8 «Свой sanity-check»** — сейчас список включает чтение
(дефолты, compose/конфиги, документы, acceptance criteria, git status, тесты). Сузить:
sanity-check проверяет связи, но **не читает diff/код ради верификации находки** — это
работа ревьюера.
- «Роли», пункт **Координатор** («делает sanity-check») — уточнить так же.
- «Роли», пункт **Независимый ревьюер** — добавить жёсткое правило superpowers: ревьюер
читает код сам и **не верит докладу**; именно он несёт верификацию.
- «Когда звать независимого ревьюера» — это и есть порог, на котором верификация (с чтением
кода) уходит в субагента; для межмодульных инвариантов — обязательно.
2. **Доверять push, не крутить `wait_agent` по кругу.** Пришло `<subagent_notification>` — сразу
обрабатывать; один разумный статус-таймер вместо polling-цикла; после `spawn_agent` не делать
длинный `wait_agent`, если есть локальная работа. Возможно, самый дешёвый одиночный выигрыш
(сток 947 КБ почти случайный, не дизайн). Куда править — **открытый вопрос** (см. ниже):
`wait_agent` — рантайм Codex, а `SKILL.md` host-agnostic. Связано со «Цикл», **шаг 4
«Дождись отчёта»**.
**Намеренная цена — НЕ трогать:**
- `/goal`-петля (~400K токенов/задача) — сознательный обмен на качество решения;
- независимое межмодульное ревью на пороге риска;
- декомпозиция «тонкий issue + толстый `/goal`».
**Кандидаты-фиксы (не приняты, проверить на прогоне) — с адресами:**
- **Точечные тесты в петле, полный тест-сет — только на гейте.** Главный потребитель токенов
(103 ретеста). Риск пропустить межмодульный регресс в середине петли ловит гейт + межмодульный
ревьюер. Куда: «Контракт задания worker-у» (методика тестов) и шаг 12 «Коммит» (полный сет
перед коммитом).
- **Отчёты в формате индекса, а не нарратива.** Куда: «Контракт задания worker-у» →
«формат финального отчёта»: находка/изменение, `файл:строка`, минимальный repro, какой
критерий, что проверить; запрет на вставку diff и полных логов.
- **Статус-контракт воркера** `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT`. Куда:
«Контракт задания worker-у».
- **Демоушн закрытых issue** в компактную durable-форму (`summary`), чтобы компактизация её не
уничтожала. Куда: новый короткий раздел + связь с observability-handoff (`summary.md`).
- **Файловый канал в общем дереве** для обмена находками (оркестрация по ссылке, а не payload
через контекст). Куда: см. observability-handoff (`coordinator-runs/`).
- **Модель по роли.** Куда: «Облегчённый и полный режим» / «Контракт задания worker-у».
- **Только качественная стадия ревью** (спек несёт `/goal`). Куда: «Роли» (ревьюер) + «Когда
звать независимого ревьюера». **(Отменено — см. поправку 2026-07-02 выше в разделе «Prior
art»: два лена ревью держим, спек-линза не избыточна.)**
## Связь с handoff про наблюдаемость
Побратим `2026-06-14-observability-design.md` (рядом) уже спроектировал файловый канал
`coordinator-runs/` (live-логи + `summary.md`, чтение по требованию, координатор не ведёт лог
сам). Это **тот же** файловый канал, что нужен кандидатам-фиксам «демоушн» и «файловый канал».
**Свести в один дизайн, не строить две файловые системы.** Оба не реализованы — слить легко.
## Открытые вопросы (с моей рекомендацией, но не закрыты)
1. **Объём первого захода.** A — полная переделка сразу; B — внести только два дёшевых правила,
остальное пометить «проверить на следующем прогоне». Рекомендация: **B** (держит навык от
разрастания).
2. **Кто верифицирует находку** — автор-воркер со своим знанием кода и проверяемым обоснованием,
или свежий ревьюер? Склонялись к автору на знании + независимый на пороге риска. Не закрыто.
3. **Где живёт правило 2 (push/`wait_agent`).** Это рантайм Codex, а `SKILL.md` host-agnostic.
Куда: короткий раздел «Синхронизация с субагентами» в `SKILL.md` с пометкой «Codex-specific»,
либо `references/rationale.md`, либо привычка оператора. Не решено.
4. **Слить ли два handoff** (этот и про наблюдаемость) в один дизайн до правки `SKILL.md`?
Рекомендация: да.
5. **Кросс-хост.** Файловый канал отчасти оправдан тем, что host-agnostic (Codex и Claude Code).
Если на деле только Codex — обоснование слабее. Уточнить требование.
6. **Носитель для проверки.** Фича почти закрыта (осталась issue 06), новой цепочки под рукой
нет. На чём гонять проверочный прогон — пока неясно; числа-ориентиры ниже остаются baseline
на будущую фичу.
## Числа-ориентиры для следующего прогона
Чтобы измерить, помогли ли фиксы, а не поверить на слово:
- пик контекста координатора: было 77 % окна (199K/258K) — должно заметно упасть;
- собственные diff-чтения координатора: было 413 КБ — должно стремиться к нулю;
- сессия ожиданий/опроса: было 947 КБ при 42/44 таймаутах — push обрабатывается, цикла нет;
- прогоны полного тест-сета: было 103 — точечные в петле, полный только на гейте.
## Что ещё не сделано
- Решения не внесены в `SKILL.md`.
- Кандидаты-фиксы не приняты и не проверены на реальном прогоне.
- Два handoff не сведены.
- Не решён объём первого захода (вопрос 1).
- Не решено, где живёт правило 2 (вопрос 3).
## Рекомендуемые следующие шаги
1. Решить объём первого захода (A vs B).
2. Свести этот handoff с handoff про наблюдаемость в один дизайн.
3. Внести минимум в `SKILL.md` (два принятых правила) по адресам выше, сверяясь с superpowers как
prior art.
4. На ближайшей новой фиче замерить числа-ориентиры; по факту резать или добавлять.
5. Опционально — лёгкая дивергенция/конвергенция через `brainstorm-with-docs`, если решение
захочется поискать шире. Возможно, и не понадобится: два дешёвых фикса метрически очевидны.
## Suggested skills
- `write-a-skill` — при переносе правил в `SKILL.md`, чтобы не раздувать основной файл.
- `brainstorm-with-docs` — если делать полноценный заход с дивергенцией/конвергенцией.
- `conventional-commits` — для коммитов изменений в навыке.
@@ -1,229 +0,0 @@
# Handoff: наблюдаемость coordinator-loop
Дата: 2026-06-14 20:00 MSK
Статус: рабочая договорённость, ещё не внесена в `SKILL.md`
## Зачем этот handoff
Нужно передать на другую машину выводы обсуждения про минимальную наблюдаемость
работы субагентов в `coordinator-loop`. Это не runtime-инструкция: обычный агент
при запуске скилла читает `SKILL.md`, а не этот файл. Если решение надо проверить
на реальном цикле, короткий минимум придётся добавить в `SKILL.md`.
## Контекст
- Скилл: `/home/dementev/dotfiles/agents/.agents/skills/coordinator-loop/`.
- Основная инструкция: `SKILL.md`.
- Человеческое описание и границы: `README.md`.
- Обоснование процесса: `references/rationale.md`.
- В `dotfiles` уже были сделаны коммиты:
- `aa3e362 fix(skill): уточнена обработка чужих правок координатором`
- `8f6d9de docs(skill): уточнено назначение README coordinator-loop`
## Проблема
При долгой работе worker-а координатор и пользователь плохо видят, что происходит.
Чатовый контекст ненадёжен: координатор может уйти в compaction, потерять детали
старта команды или не понять, сколько длится ожидание. При этом нельзя превращать
координатора в секретаря, который постоянно ведёт подробный журнал.
Нужна минимальная наблюдаемость:
- понять, какой issue сейчас в работе;
- увидеть последнюю фазу и последнюю нетривиальную команду;
- восстановить примерную длительность фаз;
- не спамить координатора сообщениями;
- не смешивать процессный шум с рабочими коммитами.
## Принятый дизайн
Использовать feature-local файлы рядом с локальными issues:
```text
.scratch/<feature>/coordinator-runs/
live/ # временные live-логи, в .gitignore
<NN>-<issue-slug>.md
summary.md # короткий итог, можно коммитить
```
Причина: `.scratch/<feature>/` уже является местом локальных issues. Наблюдаемость
должна жить рядом с ними, а не в глобальной папке.
## Git-правило
Не игнорировать весь `.scratch/`: в этом репозитории `.scratch/` используется как
локальный issue tracker и коммитится. Игнорировать только живой шум:
```gitignore
# Временные live-логи coordinator-loop.
.scratch/*/coordinator-runs/live/
```
`summary.md` можно коммитить как итоговый артефакт прогона.
## Live-log
Один файл на issue. Этого достаточно: цикл по feature одноразовый, а если worker
упал и был запущен заново, новый worker продолжает дописывать тот же файл.
Координатор перед запуском worker-а:
1. создаёт `coordinator-runs/live/<NN>-<issue-slug>.md`;
2. передаёт путь worker-у в задании;
3. передаёт тот же путь reviewer-у, если reviewer нужен.
Worker и reviewer:
- только дописывают в конец файла;
- не обязаны читать предыдущие записи;
- ставят текущую временную метку в каждой записи;
- не пишут рассуждения и полный вывод тестов.
Координатор:
- знает путь к live-log;
- читает его только при необходимости: пользователь спросил статус, worker долго
молчит, произошёл фазовый переход, нужен контекст перед коммитом;
- не обязан вручную поддерживать live-log.
## Формат записи
Append-only Markdown-блоки. Они читаются глазами лучше, чем строки с `|`, и не
ломаются от команд с кавычками или длинными путями.
```md
### 2026-06-14 19:52 MSK — worker — tests
- event: started
- command: `uv run pytest tests/generator/test_state.py`
- note: checking state v2 restore cases
```
```md
### 2026-06-14 19:58 MSK — worker — tests
- event: passed
- result: 8 passed
- next: self-review
```
Минимальные поля:
- заголовок: время, роль, фаза;
- `event`: `started`, `progress`, `passed`, `failed`, `blocked`, `heartbeat`,
`restarted`, `final`;
- `command`: команда, если запись про запуск проверки;
- `result`: короткий итог, если есть;
- `next`: следующий шаг, если понятен;
- `note`: короткая поясняющая заметка, если нужна.
## Что логировать
Обязательные события:
- старт работы по issue;
- перезапуск worker-а после сбоя: `event: restarted`;
- смена фазы;
- начало нетривиальной команды;
- результат нетривиальной команды;
- блокер;
- финальный отчёт готов.
Нетривиальная команда: тесты, линтеры, сборка, Docker, миграции, симуляции,
обращение к внешнему сервису, обработка заметного объёма данных, либо любая
команда, длительность которой агент не уверен как оценить.
Не логировать:
- каждую мелкую правку;
- каждый прочитанный файл;
- `rg`, `sed`, `ls`, `git diff`, `git status` и похожие быстрые операции;
- внутренние рассуждения;
- полный вывод тестов.
## Heartbeat
Heartbeat нужен как best-effort, а не строгий таймер.
Если работа длится больше примерно 5 минут и агент находится между командами или
может безопасно прерваться на запись, он дописывает:
```md
### 2026-06-14 19:55 MSK — worker — tests
- event: heartbeat
- note: still working; waiting for simulation/test result
```
Не строить отдельный таймер или фоновый процесс ради heartbeat. Если запущена
блокирующая команда, достаточно записи `event: started` перед ней.
## Почему не state.md
Обсуждали отдельный `state.md`, который хранил бы текущий issue, фазу и ожидаемый
следующий шаг. Отказались: если `state.md` ведёт координатор, это добавляет
нагрузку и снова делает координатора секретарём. Если координатор ушёл в
compaction, восстановиться можно из `git status` и хвоста последнего live-log.
Первый заход: без `state.md`.
## Почему без run-id
Обсуждали `live/<run-id>/<issue>.md`. Отказались: работа над feature идёт как
один проход по issues. Старые прогоны не должны накапливаться. Если worker упал,
новый worker пишет `event: restarted` в тот же файл issue.
## Summary
После завершения issue координатор переносит короткий итог в `summary.md`. Live-log
остаётся временным и игнорируемым.
Формат раздела на issue:
```md
## <NN>-<issue-slug>
Commit: <hash> <subject>
Result:
- <что наблюдаемо работает>
Checks:
- `<command>` — passed/skipped
Review:
- self-review: <summary>
- independent review: <summary or not run>
Risks:
- <none / list>
```
## Что ещё не сделано
- Это решение пока не внесено в `SKILL.md`.
- `.gitignore` проекта пока не обновлён правилом для `live/`.
- Не было реального прогона coordinator-loop с такой наблюдаемостью.
- Нужно решить, делать ли наблюдаемость всегда или только по явной просьбе / для
длинных задач. Текущая рекомендация: включить как лёгкий стандарт для
coordinator-loop, потому что нагрузка на координатора мала.
## Рекомендуемые следующие шаги
1. Внести короткий раздел «Наблюдаемость» в `SKILL.md`, иначе агент при запуске
`/coordinator-loop` не обязан читать этот handoff или README.
2. Добавить в `.gitignore` правило `.scratch/*/coordinator-runs/live/`.
3. На ближайшем реальном прогоне проверить, не создаёт ли live-log лишний шум.
4. После прогона уточнить `SKILL.md`: оставить, упростить или сделать режим
опциональным.
## Suggested skills
- `write-a-skill` — при переносе правил в `SKILL.md`, чтобы не раздувать основной
файл и оставить runtime-инструкции короткими.
- `conventional-commits` — если изменения в скилле или `.gitignore` будут
коммититься.
- `grill-me` — если нужно ещё раз стресс-тестировать развилки: always-on vs opt-in,
формат summary, порог heartbeat.
- `coordinator-loop` — только при реальном прогоне issues после обновления
`SKILL.md`.
@@ -1,52 +0,0 @@
# Handoff: рефрейм coordinator-loop вокруг «индекс, не полный текст»
Дата: 2026-07-02 MSK
Статус: сделано и принято независимым ревью (`/claude-team-review`, 2 раунда, APPROVED). Не закоммичено на момент написания записки — коммит идёт следом.
## Зачем этот handoff
Зафиксировать, что и почему сделано в сессии переписывания навыка, пока свежо. Сам дизайн живёт в `SKILL.md` — сюда его **не** дублирую, только решения, их обоснование и что осталось. Продолжает линию июньских handoff'ов (`2026-06-14-*`): те диагностировали болезнь, эта — лечение.
## Что сделано
`SKILL.md` переписан целиком (194 → 159 строк). Ядро — одно ведущее правило: **координатор работает по индексу, а не по полному тексту** (полный diff / вывод тестов / нарратив ревью в его контекст не входят). Это прямое лекарство от главной болезни из июньского handoff'а «context-economy»: контекст координатора пух от вычитывания сырья, компактился, дальше косяки.
Подробности — в `../SKILL.md`. README и `references/rationale.md` подровнены под новый дизайн; в июньский `2026-06-14-…-context-economy.md` вписана датированная поправка (см. ниже).
## Ключевые решения (и чем обоснованы)
- **User-invoked** (`disable-model-invocation: true`). Навык всегда зовут руками — авто-инвокация была no-op'ом, платившим context load за фразу «не включай меня».
- **Per-finding триаж делегирован `claude-team-review`** (single source of truth). У координатора только chain-level корзины (риск / вне скоупа). Проверено на опыте: у team-review триаж встроен, «не применять слепо» — тоже.
- **Ревьюера запускает сам worker** внутри `/goal`, не координатор → нарративы ревью не доходят до координатора. Чистота контекста «по построению».
- **Режимы ревью по риску/стоимости**: тривиальный → `/goal` + отдельное саморевью свежим взглядом; обычный → один прогон team-review по коду; риск/гейт → два прогона **разными субагентами** (по задаче + по коду), проверку по задаче можно на дешёвой модели. Два лена ловят непересекающиеся находки — **опровергает** прежний наклон июньского handoff'а выкинуть спек-линзу (там вписана поправка).
- **Коммит у координатора**; полный тест-сет на гейте, но в контекст координатора идёт **только сводка** (код возврата + имена упавших), не вывод. Эту дыру (полный тест-лог возвращал Пожар A в координатора) поймал ревьюер — не я.
- **Финал цепочки**: (1) рекомендованное ревью на соответствие замыслу **сильной моделью** — целое против исходной спеки, ловит дрейф, который per-issue срезы не видят; это Codex (одна линия), берёт охват, не кросс-линию; (2) **handoff**, который готовит опциональный ручной кросс-линия проход Клодом и фиксирует непокрытую родословную как видимый риск.
- **Родословная**: внутри Кодекса только модели Codex → team-review из-под Codex = ревьюер той же линии. Кросс-линия — это отдельный рабочий процесс пользователя (Клод пишет проектные документы, Кодекс выполняет), взаимодействие агентов **намеренно не автоматизировано**. Поэтому кросс-линия остаётся ручным опциональным проходом вне скилла.
## Процесс проверки (сам по себе — рабочий приём)
Дешёвый self-проход «проверь свежим взглядом» до дорогого ревью — сокращает список находок; сохранён в память `feedback_fresh_eyes_first_pass.md`. Полное ревью — через `/claude-team-review` (Codex-эквивалент `/adversarial-review` для опинейтед-скиллов не годится — «улучшит» намеренный дизайн). Ревью нашло 3 important + 4 minor, все закрыты, вердикт APPROVED.
## Что не сделано / открытые вопросы
- **Не замерено на реальной цепочке.** Числа-ориентиры из июньского handoff'а (пик контекста 77 %, 413 КБ diff-чтений, 103 полных тест-прогона) — baseline; рефрейм под них ещё не гонялся. Кандидат-носитель рядом: `.scratch/training-feedback-loop/issues/` в проекте pole-equipment-detector.
- **Кандидаты-фиксы намеренно не внесены в SKILL.md** (непроверены): файловый канал `coordinator-runs/`, демоушн закрытых issue в `summary.md`, точечные тесты в петле vs полный сет на гейте как метрика, live-log наблюдаемости. Живут в июньских handoff'ах — вносить по факту замера, не вслепую.
- Развилка «автор-воркер vs свежий ревьюер как верификатор нериск-находок» решена в пользу воркера с богатым контрактом — но это выбор, не доказанная истина.
## Где что лежит
- Источник-правды: `~/dotfiles/agents/.agents/skills/coordinator-loop/` (git, ветка master, remote gitverse). `~/.claude/skills` — симлинк на `~/dotfiles/agents/.agents/skills` (тот же инод), правка одной точки меняет обе.
- Память сессии: `~/.claude/projects/-home-ddmitry-sources-pole-equipment-detector/memory/feedback_fresh_eyes_first_pass.md`.
## Рекомендуемые следующие шаги
1. Прогнать реальную цепочку (`.scratch/training-feedback-loop/issues/`) под новым `coordinator-loop`, замерить числа против baseline.
2. По факту замера решить судьбу кандидатов (файловый канал / демоушн / метрика тестов).
3. Если понадобится развести наблюдаемость и файловый канал — свести два июньских handoff'а в один дизайн (их «Связь» это предусматривала).
## Suggested skills
- `coordinator-loop` — при реальном прогоне цепочки для замера.
- `writing-great-skills` — если по итогам замера править `SKILL.md` (держать от разрастания).
- `claude-team-review` — ревью правок навыка (не `adversarial-review`).
- `conventional-commits` — для коммитов изменений навыка.
@@ -1,211 +0,0 @@
# Handoff: топология ревью под Codex, эскалация и дисциплина финала
Дата: 2026-07-04 MSK
Статус: пакет правок по итогам боевого прогона; прошёл адверсарное ревью свежим
субагентом (2 блокера, 7 important, 4 minor — все закрыты правкой этого текста).
Внесено в `SKILL.md` и закоммичено той же сессией; итог сессии — в
`2026-07-04-rework-session-claude-line.md` (рядом).
## Зачем этот handoff
Зафиксировать решения по итогам первого боевого прогона переписанного скилла
(цепочка issue 07 → 11 фичи `generator-model-time-startup-history`,
репозиторий `~/sources/clickstream-ch-kafka-superset-demo`) до правки `SKILL.md`.
Источник фактов — журнал прогона
`.scratch/generator-model-time-startup-history/coordinator-journal.md`
(коммиты `d2899e9`, `5081319`, `0a240e3`): отдельного handoff'а координатор не
написал, диагностика лежит в журнале.
## Что показал прогон
Хорошее: дисциплина «индекс, не полный текст» удержалась; журнал фиксировал
происхождение ревью в момент события; финальное chain-ревью поймало дрейф PRD.
Контекст координатора, по впечатлению пользователя, не страдал (прерывания и
дополнительные вопросы прогон пережил) — но это наблюдение, не замер:
числа-ориентиры июня (пик % окна, объём diff-чтений, число тест-прогонов) на
этом прогоне не сняты, сырьё в `~/.codex` ротируется. Пункт остаётся открытым.
Проблемы:
1. **Worker не может запускать субагентов в среде Codex.** У субагентов нет
`multi_agent_v1.spawn_agent`; `tool_search` не находит ни spawn, ни
`claude-team-review`. Проверено дважды: read-only диагностом и отдельным
диагностом с `agent_type=worker` (журнал, записи «Диагностика nested review
tools»). Ключевое допущение дизайна («ревьюера запускает сам worker внутри
`/goal`») в этой среде не работает. Координатор импровизировал: запускал
ревьюеров сам и возвращал worker-у индекс находок — сработало.
2. **Пинг-понг ревью без ограничителя.** Issue 07 прошёл пять кругов code
review; спорная находка (raw-сериализация) продержалась два круга, пока
координатор не изобрёл «узкий гейт на xhigh» по одной находке (усиленный
уровень понадобился на двух кругах из пяти плюс на финальном chain-ревью —
и по делу). Ограничителя и правил эскалации в скилле нет — открытые вопросы
rationale стали боевыми.
3. **Статус-контракт смешивает «работа заблокирована» и «шаг процесса
недоступен»**: worker по issue 11 вернул `BLOCKED` при готовой реализации —
заблокирован был только механизм ревью. Со стендовыми проверками так же:
docker недоступен в песочнице worker-а (07).
4. **Финальный handoff не написан** — шаг «Финал цепочки, п.2» тихо выпал,
бриф для кросс-прохода никто не получил.
5. **Закрытие issue делалось, но внутри feature-коммитов**: статусы 07 и 11
переведены в `done` в коммитах `3c38465` и `4f8f992` — процессная правка
смешана с рабочим diff. Прошлая цепочка (01–06) хуже: статусы остались
неверными («ready-for-human от глючившего координатора», триаж 2026-07-04).
Правила в скилле нет — каждый прогон решает по-своему.
6. **Журнал без меток времени** — длительность этапов и границы issue по
времени не восстановить. Метка времени была в дизайне live-log
(`2026-06-14-observability-design.md`) и потерялась, когда live-log «вырос
в журнал» (2026-07-03).
## Решения (пакет правок)
1. **Датированный факт среды вместо preflight-пробы.** В `SKILL.md` — короткая
врезка: «Среда Codex (проверено 2026-07-04): worker не может запускать
субагентов; ревьюеров запускает координатор». Не перепроверять каждый
прогон — только при сигнале обратного (например, `tool_search` нашёл spawn).
Гонять диагностику на каждой цепочке — жечь токены и время.
2. **Топология ревью: запуск у координатора, триаж у worker-а.**
- Координатор запускает reviewer-субагентов-**наблюдателей** и пересылает
worker-у индекс находок дословно, без своих интерпретаций (он не читает
код и судить не может). Наблюдатель — не read-only субагент: инструменты
полные (тесты, воспроизведение, поиск), ограничение «не менять репозиторий
и среду» держится промптом — как в `claude-team-review`.
- `claude-team-review` запускает только **владелец правок** — worker, в
средах, где worker может запускать субагентов. Координатору запускать
team-review нельзя: его лид чинит код сам, а это второй писатель в дереве
и слом границы «координатор кода не трогает». Под Codex механизм —
reviewer-субагент координатора с ревью-промптом; промпт адаптирован в
`references/reviewer-prompt.md` самого скилла (из `claude-team-review`) —
скилл самодостаточен, внешних файлов не требует.
- Триаж находок остаётся в worker-е: у него контекст кода и «зачем» из
контракта. Worker вправе аргументированно отклонить находку — через
контракт и тест, не голословно (приём из прогона).
- Бонус топологии: координатор видит зацикливание ревью (см. п.4).
- Цена: индексы ревью идут через контекст координатора, по кругу на каждый
rerun. Прямого замера этого трафика нет (июньские 2,6 КБ — замер
финальных отчётов worker-ов, не пер-раундового трафика ревью), но порядок
тот же — килобайты. Если на длинной цепочке начнёт пухнуть — готовый
фолбэк: файловый канал из `2026-06-14-observability-design.md` (ревьюер
пишет индекс в файл, координатору — путь и вердикт). Сейчас не вносим.
3. **Контракт ревьюеру** (новый, симметричен контракту worker-а): наблюдатель
с полными инструментами (ограничение «не менять репозиторий и среду» —
промптом), код читает сам и докладу worker-а не верит; возвращает
**индекс** — находка,
`файл:строка`, какой критерий нарушен, минимальный repro; вердикт одной
строкой (`APPROVED` / `CHANGES_REQUESTED`); запрет вставлять diff, полный
вывод тестов и нарратив рассуждений. Уровень мышления и модель задаёт
координатор при запуске (см. п.5).
4. **Политика кругов ревью.** Тождество находок между кругами судит не
координатор (по индексам оно не определяется — формулировки и `файл:строка`
между кругами плывут, что видно по прогону 07), а **worker в триаже**: если
ревьюер снова поднимает вопрос, который worker уже аргументированно
отклонял, worker помечает это в своём индексе флагом **«спор»** с отсылкой
к прежнему обоснованию. Координатор реагирует на флаг и на общий счётчик:
- **спор** → не общий rerun, а узкий гейт по спорному вопросу на усиленном
уровне (паттерн «xhigh narrow gate» из прогона);
- спор пережил и узкий усиленный гейт → **стоп, решение человека**;
- независимо от споров: больше **четырёх** кругов ревью на issue → стоп,
координатор выносит человеку вопрос «дробить issue или принимать риск»
(потолок взят по прогону 07 — пять кругов прошли без управления);
- rerun после правок по гейт-находкам назначает координатор автоматически —
это больше не concern worker-а (в прогоне дважды висело «rerun ещё не
выполнен»).
5. **Две ручки стоимости: модель по роли и уровень мышления.** Это разные оси,
не смешивать: «модель по роли» в скилле уже есть (дешёвая на task-lens,
сильная на финале), прогон же эскалировал **уровень рассуждений** (xhigh)
на той же модели. Вводим три относительных уровня без имён:
*экономный* (ступень вниз: task-lens ревью, диагностика, разбор логов),
*рабочий* (дефолт: worker, обычное code review), *усиленный* (ступень
вверх: эскалация по п.4, находки про межмодульные инварианты и форму
распределений, финальное chain-ревью — усиленный уровень на сильной
модели). Соответствие ролей конкретным моделям и уровням хоста — датированная
таблица `references/effort-levels.md`; логика скилла имён не знает. Дефолт —
рабочий уровень, вверх только по триггеру. Хост без управляемых уровней:
эскалация вырождается в «свежий субагент». Уровень фиксируется в записи
журнала о запуске ревью.
6. **Происхождение ревью пишет координатор в журнал** — в момент запуска и в
момент вердикта: режим, механизм, кто запускал, уровень, вердикт. Worker
больше не автор этой строки (факты «кто запускал» и «уровень» знает только
координатор); в индексе worker-а остаются саморевью и триаж (включая флаг
«спор»). Честная граница прежняя: журнал — самозапись координатора,
append-only след для внешней проверки; ложь в моменте ловит кросс-линия и
человек, не сам журнал.
7. **Метка времени в журнале.** Каждая запись начинается с `HH:MM` (дата — в
заголовке дня; время брать вызовом `date`, модель его не знает). Порог
записей прежний — точки записи из раздела «Журнал прогона»; мельче
(каждая команда, каждый прочитанный файл) не писать, чтобы метки не
превратили журнал в спам. Heartbeat worker-а в пакет **не входит**: журнал
пишет только координатор, файлового канала нет, а слать сигналы в контекст
координатора — противоречить его экономии. Если когда-нибудь вносим
файловый канал — heartbeat возвращается вместе с ним (дизайн готов в
observability-handoff).
8. **Статус-контракт: недоступность стендовой проверки ≠ `BLOCKED`.** Если
проверка (docker, стенд, сеть) недоступна в среде worker-а, он возвращает
`DONE_WITH_CONCERNS` с фактом («docker отсутствует: <вывод>») и **готовой
командой**, которую координатор прогоняет сам. `BLOCKED` — только про саму
работу. Оговорка по прогону: команда может не пройти и у координатора
(на коммит-гейте 11 `snap-confine` ломал dry-run в sandbox — перегоняли вне
sandbox); тогда координатор фиксирует в журнале, где и как проверка
прошла фактически. Случай «ревью недоступно worker-у» из контракта уходит
совсем — worker ревью больше не запускает (п.2).
9. **Дисциплина финала.**
- Обновить PRD/трекер **до** финального chain-ревью, чтобы оно проверяло
приведённое состояние (low finding прогона — предсказуемый класс).
- После коммит-гейта issue — `Status: done` в файле issue, **docs-коммитом
вместе с журналом**, не в feature-коммите. Это смена фактического
поведения (прогон 07/11 закрывал статусы внутри feature-коммитов):
файл issue — процессный, как и журнал, и на границе шага 6 «только файлы
worker-а» он файлом worker-а не считается.
- Финальный handoff обязателен для нетривиальной цепочки и является
**условием выхода из цикла**, а не пунктом-пожеланием; место и формат — по
конвенции репозитория (AGENTS.md / ADR), если она есть.
## Куда править
- `SKILL.md`:
- frontmatter `description` («с ревью через claude-team-review» — убрать);
- «Роли» — ревьюер: запускает координатор, наблюдатель, контракт по п.3;
- врезка про среду Codex (п.1);
- «Цикл» — шаги 4–6: приём индекса ревью, политика кругов и rerun (п.4),
происхождение в журнале (п.6), закрытие issue (п.9);
- «Журнал прогона» — метка времени (п.7), происхождение пишет координатор;
- «Контракт задания worker-у» — убрать запуск team-review worker-ом,
добавить триаж находок ревью + флаг «спор», статус-контракт по п.8;
- новый раздел «Контракт ревьюеру» (п.3);
- «Режимы ревью» — две ручки (модель по роли + уровень мышления), таблица
`references/effort-levels.md` (п.5);
- «Классификация находок» — триаж делает worker, не «team-review внутри
worker-а»;
- «Финал цепочки» — порядок: PRD/трекер → chain-ревью (усиленный уровень на
сильной модели) → handoff как условие выхода (п.9);
- чек-лист — привести к новым ролям (происхождение в журнале, уровни,
handoff обязателен, закрытие issue).
- `README.md`: строка потока и раздел «Что получается» («/goal + /tdd +
claude-team-review», «per-finding триаж делает claude-team-review внутри
worker-а»), «сильной моделью» в описании финала, раздел «Статус и что
дальше» — открытый вопрос «бюджет кругов ревью» закрывается п.4.
- `references/rationale.md`: датированная поправка 2026-07-04 — факт среды
Codex, боевое подтверждение вопросов про круги ревью, закрытие вопроса
«бюджет кругов» политикой п.4.
- `references/effort-levels.md`: новая датированная таблица уровней (п.5).
## Чего сознательно не делаем
- Файловый канал / `coordinator-runs/` — не вносим, зафиксирован как фолбэк
(п.2) и носитель heartbeat (п.7).
- Preflight-проба среды на каждый прогон — отвергнута (расход без пользы).
- Автоматизация кросс-линейного прохода — по-прежнему вне скилла.
- Замер чисел-ориентиров июня — не сделан в этом прогоне и не закрыт; снять
на следующей цепочке, пока сырьё в `~/.codex` не ротировалось.
## Suggested skills
- `conventional-commits` — коммиты в dotfiles.
- `coordinator-loop` — следующий боевой прогон (цепочка 12 или 08) как замер.
@@ -1,163 +0,0 @@
# Handoff: сессия переработки скилла по итогам боевого прогона
Дата: 2026-07-04 MSK (вечер, после прогона 07 → 11); дополнено 2026-07-05
(после прогона 15 → 19, см. последний раздел).
Статус: сделано и закоммичено (`2d9fc7e` в dotfiles). Сессия Claude Code —
правки вносила модель другой родословной, чем та, что гоняла прогон.
## Зачем этот handoff
Продолжение в новой сессии: что решено, как проверено, что осталось. Сами
решения и их обоснования — в пакете правок рядом
(`2026-07-04-codex-topology-and-escalation.md`), сюда их не дублирую.
Отдельно стоит зафиксировать форму: разбор прогона Codex и переработку скилла
делал Claude — по сути это был кросс-линейный проход по **процессу** (не по
коду фичи). Он же дал главный улов сессии — см. ниже. Рабочее разделение
пользователя (Claude — документы и планы, Codex — исполнение) на скиллах
работает так же, как на коде.
## Как проверялось (сам процесс — рабочий приём, повторить)
1. Черновик пакета → **адверсарное ревью свежим субагентом** с проверкой
каждого утверждения по первоисточникам (журнал прогона, SKILL.md, старые
handoff'ы). Улов: 2 blocker, 7 important, 4 minor — все закрыты правкой
пакета до внесения в SKILL.md.
2. Внесение → **лёгкое саморевью свежим взглядом** (без субагентов): 4 находки,
3 исправлены.
3. Досоздание `reviewer-prompt.md` → ещё одно лёгкое саморевью: 2 находки
(обе реальные — untracked-файлы невидимы в diff; предусловие ревью-гейта),
исправлены амендом.
Блокеры адверсарного ревью били по ядру пакета (неисполнимый критерий «та же
находка» в политике кругов; team-review из-под координатора = второй писатель) —
без этого шага они уехали бы в SKILL.md.
## Повороты после ревью (чего не было в исходном замысле)
- **Наблюдатель, не read-only** — поправка пользователя: ревьюеру нужны
инструменты (тесты, воспроизведение, поиск), ограничение «не менять
репозиторий и среду» держится промптом, как в `claude-team-review`.
- **Скилл сделан цельным**: `references/reviewer-prompt.md` — адаптация
шаблона из `claude-team-review` под нашу топологию (чинящего лида нет,
вердикты наши, четыре фокуса, блок rerun учитывает отклонения worker-а).
Зависимость от файлов чужого скилла снята.
- **Тождество находок судит worker** (флаг «спор»), координатор считает
только круги — ответ на блокер ревью.
- Определение круга, критерий закрытия гейта, предусловие ревью-гейта
(`DONE`/`DONE_WITH_CONCERNS`) — из саморевью.
## Что не сделано / открытые вопросы
- **Числа-ориентиры июня не замерены** (пик контекста, трафик через
координатора, тест-прогоны): «контекст не пострадал» в прогоне 07 → 11 —
впечатление пользователя, не замер. Снять на следующем прогоне по горячему:
сырьё в `~/.codex` (logs/sessions) ротируется.
- **Политика кругов не проверена вживую** — потолок четыре круга и флаг
«спор» появились после прогона; первый боевой тест — следующая цепочка
(12 «DAG-пульт» или 08 «миграция курса» в clickstream-репозитории).
- **`references/effort-levels.md` — первый черновик**: соответствия уровней
подобраны по одному прогону, калибровать по журналам (уровень пишется в
происхождение ревью — данные будут копиться сами).
- **Кросс-хост не гонялся**: ветка Claude Code в effort-levels — умозрительная.
## Где что лежит
- Пакет правок с обоснованиями: `2026-07-04-codex-topology-and-escalation.md`
(рядом).
- Изменённые файлы: `SKILL.md`, `README.md`, `references/rationale.md`
(поправка 2026-07-04), новые `references/effort-levels.md` и
`references/reviewer-prompt.md`.
- Журнал боевого прогона-источника:
`~/sources/clickstream-ch-kafka-superset-demo/.scratch/generator-model-time-startup-history/coordinator-journal.md`.
## Дополнение той же ночью: вторая волна правок по живому прогону
Прогон цепочки 12 → 14 → 09 → 10 → 08 (Codex) шёл параллельно с этой сессией и
дал шесть процессных находок; все закрыты правками скилла до конца прогона
(коммиты `9fda85f`…`12a4783`):
- субагенты — свежими сессиями, без форка истории координатора; но свежая
сессия — правило запуска, не запрет продолжения: узкий rerun — тем же
ревьюером через `send_input` (обратное сожгло пять полных xhigh-кругов
финального ревью);
- уровни мышления: субагенты не наследуют уровень сессии (дефолт spawn —
medium), задавать явно; в журнал — фактическое значение, не название яруса;
таблица перекалибрована: worker обычных issue — medium, любое ревью — high
(эксперимент, критерий выхода — круги ревью по журналам), спор/финал — xhigh;
- финал: находки — по классу файла (процессные чинит координатор, проектные —
fixer-субагент; триаж — у fixer-а); словарь статусов отчётов
(«APPROVED финального ревью ≠ завершение цепочки»); предупреждение о расходе
на третьем круге.
Кросс-линейный проход по итогам цепочки (Claude, 4 параллельных адверсарных
ревьюера с исполняемыми доказательствами) дал 1 critical, 5 high, 10 medium,
4 low после APPROVED финального ревью линии — третий случай подтверждения
находки о родословной; отчёт —
`clickstream-repo:.scratch/handoffs/20260705-0002-cross-review-generator-chain.md`.
Урок сессии: живой прогон под наблюдением человека — самый дешёвый источник
процессных находок; все шесть дефектов увидел пользователь на экране/в журнале,
ни один — самоотчёт координатора.
## Дополнение 2026-07-05: ретро прогона 15 → 19 и калибровка (Claude)
Цепочка 15 → 18 плюс багфикс-issue 19 по кросс-ревью (Codex) завершена. После неё
Codex дал ретро по скиллу и разбор вопроса «не зря ли worker-ы на medium»; Claude
сверил ретро с журналом прогона — первый случай, когда самоотчёт линии полностью
сошёлся с первоисточником (Codex отвечал по журналу, а не по памяти).
- **Эксперимент medium-worker: критерий выхода не сработал.** Medium-issue в
основном закрывались за один круг ревью (16, 18, 12, 08 — по одному; 17 и 10 —
по два), а issue 15 на high тоже собрал круг находок — глубина не покупает
чистый первый проход. Решение: уровни в таблице не менять, точность даёт
классификация issue. Итог записан в `references/effort-levels.md`.
- **Три правки скилла** (коммит `b8f1fe0`): предусловие входа (качественно
подготовленные issue — обычно выход `/to-issues`; мутные — сначала прояснение
замысла, иначе цикл превращается в машину ревью-кругов); точная граница чтения
координатора (запрет только на код ради верификации, процессные артефакты — его
зона); расширенный классификатор риска (версионирование state, разрушающие пути
во внешние сервисы, fail-open проверки) — по нему issue 17 ушёл бы в гейт сразу.
- Правки держались проектно-нейтральными (поправка пользователя): полный
тест/линт-гейт — дело репозитория, скилл предписывает лишь «полный тест-сет».
- Закрыты два пункта из «не сделано» выше: `effort-levels.md` откалиброван по
журналам двух цепочек; **политика кругов прошла живой тест** — узкие rerun'ы
продолжением того же ревьюера работали, потолок четырёх кругов не достигнут ни
на одном issue.
- Осталось открытым: числа-ориентиры (пик контекста, трафик через координатора)
так и не замерены; ветка Claude Code в effort-levels — по-прежнему
умозрительная, кросс-хост не гонялся.
### Вторая волна той же сессии: кросс-ревью правок и контракт автономного прогона
Правки прошли два круга кросс-ревью Codex (та линия, что гоняла прогон, читала
правки этой), находки сходились по убыванию — признак, что текст стабилизировался:
- Круг 1, medium: «Дефолт — рабочий уровень» противоречил таблице effort-levels
(worker обычного issue — экономный) и толкал запускать всех worker-ов на high.
Остаток старой формулировки, пропущенный саморевью при правке соседнего текста.
Исправлено: уровень — по роли и классу issue из таблицы, дефолта «для всех» нет;
заодно «форма распределений» расширена до доменных инвариантов данных — скилл
общий, не только для генератора (`1d67a3f`, тронут и `reviewer-prompt.md`).
- Круг 2, одна находка: в новом разделе «живой стенд» ошибочно попал в класс
«может проверить только человек». Разведено по статус-контракту: недоступное
worker-у прогоняет координатор (часть коммит-гейта), открытый риск в handoff —
только недоступное и ему (`c959911`).
**Новый раздел «Контракт автономного прогона»** (`f6b9b3b`) — по предложению Codex
из ретро; пользователь подтвердил: скилл и проектировался под сценарий «передал
очередь issue и ушёл», но контракт вызова нигде не был записан. Внесено компактно,
не по полному эскизу Codex: вход (список issue, порядок, «зачем»), мандат (весь цикл
без уточняющих вопросов; локальные коммиты — да, push/теги/разрушение внешнего —
только по поручению), стоп-условия **сводкой со ссылками на разделы-первоисточники**,
не пересказом — чтобы не разъезжались. Попутно снят конфликт с автономностью:
предупреждение о третьем круге ревью — не вопрос, ответа не ждать, жёсткая граница —
потолок кругов. Назначение вынесено в description скилла.
Открытое: контракт автономного прогона вживую не проверен — первый тест на
следующей цепочке.
## Suggested skills
- `coordinator-loop` — багфикс-цепочка по кросс-ревью = следующий замер.
- `conventional-commits` — коммиты по итогам прогона.
@@ -1,53 +0,0 @@
# Уровни мышления и модели по ролям
Обновлено: 2026-07-05. Логика скилла оперирует относительными уровнями
(экономный / рабочий / усиленный) и «моделью по роли»; здесь — привязка к
конкретным настройкам хостов. Вышла новая модель или переименовались уровни —
правится этот файл, не `SKILL.md`.
## Codex CLI (проверено на боевых прогонах 2026-07-04 и 2026-07-05)
Ручка уровня — reasoning effort субагента (`low` / `medium` / `high` / `xhigh`).
**Субагенты НЕ наследуют уровень сессии.** У `spawn_agent` свой дефолт — `medium`:
промолчал про уровень — получил ступень ниже рабочей (наблюдение прогона issue 12:
сессия `high`, worker и ревьюер молча ушли на `medium`). Уровень задавай **явно
каждому субагенту** при запуске.
| Роль | Уровень | Настройка |
|---|---|---|
| worker на обычном issue; task-lens ревью, диагностика, разбор логов | экономный | `medium` |
| **любое code review**; worker на гейтовом issue | рабочий | `high` |
| узкий гейт по спору, финальное chain-ревью | усиленный | `xhigh` |
Почему ревью глубже worker-а, а не наравне: у worker-а есть страховочная сетка ниже
по течению (тесты в петле, саморевью, ревью, коммит-гейт), у ревьюера её нет —
пропущенную находку не ловит никто до кросс-линии и человека, «не нашёл» выглядит как
«искать было нечего». Плюс экономика: worker — самая дорогая петля (~400K токенов на
issue), ревью — один короткий прогон; глубина дешевле там, где прогон короткий, а цена
пропуска — целый лишний круг.
Калибровка по журналам двух цепочек (2026-07-05): worker-ы на `medium` в основном
закрывались за один круг ревью; worker на `high` всё равно собрал круг находок — глубина
не покупает чистый первый проход, ревью нужно при любом уровне. Вывод: уровни в таблице
не менять; точность даёт **классификация issue** (обычный или гейтовый — «Порог риска»
в SKILL.md), а не повышение уровня всем worker-ам.
Модель по роли: во всех ролях — модель сессии; отдельной дешёвой модели для
субагентов в текущей конфигурации нет, экономия достигается уровнем.
## Claude Code (если прогон под этим хостом)
Ручки: effort субагента (`low` / `medium` / `high` / `xhigh` / `max`) и model
(`haiku` / `sonnet` / `opus`).
| Роль | Уровень | Настройка |
|---|---|---|
| worker на обычном issue; task-lens ревью, диагностика, разбор логов | экономный | модель ступень ниже, effort `low`–`medium` |
| любое code review; worker на гейтовом issue | рабочий | модель сессии, effort `high` |
| узкий гейт по спору, финальное chain-ревью | усиленный | сильная модель, effort `xhigh`–`max` |
## Хост без управляемых уровней
Эскалация вырождается в запуск свежего субагента — слабее, но не пусто
(см. `SKILL.md`, «Режимы ревью»).
@@ -1,124 +0,0 @@
# Почему цикл устроен именно так
Это эмпирика, на которой стоят правила в `SKILL.md`. Читать не обязательно перед
каждым запуском — нужна, когда хочешь понять, какому классу дефектов какой шаг
противостоит, или решить спорный случай.
Источник — эксперимент на цепочке из трёх зависимых задач генератора кликстрима
(калибровка интенсивности, state версии 2 и рестарт, интеграция сервиса). Задачи
меняли близкий код, поэтому шли строго последовательно, по одному worker-у на
issue. Выводы — хороший сигнал для класса «последовательные инженерные срезы с
тестами и acceptance criteria», но не универсальная истина: один репозиторий, один
домен, три задачи.
## Что какой шаг ловит
> **Поправка 2026-07-02.** Ниже — эмпирика эксперимента, не текущий процесс. В переписанном
> `SKILL.md` координатор больше **не** верифицирует чтением кода: сквозной sanity-check (связи
> дефолтов/конфигов/документов/acceptance) ушёл независимому ревьюеру и финальному ревью на
> соответствие замыслу. Читай раздел как «что какой шаг ловил», а роли бери из `SKILL.md`.
- **Саморевью worker-а** хорошо ловит локальные несостыковки своей же реализации:
забытый старый дефолт, слишком широкий тест, устаревшие числа в конфиге,
двусмысленный README. У worker-а уже есть подробный контекст, поэтому он дёшево
находит такие вещи — но только если запретить ему править на первом шаге и
попросить сначала выдать находки.
- **Sanity-check координатора** добавляет то, что саморевью структурно не видит:
связи между дефолтами, обычным запуском, документами и acceptance criteria.
Пример из эксперимента: новый базовый поток конфликтовал со старым нижним
пределом числа событий на тик — каждая настройка по отдельности «корректна», а
вместе ломали критерий интенсивности.
- **Отдельный ревьюер** ловит то, что не видит ни worker, ни его саморевью:
падение на битом сохранённом состоянии, которое проходит первичную загрузку;
слишком большой снимок состояния (мегабайты вместо компактного); слабый
интеграционный тест, который формально проходит, но не доказывает уход от
старой плоской модели.
- **Повторный круг ревью после большого исправления.** Когда правка по находке
меняет дизайн или формат данных, она сама нуждается в ревью. В эксперименте
переделка компактного состояния закрыла старый дефект и тут же внесла рядом
новый — его поймал именно второй круг.
## Центральная находка про родословную
Главную гипотезу эксперимента проверяло отложенное ревью **моделью другой
родословной** — той, что вела дизайн и спеки, а не той, что писала код.
Прогноз, что цикл пропустит ссылочную целостность при восстановлении состояния, **не
оправдался**: этот точечный дефект цикл поймал сам (саморевью и отдельный ревьюер
независимо нашли «битое состояние проходит загрузку, но роняет восстановление», и в
коммит легли обёртка и регрессионный тест).
А до внешнего взгляда дожили дефекты **не точечные, а сквозные**:
- **Расхождение живого и восстановленного путей.** Живой визит и восстановленный
после рестарта брали атрибуты из разных источников и по-разному генерировали
идентификаторы событий. Инвариант «один визит — однородный контекст» нарушался на
стыке двух путей, который ни один тест не сводил вместе.
- **Форма распределения длины визита.** Среднее и конверсия — на цели, воронка
монотонна (тесты это подтверждали), но форма уехала от эталона: спайк на коротких
визитах, заметная доля срезов о верхний потолок, медиана у нижней границы тестовой
полосы. Тесты пинили средние и пороги, но не форму.
Отсюда уточнение: ценнее всего ревьюер **другой родословной**, и именно там, где
свойство (а) тянется через несколько модулей или путей, либо (б) корректность
распределительная (форма, а не одно среднее). Для точечных дефектов на входе
хватает саморевью и отдельного ревьюера той же линии.
Поэтому в `SKILL.md` независимый ревьюер по умолчанию — свежий субагент той же
модели, но с честной оговоркой: свежий контекст снимает память о реализации, а не
общую слепоту линии. Эти два семейства (межмодульное и распределительное) ему надо
давать как явную цель, а незакрытое кросс-линейное ревью на gate — фиксировать как
риск.
> **Поправка 2026-07-03.** Второй случай подтвердил находку: в прогоне цепочки
> training-iteration-pipeline (Codex) кросс-линейный проход Claude нашёл 2 серьёзных
> расхождения с планом **после** APPROVED ревьюера той же линии. Поэтому в `SKILL.md`
> кросс-проход для нетривиальной цепочки поднят до рекомендованного по умолчанию
> (по-прежнему вне скилла). Тот же прогон дал урок честности: координатор молча
> подменил team-review своими субагентами и записал недоказанную причину
> («Agent Teams недоступны») — отсюда происхождение ревью в индексе worker-а,
> append-only журнал прогона (запись в момент события, след для внешней проверки)
> и запрет причин-предположений в handoff. Границы журнала честные: он закрывает
> наблюдаемость при обрыве, ретроспективную правку истории и handoff «по памяти»;
> ложь в момент события ловит только внешняя проверка (кросс-линия, человек).
> **Поправка 2026-07-04.** Боевой прогон цепочки 07 → 11 (генератор кликстрима) дал два
> уточнения. Первое — факт среды: в Codex worker не может запускать субагентов
> (проверено диагностом с `agent_type=worker`), поэтому топология изменена — ревьюеров
> запускает координатор, а триаж находок остаётся в worker-е (см. `SKILL.md` и handoff
> `2026-07-04-codex-topology-and-escalation.md`). Второе — вопросы про число кругов
> ревью из списка ниже стали боевыми: issue 07 прошёл пять кругов без ограничителя, а
> спор с ревьюером разрешил изобретённый по ходу «узкий гейт на xhigh». Ответ закреплён
> политикой кругов в `SKILL.md`: флаг «спор» в триаже worker-а, узкий гейт на усиленном
> уровне, потолок четыре круга на issue, дальше — человек.
> **Поправка 2026-07-05.** Третий случай подтверждения находки о родословной, самый
> сильный по контрасту: кросс-проход Claude по цепочке 12 → 14 → 09 → 10 → 08 дал
> 1 critical, 5 high (и 14 находок ниже) **после** APPROVED финального xhigh-ревью
> той же линии. Улов лёг ровно в предсказанные классы: сквозные сценарии через
> несколько модулей («смешение миров» тремя дорогами, «чистый клон никто не прошёл»)
> и честность проверок (ложнозелёные тесты и стыковая проверка). Локальные дефекты
> внутренние ревью закрыли честно — кросс-линия их не переоткрывала. Отчёт:
> `clickstream-repo:.scratch/handoffs/20260705-0002-cross-review-generator-chain.md`.
## Чего не делать слепо
- Не запускать ревьюера после каждой мелкой правки — дорого и раздувает задачу.
- Не принимать все находки за правду — каждую классифицировать.
- Не давать координатору верхнеуровневый `/goal` на всю цепочку — нужна
управленческая осторожность, а не достижение цели любой ценой.
- Не смешивать процессные и handoff-заметки с рабочими коммитами задач.
- Не требовать реальный внешний стек на каждом шаге, если acceptance criteria
допускают мок, — но явно фиксировать, что именно осталось непроверенным.
## Открытые вопросы
Эксперимент оставил нерешённым:
- как заранее понять, что задаче нужен отдельный ревьюер, а не только саморевью;
- стоит ли заранее обязывать worker-а к промежуточным отчётам на статистике и
долгих тестах;
- нужно ли явно ограничивать бюджет worker-а (число кругов ревью закрыто политикой
кругов — поправка 2026-07-04);
- как формализовать порог «большое исправление требует второго круга» (частично
закрыто: rerun после правок по гейт-находкам координатор назначает автоматически).
@@ -1,120 +0,0 @@
# Шаблон промпта ревьюеру
Координатор заполняет плейсхолдеры и передаёт текст как промпт
reviewer-субагенту. Адаптирован из `reviewer-prompt.md` скилла
`claude-team-review` (2026-07-04) под топологию coordinator-loop: чинящего
лида здесь нет — правит worker по индексу находок, круги считает координатор.
---
## Шаблон
```text
Ты — старший адверсарный ревьюер. Твоя работа — подорвать доверие к изменению,
а не подтвердить его. Скепсис по умолчанию: считай, что в работе есть дыры,
пока доказательства не показали обратное. Не засчитывай добрые намерения и
«допилят следом». Работает только на happy path — это настоящая слабость.
## Фокус проверки
{FOCUS}
# по коду — тонкие баги, межмодульные инварианты, доменные инварианты данных
# (например, форма распределений, если она важна проекту)
# по задаче — сделано ли то, что требует issue/спека (acceptance criteria)
# узкий гейт — только спорный вопрос: {SPOR_SUMMARY}
# chain — вся реализация цепочки против исходной спеки/PRD (дрейф целого)
## Что проверяем
{ARTIFACT}
# для issue: текст issue, ссылки на PRD/спеку/смежное — «зачем».
# Работа worker-а НЕ закоммичена: смотри рабочее дерево целиком —
# `git status --short` (новые файлы untracked, в diff их нет!) плюс
# `git diff`; закоммиченная история — контекст, не объект ревью
# для chain: ключевые пути реализации + исходная спека/PRD;
# объект — закоммиченная реализация цепочки
## Круг
{ROUND} # 1 — первичное ревью; N — rerun после правок worker-а
{PREVIOUS_FINDINGS_BLOCK}
# Только когда rerun делает СВЕЖИЙ субагент (не знает прошлого круга): дословно
# находки прошлого круга; что worker исправил; что отклонил и с каким
# обоснованием (контракт/тест). Отклонённое оценивай по существу: обоснование
# верно — признай; неверно — переформулируй находку с контраргументом и новым
# доказательством, а не повторением прежней формулировки.
# При продолжении того же ревьюера блок не нужен: передай через send_input
# только узкий вопрос — закрывают ли правки твои находки, не внесено ли нового
# рядом; полный обход заново не повторять.
## Что можно
- Читать любые файлы репозитория; git-историю, диффы, ветки.
- Запускать команды: тесты, линтеры, сборку, воспроизведение находок.
- Искать в сети и документации (Context7) для проверки предположений.
## Что нельзя
- Создавать, менять или удалять файлы проекта; менять среду (git-операции с
записью, установка пакетов, правка конфигов).
- Чинить находки — это работа worker-а. Ты аудитор, не участник.
## Планка находки
Каждая находка отвечает на четыре вопроса:
1. Что сломается? — конкретный сценарий, не гипотеза.
2. Почему уязвимо? — `файл:строка` или раздел.
3. Последствия — что и насколько плохо (потеря данных > простой > деградация).
4. Рекомендация — конкретный фикс, достаточный worker-у для работы.
Вне скоупа: стиль и нейминг; спекуляции без конкретного сценария; «неплохо
бы» без связи с корректностью или безопасностью.
Перед докладом верифицируй находку: прогони тесты, сверь документацию,
воспроизведи путь. Одна проверенная находка стоит десяти догадок; ссылки на
доки и upstream-issue давай точно — их проверят.
## Калибровка
- Одна сильная находка лучше нескольких слабых.
- Серьёзность: critical (данные/безопасность) > high (баг в проде) >
medium (крайний случай).
- Работа крепкая — так и скажи: ложные тревоги подрывают доверие.
## Формат ответа — индекс, не нарратив
**Findings:** на каждую — `[severity]`, `файл:строка`, какой критерий нарушен,
минимальный repro, рекомендация. Без diff, без полного вывода тестов, без
нарратива рассуждений. Нет находок — «No actionable findings».
Последняя строка ответа — ровно одна из:
VERDICT: APPROVED
VERDICT: CHANGES_REQUESTED
APPROVED — находок нет или все medium без нарушения acceptance criteria.
CHANGES_REQUESTED — есть high/critical или нарушен критерий issue/спеки.
## Язык
Отвечай на русском. Severity, заголовки полей и строку VERDICT оставляй
латиницей как есть.
```
---
## Заметки по запуску
- Координатор собирает бриф сам — ревьюер не наследует историю сессии;
передавай только нужное.
- Модель и уровень мышления — по [effort-levels.md](effort-levels.md):
обычное ревью — рабочий уровень, узкий гейт по спору и chain-ревью —
усиленный на сильной модели.
- **Не запускай ревьюера в урезанном/read-only субагенте**: тесты и
воспроизведение требуют исполнения команд. Ограничение «не менять
репозиторий и среду» держит промпт (раздел «Что нельзя») — как в
`claude-team-review`.
- На узком гейте `{SPOR_SUMMARY}` — формулировка спора из индекса worker-а
(находка + его обоснование отклонения) дословно, без интерпретаций
координатора.