Files
clickstream-ch-kafka-supers…/.scratch/handoffs/2026-06-14-coordinator-loop-context-economy.md
T
ddadminandClaude Opus 4.8 5660d9e614 docs(handoff): зафиксирован разбор экономии контекста coordinator-loop
- Зачем:
  - сохранить выводы сессии проектирования, пока свежие; без записи они теряются при компактизации и в новой сессии.
- Что:
  - добавлен handoff с диагностикой двух «пожаров» — контекста координатора и токенов — по логам прогона Codex.
  - зафиксированы prior art (obra:superpowers), два принятых правила, кандидаты-фиксы и открытые вопросы.
- Проверка:
  - открыть .scratch/handoffs/2026-06-14-coordinator-loop-context-economy.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 21:09:10 +03:00

184 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff: экономия контекста в coordinator-loop
Дата: 2026-06-14 MSK
Статус: рабочая договорённость по итогам сессии проектирования, в `SKILL.md` ещё не внесена.
## Зачем этот handoff
Сохранить выводы сессии, пока они свежие. Разбирались, почему навык `coordinator-loop`
(координатор + субагенты) при длинной цепочке задач переполняет контекст координатора и
дорого стоит по токенам. Это снимок для продолжения в новой сессии, а не готовая
спецификация: часть решений принята, часть осталась открытой — так и записано.
Навык живёт в dotfiles: `~/.claude/skills/coordinator-loop/` (`SKILL.md`, `README.md`,
`references/rationale.md`).
## Что болит
Прогон Codex по двум фичам (`feature-data-generator`, 8 задач, и
`generator-model-time-startup-history`, 6 задач) вёлся как `/coordinator-loop`. У
координатора дважды заканчивался контекст (по разу на прогон), и работа съела почти весь
5-часовой лимит подписки (по логам — около 3 ч 45 мин на втором прогоне).
## Диагностика
Главный метод и главный урок: **логи — истина, самоотчёт модели — нет.** Codex на прямой
вопрос искренне назвал виновником многословные отчёты субагентов, пересекающие границу. Логи
это опровергли. Модель не видит свой токен-счёт и сочиняет правдоподобную, но неверную
картину. Спасло то, что полезли в логи (`~/.codex/logs_2.sqlite`, `~/.codex/sessions/`), а
не поверили рассказу. Анализ делал отдельный субагент на дешёвой модели, чтобы не забивать
контекст разбором.
### Два разных пожара (мы их сначала склеивали)
**Пожар A — контекст координатора.** Горел не от отчётов на границе (они были компактны:
в среднем 2,6 КБ, максимум 7,3 КБ, полных 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);
- 13 Docker-сборок и накладные расходы опроса.
### Гипотезы и вердикты
| # | Гипотеза | Вердикт | Доказательство |
|---|---|---|---|
| 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 дал верно, несмотря на промах с локацией
Его интроспекция угадала **форму** балласта (материал, который должен был сжиматься после
своего момента) и продиктовала точные компактные форматы. Ключевой ответ про классификацию
находок: отчёта субагента **хватало для маршрутизации** (blocker / риск / docs-мелочь /
ложная тревога), но для финального решения «чинить или нет» по межмодульному инварианту он
**всё равно лез в код** — отчёт был индексом и аргументацией, а не заменой чтения. Отсюда
вывод: лучший отчёт — это индекс (находка, `файл:строка`, минимальный путь воспроизведения,
какой критерий нарушен, что проверить в коде), а не нарратив.
Про `wait_agent`: таймауты стояли 10/15/3 минуты, push-уведомления (`<subagent_notification>`)
приходили, но Codex им не доверял и ждал заново — отсюда лишний опрос. Сам прописал лечение:
на уведомление сразу обрабатывать результат, а не запускать `wait_agent` повторно.
## Prior art: obra:superpowers `subagent-driven-development`
Нашли, что чужой навык глубоко проработан и стоит на той же идее: оркестратор не делает работу
сам, держит контекст чистым, субагенты — «свежий контекст». По части ядра мы переизобретали
его.
**Берём оттуда:**
- **Ревьюер читает код сам и не верит докладу** — это жёсткое правило убивает Пожар A по
построению (координатор перестаёт быть верификатором).
- **Модель по роли** (минимально достаточная: дешёвая — на механику, сильная — на архитектуру
и ревью). Поправка под нас: наш implementer «толстый» (`/goal`), ему нужна сильная модель;
дешёвая выигрывает на субагенте-верификаторе простых находок, docs-проверках и диагностике.
- **Статус-контракт воркера** `DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT`
протокол эскалации, которого у нас нет.
- **Качественная стадия ревью** (хорош ли код, межмодульные инварианты).
**Не берём (сознательно другой выбор):**
- У superpowers **толстый план** (~2000 строк, почти реализация) + тонкий механический
implementer. У нас **тонкий issue** (acceptance criteria) + толстый `/goal`, который сам
додумывает реализацию и самопроверяется. Для учебного репозитория наш путь лучше: issue
читаемы менти, реальное решение живёт в петле, нет огромного плана.
- Их **спек-стадия ревью** у нас по большей части избыточна: «выполнили ли спеку» уже
проверяет петля `/goal`.
Вывод: `coordinator-loop` остаётся отдельным навыком (своя идентичность — цепочка issue из
`/to-issues`, гейт-классификация находок, владение коммитом). Заимствуем механику делегирования,
а не план-центричную философию.
## Решения сессии
**Принято (дёшево, метрически обосновано):**
1. Координатор **не читает diff ради проверки находки** — чтение кода уходит ревьюеру-субагенту
(он читает код сам и возвращает только вердикт). Чинит Пожар A (413 КБ).
2. **Доверять push, не крутить `wait_agent` по кругу**: пришло `<subagent_notification>`
сразу обрабатывать; один разумный статус-таймер вместо polling-цикла. Возможно, самый
дешёвый одиночный выигрыш (сток 947 КБ почти случайный, не дизайн).
**Намеренная цена — НЕ трогать:**
- `/goal`-петля (~400K токенов/задача) — сознательный обмен на качество решения;
- независимое межмодульное ревью на пороге риска;
- декомпозиция «тонкий issue + толстый `/goal`».
**Кандидаты-фиксы (не приняты, проверить на прогоне):**
- точечные тесты в петле, полный тест-сет — только на гейте (риск пропустить межмодульный
регресс в середине петли ловит гейт + межмодульный ревьюер);
- отчёты в формате индекса, а не нарратива;
- демоушн закрытых issue в компактную durable-форму (`summary`), чтобы компактизация её не
уничтожала;
- файловый канал в общем дереве для обмена находками (оркестрация по ссылке, а не payload
через контекст);
- модель по роли.
## Связь с handoff про наблюдаемость
Есть параллельный handoff `2026-06-14-observability-design.md` (в dotfiles, в каталоге навыка),
где уже спроектирован файловый канал `coordinator-runs/` (live-логи + `summary.md`, чтение по
требованию, координатор не ведёт лог сам). Это **тот же** файловый канал, что нужен нашему
кандидату-фиксу. **Свести в один дизайн, не строить две файловые системы.** Оба не реализованы —
слить легко.
## Открытые вопросы (с моей рекомендацией, но не закрыты)
1. **Объём первого захода.** A — полная переделка сразу; B — внести только два дёшевых правила,
остальное пометить «проверить на следующем прогоне». Рекомендация: **B** (держит навык от
разрастания).
2. **Кто верифицирует находку** — автор-воркер со своим знанием кода и проверяемым обоснованием,
или свежий ревьюер? Склонялись к автору на знании + независимый на пороге риска. Не закрыто.
3. **Слить ли два handoff** (этот и про наблюдаемость) в один дизайн до правки `SKILL.md`?
Рекомендация: да.
4. **Кросс-хост.** Файловый канал отчасти оправдан тем, что host-agnostic (Codex и Claude Code).
Если на деле только Codex — обоснование слабее. Уточнить требование.
## Числа-ориентиры для следующего прогона
Чтобы измерить, помогли ли фиксы, а не поверить на слово:
- пик контекста координатора: было 77 % окна (199K/258K) — должно заметно упасть;
- собственные diff-чтения координатора: было 413 КБ — должно стремиться к нулю;
- сессия ожиданий/опроса: было 947 КБ при 42/44 таймаутах — push обрабатывается, цикла нет;
- прогоны полного тест-сета: было 103 — точечные в петле, полный только на гейте.
## Что ещё не сделано
- Решения не внесены в `SKILL.md`.
- Кандидаты-фиксы не приняты и не проверены на реальном прогоне.
- Два handoff не сведены.
- Не решён объём первого захода (вопрос 1 выше).
## Рекомендуемые следующие шаги
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` — для коммитов изменений в навыке.