Skip to content

Architecture and runtime

One Bun engine, two clients, durable effects.

The Electron desktop and the CLI both present state and submit versioned commands to the same Bun Engine Host. The Engine Host composes the runtime; packages own reusable behavior. A client does not gain execution authority by displaying a tool, model, or approval.

In the desktop, the React renderer talks to the Electron main process over IPC. Main owns windows, native integration and process supervision; through a small native guardian it runs the Bun support host and engines as supervised children. Electron’s embedded Node never runs the engine. The Swift app is gone.

flowchart TD
Renderer[Desktop renderer] --> Main[Electron main process]
Main --> Support[Desktop support host · Bun]
CLI[CLI] --> Protocol[Versioned host protocol]
Support --> Protocol
Protocol --> Host[Engine Host composition]
Host --> Turn[Agent turn state machine]
Turn --> Context[Trusted context planning]
Turn --> Routing[Provider routing and adapters]
Turn --> Tools[Tool runtime and policy]
Host --> Workflows[Tasks and registered-workflow queue]
Tools --> Execution[Durable attempts and receipts]
Routing --> Execution
Workflows --> Execution
Execution --> SQLite[(SQLite execution authority)]
Execution --> Transcript[(Canonical transcript)]

The arrows show logical ownership/data flow, not permitted package imports. The exact import rules are in dependency rules. The generated composition map and request traces locate concrete source owners.

Process Serves
Chat engine All of a workspace’s chats and their read-only subthreads, one per workspace root, Profile, permission mode and extra folders
Worktree engine A writing subthread, which works in its own Git worktree
Agora engine The browser chat, with its browser-only toolset
Utility engine Helper turns such as chat titles: bare, no tools, memory or MCP
Reporting and inspection helpers History inspection and read-only usage reporting

Each turn carries its own model route (turn.submit and turn.continue take route), so chats on different models share one engine and no chat inherits another’s model. Approvals and questions belong to their own session. When a shared engine stops, every chat it served moves to saved-state review; turns are durable, so committed work is kept. Each engine keeps one long-lived MemPalace worker for its memory index, stopped after two quiet minutes.

  1. The host validates and admits a request against the current session and scope.
  2. It freezes the turn’s model route and builds context from trusted history and permitted project inputs.
  3. A provider adapter normalizes its stream into model events. Provider wire objects never become transcript or frontend protocol objects.
  4. Tool requests enter the common validation, policy, approval, and execution path.
  5. Durable results and verified payloads become ordered conversation events.
  6. Clients project the result, usage, changes, and any recovery state.

Standing context budgets (instructions, catalog, history) follow the model’s window. A request keeps the provider’s cached prefix: later instructions travel as host-marked user text instead of edits to the system block, OpenAI-compatible hosts receive a prompt_cache_key, and estimator calibration is persisted so a restarted engine does not misjudge a half-empty window. Automatic compaction is judged on the whole chat before any reduction; a summary given up before dispatch is recorded on the receipt and shown in the thread rail’s Context card. Capacity summaries chain until the request fits, and the presentation tail sits at the start of the turn’s tool activity.

Data Authority Recovery implication
Conversation meaning Fingerprint-chained canonical transcript Replay only validated complete records
Whether an effect may run or resume SQLite execution rows, attempts, receipts, leases Reconcile exact durable facts before doing more work
Conversation query views Rebuildable SQLite projections Repair only from valid canonical history
Artifacts and attachments Referenced payloads with ownership and integrity checks Missing or mismatched bytes cannot be treated as valid output

Current versions and supported migration inputs are listed once in project status.

flowchart TD
Interrupted[Interrupted work] --> Inspect[Inspect durable attempt and receipt]
Inspect --> Committed{Committed result exists?}
Committed -->|Yes| Deliver[Deliver existing result]
Committed -->|No| Safe{Safe continuation authorized?}
Safe -->|Yes| Resume[Resume through execution owner]
Safe -->|No| Review[Require explicit recovery decision]
Review --> Close[Reconcile or cancel interrupted work]
Close --> Idle[Confirm session can accept new work]

No receipt means no invented success. A timeout does not authorize repeating an external effect. Recovery UI is explained in operations; the precise contract is session recovery.

  • One effect path: policy, durable attempt, handler, receipt, semantic delivery.
  • One runnable workflow queue for registered workflows; clients do not create private schedulers.
  • Provider-specific behavior stays inside adapters.
  • Scope, policy ceilings, and the turn’s model route are frozen at admission.
  • Unknown versions, corrupt authority, unsafe paths, and stale revisions fail closed.
  • Processes and native resources have an owner that drains and reaps them.

See durable effects, core contracts, and storage/execution before changing these boundaries.

Decisions behind this page: 0147, 0189, 0223, 0229, 0233, 0252, 0264, 0273, 0274 — see the decisions index.