Skip to content

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):

ComponentResponsibility
Runtime APIHTTP + streaming ingress
TaskRun ManagerLifecycle — create, resume, cancel, terminal
SchedulerAdmission, queues, bounded parallelism
Execution EngineAgent loop, model-call orchestration
State/Checkpoint StoreDurable state, checkpoints, reconciliation
Event LogDurable event append + replay
Budget ManagerTyped per-run budget enforcement
Capability EnginePermission evaluation, grant management
Workspace ManagerWorkspace leases, coordination
Tool GatewayTool dispatch, idempotency, output limits
Process SupervisorProcess ownership tree, signal propagation
Provider GatewayNormalized model calls, stream events
Context EngineDeterministic prompt assembly, budgets
Plugin HostIsolated plugin execution
MCP GatewayRust MCP SDK behind a bounded project port; capability mediation
ObservabilityCorrelated logs, traces, metrics, audit
OpenCode AdapterAPI/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:

GroupCrates
Runtime corerunne-domain, runne-application, runne-app-core, runne-runtime, runne-api, runne-http
Daemonrunne-daemon, runne-daemon-openai-effect, runne-daemon-deepseek-effect, runne-daemon-local-engine-effect, runne-daemon-loopback-fixture
Providersrunne-provider, runne-provider-openai, runne-provider-deepseek, runne-provider-http
Store / persistencerunne-store, runne-local-store, runne-secure-store
Security / credentialsrunne-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
MCPrunne-mcp
Toolsrunne-tools
Plugin hostrunne-plugin-host, runne-plugin-protocol
CLI / clientrunne-cli, runne-runtime-client
Compatibilityrunne-opencode-compat, runne-opencode-adapter-sqlite
Observabilityrunne-observability
Qualification / releaserunne-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.