Three planes: control · state · execution
When debugging, ask first: is this scheduling, authoritative state, or the tool/model loop?
CONTROL
Control plane
Session lifecycle, SessionTurnLock, cancel, permission / question / MCP confirm, client registry. Desktop / TUI: agent/startTurn. CLI: blocking agent/chat (cancelOnDisconnect: true). /goal runs GoalRunner without holding the turn lock for the whole loop. Live-session LRU targets 16 and never evicts a busy session; agent/cancel stops that session's turn and bash jobs only.
STATE
State plane
Authority is workspace .CodePapr/project.sqlite (node:sqlite first): messages Archive, context_surfaces, memory_entries, todo. VFS overlay lets terminal read see unsaved desktop buffers. HostEventBus is monotonically sequenced.
EXECUTION
Execution plane
agentRunner builds requests, runs tools, subagents via runSubagentSession, compact, Recall. bash (macOS SBPL sandbox), browser (system Chrome CDP), MCP (stdio / SSE / Streamable-HTTP), LSP all live on Host. workspace/list / read have entry, time, and byte budgets; LSP / MCP frames are capped.
Desktop / TUI / CLI / tests / future WebUI
│ JSON-RPC 2.0 Unix socket / named pipe
▼
Workspace Host (Source of Truth)
Control: startTurn / chat / startGoal / cancel / compact
State: sqlite + EventBus(sequence) + overlay
Execute: agentRunner → LLM + tools + GoalRunner
CQE: command, query, event
Method names are frozen in protocol.ts. Do not invent aliases in the UI. Reconnect recovery only trusts sequence.
Command
agent/chat agent/startTurn agent/startGoal agent/cancel agent/compact agent/runVerifier agent/app_run + permission/question/MCP decisions. Mutate state.
Query
agent/getEvents (replay with afterSequence, plus hasMore / oldestSequence / replayUnavailable) agent/turnStatus agent/goalStatus agent/pendingInteractions workspace/read. Read facts.
Event
agent/stream: text / reasoning / tool-start / tool-end / turn/* / goal-progress / goal-finished / context-compacted / context-pruned / permission, question, MCP. Each event has sequence.
01
Turn
One user utterance. Desktop/TUI startTurn, CLI chat. Wait for turn/finished.
02
Goal
User /goal. Host runs plan → worker chat → Verifier. Wait for goal-finished; inner turn/finished is not the Goal end.
03
Compact
checkpoint writes Surface (started→completed). prune only trims live-log tool noise. Archive user text is untouched.
04
Reconnect
A dead Client is not a dead Session. After lease reconnect, getEvents(afterSequence). Drop already-seen sequences so optimistic UI does not flash twice.
Three clients, one Host
Capabilities live in initialize.capabilities. A client without a capability must not try to paint permission dialogs or .papr panels.
DESKTOP
Tauri shell + HostBackedAgent
Chat uses startTurn; /goal calls startGoal. Reverse RPC: permission, question, MCP confirm, tools.app. Monaco overlay syncs to Host. Worker path is rollback only.
window.permission · question · mcpConfirm · tools.app
TUI
Ink + startTurn
Same startTurn. /goal upgrades to Goal and waits for goal-finished. Has permission/question, no .papr. Transcript in .CodePapr/tui/; authority is still sqlite.
window.permission · question
CLI
One-shot agent/chat
Blocks until the turn (or the whole Goal) ends. cancelOnDisconnect: true: closing the terminal cancels. Default session cli-<pid>.
agent.stream · no interactive windows
Authority is sqlite, not the UI
The UI may paint an optimistic user message. Replay, compact, memory, and checkpoints take the Host database as truth.
messages
Archive originals. Tool results fold into assistant tool_invocations and hydrate back into synthetic tool messages. role=tool rows are not stored.
context_surfaces
The selection authority for the model history. Compaction rows go started → completed; leftover started becomes interrupted on Host boot.
memory_entries
The only memory ledger. Short instructions enter Bootstrap; procedures are recalled per turn; citation / untrusted never auto-recall. Legacy memory.json is migrated once and never written back.
EventBus
Ring buffer + monotonic sequence. Desktop deliverHostAgentStream drops sequence ≤ last.
How to extend
Change the owner of the authority, not the nearest React file.
New RPC / stream type
Freeze it in packages/@codepapr/host/src/protocol.ts, then wire inProcessHost.ts. UI only maps names; it does not invent them.
New tools
Host agentTools. MCP uses Host transports (stdio / SSE / HTTP). Do not add a second Agent tool stack in Rust.
Bytes sent to the model
core ImmutablePrefix + Host agentRunner. Desktop sends raw user text, mode, images, Recall insertions.
Goal behavior
hostGoal.ts + hostVerifier.ts. TUI/CLI must not expand /goal into a one-shot prompt.
Sandbox
macOS: Host SBPL on by default. Linux / Windows: no kernel sandbox; static reject of ~ / $VAR / .. / unauthorized absolute paths. CODEPAPR_HOST_SANDBOX=0 turns off SBPL and uses the same static guard.
How to optimize (highest leverage first)
1. Prefix cache
01 Prefix holds stable system + sorted tool defs + sampling. Skills / memory / character live in 02 Bootstrap. Adding or removing tools splits the cache. Prefix hits can only be measured against a real model.
2. When to compact
Near the soft budget, checkpoint (summary + tail). Tool noise uses prune. Do not compact every turn. On Surface failure, keep the last completed generation.
3. Goal and depth
The Goal outer loop does not hold the lock; each worker turn does. Root task must use currentDepth: 0 or exploreMaxDepth: 1 blocks explore. Recall drops untrusted; checkpoint bodies are weighted into the corpus.
4. Bounded I/O
workspace/list uses Dirent with a 4000-entry / 250ms budget. workspace/read honors maxBytes, streams line ranges, and rejects NUL. LSP / stdio MCP reassemble chunked frames (8MB / 16MB / 64 pending); overflow kills the child.
Intentionally unmerged: Host headless browser uses system Chrome CDP; desktop still has Rust headless_chrome. synthetic: true exists only in the desktop optimistic layer, not the Host Archive. Do not treat these as missing P0s.
Code: inProcessHost.ts, agentRunner.ts, hostGoal.ts, hostProjectStore.ts, hostRecall.ts, hostSandbox.ts, protocol.ts. Protocol: docs/HOST.en.md. System design: docs/ARCHITECTURE.en.md.