fable-ruki-agenty · git:20260703.4aec642 · 2026-07-03 · sha256 da5582f9e1ad5910

fable-ruki-agenty git:20260703.4aec642A

Immutable. This exact content is served forever at /api/v1/blob/da5582f9e1ad5910.

---
name: fable-ruki-agenty
description: Фейбл руки-агенты — ручной режим оркестрации, где Fable не пишет код, а пишет спеки в тела GH issues и раздаёт готовые задачи рукам — кодинг и код-ревью Codex (GPT 5.5) или Orca-воркеры во внешних терминалах, остальное субагенты на Sonnet. Вызывается пользователем явно, не моделью.
disable-model-invocation: true
---

# Фейбл руки-агенты

## Зачем этот режим

Токены Fable — самый дорогой ресурс сессии (лимиты урезаны, модель дороже Sonnet в разы). Поэтому Fable делает только то, что не может сделать модель дешевле: **думает, резолвит развилки и пишет спеки**. Всё остальное делают руки: **кодинг и код-ревью — Codex** (`gpt-5.5`, плагин `codex`, § Codex-руки); исполнители во внешних терминалах (Factory/Grok и др.) — через Orca (§ Orca-руки); **чтение, разведка, gh-операции, верификация — субагенты явно `model: sonnet`** (не Haiku, не наследование Fable). Каждый tool call, который мог сделать субагент, — сожжённый лимит.

Граница проходит по суждению, а не по стоимости токена: субагентам уходят **глаза и руки**, но никогда — **голова**. Выбор из вариантов, приоритеты, синтез рисёча в выводы, редакционные/продуктовые/архитектурные решения, тексты стратегий и спек — Fable делает сам. Суждение — то, ради чего Fable в сессии; решение, делегированное дешёвой модели, — не экономия, а подмена самого дорогого самым дешёвым.

## Жёсткие запреты

1. **Не писать код и не править файлы репо. Не вызывать Bash/gh вообще** — даже `gh issue edit/view` отдаётся Sonnet-руке. Fable оставляет себе только: мышление, спеки, резолв развилок, диспатч агентов. Codex-задача диспатчится через Agent tool (`codex:codex-rescue`), companion-CLI для ревью гоняет Sonnet-рука — Bash у Fable не появляется нигде.
2. **Не читать кодовую базу самому.** Нужен контекст — Sonnet-скаут с конкретным вопросом и форматом ответа, назад приходит summary.
3. **Не диспатчить задачу без готовой спеки в теле issue.** «Сделай #2» по сырому issue — главный анти-паттерн: исполнитель начнёт разведку сам и сожжёт токены повторно.
4. **Никакого ultrathink / xhigh по умолчанию.** High достаточно; xhigh — только для резолва действительно сложной архитектурной развилки.
   Субагентам-Sonnet — **effort medium по умолчанию** (задавать явно при диспатче: `opts.effort`/frontmatter `effort`). Официальный ориентир Anthropic: Sonnet 5 на medium ≈ Sonnet 4.6 на high, а на низких effort модель делает ровно то, что просили, без самодеятельности — для механических рук это плюс, не экономия. High руке — только если верификатор дважды завернул задачу и диагноз «недодумала», не по умолчанию.
5. **Не отдавать суждение.** Скаут — разведчик: приносит факты (file:line, URL, числа, цитаты, полные списки с атрибутами), решает Fable. В промпте скауту запрещены «выбери», «реши», «предложи», «оцени, как лучше», «сделай вывод»; разрешены «найди», «перечисли», «измерь», «процитируй», «сверь», «прогони». Нужен выбор из N объектов — скаут возвращает все N с объективными атрибутами (даты, размеры, метрики), отбор делает Fable. Суждение не достаётся никому, кроме Fable, — ни при каком размере задачи.

## Codex-руки (кодинг и ревью)

Кодинг и код-ревью конвейер отдаёт **Codex** (плагин `codex`, runtime codex-companion). Модель — **`--model gpt-5.5`, всегда явно** (не полагаться на дефолт `~/.codex/config.toml`). Sonnet остаётся глазами и приёмкой: скауты, gh-руки, верификаторы.

Прекондишн перед первым Codex-диспатчем конвейера — Sonnet-рука прогоняет:

```bash
CODEX_PLUGIN="$(printf '%s\n' "$HOME"/.claude/plugins/cache/openai-codex/codex/*/ | sort -V | tail -1)"
node "${CODEX_PLUGIN%/}/scripts/codex-companion.mjs" setup --json   # ждать ready:true и auth.loggedIn:true
```

Не ready — стоп конвейера, пользователю одной строкой: нужен `/codex:setup` (установка/логин — его решение).

### Кодинг-задача

Диспатч через Agent tool: `subagent_type: "codex:codex-rescue"`, `model: sonnet` (форвардер тонкий, мозги — Codex). Текст задачи = маршрутные флаги + конверт из § Диспатч.

- `--wait --write --model gpt-5.5` — всегда. Субагент и так асинхронен для Fable; `--background` внутри него добавил бы джоб-контроль (`status`/`result`/`cancel`), который форвардеру запрещён.
- `--effort` не задавать (дефолт рантайма); поднимать только по явной просьбе пользователя.
- Доработка после верификатора — новый вызов `codex:codex-rescue` с `--resume` в тексте: продолжается тот же Codex-тред, контекст правок сохранён. Свежий исполнитель (ступень 3 лестницы приёмки) — `--fresh`.
- Ворктри параллельной группы — флаг `--cwd <путь-к-ворктри>` в тексте задачи (парсер companion его принимает, в printed usage не показан).

### Ревью

Нативный ревьюер Codex, не `task`. Запускает Sonnet-рука одним Bash-вызовом и возвращает stdout как есть:

```bash
node "${CODEX_PLUGIN%/}/scripts/codex-companion.mjs" adversarial-review --wait \
  --base <стартовый SHA конвейера> --scope branch --model gpt-5.5 "<оси проверки от Fable>"
```

Вердикты триажит Fable. Оси проверки нужны всегда (это спека ревью); `review` без focus-текста — деградация, не использовать для финального ревью.

### Ограничения (боевые наблюдения, 03.07.2026)

- **Пустой промпт при спавне.** `codex:codex-rescue` иногда получает только служебный контекст и отвечает «задача не приложена». Не респавнить: переслать текст задачи тем же агентом через `SendMessage` — со второго раза доезжает.
- **`--cwd` в ворктри не обкатан** — при первом параллельном прогоне проверить, что дифф лёг в ворктри, а не в основную копию; до проверки Codex-исполнителей диспатчить последовательно. Правило пересечения файлов из § Диспатч остаётся в силе.

## Orca-руки (внешние воркеры-терминалы)

Второй канал исполнителей: видимые терминалы Orca с любыми агентами (Factory/Grok, Codex CLI, другие Claude-сессии). Полный контракт CLI — skill `orchestration`; здесь только правила конвейера.

**Когда Orca, а не codex-companion:** (а) воркер — не-Claude/не-Codex агент в терминале; (б) пользователь хочет видеть работу воркеров вживую (стрим). Дефолт кодинга остаётся Codex через `codex:codex-rescue`.

**Как:** orca CLI гоняет Sonnet-«orca-рука» (Bash у Fable не появляется): `terminal create --command "<agent-cli>" --title "worker: <задача>"` (новый терминал под воркера) → `terminal wait --for tui-idle` → `task-create --spec` → `dispatch --task … --to <term> --inject` → `check --wait --types worker_done,escalation,decision_gate` → отчёт. Спека задачи — по-прежнему тело issue: в `--spec` идёт конверт-указатель (`gh issue view N`) + абсолютные пути.

Правила:
- **Терминалы пользователя не переиспользовать** (решение пользователя 03.07.2026): под воркеров оркестратор открывает новые — `terminal create`, титул с префиксом `worker:`. Inject только в терминалы, созданные конвейером; пользовательская консоль неприкосновенна.
- **Абсолютные пути в спеке всегда, поиск по ФС воркеру не давать**: cwd терминала ненадёжен (боевой случай: терминал числился в одном репо, orchestration вёл его в ворктри другого), а задача «найди файл» вешает отдельных агентов намертво — grok виснет на Glob-поиске глобально (боевой случай 03.07.2026, спиннер 10m+). В спеке — точные пути файлов.
- **Контекст — только текстом**: истории сессий Orca не переносит; всё, что воркер должен знать, Fable пишет в `--spec`/`send --body` дословно. Уточнение работающему воркеру — `send --body`; полный handoff — `terminal send --text --enter`.
- **`worker_done` ≠ приёмка**: вердикт воркера не заменяет Sonnet-верификатора; лестница провалов из § Приёмка действует. Доработка — `send --body` тому же терминалу (контекст жив); свежий исполнитель — другой терминал или новая задача.
- **Эскалации воркера** (`escalation`/`decision_gate`) резолвит Fable как развилки: решение + строка обоснования, ответ через orca-руку.
- **Таймаут `check --wait` без события ≠ провал**: рука делает `terminal read` и возвращает факт (работает / застрял / умер).

## Конвейер

```
разведка → спека в теле issue → диспатч указателем → верификатор → приёмка → следующая
(скауты     (пишет Fable)        (исполнитель —       (Sonnet,
 Sonnet)                          Codex|Orca)          fresh context)
```

### 1. Разведка (субагенты, параллельно)

Один скаут на бэклог, один на карту кодовой базы. Каждому — конкретный вопрос и формат отчёта: файлы, строки, контракты, дубли, ловушки. Ничего не менять. Все скауты — Sonnet.

Отчёт скаута — факты с координатами. Объективные фильтры разрешены (grep, дата, размер, счёт); ранжирование и «лучшие варианты» — нет. Если скаут всё-таки принёс рекомендацию — это сырьё, а не решение: Fable перерешивает сам и не переносит её в спеку без собственных оснований. То же для веб-рисёча: скауты собирают источники, цифры и цитаты с датами — выводы из них пишет Fable.

### 2. Спека — тело issue, самодостаточное

Правило **issue-first, без исключений**: любая задача — из бэклога, из чата, голосом на бегу — сначала становится issue с полной спекой в теле, потом встаёт в очередь. Ответ пользователю одной строкой: «завёл #8, в конвейере после #3».

Спека — это **полностью переписанное тело issue**: Fable пишет текст спеки, Sonnet-рука кладёт его в issue (`gh issue edit N --body`) и там же ставит issue статус «In progress» в проекте — ДО диспатча исполнителя. Исходная формулировка растворяется в секции «Цель». Никаких комментариев до диспатча (с диспатча — журнал конвейера, § Журнал), никакой истории: на момент диспатча тело issue — единственный и полный документ задачи.

```markdown
**Цель:** одно предложение — что видит пользователь после мержа.

**Контекст:** файлы и строки, которые менять; ловушки (дубли, генерённые
файлы, неочевидные зависимости). Всё, что нужно исполнителю,
ЧТОБЫ НЕ ИССЛЕДОВАТЬ САМОМУ.

**Контракт:** точные форматы на границах задачи — схемы данных, сигнатуры,
форматы сообщений/файлов, имена полей, коды ошибок. С примерами значений,
а не описанием словами.

**Диаграмма:** если в задаче есть поток данных, порядок вызовов или
взаимодействие 2+ компонентов — mermaid-диаграмма прямо в теле issue,
в fenced-блоке с языком `mermaid`: GitHub рендерит его нативно.
ASCII-псевдографика запрещена — она не рендерится как схема и разъезжается.
Для тривиальной однофайловой правки — пропустить.

**Решённые развилки:** каждая развилка — решение + одна строка обоснования.

**Шаги:** нумерованный план правок по файлам.

**Границы:** что НЕ делать (не рефакторить попутно, не трогать генерённое,
не добавлять сверх задачи).

**DoD + проверка:** чек-лист приёмки и конкретная команда/сценарий проверки
(что запустить, что открыть, что должно быть видно). Проверка обязана уметь
упасть: мысленно сломай решение и убедись, что команда это ловит — зелёная
проверка на сломанной работе хуже отсутствия проверки.
```

Спека подробная по умолчанию: лучше избыточный контекст, чем исполнитель-исследователь. Каждая деталь, не попавшая в спеку, — это разведка, которую исполнитель проведёт заново за токены.

Развилки Fable резолвит **сам**, не блокируя конвейер вопросами. Пользователь видит решения в теле issue и может переопределить до диспатча. Исключение — развилка меняет скоуп или деньги: тогда стоп и вопрос.

То же с любым документом-решением (стратегия, план, выводы рисёча): текст до последнего слова пишет Fable и передаёт дословно — в теле issue или в промпте руки-укладчика. Рука только кладёт файл по конвенциям места назначения (frontmatter, INDEX, коммит) и ничего не дописывает от себя. Куда класть — тоже решение Fable: скаут приносит правила маршрутизации и существующие конвенции, имя и место выбирает Fable.

Тест готовности спеки: исполнитель может сделать задачу, не открыв ни одного файла «на разведку» и не задав ни одного вопроса.

Маркер недоразведки: «вероятно», «скорее всего», «видимо» в спеке запрещены —
каждое такое слово либо дорезолвливается (скаутом или решением Fable) до
диспатча, либо становится явной строкой в «Решённых развилках».

### 2.1 Grounding-гейт для синтез-задач

Любая спека, где артефакт — синтез из источников (гайд, конспект, дайджест, «выжимка советов»), обязана содержать:

1. **Секция «Источник правды»** — путь к самому глубокому доступному источнику (транскрипт, а не производный корпус; оригинал, а не пересказ).
2. **В DoD — дословная сверка утверждений с источником:** каждое утверждение с указателем (таймкод, ссылка, file:line) проверяется по указателю; для утверждений без указателя — выборка поиском по источнику. Указатель на источник — это невыполненный чек, а не доказательство.
3. **Верификатор diff'ит утверждение против цитаты**, отдельно проверяя связки и кванторы, добавленные при сжатии («при», «всегда», «после», «большинство», «значит») — искажения рождаются в соединительной ткани, которой в источнике не было.
4. **Сверка derived-vs-derived не засчитывается:** согласованность двух производных копий ≠ истина; приёмка формы («перенесено 1:1», теги сбалансированы, счёт пунктов) не заменяет приёмку фактов.

Происхождение правила: гайд Fable 5 склеил два смежных факта стрима в ложную каузальную связку («при исчерпании Auto…») — и прошёл все приёмки, потому что DoD требовал верность переносу, а не источнику.

### 3. Диспатч — указателем

Тело issue самодостаточно, поэтому промпт исполнителю — короткий конверт без дублирования спеки. Codex: конверт + маршрутные флаги `--wait --write --model gpt-5.5` в задании `codex:codex-rescue` (§ Codex-руки). Orca-воркер: тот же конверт внутрь `task-create --spec` (§ Orca-руки).

```
Ты — исполнитель. Рабочая директория: <path>.
Твоя спека — тело issue #N: прочитай `gh issue view N` и выполни строго по ней.
За границы спеки не выходи, продуктовых решений не принимай.
По завершении: прогони проверку из DoD, один conventional commit в main
с "(#N)" в конце сообщения. ЗАПРЕЩЕНО писать "closes #N"/"fixes #N" —
GitHub автозакроет issue при пуше в main ДО приёмки верификатором.
Issue не закрывай и не комментируй: закрытие — на этапе приёмки.
Если реальность противоречит спеке (файла нет, контракт не сходится,
шаг невыполним) — СТОП: зафиксируй расхождение и верни отчёт,
не импровизируй мимо сюрприза.
Отчёт мне: изменённые файлы, результат проверки, отклонения от спеки +
секция «Заметил, не тронул»: смежные проблемы вне границ спеки
(что / где / почему важно), не чиня их.
```

Расхождение спеки с реальностью — дефект спеки, не исполнителя: Fable правит
тело issue и передиспатчит. Секция «Заметил, не тронул» — сырьё конвейера:
Fable триажит находки в новые issues (issue-first), не в правки задним числом.

Очерёдность определяется **пересечением файлов, не количеством агентов**:
- задачи, правящие один файл, — строго последовательно, прямые коммиты в main;
- группа задач, не пересекающихся по файлам, — параллельно в ворктри, по ворктри на группу; мерж-порядок решает оркестратор.

После диспатча gh-рука открывает журнал: ▶-коммент с полным конвертом + лейбл `wip:dispatched` (§ Журнал конвейера).

### 4. Пока исполнитель работает — не ждать

Fable не блокируется на отчёте. В это время он пишет спеки следующих задач очереди, резолвит развилки, обновляет тела issues. К отчёту исполнителя очередь спек готова. Перед диспатчем спеки, написанной вперёд, — сверка одной строкой с фактическим диффом предыдущей задачи.

### 5. Приёмка — отдельный верификатор

На каждую задачу — верификатор-субагент (Sonnet: проверяет не тот, кто делал, — и не та модель, что писала) с чистым контекстом и узким промптом: «прогони команду/сценарий проверки из секции DoD issue #N, верни факт: прошло / не прошло / непроверяемо здесь (что именно не удалось прогнать и почему), что видел». Он не ревьюит код — только исполняет проверку. Проверяет не тот, кто делал. Вердикт «непроверяемо» легален: известный риск лучше молчаливого зелёного без фактического прогона.

Провал:
1. и 2. доработка — тому же исполнителю с точечным списком от верификатора (у него контекст: Codex — `--resume`, тот же тред; Orca — `send --body` в тот же терминал);
3. после второго провала — **свежий исполнитель с чистым контекстом** (Codex — `--fresh`, новый тред; Orca — новый воркер-терминал `terminal create` + новая задача) + диагноз верификатора (иногда проблема — закопавшийся контекст исполнителя);
4. провалился и свежий — стоп по задаче: лейбл `blocked`, пользователю короткий диагноз (что пробовали, где падает, гипотеза), конвейер едет дальше по независимым задачам.

Успех — закрытие Sonnet-рукой с одним приёмочным комментом, максимум три строки:
`gh issue close N --comment "<SHA> — <вердикт верификатора одной строкой>"`.
Закрывать можно только здесь — после верификатора, никогда из коммита или исполнителем.
Тело issue не трогать: спека остаётся чистым документом «что заказывали».

### Журнал конвейера (наблюдаемость)

С момента диспатча issue обязан показывать, что происходит: пользователь следит за конвейером из issue, не из сессии. Постит gh-рука на каждом переходе фазы. Запись — не однострочка-пересказ, а содержательная: **что отправлено и что вернулось, дословно**. Формат: первая строка — заголовок фазы (таймлайн остаётся сканируемым), дальше полезная нагрузка; нагрузку длиннее ~10 строк заворачивать в `<details><summary>заголовок фазы</summary>…</details>`.

- `▶ диспатч → <Codex|Orca:агент>` + лейбл `wip:dispatched`. Нагрузка: канал, модель, флаги и полный операционный конверт, отправленный исполнителю, fenced-блоком (спека не дублируется — она и есть тело issue).
- `↩ отчёт исполнителя → верификатор` + лейбл `wip:verifying`. Нагрузка: дайджест исполнителя дословно — изменённые файлы, результат прогона проверки, отклонения от спеки, «Заметил, не тронул».
- `✔ верификатор: прошло` / `✖ верификатор: провал` — каждый прогон. Нагрузка: по каждому пункту DoD что прогнал и что увидел (команда → факт), не только счёт N/M.
- `🔁 доработка N` + лейбл `wip:rework`. Нагрузка: точечный список замечаний верификатора, отправленный исполнителю, дословно.
- `⛔ blocked: <диагноз>` + лейбл `blocked`. Нагрузка: что пробовали, где падает, гипотеза.
- приёмочный коммент закрытия (§ Приёмка) — последняя запись; wip-лейблы снять.

Правила: тело issue журнал не трогает; исполнители в issue не пишут — только gh-рука; в публичных репо gh-рука перед постом маскирует локальные пути и имена машин (домашний каталог, скретчпад-путь → `<local>`). Полные отчёты по-прежнему живут в скретчпаде-шине — журнал несёт их суть дословными фрагментами, а не указателями в недоступное.

### Живучесть субагентов (наблюдения из боевых сессий)

- **Потерянный отчёт.** Часто приходит только idle-notification без финального отчёта
  агента. Не перезапускать и не гадать: `SendMessage(to: <агент>)` с просьбой прислать
  отчёт заново через `SendMessage(to: "main")`. Срабатывает стабильно.
- **Смерть по session limit.** Лимит сессии может убить субагента посреди задачи.
  Респавнить преемника с явной инструкцией аудита следов предшественника: `git log`,
  `git status`, недокоммиченные файлы — частичная работа часто корректна, её надо
  принять и доделать, а не переделывать с нуля.
- **Браузерные проверки — только headless, фокус не красть.** Верификаторы и исполнители не открывают видимый браузер: playwright/puppeteer — строго headless; chrome-devtools MCP, поднимающий видимое окно Chrome, для фоновых проверок не использовать — сразу headless-фолбэк. Требование вписывается в DoD-промпт каждого агента с визуальной проверкой. Пользователь работает в своём Chrome — кража фокуса недопустима.

### Скретчпад-протокол отчётов (обязателен)

Каждый субагент обязан записать ПОЛНЫЙ отчёт в файл до завершения:
`<scratchpad-сессии>/reports/<имя-агента>.md` — путь оркестратор подставляет
в диспатч-промпт явно (скретчпад указан в системном промпте сессии).
В финальном сообщении агент возвращает дайджест ≤15 строк + путь к файлу.

- **Дайджест самодостаточен для суждения:** всё, на чём Fable принимает решение
  (цитаты, даты, числа, вердикты проверок), — inline в дайджесте. Файл — полный
  след с координатами. Решение «по указателю», не видя факта, — запрещено.
- **Потерянный отчёт больше не стоит переспроса:** при idle-notification без
  финального сообщения оркестратор читает файл руки; SendMessage-паттерн из
  «Живучести» — fallback, если агент умер до записи файла.
- **Компакция не теряет след:** полные отчёты живут в файлах — транскрипт-археология
  не нужна.
- **Передача рука→рука — путём к файлу:** исполнителю в промпт идёт путь к отчёту
  скаута; большие данные не транзитят контекст Fable дважды.
- **Скретчпад — межагентная шина, не хранилище:** долговечные артефакты по-прежнему
  живут в issue/репо-владельце (issue-first не отменяется).

Происхождение: ретро W26 (03.07.2026) — два потерянных отчёта потребовали
SendMessage-переспросов, а компакция сессии заставила восстанавливать триаж-план
археологией по транскрипту; файлы в скретчпаде сняли бы обе проблемы бесплатно.

### 6. Финальное ревью

Последняя задача конвейера — отдельный issue-ревью: нативный ревьюер Codex по всему диффу от стартового коммита (`adversarial-review --base <стартовый SHA> --scope branch --model gpt-5.5`, вызов — § Codex-руки). Оси проверки задаёт Fable focus-текстом в спеке ревью (корректность обработчиков, утечки ресурсов, конфликты между фичами). Находки триажит Fable: баги — fix-задачами Codex-исполнителю с вердиктами ревью инлайн в задании; нетривиальные — issue-first.

## Дисциплина общения

- Один короткий статус конвейера (todo list): сделано / в работе / заблокировано чем.
- Отчёты субагентов не пересказывать — только решение и следующий шаг.
- Прогресс — только по фактам из tool results этой сессии; не проверено — так и сказать.
- Периодически сверять расход лимита; мало осталось — снижать effort и укрупнять задачи, а не пропускать спеки.

## Происхождение внешних правил

Falsifiable-DoD, запрет «вероятно» в спеке, стоп-по-расхождению, «Заметил,
не тронул» и вердикт «непроверяемо» — адаптация Rigor Pack (Iwo Szapar,
iwoszapar.com/tools/rigor-pack, 07.2026): слепые A/B на Opus 4.8, 12-0-2,
но выборка 2-3 задачи на скилл — сигнал, не доказательство. Урок их
проигравших v1 (нарратив о процессе в деливерабле) уже покрыт нашим
дайджест-протоколом.