Understand how kxen decides what runs, and where
Orchestration: how work gets split, parallelized, and resumed#
Orchestration decides how a task splits, runs in parallel, persists, and recovers. It doesn't change the underlying model, tool, or Safety contract.
The hierarchy#
flowchart TB
Workspace --> Session
Workspace --> Bot
Session --> Run["run"]
Run --> Goal
Run --> Subagent
Run --> Workflow
Run --> Team
Team --> Member["member"]
Team --> Task["shared task"]
Bot --> BotRun
Bot --> Routine
Bot --> Conversation["Bot Conversation"]
Conversation --> Peer["peer BotRun"]
Subagent --> MRM
Workflow --> MRM
Member --> MRM
Subagent --> Safety
Workflow --> Safety
Member --> SafetyWorkspace gives you a file boundary. Session gives you a durable conversation boundary, and a run is one execution inside a Session. Bot is a different, application-level durable boundary, with its own definition revision, Memory, Routine, Conversation, and BotRun.
Goal#
Goal holds the objective, completion criteria, constraints, budget, and state for a task that spans multiple turns. Reaching complete requires verified evidence; blocked is triggered immediately by a terminal-class reason, or after the same blocking reason repeats for 3 turns in a row. See the full lifecycle in Goal.
Subagent#
Subagent fits a single, independent problem domain. It gets its own context and role permissions, and returns a result to its caller. A synchronous dispatch waits for the result; a background dispatch returns through a task notification.
Workflow#
Workflow runs JavaScript inside a QuickJS sandbox. The script can call agents, run tasks in parallel, mark phases, and read constraints. The sandbox limits memory, stack, runtime, and agent call count. run_id combined with the journal lets a re-run reuse agent results that already completed.
Agent Teams#
Team fits work that needs sustained collaboration, shared task dependencies, and messages between members. Each member has its own transcript and inbox, and can bind its own role and model. A Team shares its Session's working directory — if you need file isolation, put the whole Session inside a Worktree.
Bots#
Bot fits repeated work you want to publish as an independent definition. A Routine creates BotRuns on a schedule; a Bot-to-Bot Conversation dispatches peer BotRuns asynchronously through Message, Delivery, and CollaborationTask. Inside a Group, every Bot keeps its own revision, permissions, and budget — nothing merges into a shared permission context.
Agent Teams serve the task orchestration of the current Session. Bot Groups serve the long-term collaboration of multiple independent Bots. Neither is a multi-human chat.
One control surface, regardless of orchestration style#
- Every model call must go through MRM.
- Every tool call must pass role permissions and Safety.
- Stopping a Session must be able to interrupt anything it's waiting on.
- Running state must land in the event stream.
- The final result must be written to the Session or its matching durable object.
Runtime: the app underneath everything#
kxen is a Tauri 2 desktop app that also ships as the kxen headless server. The SolidJS frontend handles interaction; the Rust backend owns long-lived state, model calls, tool execution, and persistence. The desktop webview and your browser are two equal clients of the same embedded service, talking to it over the same /ws endpoint.
Layers#
flowchart TB
UI["SolidJS UI"]
State["Rust AppState"]
Runtime["Session, Agent, Bots, MRM, Tools, Knowledge, MCP, LSP"]
Host["Local files, processes, providers, system capabilities"]
UI -->|"WebSocket (RPC frames)"| State
State -->|"same WebSocket (stream event frames)"| UI
State --> Runtime
Runtime --> HostThe UI never calls a provider directly, and never owns an agent run itself. Frontend and backend talk over exactly one WebSocket connection: operations go out as JSON-RPC frames, and tokens, tool activity, approvals, live status, and terminal events stream back on the same connection — there's no separate streaming channel.
AppState#
AppState holds the shared runtime objects that span Sessions:
- The Session and active-run registry.
- The Auth store and Provider catalog.
- The WorkspaceRuntime registry, each Workspace's MRM view, and the process-wide shared concurrency, RPM, and routing history.
- The Approval broker.
- Task, PendingQueue, Team, BotSystem, Browser, and usage runtime state. Goal, Schedule, Bot, and Knowledge are long-lived objects backed by their own local persistent storage.
- The event bus.
Shared state doesn't end when a frontend component unmounts. After a reconnect, the UI restores from a backend snapshot and then keeps up to date through the event stream.
Session#
Session is the durable boundary for your work. A run is one execution inside a Session, not a new Session. The pending queue, Goal, Team, and Schedule all attach through the Session ID.
Bot is a durable boundary independent of Session. A BotRun fixes its definition revision, permission snapshot, and provider-neutral context. Both the Routine and the Bot-to-Bot dispatcher only ever create ordinary BotRuns — neither builds a second execution path that bypasses MRM, Safety, or Approval.
Terminal states#
Every run must reach a completed, canceled, or errored terminal state. A dropped connection, a frontend refresh, or a stalled model stream can never end a run silently.
Platform boundaries#
The current Runtime covers macOS 14 and later (Apple Silicon and Intel), Windows (x64 and ARM64), and Linux (x86_64 and ARM64); kxen covers the same six platforms. kxen is still in developer preview — installers and the update channel are already public. See platform availability for install details.