22 KiB
Executable File
Balda + Prism/Beads + Execution Broker + Callee + Codex
Обновлено: 2026-09-29
Статус: целевая архитектура зафиксирована; Broker и интеграции ещё не реализованы.
1. Цель
Balda принимает задачу в Mattermost, ведёт её состояние в Prism/Beads и запускает изолированное выполнение в одноразовой macOS VM.
Код, сборка, тесты и Xcode выполняются только внутри VM. Хост Mac управляет VM через Virfield, но не исполняет команды агента в основной системе.
Единственная целевая цепочка исполнения:
Mattermost
→ Balda
→ Execution Broker
→ Virfield на Mac
→ macOS VM
→ Callee workflow
→ Codex ACP sessions
Контур состояния задачи:
Balda
→ Prism adapter
→ bd
→ Dolt/Beads database
Обратный поток:
Codex
→ ACP result
→ Callee event
→ Broker event log
→ Balda
→ Prism/Beads + Mattermost
2. Что уже есть
Подтверждено
- Balda работает в Docker на Mac и отвечает в Mattermost.
- Mattermost-сервер остаётся на Kraken; Balda подключается к нему с Mac.
- Obsidian MCP доступен Balda по
http://host.docker.internal:3101/sse. - Virfield MCP работает на хостовом Mac и умеет подготовить VM: clone golden image, start, wait for IP/SSH, create tunnel.
- Host Codex и Claude уже подключены к Virfield MCP.
Текущая конфигурация Balda
- основной provider: DeepSeek через OpenAI-compatible API;
permissions.mode: allow_all;workspace.mode: off;- Virfield в Balda не подключён;
- Callee CLI и описания агентов находятся в окружении Balda по текущему сетапу, но целевой запуск Callee должен происходить внутри VM.
Чего пока нет
- Execution Broker;
- сетевого API управления Virfield для Broker;
- VM runner для управляемого запуска Callee;
- обратного журнала событий Callee → Balda;
- адаптера Balda → Prism/Beads;
- подтверждённого сквозного запуска Story → VM → build/test → отчёт.
3. Владельцы ответственности
Balda — оркестратор верхнего уровня
Balda:
- принимает задачу и уточнения из Mattermost;
- создаёт и обновляет Story в Prism/Beads;
- выбирает разрешённый workflow по его идентификатору;
- запускает выполнение через Broker;
- показывает запросы Human и итог пользователю.
Balda не управляет процессами внутри VM напрямую. Она работает только через контракты Prism adapter и Execution Broker.
Prism adapter + Beads — долговременное состояние
Prism adapter принадлежит контуру Balda и физически может быть отдельным sidecar-контейнером.
Он:
- предоставляет Balda узкие операции Story/Task/phase;
- вызывает
bd; - подключается к Dolt/Beads database в соседнем контейнере;
- обеспечивает идемпотентную запись событий Broker;
- остаётся единственным писателем предметного состояния задачи.
Broker, Callee и Codex не пишут в Beads напрямую. Они возвращают факты выполнения, а Balda решает, как отразить их в Story.
Execution Broker — инфраструктурный исполнитель
Broker живёт отдельным sidecar-контейнером рядом с Balda.
Он:
- получает от Balda команду запуска;
- арендует VM через Virfield;
- запускает VM runner и Callee;
- хранит техническое состояние run и журнал событий;
- передаёт ввод, отмену и ссылки на артефакты.
Broker не выбирает workflow, не исполняет его граф и не меняет Prism/Beads.
Virfield — граница управления хостом
Virfield работает на Mac-хосте и владеет жизненным циклом VM:
- clone/start/stop/delete;
- IP и SSH readiness;
- сетевые туннели;
- lease и принудительная уборка VM.
Для Broker нужен узкий аутентифицированный HTTP API или HTTP MCP-обёртка над этими операциями. Произвольного host shell в этом API нет.
Callee и Codex — выполнение внутри VM
Callee исполняет workflow: фазы, ветвления, циклы, Human-паузы и запуск ролей.
implementer, reviewer, verifier — роли Callee. Каждая роль запускает новую Codex ACP-сессию с отдельным prompt и контекстом.
Codex изменяет код, запускает xcodebuild, тесты и другие команды внутри VM. Codex не запускает Callee и не управляет Story.
4. Prism и prism-callee
Официальный prism-callee — плагин к coding-agent host. В штатной схеме он делает coding agent владельцем Beads и запускателем Callee:
Codex → prism-callee skill → Callee → дочерние Codex sessions
Эта штатная топология не является целевой, потому что верхним оркестратором должен оставаться Balda.
В целевой схеме используются отдельно:
- lifecycle и правила Prism — как основа skill/адаптера Balda;
- Callee workflow pack — как версионируемые workflow-файлы внутри VM;
- Beads — через отдельный Prism adapter;
- Codex — только как исполнитель ролей Callee.
До реализации требуется проверить, какие части официального плагина можно импортировать без изменений, а какие нужно адаптировать для Balda.
5. Прямой data flow
- Пользователь ставит задачу Balda в Mattermost.
- Balda через Prism adapter создаёт Story и получает
story_id. - Balda выбирает
workflow_idиз статического allowlist и вызываетexecution_start. - Broker просит Virfield создать VM, затем запускает внутри неё VM runner и Callee.
- Callee выполняет граф и для каждой Role запускает локальный Codex через ACP stdio.
Минимальный запрос запуска:
{
"idempotency_key": "story:bd-42:attempt:1",
"story_id": "bd-42",
"workflow_id": "prism/story",
"workflow_version": "pinned-git-sha",
"repository": "git@host:org/repo.git",
"revision": "main",
"vm_template": "macos-27-golden",
"task": "Добавить CSV export"
}
Broker возвращает run_id сразу после надёжной записи команды. Подготовка VM продолжается асинхронно.
6. Обратный data flow
- Codex возвращает результат роли в Callee по ACP.
- Callee переводит workflow в следующее состояние и отдаёт структурированное событие VM runner.
- VM runner передаёт событие Broker; Broker сохраняет его до ответа Balda.
- Balda читает события через
execution_events(run_id, after_event_id)и подтверждает курсор. - Balda обновляет Story через Prism adapter и публикует значимые изменения в Mattermost.
События доставляются как минимум один раз. Повторная доставка безопасна благодаря уникальному (run_id, event_id).
Минимальное событие:
{
"event_id": 17,
"run_id": "run-123",
"story_id": "bd-42",
"type": "role_completed",
"phase": "review",
"role": "reviewer",
"status": "passed",
"summary": "Tests pass",
"artifacts": [
{"kind": "git_commit", "ref": "abc123"},
{"kind": "xcresult", "ref": "artifact://run-123/tests"}
]
}
Тяжёлые логи и .xcresult не помещаются в журнал. Broker хранит только ссылки, checksum, размер и срок жизни.
7. Human approval
- Callee доходит до Human node и приостанавливает workflow.
- VM runner отправляет
human_requiredс вопросом и вариантами. - Broker фиксирует состояние
waiting_human. - Balda показывает вопрос в Mattermost и получает ответ в том же session/topic.
- Balda вызывает
execution_respond; Broker доставляет ответ в конкретный paused run.
Связка обязательна: chat_id/topic_id ↔ story_id ↔ run_id ↔ human_request_id.
Ответ должен быть идемпотентным: повторный human_request_id не возобновляет workflow дважды.
8. Execution Broker: контракт
Где живёт
Отдельный контейнер в одном Docker network с Balda. У Broker собственный persistent volume с SQLite.
Northbound: HTTP MCP для Balda.
Southbound: узкий HTTP API Virfield и SSH к выданной VM.
Внутри VM: VM runner → Callee → Codex ACP stdio.
MCP tools
execution_start(request) → run_idexecution_status(run_id) → state, phase, last_event_idexecution_events(run_id, after_event_id) → events, next_cursorexecution_respond(run_id, human_request_id, answer)execution_cancel(run_id, reason)иexecution_artifacts(run_id)
Состояния run
accepted
→ provisioning
→ booting
→ running
→ waiting_human
→ running
→ succeeded | failed | canceled | expired
Каждый переход записывается транзакционно вместе с событием. После рестарта Broker продолжает незавершённые run или переводит их в явно диагностируемое состояние.
Внутреннее состояние Broker
Broker хранит только технические данные:
run_id,story_id, idempotency key;- VM id, IP, lease deadline;
- workflow id/version и process/session id;
- event cursor, terminal status и error code;
- artifact references и cleanup status.
VM runner
Нужен небольшой процесс внутри образа VM. Он отделяет Broker от консольного формата Callee.
Runner:
- проверяет входной manifest и allowlist workflow;
- запускает Callee в рабочей директории репозитория;
- преобразует lifecycle/output в стабильные JSON events;
- принимает cancel и Human response;
- возвращает terminal result и artifact manifest.
Broker не должен парсить человекочитаемый ANSI/TTY-вывод Callee. Если Callee уже имеет стабильный machine-readable API, runner становится тонким адаптером.
9. Изоляция и секреты
Основная граница безопасности — одноразовая macOS VM.
- исходный проект клонируется в VM без host bind mounts;
- Codex, Callee, Xcode и тесты работают внутри VM;
- Broker получает только scoped SSH key для конкретной VM;
- Git credentials выдаются на один репозиторий и ограниченный срок;
- VM удаляется после выгрузки результатов или по lease timeout.
Хостовый Virfield API разрешает только операции жизненного цикла VM. Balda и Broker не получают docker.sock, пользовательский ~/.ssh или произвольный shell на Mac.
10. Неподтверждённое
Блокирует прототип
- Есть ли у Callee стабильный machine-readable event stream и программный resume Human node.
- Можно ли запустить workflow pack
prism/storyотдельно от stock plugin host. - Как Codex ACP получает workspace/cwd и сохраняет его между Role visits.
- Как передавать cancel в Callee без повреждения terminal result.
- Какой минимальный Virfield API можно безопасно открыть Broker.
Требует проверки до production
- установка и авторизация Codex внутри golden VM;
- доступность Dolt/Beads из Prism adapter после рестартов;
- формат и размер Xcode артефактов;
- восстановление Broker после падения во время
waiting_human; - параллельные Story и лимиты VM/CPU/RAM на Mac.
11. Варианты
A. Sidecar Broker + VM runner — выбран
Balda остаётся оркестратором, Broker изолирует инфраструктуру, Callee владеет workflow, Codex работает в VM. Это целевая схема.
B. Broker как host daemon
Меньше сетевых переходов к Virfield и SSH, но Broker получает более широкую поверхность хоста. Использовать только если контейнерный sidecar не может надёжно управлять VM.
C. Stock prism-callee plugin
Codex → plugin → Callee → Codex. Быстрее для проверки Prism, но Balda перестаёт быть владельцем lifecycle. Подходит как временный reference test, не как production topology.
D. Native remote ACP
Будущая transport abstraction в runtime + acpagent позволит Balda или Callee подключаться к ACP по WebSocket/Streamable HTTP. Она может заменить SSH-транспорт, но не заменяет Broker, VM lifecycle, durable events и cleanup.
12. Pitfalls
Архитектура
- Смешивание двух топологий: stock
Codex → Calleeи целевойBalda → Broker → Callee. - Перенос workflow-логики в Broker превращает его во второй оркестратор.
- Прямая запись Broker/Callee/Codex в Beads создаёт несколько владельцев состояния.
- Запуск Callee вне VM переносит Script nodes и часть команд на хост.
- Парсинг консольного вывода Callee вместо стабильного event protocol ломает resume и диагностику.
Надёжность
- Потеря события между Callee и Balda без durable event log.
- Двойной запуск VM без idempotency key.
- Повторный Human response возобновляет workflow дважды.
- Падение Broker оставляет VM без lease и cleanup.
- Большие build-логи забивают SQLite или MCP-ответы.
Безопасность
- Непроверенный
workflow_id, repository URL или revision превращается в выполнение произвольного ввода. - Общий SSH/Git credential между VM расширяет последствия компрометации.
- Секреты в prompt, events или build logs попадают в Mattermost/Beads.
- Host path, переданный как ACP cwd, не существует или указывает не туда внутри VM.
- VM с доступом в локальную сеть может атаковать хостовые сервисы; egress и host API нужно ограничить.
13. План реализации Broker
Этап 1 — spike контрактов, 4–8 часов
- Запустить один Callee workflow вручную внутри тестовой VM.
- Зафиксировать фактический stdout/API, Human pause/resume и cancel.
- Запустить Codex Role через локальный ACP stdio.
- Проверить workspace path, build и terminal result.
- Принять формат VM runner protocol на основании фактов.
Результат: подтверждённый протокол Callee/runner без предположений.
Этап 2 — Virfield control API, 4–8 часов
- Обернуть существующий
vm_prepare_sessionв узкий authenticated HTTP API. - Добавить операции lease status, stop и delete.
- Ограничить templates, TTL и число параллельных VM.
- Добавить idempotency key и audit log.
- Проверить cleanup после таймаута и падения клиента.
Результат: Broker может безопасно получить и освободить VM без host shell.
Этап 3 — VM runner, 1–2 дня
- Описать versioned JSON protocol command/event.
- Реализовать start, events, Human response и cancel.
- Подключить Callee workflow pack и Codex ACP.
- Сформировать artifact manifest для git diff, commit, logs и
.xcresult. - Добавить terminal result и гарантированное завершение дочерних процессов.
Результат: одна команда запускает workflow в VM и возвращает структурированные события.
Этап 4 — Broker MVP, 1–2 дня
- Реализовать SQLite schema для runs, events, responses и artifacts.
- Реализовать state machine и транзакционный event journal.
- Подключить Virfield API и SSH/runner transport.
- Опубликовать MCP tools из §8.
- Добавить restart recovery, lease renewal и cleanup worker.
Результат: Balda управляет долговечным run через HTTP MCP.
Этап 5 — Balda + Prism, 1–2 дня
- Подключить Broker MCP к runtime Balda.
- Развернуть Prism adapter и Dolt/Beads container.
- Реализовать отображение events → Story phases.
- Связать Human request с Mattermost session/topic.
- Сформировать финальный отчёт Result/Artifacts/Confidence/Next action.
Результат: Story ведётся в Beads, выполнение и approvals видны в Mattermost.
Этап 6 — сквозная приёмка, 4–8 часов
- Создать Story из реального сообщения Mattermost.
- Пройти specify/design/approval/implement/review/verify.
- Собрать Xcode-проект и запустить тесты внутри VM.
- Перезапустить Broker во время run и проверить восстановление.
- Проверить terminal cleanup VM и доступность артефактов.
Результат: воспроизводимый end-to-end прогон без исполнения агентских команд на хосте.
Оценка MVP после spike: 4–7 рабочих дней. Production hardening зависит от возможностей Callee API и обычно добавит 3–7 дней.
14. Критерии готовности
- Balda создаёт одну Story и один idempotent run из сообщения Mattermost.
- Все команды Codex, Xcode build и тесты исполняются внутри leased VM.
- Callee управляет ролями и циклами; Broker не содержит workflow policy.
- После рестарта Balda или Broker прогресс восстанавливается без двойного запуска.
- Terminal run обновляет Beads, публикует артефакты и удаляет VM по lease policy.
Связанные заметки
- personal/tech/callee-prism — контракты Callee, ACP и Prism.
- personal/tech/agents-bridge — предыдущий мост; не часть целевой схемы.
- personal/tech/balda-executor-mcp — предыдущий исполнитель; не часть целевой схемы.
- personal/plans/balda-mm-phase4-agents — история предыдущей интеграции.