kernel/surface

lash-core is the runtime kernel: it owns the mechanisms that must be uniform for every host, protocol, process runtime, store, and tool. Everything else enters through named extension contracts.

Kernel Rule

A type belongs in the kernel only when core must understand its semantics to enforce runtime mechanism: turn effects, durable commits, process leases, handle grants, plugin dispatch, tool execution, provider calls, or store consistency. Runtime policy, prompt language, product resources, and protocol-specific meaning live outside the kernel.

  1. Core owns mechanisms, not languages.

    lash-core depends on lash-sansio and runtime support crates. It does not depend on lashlang, lash-lashlang-runtime, or lash-protocol-rlm. RLM and Lashlang are integration runtimes installed around core.

  2. New process kinds use engines.

    ProcessInput::ToolCall, ProcessInput::SessionTurn, and ProcessInput::External are kernel primitives because core must orchestrate tool calls, child-session turns, and externally completed work directly. New process runtimes use ProcessInput::Engine { kind, payload } plus a registered ProcessEngine unless core must enforce a new mechanism.

  3. Protocol drivers are kernel extension slots.

    Core owns HostTurnProtocol, the sans-IO state type, and the singleton ProtocolDriverPlugin slot. Standard and RLM are protocol plugins that fill that slot; they are not kernel primitives and they do not require protocol-specific code in the turn loop.

Extension Contract

These are the stable kernel-facing seams. Add integration behavior by implementing one of these contracts, not by reaching into session/runtime internals.

ContractImplemented byKernel responsibility
Provider, ProviderFactory, ProviderHandleProvider crates and hostsResolve a live model provider and execute normalized LlmRequests behind a stable runtime handle.
ToolProviderTool crates, plugins, hostsAdvertise callable tools, resolve contracts, prepare calls, and execute them through core's tool-dispatch and effect boundaries.
PluginFactory, SessionPlugin, PluginRegistrarProtocol plugins, tool plugins, host pluginsInstall lifecycle hooks, prompt/catalog contributions, session state, tools, projections, and plugin RPCs without exposing mutable runtime internals.
ProtocolSessionPlugin, ProtocolDriverPlugin, ProtocolDriverHandle<HostTurnProtocol>lash-protocol-standard, lash-protocol-rlm, custom protocolsBuild a per-turn preamble and interpret provider output through the sans-IO machine. Core owns the slot and lifecycle; protocol crates own mode-specific prompts, state, and output parsing.
ProcessEnginelash-lashlang-runtime, custom process runtimesRun opaque ProcessInput::Engine payloads under the generic process registry, lease, cancellation, environment, and event machinery.
EffectHost, RuntimeEffectController, ScopedEffectControllerInline runtime, lash-restate, workflow adaptersExecute nondeterministic work with typed invocation metadata and replay keys while the turn machine remains deterministic.
RuntimePersistence, SessionStoreFactorySQLite, Postgres, host storesPersist committed session graph state, final turn stamps, checkpoints, pending turn input, queued work, and the fenced session execution lane.
ProcessRegistry, TriggerStoreSQLite, Postgres, host storesPersist process records/events/leases/handle grants and source-keyed trigger subscriptions/deliveries.
AttachmentStoreFile, S3-compatible, host storesPersist or serve attachment bytes while the graph stores refs and metadata.
ToolResultProjector, ToolCatalogContributorPlugin cratesProject model-facing tool results and contribute tool-catalog entries through explicit exclusive or additive plugin hooks.

What Stays Outside

The following are intentionally not kernel concepts even when first-party crates provide them.

RLM and Lashlang

lash-protocol-rlm owns the protocol prompt, driver state, projected bindings, and RLM control tools. lash-lashlang-runtime owns Lashlang surface construction, artifact storage, foreground execution bridge, and the kind == "lashlang" process engine.

Generic tools

Tool manifests are generic by default. First-party tool crates can opt into lashlang feature metadata, but ordinary default builds do not depend on the Lashlang runtime.

Remote DTOs

lash-remote-protocol is a neutral service-boundary crate. Its bindings map stores arbitrary metadata; it does not import Lashlang constants or derive generic tool identity from a Lashlang call path.

read on ·