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

654 lines
66 KiB
Markdown
Executable File
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.
# 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, но не исполняет команды агента в основной системе.
Единственная целевая цепочка исполнения:
```text
Mattermost
→ Balda
→ Execution Broker
→ Virfield на Mac
→ macOS VM
→ Callee workflow
→ Codex ACP sessions
```
Контур состояния задачи:
```text
Balda
→ Prism adapter
→ bd
→ Dolt/Beads database
```
Обратный поток:
```text
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](https://github.com/mallexxx/execution-broker/actions/runs/36842265997) прошёл все 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](https://github.com/baldaworks/balda/pull/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](https://github.com/mallexxx/execution-broker/actions/runs/36854040694) 14/14, приватный [draft RC6](https://github.com/mallexxx/execution-broker/releases/tag/untagged-4a40999515a9662c914c): четыре 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:
```text
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.
Минимальный запрос запуска:
```json
{
"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)`.
Минимальное событие:
```json
{
"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
```text
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:
```json
{
"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](https://github.com/mallexxx/virfield/releases/tag/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](https://github.com/mallexxx/virfield/blob/main/docs/VERIFICATION.md).
### Граница проектов и репозиториев — принятое решение
`virfield` и `execution-broker` — два независимых проекта. Их нельзя объединять в один репозиторий или один daemon.
Репозиторий `virfield` содержит host control plane: корневой Go module, `cmd/virfieldd`, `cmd/virfield`, `cmd/virfield-mcp`, `cmd/virfield-lume`, реализации в `internal/`, deployment в `deploy/`. Актуальная карта модулей — [Architecture](https://github.com/mallexxx/virfield/blob/main/docs/ARCHITECTURE.md); отдельного каталога приложения v2 нет.
Целевая структура отдельного `execution-broker` (реализацию сверять в его репозитории):
```text
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.
## Связанные заметки
- [[personal/projects/virfield]] — текущий релиз, подтверждённый scope и каноническая документация.
- [[personal/tech/callee-prism]] — контракты Callee, ACP и Prism.