[2026-10-02] eagle: personal/plans/balda-callee-prism-plan.md

This commit is contained in:
Alexey Martemyanov committed 2026-10-02 16:09:09 +06:00
1 parent dbd0da1252
commit ef1d7ffbb0
1 file changed
+51 -125
+51 -125
View File
@@ -21,41 +21,16 @@
## 1. Цель
Balda принимает задачу в Mattermost, ведёт её состояние в Prism/Beads и запускает изолированное выполнение в одноразовой macOS VM.
Код, сборка, тесты и Xcode выполняются только внутри VM. Хост Mac управляет VM через Virfield, но не исполняет команды агента в основной системе.
Единственная целевая цепочка исполнения:
Balda принимает задачу в Mattermost, ведёт Story через Prism/Beads и запускает выполнение через Execution Broker. Класс выполнения выбирается по задаче: обычная разработка — изолированный Docker worker; Xcode и macOS API — одноразовая VM Virfield; изменение управляемого хоста — отдельный capability lease.
```text
Mattermost
→ Balda
→ Execution Broker
→ Virfield на Mac
→ macOS VM
→ Callee workflow
→ Codex ACP sessions
Mattermost → Balda → Broker → Docker gateway → disposable Linux worker → Callee → OpenCode/Claude/Codex ACP
↘ Virfield → macOS VM → Runner → Callee → ACP
Balda → Prism adapter → bd → Dolt/Beads
ACP result → Callee event → Broker event log → Balda → Prism/Beads + Mattermost
```
Контур состояния задачи:
```text
Balda
→ Prism adapter
→ bd
→ Dolt/Beads database
```
Обратный поток:
```text
Codex
→ ACP result
→ Callee event
→ Broker event log
→ Balda
→ Prism/Beads + Mattermost
```
При создании локального проекта Broker/Gateway создаёт Git-репозиторий в настроенном каталоге Mac. В worker монтируется только этот репозиторий; Docker socket, credential vault и весь каталог `~/Developer` внутрь worker не передаются. Для macOS VM действуют отдельные правила без host shared folders.
## 2. Подтверждённый статус и оставшаяся интеграция
@@ -251,28 +226,34 @@ Codex → prism-callee skill → Callee → дочерние Codex sessions
## 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.
1. Пользователь даёт Balda задачу в Mattermost без готового репозитория.
2. Balda читает `execution_profiles`, выбирает `workspace_enabled` Docker worker и вызывает `execution_repository_create` со стабильным idempotency key, текущими `chat_id/topic_id` и собственным коротким `name_hint`.
3. Broker через gateway создаёт локальный Git-репозиторий под настроенным workspace root и возвращает `workspace://` ID с полным commit SHA; Balda создаёт Prism Story.
4. Balda вызывает `execution_start` с этим ID/revision, `story_id`, теми же chat/topic и allowlisted workflow/agent profile.
5. Broker durable-записывает run, gateway монтирует только выбранный repo в одноразовый Linux worker, Runner запускает Callee и установленный ACP-исполнитель. Для Xcode вместо Docker используется отдельная VM Virfield.
6. События, Human response, артефакты и cleanup идут через Broker; Prism/Beads и Mattermost обновляет Balda.
Минимальный запрос запуска:
Пример полей запуска после создания репозитория:
```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"
"idempotency_key": "story-42-attempt-1",
"story_id": "story-42",
"chat_id": "mattermost-chat-id",
"topic_id": "mattermost-topic-id",
"workflow_id": "opencode/story",
"workflow_version": "sha256:<точный digest установленного workflow>",
"repository": "workspace://broker-created-name",
"revision": "<полный Git commit SHA>",
"runtime_class": "linux-container",
"worker_profile": "docker-dev",
"agent_profile": "opencode-deepseek",
"task": "Добавить Go CLI и тесты",
"ttl_seconds": 3600
}
```
Broker возвращает `run_id` сразу после надёжной записи команды. Подготовка VM продолжается асинхронно.
Broker возвращает `run_id` после надёжной записи команды; выполнение продолжается асинхронно.
## 6. Обратный data flow
@@ -324,16 +305,16 @@ Broker возвращает `run_id` сразу после надёжной за
Отдельный контейнер в одном Docker network с Balda. У Broker собственный persistent volume с SQLite.
Northbound: HTTP MCP для Balda.
Southbound: узкий HTTP API Virfield и SSH к выданной VM.
Внутри VM: VM runner → Callee → Codex ACP stdio.
Southbound: Docker gateway для `linux-container`, Virfield API и scoped SSH для `macos-vm`, отдельный host-runner для `remote-host`.
Внутри одноразового worker: Runner → Callee → выбранный ACP-исполнитель.
### MCP tools
### Основные 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)`
1. `execution_profiles` — workflow, worker и agent allowlist.
2. `execution_repository_create` — идемпотентно создать новый локальный Git repo для chat/topic.
3. `execution_start`, `execution_status`, `execution_events`, `execution_ack` — durable run и события.
4. `execution_respond`, `execution_cancel`, `execution_artifacts` — Human response, отмена и артефакты.
5. `execution_remote_plan` и отдельные Virfield image tools — управляемые host/VM сценарии.
### Состояния run
@@ -377,7 +358,7 @@ Broker не должен парсить человекочитаемый ANSI/TT
Broker планирует не только macOS VM. Все среды исполняют один versioned Runner protocol, но имеют разные `runtime_class`:
- `linux-container` — обычный код, CLI, Docker builds и инфраструктурная автоматизация;
- `linux-container` — обычный код, CLI, Go build/test и статическая проверка Dockerfile; Docker socket в worker не передаётся, фактическая сборка образа требует отдельного host/builder шага;
- `macos-vm` — Xcode, macOS APIs, GUI и UI tests;
- `remote-host` — изменение конкретного хоста после Human approval.
@@ -414,15 +395,11 @@ Callee поддерживает `Parallel`, но это fan-out Role visits вн
## 10. Изоляция, shared folder и секреты
Основная граница безопасности — одноразовая macOS VM.
Для `macos-vm` основная граница — одноразовая VM: исходники и Xcode build живут на её локальном диске, без host shared folders. Virfield выдаёт scoped lease/SSH, а VM удаляется после выгрузки результатов.
- исходный проект клонируется в VM без host bind mounts;
- Codex, Callee, Xcode и тесты работают внутри VM;
- Broker получает только scoped SSH key для конкретной VM;
- Git credentials выдаются на один репозиторий и ограниченный срок;
- VM удаляется после выгрузки результатов или по lease timeout.
Для `linux-container` граница — одноразовый worker с read-only root, UID 65532, ограниченными capabilities и отдельным `/state`. Gateway имеет Docker socket и mount настроенного workspace root; сам worker получает только bind mount одного проверенного локального Git repo в `/workspace`. Broker и Balda не получают этот host mount. Запуск с `workspace://` требует `workspace_enabled`, соответствия chat/topic, точного commit SHA и чистого checkout. Credential issuer выдаёт scoped lease только после durable admission, checkpoint и cleanup завершают владение. Docker CLI/socket внутри worker отсутствуют.
Хостовый Virfield API разрешает только операции жизненного цикла VM. Balda и Broker не получают `docker.sock`, пользовательский `~/.ssh` или произвольный shell на Mac.
Ни Balda, ни модель не получают пользовательский `~/.ssh`, credential vault или произвольный host shell.
### Credential management — обязательный scope (2026-09-30)
@@ -593,74 +570,23 @@ DeepSeek подходит для ограниченного routing и прос
4. Свободный provider command или agent-generated `cmd` превращает профиль в arbitrary code execution.
5. Установка всех provider credentials в один golden image нарушает isolation и усложняет rotation.
## 16. План реализации
## 16. План работ после push `f237556`
### Этап 1 — live spike интеграционных контрактов
Предыдущие этапы Broker/Runner, Virfield v2 и credential lifecycle выполнены частично и описаны выше как история. Текущий критический путь относится к новому локальному repo и Docker/OpenCode:
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 контрактов.
1. **Свести исходники и принять точный build.** Ветка `codex/broker-workspace-repos` (`f237556`) основана на RC9, поэтому соединить её с Docker/OpenCode runtime-исправлениями `5792cff`; зафиксировать plugin version, workflow digest, Runner/Callee и immutable worker image ID. Проверить `make check` и повторить изолированный Story на этом exact commit.
2. **Развернуть live контур.** Настроить выделенный Docker worker profile, `workspace_root=/Users/admin/Developer`, mount корня только в gateway и `--workspace-repositories` у issuer; установить новую версию Broker/gateway и managed plugin Balda. Проверить MCP discovery и отсутствие регрессии действующих VM профилей.
3. **Принять пользовательский Mattermost flow.** Сообщение Balda не содержит repo name/path. Она сама вызывает `execution_repository_create`, создаёт Prism Story, запускает run, доставляет Human approval и события в исходный chat/topic, публикует артефакты и фиксирует cleanup. Проверить Git commit в новом repo и отсутствие двойного создания при повторе idempotency key.
4. **Закрыть release gates.** Разобрать наблюдённый ACP `fs/write_text_file: Method not found`, выполнить CI/publication checks на точном SHA, проверить rollback и оставшиеся credential/managed-host ограничения. Public stable объявлять только после live приёмки.
## 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.
1. Balda сама создаёт новый локальный Git repo под настроенным workspace root из обычной Mattermost-задачи; пользователь не передаёт заранее repo name/path.
2. Один chat/topic получает одну Prism Story и идемпотентный Broker run с полным pinned commit SHA, allowlisted workflow и agent profile.
3. Docker worker запускает установленный ACP-исполнитель без Docker socket и host secrets; Xcode/macOS задачи остаются в VM Virfield.
4. Human approval возвращается в исходную тему, события и артефакты доходят до Balda/Prism/Mattermost, terminal cleanup и credential checkpoint завершаются.
5. Повторный запрос/рестарт не создаёт второй repo или run; отказ, cancel и rollback дают диагностируемое состояние.
6. CI и release доказательства относятся к одному exact SHA объединённого кода; remote-host задачи требуют отдельный capability lease.
## Связанные заметки