601 lines
49 KiB
Markdown
Executable File
601 lines
49 KiB
Markdown
Executable File
# Balda + Prism/Beads + Execution Broker + Callee + Codex / Claude / OpenCode
|
||
|
||
> Обновлено: 2026-10-01
|
||
> Статус: Virfield v2.0.0 опубликован. Broker 0.1.0-rc.4 подготовлен как приватный draft с чистой публикационной историей и полным CI. Managed plugin установлен в рабочую Balda. Общий production/stable acceptance ещё не закрыт: сохраняются ограничения Docker Codex, OAuth Docker/remotes, реальных managed hosts и официальной публикации.
|
||
> Текущий проект и 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. Подтверждённый статус и оставшаяся интеграция
|
||
|
||
|
||
### Проверка 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 — 2026-10-01, 14:15 Бишкек
|
||
|
||
- У v4 `callee.log` подтверждены ACP `session/create` и ошибка `Query closed before response received` до первого ответа. Это не доказывает ни истечение credentials, ни успешный inference. Важное совпадение описано в [upstream ACP issue #1193](https://github.com/agentclientprotocol/claude-agent-acp/issues/1193).
|
||
- Runner воссоздавал `oauthAccount`, но не метку `hasCompletedOnboarding` в приватном конфиге Claude. Исправлено для проверенной полной account-сессии: development `2cee913`, чистая publication history `f10d103`. Полный `make check` и publication check прошли. Новый credential-free bootstrap развернут в профиль `macos-claude`; прежний Callee и workflow сохранены. Broker после перезапуска доступен.
|
||
- Повторный inference ещё не принят: Virfield показывает `available: 0` из-за соседней операции обслуживания образа `vf-ghcr-sequoia152`. Её VM/образ не менялись. PR #1 связан с новой private веткой, но CI именно для `f10d103` на момент проверки ещё не появился. Подробности: `/Users/admin/Developer/execution-broker/state/private-publication-audit-20261001/claude-onboarding-20261001.md`.
|
||
|
||
Production/stable release остаётся незакрытым: полный Claude Story/inference, реальный refresh и повторная VM без входа; OpenCode chat auth/inference; Docker/remotes credential lifecycle; provider-side expiration/revocation; ранее перечисленные full-stack gates. Credentials и login capabilities в этой заметке не сохраняются.
|
||
|
||
Virfield v2.0.0 опубликован: Go daemon, leases/images, аутентифицированные HTTP/MCP, SSH isolation, tunnels и embedded console. Live golden/clone E2E и release CI прошли в объёме [[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.
|