Files
obsidian-vault/personal/plans/balda-callee-prism-plan.md
T

66 KiB
Executable File
Raw Blame History

Balda + Prism/Beads + Execution Broker + Callee + Codex / Claude / OpenCode

Обновлено: 2026-10-02 Статус: Balda обновлена до официального v0.4.2, managed plugin до execution-broker 0.1.0-rc.10; конфигурация проверена, Mattermost подключён, свежий chat-origin /execute ещё не принят. Virfield v2.0.0 опубликован; VM pool сейчас свободен. RC10 clean publication ef1af48 подготовлен локально, но GitHub Actions отложены по решению оператора и RC10 не запушен. Полный make check в dev и publication checkout, scan 215 файлов и локальный release kit из пяти SHA-проверенных архивов прошли. Live full Story с точным RC10 Broker и DeepSeek прошёл шесть ролей, Human approval, пять выполненных проверок verifier, review/quality gate, restart Broker/issuer и cleanup. OpenCode read-only policy принудительно запрещает эффекты; ACP denied-write доказан. Public stable остаётся no-go до native release/подписи, live Docker provider+sandbox, upstream revocation disposable identity, Mattermost first-command и managed-host acceptance. Текущий проект и runbook: personal/projects/virfield.

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 v0.4.2 + RC10 plugin — 2026-10-02, 01:08 Бишкек

  • Рабочая Balda обновлена с 0.1.16-session-feedback до официального v0.4.2 (86f9139) через локальный образ из SHA-проверенного release binary; прежний образ и полный snapshot состояния сохранены для отката. Плагин обновлён с rc.6 до 0.1.0-rc.10. После restart: balda validate: ok, Mattermost transport configured, ошибок запуска нет. GitHub Actions и push не выполнялись.
  • Первый пользовательский /execute вернул Unknown command: Balda CLI установила файлы плагина, но не активировала его в managed-каталоге. После второй полной резервной копии официальный startup-import Balda активировал RC10. В live DB: enabled plugin, 1 command, 1 skill, 0 diagnostics; snapshot содержит execute, Mattermost запущен без ошибок. Повторная пользовательская команда ещё нужна для end-to-end приёмки. Старые сессии сохраняют прежний каталог возможностей. Детали и резервные копии: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc10.md.

RC10 OpenCode permission и локальный релиз-кандидат — 2026-10-01, 23:20 Бишкек

  • Чистый publication commit ef1af48d33bf4e25d053c8d5d1fab62d5afa9c8b создан только локально. GitHub Actions и push не запускались по решению оператора. Исходники проверены (make check в обоих checkout, Callee race, publication scan 215 файлов). Локальный release kit из пяти архивов прошёл SHA256 и exact-SHA проверку; Darwin ARM64 принят без Go, Linux ARM64 запущен без сети и записи. Доказательства: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc10.md. Это не CI/signing evidence.
  • Предыдущий OpenCode build/deny тест реально выполнил запрещённую команду и экспортировал созданный файл. После исправления ACP diagnostic run-3d420f795cdfcedac909b75167ded1b6 записал отказ tool_kind=execute; файл и patch отсутствовали, VM удалена. Штатный read-only OpenCode теперь использует plan/deny со строгим policy, пишущий — build/allow через ACP; остальные пары отклоняются до inference.
  • Обычный macos-opencode-deepseek профиль обновлён на credential-free bootstrap policy-v5 и workflow digest sha256:f24146978e3c2a8792d98ab5d960e3032e51aa93f20dda3505e43f090f55a355. Live Broker обновлён на локальный образ из точного RC10 релизного бинарника; /healthz вернул 0.1.0-rc.10. Full Story run-bc593b5eab0c18c49f2a16b395387b53 прошёл шесть ролей, Human approval, пять выполненных проверок verifier, review, quality gate, restart Broker/issuer, checkpoint и cleanup; шесть артефактов SHA-проверены. DeepSeek vault свободен, VM pool 2/2 свободен. Mattermost-сообщений не отправлялось.
  • Public stable по-прежнему не объявлен: CI отложен, а Docker sandbox/live provider, upstream revoke, Mattermost-origin и реальные managed-host проверки остаются открытыми.

Проверка chat login — 2026-10-01, 13:36 Бишкек

  • Clean publication HEAD 4dc0615, исходная локальная repo 5875e5a, ветка codex/multi-executor-profiles, PR https://github.com/mallexxx/execution-broker/pull/1 (draft/private). Изменения запушены и синхронизированы в Developer. Полный make check, реальный synthetic Keychain probe/checkpoint и Gitleaks по полной публикационной истории прошли. Оба CI-запуска нового HEAD 4dc0615 завершились успешно (branch и PR).
  • Реализован полноценный claude auth login --claudeai: profile/inference scopes, native access/refresh cache, привязка account+organization при checkpoint. Старый setup-token сохраняется до успешного обновления. Terminal handle очищается; остаётся только несекретная метка формата. Existing Codex vault не изменялся.
  • v2 сохранил static OAuth, создал VM и запустил первую роль; server-managed organization policy отклонила setup-token. Cleanup/checkpoint исправлены и подтверждены. v3 run-36c7622122d50c626c17c3e913acf3a7 завершился authentication_failed, cleanup done: временный HOME скрывал системный Keychain. Это воспроизведённая ошибка окружения, а не подтверждённая задержка пользователя или expiration.
  • Исправление Keychain развернуто в issuer helper и worker bootstrap: системный HOME нужен macOS Security.framework, CLAUDE_CONFIG_DIR и CLAUDE_SECURESTORAGE_CONFIG_DIR остаются отдельными для login/run. Default Keychain/search-list не меняются. Проверены native write/read/auth status/export/delete и чтение обновлённого synthetic cache Runner с private HOME; эти проверки не заменяют реальный network refresh/inference.
  • Balda создал v4 Story eb-73afda6e242885a0ff4503e3, run run-558545102ec40e23c6562eb2c4bf85fd, key chat-login-claude-account-20261001-v4. Human auth доставлен в существующую тестовую тему; native browser consent уже завершён, полная account session сохранена в encrypted vault. Тот же run возобновился автоматически. Блокировка image_in_use снята соседней задачей; VM выделена, Claude ACP прошёл session initialization. Первая роль specify завершилась без final text (callee_failed, peer connection closed); точная причина ещё не установлена. Run failed, артефакты сохранены, cleanup done. Успешный Claude inference пока не принят. Образ и работу соседней задачи не меняли. UI automatic redirect, native local callback без copy/paste, success/failure состояния реализованы. Неверная версия Балди про expiration v3 исправлена в теме и ограничена правилом в plugin skill.

Проверка Claude onboarding и ACP — 2026-10-01, 14:58 Бишкек

  • Для валидированной Claude account-сессии Runner теперь восстанавливает hasCompletedOnboarding вместе с OAuth account metadata. Development commit 2cee913, чистая публикация f10d103; полный make check прошёл. Credential-free bootstrap с новым Runner развернут в обычный macos-claude; Broker доступен.
  • Полный Claude Story повторно не прошёл: v5 run-dfcd654b35e5e2dfeccf9e738f914ae4, v6 run-dd66bb66eacb1bda7b59a170775ea071 и warm-up Story run-a7b2982dcf494c463f595944db4869a6 остановились в первом specify без final text. Все VM удалены. Диагностический Callee подтвердил пустые provider error code/message при полном prompt: run-04fe781d89f9ccc3c172b7677e8c67b1.
  • Короткие native CLI и ACP specify прошли в одной VM run-8fc39c972340f894b30405aa06008a52. Тот же полный prompt отдельно прошёл native Claude CLI в новой VM run-b8f4f3970264eeffadafbc0040849692: exit 0, непустой ответ, cleanup done. Лог title generation error был также в успешном ACP probe, поэтому сам по себе он не доказывает отказ auth. Похоже на сбой ACP session lifecycle на содержательных запросах; первопричина не установлена. Профиль Claude не принят для full Story. Временные диагностические профили удалены из Broker. Соседний образ Virfield не менялся.
  • Текущий кандидат — 0.1.0-rc.5, clean publication commit 12a5add. Канонический комплект из четырёх платформенных CI-архивов, plugin архива и SHA256SUMS загружен в приватный draft release. Все пять SHA256 совпали с CI, проверки прошли нативно на четырёх платформах, распакованные файлы прошли publication/Gitleaks. Локальные платформенные архивы отличаются из-за версии Go и дополнительных лицензий из кеша и не используются для публикации. Clean-machine install и Mattermost first-command остаются открытыми. Remote Git ref уже 12a5add; CI для точного SHA прошёл все 14 jobs через отдельный нерелизный validation tag. Private draft PR #1 всё ещё показывает прежний head f10d103, поэтому его старые checks не используем как доказательство RC5. Подробная запись: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/claude-onboarding-20261001.md. Решение по RC5 и полный список release gates: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc5.md.

Balda PR #11 смержен в main 2026-10-01 15:00 Бишкек (86f9139); восемь CI checks успешны. Это закрывает upstream gate для исправления session-preparation feedback, но установленная Balda требует отдельной сверки с merge commit.

Production/stable release остаётся незакрытым: Claude Story и повторная свежая VM после рестарта issuer/Broker теперь проходят без входа (v4 run-bd291c97e5e098ed2e2ca57b876a0b1a, обычный профиль run-1039e027ec5c7862367cb95a7fc02a51; оба quality gate passed, cleanup done, Prism completed). Код исправления — dev commit 05e7c44; RC5 draft устарел. Открыты provider-side expiration/revocation, OpenCode login/inference, Docker/remotes credential lifecycle и ранее перечисленные full-stack gates. Credentials и login capabilities в этой заметке не сохраняются.

RC9 Docker credential lifecycle — 2026-10-01, 19:26 Бишкек

  • Dev commit 74a10f2, чистый publication commit 6091a610992c83abdf706c3721d2c5d75c117e56 запушен в приватный PR #1. Docker worker теперь получает credential от host issuer при первом start после durable admission, checkpoint-ит остановленный Runner до удаления container/volume и освобождает identity только после подтверждённого cleanup. Потерянный worker или отклонённый checkpoint удерживает владельца до явного revoke/recovery. Remote-host fixed plans остаются отдельными без provider credentials.
  • Синтетические DeepSeek-тесты покрывают reuse в двух свежих Docker run, запрет замены API key, capacity refusal без утечки owner, lost-worker revoke cleanup и private gateway checkpoint RPC. Полный make check в dev и publication checkout прошёл; publication scan — 214 файлов. Live Docker provider Story и Codex sandbox на совместимом хосте не приняты.
  • Локальный RC9 release kit точного SHA собран для Darwin/Linux ARM64/AMD64 и plugin; все 5 SHA256SUMS совпали. Darwin ARM64 check-release прошёл в fresh HOME без Go в PATH (7 бинарников, vault import/revoke, Broker MCP/auth, SQLite backup); Linux ARM64 семь бинарников запустились в изолированном контейнере без сети. Это локальные артефакты, не exact-CI и не подпись.
  • Push CI 36868572492 и PR CI 36868579280 для точного RC9 SHA завершились до первого шага: GitHub annotation указывает failed account payments или spending limit. RC9 CI assets и подписанной provenance нет; public release остаётся no-go. OpenCode/DeepSeek disposable run run-ab12be94116626bc5e2ed8d42889d7b1 завершился succeeded, patch пустой, cleanup done, vault owner null; модель в plan mode прямо сообщила, что не вызывала touch, поэтому tool-level denial ещё не принят. Второй build-mode/permissions-deny bootstrap подготовлен, но новая Virfield image operation снова держит available=0. Временный профиль удалён, обычный Broker healthz=200.

RC8 retry/backoff fix — 2026-10-01, 19:00 Бишкек

  • В OpenCode denied-write probe Virfield вернул image_in_use из-за отдельной image_build операции, которая при лимите 2 VM намеренно устанавливает available=0 для всех новых leases. Run был отменен до получения VM; чужая загрузка не прерывалась. Обнаружен Broker bug: промежуточная выдача credential snapshot сбрасывала exponential backoff, поэтому issuer выполнял частые issue/abort циклы. Исправлено в dev f937ccc, добавлен regression test; полный make check прошёл.
  • Live Broker image собран из точного RC8 commit и развернут только для Broker. Синтетический run run-594708d118987f24a406c9410d3814ae во время Virfield image lock показал retry_count 0 → 1 → 2, затем был отменён с cleanup=done; DeepSeek inference и Mattermost-сообщений не было. Evidence: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/rc8-live-backoff-probe.json.
  • Дополнительный Linux ARM64 архив RC8 точного SHA собран локально; все семь бинарников запустились в контейнере без сети, Go и provider credentials. Это не exact-CI артефакт. Docker Codex в credential-free диагностике прошёл дальше только при отключённых seccomp и AppArmor, затем упёрся в RTM_NEWADDR: Operation not permitted; production изоляция не менялась.
  • Соседний Virfield image job job-a56dffdf456ecf269dc7c18bce963a97 после полной загрузки IPSW и установки macOS перешёл в needs_attention на assistant_dispatched с image_command_failed. Общий maintenance lock остаётся, available=0; OpenCode denied-write VM ждёт восстановления владельцем Virfield job.
  • Clean publication RC8 6984bc67e4a9b991ae66acf06d91578ffcff586b запушен в приватный PR. Push CI 36863848919 и PR CI 36863854456 не стартовали из-за GitHub Billing & plans, подтверждено annotation. Локальный Darwin ARM64 архив точного commit прошёл binary-only check-release с Go вне PATH и SHA256SUMS, но не является exact-CI release asset. Public stable no-go.
  • Docker Engine 29.2.1 диагностирован отдельно: узкий seccomp профиль разрешает только user namespace и сохраняет запрет mount/network namespaces, но полный Codex bwrap sandbox всё ещё не запускается; даже одноразовый seccomp=unconfined дошёл до Failed to make / slave: Permission denied. Production worker flags не ослаблены.
  • Подробный ledger: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc8.md.

RC7 exact-SHA gate — 2026-10-01, 18:35 Бишкек

  • Clean publication commit 5c213bb98b0caaa24bc7bb07ba73bd8589bdd07a запушен в существующий приватный PR #1. Его push CI 36862025838 и PR CI 36862030297 не выполнили ни одного шага: GitHub annotation сообщает failed account payments или недостаточный spending limit. Старый RC6 CI не является доказательством для RC7. Обновление Billing & plans необходимо до публикации exact-CI release assets.
  • Локально в чистом checkout прошли make check, Callee race test, проверка 213 публичных файлов, plugin version 0.1.0-rc.7. Локальный Darwin ARM64 RC7 архив из точного SHA прошёл check-release.py в чистом временном состоянии без Go в PATH, включая версии, vault, Broker MCP/auth и SQLite backup. Это локальный архив без подписи, не замена native CI artifacts.
  • Подробный release ledger: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc7.md. Public stable по-прежнему no-go.

OpenCode DeepSeek acceptance — 2026-10-01, 18:25 Бишкек

  • Существующий DeepSeek provider Balda использован без вывода ключа: ключ через private pipe импортирован в отдельный зашифрованный opencode-deepseek-work vault. Нативный OpenCode 1.18.34 вернул OK на реальном deepseek/deepseek-flash запросе. Credential-free VM bootstrap и постоянный issuer на 127.0.0.1:7796 установлены; рабочий профиль macos-opencode-deepseek подключен к Broker.
  • Два полных синтетических Story (run-cf83a0a3a0768d45f82199ae8db4176e, run-6b12f6189bc2e9b32fccadb596fc06b5) прошли шесть ролей, Human approval, quality gate, шесть SHA-256-verified artifacts, Prism completion и cleanup. Второй запустился в новой VM и пережил перезапуск Broker/issuer на approval без browser login.
  • Между ними был отказ run-c6d2008abe6308000375c2a4e55c0c3e только из-за добавленного моделью поля notes в валидный отчет verifier. Узкое исправление parser в dev 396eb5a принимает notes, но всё ещё отвергает другие неизвестные поля и неисполненные/ошибочные проверки; Callee race и полный make check прошли. Для публикации нужен новый exact-SHA кандидат.
  • OpenCode denied-write probe не дошёл до VM: Virfield зарезервирован соседней операцией image export (image_in_use). Проверочный run отменен с cleanup done, временный профиль удален. Upstream revocation/expiry ещё не проверены; static DeepSeek API key не имеет OAuth refresh.

RC6 candidate и актуальная приёмка — 2026-10-01, 17:25 Бишкек

  • Clean publication commit 2d786c4, CI 36854040694 14/14, приватный draft RC6: четыре native CI-архива, plugin archive и SHA256SUMS побайтно сверены. GitHub draft SHA256 совпадают с локальным bundle. Remote main ещё не обновлён, публичного релиза нет.
  • Claude full Story прошёл в двух свежих macOS VM, включая обычный профиль после restart issuer/Broker без browser login; reviewer/verifier/quality gate passed, cleanup done, Prism completed. Запрещённая запись в read-only роли отклонена. Managed plugin 0.1.0-rc.6 установлен в рабочую Balda из CI архива.
  • Оставшиеся gates, доказательства и решение no-go: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/release-readiness-rc6.md. До их закрытия RC6 остаётся приватным draft.

Базовый релиз Virfield v2.0.0 опубликован. На Mac установлен более новый versioned-images/GHCR кандидат, который ещё не принят как production release. Актуальные Git/runtime, матрица golden/clone E2E и полный оставшийся план поддерживаются только в personal/projects/virfield. Сервисы используют deployment вне checkout; публикация архива и коммит исходников не обновляют runtime автоматически.

Локально подтверждено 2026-09-30:

  • отдельный execution-broker repo и sidecar deployment; доступ из реального Balda container через MCP;
  • Virfield v2 lease → pinned SSH tunnel → Runner/Callee; чистый clone выполняет XCTest и отдаёт xcresult до cleanup;
  • полный Codex workflow с шестью свежими ролями и Human approval; реальный локальный commit и пять unittest проходят;
  • persistent OAuth vault/Keychain и host issuer: две последовательные свежие VM работают без нового browser login, checkpoint сохраняется до удаления VM; последняя проходит quality gate, restart Broker/issuer и Story completion;
  • Prism/Beads projection и local Story lifecycle. Доказательства: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/acceptance.md.

До production/public stable release остаются Mattermost-origin/delivery, совместимый Docker Codex sandbox, приёмка credential lifecycle на Docker/remotes, реальные managed-host identities/TLS/rollback, согласованное восстановление всего стека, remote CI/clean-machine distribution/signing. Встроенные роли пока sequential; параллельные worktrees и модельные бюджеты не реализованы. Полный аудит: /Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/production-review.md.

Статус остальных проектов и provider-конфигурация проверяются в их собственных источниках; релиз Virfield не является подтверждением их готовности.

Подтверждено 2026-10-01:

  • Чистый publication repo: /Users/admin/Developer/execution-broker-public, remote https://github.com/mallexxx/execution-broker (private), коммит cb9d54b8369bfd7437b98ccf76b9ff3d2df397f5. Частная development history не отправлена. Аудитные истории перенесены из public docs в private state.
  • CI 36815717157: 10/10 успешных заданий. Нативное исполнение Darwin/Linux ARM64/AMD64; Linux дополнительно устанавливается из архива без Go, собирает четыре образа, проходит real Callee/Beads Human, рестарт Broker/Prism, проверку пяти артефактов и cleanup. Пять именно CI-архивов и SHA256SUMS загружены в private draft v0.1.0-rc.4; подписи отсутствуют.
  • Managed plugin execution-broker 0.1.0-rc.4 установлен через штатный Balda CLI. Старый standalone skill сохранён вне discovery roots. Файл Balda с MCP credentials имеет mode 0600; OAuth vault/Keychain сохранены.
  • Balda PR 10 принят upstream. Исправление bounded user-visible preparation failure отправлено в PR 11; локальные race/lint/architecture проверки прошли. Рабочая Balda обновлена до 0.1.16-session-feedback, подключение Mattermost подтверждено. Первый PR 11 CI выявил отдельную гонку старого restart-теста; исправлена в e0e953bc, 50 повторов под race detector прошли. Финальный PR 11 CI 36817575956/36817575952: 8/8 успешных проверок. PR открыт; upstream merge ещё не выполнен.

Весь стек нельзя объявлять полностью production-ready: свежий Mattermost-origin запуск нового managed /execute ещё не принят; Docker provider sandbox/автоматический OAuth на Docker и remotes, реальные host identities/TLS/rollback, per-role worktrees/model budgets и официальное подписанное распространение остаются отдельными незакрытыми границами. Имеющаяся приёмка Mattermost recovery и drained backup/restore не заменяет эти проверки.

Дополнение 2026-10-01: Claude CLI и OpenCode

В целевой объём включены Claude CLI и OpenCode с несколькими моделями. Balda выбирает allowlisted agent_profile из каталога Broker; executor/model задаются оператором. Секреты не входят в конфиг профиля, плагин, репозиторий или VM image. Callee остаётся владельцем workflow, а профиль не может ослабить authored permissions.

Реализовано в ветке codex/multi-executor-profiles, clean publication commit 35cbe3ad5710f8eb5a52147da068ac016fb137c6:

  • отдельные encrypted identities/Keychain accounts с backward compatibility существующего Codex vault; типизированные cache leases, проверка executor/provider/account и сохранение обновлённых credentials до освобождения VM;
  • automated enrollment: Claude official setup-token через private PTY без печати токена; OpenCode auth login в отдельном HOME/XDG с импортом только выбранного provider; API-key ввод скрыт; браузерное согласие остаётся одноразовым действием человека;
  • integrity-locked optional runtimes: Claude Code 2.1.286, Claude ACP 0.84.0, OpenCode 1.18.34; конфигурации и workflow packs, выбор модели, поддержка в каталоге и skill Balda; backup проверяет все identities;
  • локально прошли race/vet/build, Callee, credential/enrollment/backup/publication checks; реальный credential-free CLI/ACP probe на macOS ARM64 прошёл, npm audit и полный clean-history Gitleaks без находок. CI на четырёх платформах: https://github.com/mallexxx/execution-broker/actions/runs/36820468335 — 14/14 успешных заданий; native optional executor probe прошёл на всех четырёх платформах. Draft PR: https://github.com/mallexxx/execution-broker/pull/1.

Это ещё не принятые production-профили: нужны реальные Claude/OpenCode login/inference, повторная свежая VM без логина, expiration/revocation, проверка read-only режима и полный Balda Story. OpenCode OAuth без стабильного accountId отклоняется; Anthropic subscription OAuth не переносится в OpenCode. Автоматический issuer для Docker/remotes по-прежнему не реализован. RC4 и live Codex deployment не изменены.

Документация: /Users/admin/Developer/execution-broker/docs/executors.md. Подготовлены private launchers /Users/admin/Developer/execution-broker/state/executor-enrollment/enroll-claude.command и enroll-opencode.command; пока не запускались и не обращались к действующим credentials.

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 — отдельный проект и отдельный репозиторий execution-broker. В production он живёт отдельным 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.

Аутентифицированный HTTP API /api/v1 и HTTP MCP /mcp реализованы; daemon слушает loopback. Для Broker остаются проверяемая сетевая доступность и integration contract. Произвольного 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

  1. Пользователь ставит задачу Balda в Mattermost.
  2. Balda через Prism adapter создаёт Story и получает story_id.
  3. Balda выбирает workflow_id из статического allowlist и вызывает execution_start.
  4. Broker просит Virfield создать VM, затем запускает внутри неё VM runner и Callee.
  5. 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

  1. Codex возвращает результат роли в Callee по ACP.
  2. Callee переводит workflow в следующее состояние и отдаёт структурированное событие VM runner.
  3. VM runner передаёт событие Broker; Broker сохраняет его до ответа Balda.
  4. Balda читает события через execution_events(run_id, after_event_id) и подтверждает курсор.
  5. 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

  1. Callee доходит до Human node и приостанавливает workflow.
  2. VM runner отправляет human_required с вопросом и вариантами.
  3. Broker фиксирует состояние waiting_human.
  4. Balda показывает вопрос в Mattermost и получает ответ в том же session/topic.
  5. 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

  1. execution_start(request) → run_id
  2. execution_status(run_id) → state, phase, last_event_id
  3. execution_events(run_id, after_event_id) → events, next_cursor
  4. execution_respond(run_id, human_request_id, answer)
  5. 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. Execution workers и распределение ресурсов

Broker планирует не только macOS VM. Все среды исполняют один versioned Runner protocol, но имеют разные runtime_class:

  • linux-container — обычный код, CLI, Docker builds и инфраструктурная автоматизация;
  • macos-vm — Xcode, macOS APIs, GUI и UI tests;
  • remote-host — изменение конкретного хоста после Human approval.

Минимальный WorkerSpec:

{
  "runtime_class": "macos-vm",
  "worker_profile": "xcode-27",
  "agent_profile": "codex-default",
  "workflow_id": "prism/story",
  "repository": "git@host:org/repo.git",
  "revision": "main"
}

Параллельные задачи

Balda поддерживает несколько независимых chat sessions. Turns внутри одной session сериализуются, разные sessions могут работать параллельно.

Callee поддерживает Parallel, но это fan-out Role visits внутри одного workflow. VM создаёт и распределяет Broker, не Balda и не Callee.

Политика пула:

  1. Одна изменяющая macOS Story получает одну эксклюзивную VM.
  2. Implementer, reviewer и verifier используют ту же VM, но свежие ACP-сессии.
  3. Отдельная VM на каждый Role не создаётся.
  4. Одновременно работают максимум две macOS VM; остальные run стоят в очереди.
  5. Linux containers масштабируются отдельно и не занимают macOS VM slots.

Параллельные read-only роли могут работать в одной VM. Параллельные изменения получают отдельные Git worktrees; запись нескольких агентов в один checkout запрещена политикой Runner.

Ограничение в две macOS VM задаёт Apple Virtualization.framework, а не Balda. Практический лимит дополнительно зависит от RAM и CPU.

10. Изоляция, shared folder и секреты

Основная граница безопасности — одноразовая 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.

Credential management — обязательный scope (2026-09-30)

OAuth-вход выполняется один раз при enrollment или при необходимости повторной авторизации у провайдера. Перезапуск или пересоздание VM сам по себе не должен требовать нового входа.

Владелец provider credentials — отдельный host credential issuer Execution Broker. Virfield управляет VM/SSH leases, но не хранит OAuth пользователя. Balda, Prism/Beads и Callee-события получают только состояние; токены в их сообщения не передаются.

Обязательные свойства:

  • долговременное зашифрованное хранилище вне VM и Git; на macOS master key находится в Keychain; права 0700/0600, atomic write и fsync;
  • выдача в конкретный run, repository и agent profile после durable admission; приватный файл в HOME гостя, не в checkout, environment, argv или golden/bootstrap;
  • одна OAuth identity арендуется одним run одновременно, чтобы VM не конкурировали за refresh token; ownership переживает restart Broker/issuer;
  • перед release VM обновлённый cache сохраняется обратно через приватный канал только после остановки ролей; блокировка снимается после подтверждённого удаления VM;
  • local revoke, provider-side revoke как отдельная операция, безопасное восстановление после утраты VM, отсутствие токенов в публичных API/артефактах; TTL Broker не считается upstream revocation.

Приёмка: новый clone выполняет реальные Codex роли без браузерного login; Broker/issuer переживают restart; checkpoint сохраняется до cleanup; следующий clone использует сохранённую сессию. Отдельно тестируются конфликт владельца, повреждение vault, отказ refresh, revoke и невозможность восстановить отозванный токен поздним checkpoint. Потерянный checkpoint блокирует повторную выдачу до явного восстановления, а не молча использует старый token.

Реализация и границы текущей версии: /Users/admin/Developer/execution-broker/docs/credentials.md. Live macOS приёмка завершена: run-f94853e932ef9b620a28412b609c62c7, все 6 ролей и quality gate пройдены, 5 unittest, cleanup done, encrypted checkpoint generation 6. Активный профиль Balda — macos-codex + prism/story; enrollment-only профиль отключён. Поддержка автоматического issuer сначала включена для macOS VM; Docker/remotes требуют отдельной приёмки того же жизненного цикла. OAuth может требовать нового входа после provider revoke/refresh rejection; это не штатный шаг каждого запуска VM.

Workspace и артефакты

Текущий recipe Virfield создаёт VM без shared host folders. Код, mutable workspace и Xcode build живут на локальном диске VM; перенос исходников/результатов — через scoped SSH и Git либо rsync/scp. Артефакты выгружаются до release lease и получают уникальный путь run_id/....

Добавление host mounts потребует отдельного решения по изоляции и проверки согласованности данных; это не часть принятого recipe.

Изменение других хостов

Задачи настройки Mac, Kraken, TrueNAS и других машин используют runtime_class: remote-host.

  1. Agent в контейнере формирует plan и выполняет read-only preflight.
  2. Balda показывает точный diff действий и запрашивает Human approval.
  3. Broker выдаёт capability lease на конкретные host, identity, operations и TTL 15–30 минут.
  4. Runner применяет изменения через dedicated service account или установленный host-runner.
  5. Verify, audit log и rollback закрывают lease.

Личные ключи из пользовательского ~/.ssh не передаются. Для managed host используется небольшой Go host-runner. Для первичного bootstrap допускается отдельный SSH account с short-lived certificate и ограниченным sudo.

Изменения самого Mac выполняет отдельный native launchd helper. Он принимает подписанный capability lease; Balda и модель не получают постоянный host shell.

11. Неподтверждённое

Блокирует прототип

  1. Есть ли у Callee стабильный machine-readable event stream и программный resume Human node.
  2. Можно ли запустить workflow pack prism/story отдельно от stock plugin host.
  3. Как Codex ACP получает workspace/cwd и сохраняет его между Role visits.
  4. Как передавать cancel в Callee без повреждения terminal result.
  5. Как подключить Broker к реализованному Virfield API через TLS/routing и проверить lease/SSH contract из его окружения.

Требует проверки до production

  • credential-free установка Codex; отдельное долговременное credential management с выдачей в каждую disposable VM (авторизация в golden image запрещена);
  • доступность Dolt/Beads из Prism adapter после рестартов;
  • формат и размер Xcode артефактов;
  • восстановление Broker после падения во время waiting_human;
  • параллельные Story и лимиты VM/CPU/RAM на Mac.

12. Варианты

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.

13. Virfield v2 — реализовано и опубликовано

Релиз v2.0.0 опубликован 2026-09-30, commit ee3aa1d. Текущая карточка — personal/projects/virfield; команды и контракты принадлежат документации репозитория.

Реализованы единый Go control plane, SQLite journal, reconciliation, leases/idempotency, resource admission, image pipeline, scoped SSH, cleanup, CLI/MCP и embedded console. Лимит двух VM и неизвестные состояния обрабатываются явно; неопределённая мутация не повторяется автоматически. Personal SSH keys/PAT storage и client-side lifecycle fallback в текущей реализации отсутствуют.

Lume остаётся backend; используется закреплённый 0.5.3 с двумя проверенными исправлениями shutdown. Guest automation встроена и версионируется вместе с Go-кодом. Полный golden/clone E2E пройден на одном Mac; Linux/macOS CI и проверки переносимости/секретов прошли для release commit. Точные результаты и непринятый scope — в Verification.

Граница проектов и репозиториев — принятое решение

virfield и execution-broker — два независимых проекта. Их нельзя объединять в один репозиторий или один daemon.

Репозиторий virfield содержит host control plane: корневой Go module, cmd/virfieldd, cmd/virfield, cmd/virfield-mcp, cmd/virfield-lume, реализации в internal/, deployment в deploy/. Актуальная карта модулей — Architecture; отдельного каталога приложения v2 нет.

Целевая структура отдельного execution-broker (реализацию сверять в его репозитории):

cmd/broker
cmd/runner
cmd/host-runner
internal/scheduler
internal/execution
internal/events
internal/drivers/virfield
internal/drivers/container
internal/drivers/remotehost
api/

Границы ответственности:

  1. virfield управляет VM, images, leases и host-level cleanup; он ничего не знает о Callee, Prism, Beads и model providers.
  2. execution-broker выбирает execution class, запускает Runner/Callee, управляет agent profiles и хранит run event log; он не управляет Lume напрямую.
  3. balda вызывает Broker по MCP и отражает события в Prism/Beads; Virfield напрямую из Balda не вызывается.
  4. execution-broker → virfieldd использует versioned authenticated HTTP API /api/v1; текущие модели и маршруты — internal/domain, internal/httpapi, internal/client. Отдельная OpenAPI-спецификация Virfield в v2.0.0 не опубликована.
  5. Общих Go-пакетов между репозиториями нет; совместимость обеспечивается API contract и contract tests.

14. Agent profiles и модельная политика

Broker и Runner не содержат vendor-specific workflow logic. Run выбирает agent_profile из статического allowlist.

Для Callee напрямую подтверждены Codex, Claude, Copilot, Grok, OpenCode и Cursor. Gemini и GLM подключаются через generic_acp или отдельный ACP adapter и считаются неподтверждёнными до integration test.

Worker image содержит Runner, Callee и нужные provider binaries. Credentials выбранного provider выдаются только на срок run. Node отсутствует в Virfield/Broker control plane; он допускается внутри специализированного worker image, если конкретный agent CLI без него не работает.

Распределение моделей

Схема Balda → Callee → coding agent остаётся правильной. Provider для Balda и профили исполнителей настраиваются в соответствующих проектах; конкретное назначение не фиксируется в плане Virfield.

Рекомендуемая раскладка:

  • Balda — надёжное понимание запроса, выбор workflow, управление state и Human interaction;
  • specify/design/review — сильная reasoning-модель;
  • implementation — Codex или другой сильный coding agent;
  • build/test/SSH apply — детерминированные Script/Runner operations;
  • дешёвая модель — routing, summarization и простая диагностика.

DeepSeek подходит для ограниченного routing и простых операций с жёсткими tool schemas. Он не принимает самостоятельные решения о privileged SSH-командах и сложной архитектуре.

Оптимизация стоимости строится на deterministic routing, token/run budgets, bounded retries и escalation: после повторной неудачи задача повышает model tier, а не повторяет дешёвую модель бесконечно.

15. Pitfalls

Архитектура

  1. Смешивание двух топологий: stock Codex → Callee и целевой Balda → Broker → Callee.
  2. Перенос workflow-логики в Broker превращает его во второй оркестратор.
  3. Прямая запись Broker/Callee/Codex в Beads создаёт несколько владельцев состояния.
  4. Запуск Callee вне VM переносит Script nodes и часть команд на хост.
  5. Парсинг консольного вывода Callee вместо стабильного event protocol ломает resume и диагностику.

Надёжность

  1. Потеря события между Callee и Balda без durable event log.
  2. Двойной запуск VM без idempotency key.
  3. Повторный Human response возобновляет workflow дважды.
  4. Падение Broker оставляет VM без lease и cleanup.
  5. Большие build-логи забивают SQLite или MCP-ответы.

Безопасность

  1. Непроверенный workflow_id, repository URL или revision превращается в выполнение произвольного ввода.
  2. Общий SSH/Git credential между VM расширяет последствия компрометации.
  3. Секреты в prompt, events или build logs попадают в Mattermost/Beads.
  4. Host path, переданный как ACP cwd, не существует или указывает не туда внутри VM.
  5. VM с доступом в локальную сеть может атаковать хостовые сервисы; egress и host API нужно ограничить.

Исполнение и ресурсы

  1. Mutable build через virtiofs может прочитать stale content; workspace должен жить на локальном диске worker.
  2. Более двух активных macOS VM невозможны; Broker обязан иметь очередь и admission control.
  3. Parallel Callee roles, пишущие в один checkout, создают file conflicts даже внутри одной VM.
  4. Свободный provider command или agent-generated cmd превращает профиль в arbitrary code execution.
  5. Установка всех provider credentials в один golden image нарушает isolation и усложняет rotation.

16. План реализации

Этап 1 — live spike интеграционных контрактов

  1. Выполнено для Virfield: clone/start/stop/delete, SSH readiness и cleanup проверены live; повтор для полного Broker/Runner flow входит в сквозную приёмку.
  2. Проверить передачу workspace/artifacts через Git/scoped SSH на локальный диск VM; shared host folders в recipe отсутствуют.
  3. Запустить один Callee workflow вручную внутри тестовой VM.
  4. Проверить Codex ACP, Human pause/resume, cancel и terminal result.
  5. Принять versioned contracts Virfield API и VM Runner.

Результат: фактические runtime-контракты без предположений.

Этап 2 — Virfield v2 core: завершён 2026-09-30

Результат опубликован как v2.0.0: один владелец VM/images, durable jobs/events, API/CLI/MCP/UI, image automation и проверенная переносимая сборка. Выполненные задачи не остаются в backlog. Непринятые проверки перечислены в personal/projects/virfield и repository Verification.

Этап 3 — универсальный Runner

  1. Описать versioned JSON protocol command/event.
  2. Реализовать start, events, Human response и cancel.
  3. Подключить Callee workflow pack и allowlisted agent profiles.
  4. Сформировать artifact manifest для git diff, commit, logs и .xcresult.
  5. Добавить terminal result и гарантированное завершение дочерних процессов.

Результат: один протокол запускает workflow в VM или container и возвращает структурированные события.

Этап 4 — Broker MVP

  1. Реализовать SQLite schema для runs, events, responses и artifacts.
  2. Реализовать state machine и транзакционный event journal.
  3. Подключить Virfield API, container driver и Runner transport.
  4. Опубликовать MCP tools из §8.
  5. Добавить restart recovery, lease renewal и cleanup worker.

Результат: Balda управляет долговечным run через HTTP MCP.

Этап 5 — Balda + Prism

  1. Подключить Broker MCP к runtime Balda.
  2. Развернуть Prism adapter и Dolt/Beads container.
  3. Реализовать отображение events → Story phases.
  4. Связать Human request с Mattermost session/topic.
  5. Сформировать финальный отчёт Result/Artifacts/Confidence/Next action.

Результат: Story ведётся в Beads, выполнение и approvals видны в Mattermost.

Этап 6 — сквозная приёмка

  1. Создать Story из реального сообщения Mattermost.
  2. Пройти specify/design/approval/implement/review/verify.
  3. Собрать Xcode-проект и запустить тесты внутри VM.
  4. Перезапустить Broker во время run и проверить восстановление.
  5. Проверить terminal cleanup VM и доступность артефактов.

Результат: воспроизводимый end-to-end прогон без исполнения агентских команд на хосте.

Срок оставшихся этапов определяется после сверки текущего Broker/Runner и проверки Callee/Prism контрактов.

17. Критерии готовности

  1. Balda создаёт одну Story и один idempotent run из сообщения Mattermost.
  2. Все команды Codex, Xcode build и тесты исполняются внутри leased VM.
  3. Callee управляет ролями и циклами; Broker не содержит workflow policy.
  4. После рестарта Balda или Broker прогресс восстанавливается без двойного запуска.
  5. Terminal run обновляет Beads, публикует артефакты и удаляет VM по lease policy.
  6. Linux-задачи исполняются в containers и не занимают macOS VM slots.
  7. Remote-host задача не использует личные SSH keys и не выполняется без capability lease.
  8. UI и MCP показывают одно состояние из virfieldd, без собственных fallback orchestration paths.

Связанные заметки