Architecture
Control plane vs execution plane
The runtime splits into two planes:
- Control Plane — manages TaskRuns: creation, configuration, monitoring.
- Execution Plane — executes TaskRuns: the agent loop, model calls, tool calls.
These are the same 17 logical components in every deployment mode (embedded, daemon, desktop-managed). Only the host/API adapters differ.
Component inventory
The target architecture defines 17 components, each a logical responsibility boundary (not a deployment service):
| Component | Responsibility |
|---|---|
| Runtime API | HTTP + streaming ingress |
| TaskRun Manager | Lifecycle — create, resume, cancel, terminal |
| Scheduler | Admission, queues, bounded parallelism |
| Execution Engine | Agent loop, model-call orchestration |
| State/Checkpoint Store | Durable state, checkpoints, reconciliation |
| Event Log | Durable event append + replay |
| Budget Manager | Typed per-run budget enforcement |
| Capability Engine | Permission evaluation, grant management |
| Workspace Manager | Workspace leases, coordination |
| Tool Gateway | Tool dispatch, idempotency, output limits |
| Process Supervisor | Process ownership tree, signal propagation |
| Provider Gateway | Normalized model calls, stream events |
| Context Engine | Deterministic prompt assembly, budgets |
| Plugin Host | Isolated plugin execution |
| MCP Gateway | Rust MCP SDK behind a bounded project port; capability mediation |
| Observability | Correlated logs, traces, metrics, audit |
| OpenCode Adapter | API/SDK/event translation (outside the core) |
Every transition has exactly one canonical writer (TaskRun Manager, Scheduler, Execution Engine, State Store, Event Log). State/event consistency is event-sourced — the Event Log is the source of truth, and the State/Checkpoint Store holds materialized projections for fast queries.
Layered crate model
Dependencies flow inward. The domain is pure; adapters implement port traits; the host composes everything:
Host (daemon / embedded / CLI)
→ runne-runtime
→ runne-application
→ runne-domain (pure, no async, no IO)
→ Ports (traits) ← Adapters (store, event, provider, tools, process, plugin, MCP, API, obs, compat)The 16 target crates: runne-domain, runne-application, runne-runtime, runne-store, runne-scheduler, runne-provider-*, runne-tools, runne-plugin-host, runne-plugin-protocol, runne-mcp, runne-api, runne-opencode-compat, runne-opencode-adapter-sqlite, runne-observability, runne-platform — plus the host artifacts runned (daemon), runne (CLI), runne-embed (embedded library facade), and runne-plugin-host (conditional separate-process binary).
Actual crate workspace (48 crates)
The repository's crates/ directory currently holds 48 crates, grouped here by responsibility:
| Group | Crates |
|---|---|
| Runtime core | runne-domain, runne-application, runne-app-core, runne-runtime, runne-api, runne-http |
| Daemon | runne-daemon, runne-daemon-openai-effect, runne-daemon-deepseek-effect, runne-daemon-local-engine-effect, runne-daemon-loopback-fixture |
| Providers | runne-provider, runne-provider-openai, runne-provider-deepseek, runne-provider-http |
| Store / persistence | runne-store, runne-local-store, runne-secure-store |
| Security / credentials | runne-security, runne-credential-service, runne-credential-service-core, runne-pairing-crypto, runne-sandbox-helper, runne-native-enrollment-authority, runne-project-owner-authority, runne-release-authority |
| Platform (macOS / Windows / mobile) | runne-platform, runne-platform-ports, runne-platform-desktop, runne-platform-mobile, runne-macos-xpc, runne-macos-keychain-acl, runne-macos-process-identity, runne-windows-native-handle, runne-sqlite-handle-identity, runne-sqlite-native-identity |
| MCP | runne-mcp |
| Tools | runne-tools |
| Plugin host | runne-plugin-host, runne-plugin-protocol |
| CLI / client | runne-cli, runne-runtime-client |
| Compatibility | runne-opencode-compat, runne-opencode-adapter-sqlite |
| Observability | runne-observability |
| Qualification / release | runne-native-qualification, runne-promotion-contracts, runne-update-metadata-producer |
Grouping is by crate name. For exact per-crate responsibilities and dependency rules, see the repository's
docs/02-target-architecture/CRATE_STRUCTURE.md.
runtime-client separation
The runtime is the only owner of authoritative state. The CLI and Tauri host interact with it only through runtime-client and an authenticated canonical API; the Vue renderer receives only typed DTOs over Tauri IPC. runned is the daemon binary, runne the CLI, runne-embed the embedded library facade.
Local Engine integration
local-engine/ is the bundled local-inference engine (GGUF, llama-cpp-2, CPU profile; no Ollama, no network downloads). It is its own Cargo workspace and lockfile, with 8 crates: runne-local-model, runne-inference-protocol, runne-model-store, runne-engine-broker, runne-inference-host, runne-llama-worker, runne-provider-local, runne-engine-platform. Product integration wires it into the daemon via the runne-daemon-local-engine-effect effect boundary, LocalEngine credential identity, and GET /local-engine/status in runne-api. See local-engine/README.md in the repository.