overview/map

Lash is organized around one runtime boundary. The app-facing lash facade and the CLI compose replaceable host edges (providers, protocol plugins, tool providers, the plugin-backed Tool Catalog such as MCP, UI extensions, persistence, tracing, and the TUI) around a core that owns session records, effect control, process execution, and durable commits.

System Shape

Dependency direction runs from host-owned surfaces inward to the runtime, then into the sans-IO protocol model. Providers, protocol plugins, tools, stores, and plugins are replaceable edges around the runtime core.

Workspace topology
flowchart TD subgraph Host["Host applications"] CLI["lash-cli
TUI, setup, resume/fork, --print
(bin + lib half hosting LashConfig)"] Facade["lash (facade)
app-facing core/session/turn API"] Export["lash-export
multi-session tree → HTML / JSON"] TraceViewer["lash-trace-viewer
JSONL trace browser"] end subgraph Runtime["Async host runtime"] L["lash-core
LashRuntime, Session, Store, PluginHost"] EffectController["RuntimeEffectController
durable side-effect boundary"] Env["RuntimeEnvironment
shared runtime infrastructure"] Graph["SessionGraph
durable event graph"] Read["SessionReadView
public read seam"] Tools["Tool dispatch
dynamic tools, built-ins"] Stores["lash-sqlite-store / lash-postgres-store
runtime persistence"] Trace["lash-trace
JSONL trace records"] end subgraph Kernel["Pure protocol kernel"] S["lash-sansio
TurnMachine, Effect, Response"] end subgraph LangRuntime["RLM language runtime"] LLR["lash-lashlang-runtime
Lashlang surface, artifacts, process engine"] LL["lashlang
parser, AST, VM, persistent REPL state"] end subgraph Extensions["Replaceable edges"] Protocols["protocol plugins
standard + rlm"] Providers["provider crates
OpenAI, Codex, Anthropic, Google"] Plugins["tool/plugin crates
llm_query, plan, memory, context, UI activity"] Mcp["lash-plugin-mcp
rmcp-based MCP plugin
stdio / streamable-http / sse"] Subagents["lash-subagents
spawn_agent host + RLM bridge"] end CLI --> Facade CLI --> L Facade --> L Export --> Read TraceViewer --> Trace L --> Env L --> S L --> EffectController EffectController --> Env L --> Graph L --> Stores L --> Trace Graph --> Read L --> Tools Protocols --> L Protocols --> LLR LLR --> L LLR --> LL Providers --> L Plugins --> L Mcp --> L Subagents --> L

Current KPIs

These figures are workspace-level and exclude generated build output.

Cargo members
45Runtime core, facade, CLI/TUI, providers, plugins (including MCP), language/runtime integration, export, tracing, file-index, harness optimizer, the deterministic-simulation harness, examples, and the distributed E2E harness.
Rust source
~361k LOCMeasured by line count over *.rs outside target; Rust dominates the workspace.
Rust files
789Includes library crates, CLI/TUI, providers, tests, examples, and trace/export utilities.
Execution modes
2 activestandard uses native tool calls; rlm drives work through Lashlang and can switch to a fresh AgentFrame via continue_as.

Authority Boundaries

The durable source of truth is the session graph. Everything else is either an execution environment, an external transport, or a projection.

  1. Graph is durable.

    SessionGraph stores conversation records, tool events, protocol events, plugin nodes, active-path metadata, checkpoint references, and replay material.

  2. Projection is derived.

    SessionReadView and ChronologicalProjection read graph state into semantic order. The CLI's UiTimeline is downstream of that and never writes persistence.

  3. Protocol plugins own protocol behavior.

    ProtocolBuildInput, TurnDriverPreamble, ContextProjector, and ProtocolDriverHandle decide what providers see and how model output advances a turn. Runtime-owned ProtocolBuildInput carries the effective tool catalog and generic protocol context into the protocol plugin; RLM builds its Lashlang host environment and projected read-only bindings (e.g., history) in the RLM/Lashlang runtime path.

  4. Tool output is projected, not raw.

    The durable session graph stores each tool call's full ToolCallOutput, while the ToolOutputBudgetPluginFactory runs a single tool-result projector to derive the budgeted model-facing ModelToolReturn that the next request and rolled-up history see.

  5. AgentFrame switches are runtime continuations.

    A turn can finish as TurnOutcome::AgentFrameSwitch { frame_id, task }, which transparently activates an RLM AgentFrame with a fresh window. App hosts that use TurnBuilder::stream_to, run, or pull-style stream get the final TurnResult; lower-level runtime hosts can still inspect the underlying AgentFrame chain.

  6. Runtime host capabilities are trait-shaped.

    RuntimeSessionServices implements focused plugin host traits for snapshots, tool catalogs, session tool state, session lifecycle, turns, processes, the session graph, prompt state, direct completion, durable tool effects, and tracing. Public tools see these through named ToolContext capabilities, not through a general host escape hatch. A configured process registry enables the generic process admin plane; protocol/language runtimes decide how that plane is exposed to authored code. ProcessCancelAbility lets the host customize intentional cancellation.

read on ·