crates/invariants

The checkable boundaries for every workspace crate below crates/. Entries use crate directory and Rust library names, even when the crates.io package name differs.

How To Read This Page

An invariant says what a crate must never know, own, or depend on. A cited gate or test is executable enforcement; (unenforced) means review is currently the only guard. The workspace manifest is the source of the 32-crate inventory; examples and runbooks are intentionally excluded.

Kernel And Shared Contracts

Dependency direction begins with protocol-neutral data and moves outward toward runtime integration.

lash-sansio

Must remain a synchronous state machine and shared data-contract crate: it must not perform I/O, require an async runtime, know any provider wire protocol, or depend on lash-core, Lashlang, a protocol plugin, or a host application (unenforced). Runtime and integration crates may depend on it; the dependency must never point back upward. Anchors: crates/lash-sansio/Cargo.toml, crates/lash-sansio/src/lib.rs, docs/architecture/modules.html.

lash-trace

Must define diagnostics records and sinks only; a trace record must never become authoritative session state, the app-facing TurnActivity stream, or the low-level SessionStreamEvent stream (unenforced). It may depend on lash-sansio vocabulary but must not depend on lash-core or a provider, protocol, store, or host. Anchors: crates/lash-trace/src/lib.rs, crates/lash-trace/Cargo.toml, docs/reporting.html.

lash-rlm-types

Must contain serializable RLM trajectory and history vocabulary, not protocol execution, Lashlang evaluation, provider calls, or durable writes (unenforced); its only Lash dependency may point down to lash-sansio. The shared serialized fields of RlmTrajectoryEntry and RlmHistoryItem::LashlangStep must remain congruent, enforced by trajectory_and_history_step_serde_shapes_stay_in_parity. Anchors: crates/lash-rlm-types/src/lib.rs, crates/lash-rlm-types/Cargo.toml.

lash-core

May know only runtime mechanisms and integrator seams: it must not depend on or name Standard, RLM, lash-lashlang-runtime, or lashlang; crates/lash-core/tests/integration_boundary.rs enforces that rule by source scan and Cargo metadata. MCP, concrete provider credentials, user configuration, and host UI policy must also remain outside core (unenforced). Anchors: crates/lash-core/src/lib.rs, ADR 0051, docs/architecture/kernel-surface.html.

lash-lashlang-runtime

May bridge lash-core mechanisms to lashlang, but neither lower crate may depend back on this integration crate (unenforced). Durable Lashlang work must enter core as opaque ProcessInput::Engine data under LASHLANG_ENGINE_KIND; adding a Lashlang-specific process variant to core is forbidden by the core integration-boundary test. Anchors: crates/lash-lashlang-runtime/src/lib.rs, crates/lash-lashlang-runtime/src/process.rs, ADR 0037.

lash-remote-protocol

Must own versioned wire DTOs and optional core conversions only; it must not run a turn, execute a remote tool, or depend on the lash facade, which already depends on it (unenforced). Every accepted wire version must pass the explicit-version decoding cases in crates/lash-remote-protocol/src/versioned_decode_tests.rs. Anchors: crates/lash-remote-protocol/src/lib.rs, crates/lash-remote-protocol/Cargo.toml, ADR 0051.

Transport, Providers, And Credentials

Generic transport flows downward; provider-specific policy stays at the provider edge.

lash-http-transport

Must expose host-configurable HTTP request, response, body, timeout, and streaming primitives without encoding LLM or provider semantics (unenforced). It may depend on lash-sansio for shared async abstractions, but must not depend on lash-core, an LLM transport, or a provider crate. Anchors: crates/lash-http-transport/src/lib.rs, crates/lash-http-transport/Cargo.toml.

lash-llm-transport

May normalize HTTP/SSE framing, timeouts, usage, response metadata, and provider trace plumbing shared by LLM providers; it must not own provider endpoints, authentication flows, model policy, or runtime turn state (unenforced). Provider crates may depend on it; it must never depend on a provider crate. Anchors: crates/lash-llm-transport/src/lib.rs, crates/lash-llm-transport/Cargo.toml, docs/architecture/providers.html.

lash-provider-auth

May own shared credential leasing, refresh policy, PKCE, and generic OAuth error classification; provider-specific endpoints, device-code exchanges, and refresh requests must remain in the provider crates, while API-key providers must bypass this crate (unenforced). It must not choose models or issue LLM completions. Anchors: crates/lash-provider-auth/src/lib.rs, crates/lash-provider-auth/src/credential.rs.

lash-provider-anthropic

Must translate Lash provider contracts to Anthropic request, stream, cache-breakpoint, attachment, usage, and error semantics only; it must not implement generic HTTP transport, runtime persistence, protocol behavior, or host admission policy (unenforced). Shared transport must flow through lash-llm-transport, and deterministic wire behavior must remain exercisable through the crate's testing transport and conformance fixtures. Anchors: crates/lash-provider-anthropic/src/lib.rs, crates/lash-provider-anthropic/Cargo.toml, ADR 0015.

lash-provider-google

Must contain Google Code Assist/Gemini wire mapping and provider-specific OAuth flow only; shared credential lifecycle belongs to lash-provider-auth, shared HTTP/SSE behavior belongs to lash-llm-transport, and runtime/protocol/storage policy must not move here (unenforced). Provider request and stream behavior must remain runnable through crates/lash-provider-google/src/tests/conformance.rs. Anchors: crates/lash-provider-google/src/lib.rs, crates/lash-provider-google/Cargo.toml.

lash-provider-openai

May own OpenAI Responses, OpenAI-compatible Chat Completions, Codex-specific OAuth/session behavior, and OpenAI schema projection; it must not duplicate shared credential leasing, generic LLM transport, runtime persistence, or protocol execution (unenforced). Its distinct API routes must continue to satisfy the route-specific conformance tests under crates/lash-provider-openai/src/tests/. Anchors: crates/lash-provider-openai/src/lib.rs, crates/lash-provider-openai/Cargo.toml, docs/architecture/providers.html.

Persistence And Durable Execution

Core defines contracts; adapters implement them without creating rival runtime semantics.

lash-sqlite-store

Must implement core persistence, registry, trigger, artifact, effect-replay, and attachment-manifest contracts over one SQLite durable-core database; it must not redefine their semantics or store S3 attachment bytes (unenforced). Opening an obsolete schema must reject rather than migrate it, and SQLite/Postgres shape differences must be declared in crates/lash-sim/tests/schema_congruence.rs, which enforces the cross-backend registry. Anchors: crates/lash-sqlite-store/src/lib.rs, crates/lash-sqlite-store/src/schema.rs.

lash-postgres-store

Must implement the same core durable contracts over PostgreSQL without inventing host or protocol policy (unenforced). schema.sql is the published DDL authority and open/verification must compare the live catalog structurally rather than trust a version stamp; ADR 0052 and store tests enforce that check. Any intentional SQLite divergence must also be registered in the schema-congruence gate. Anchors: crates/lash-postgres-store/src/lib.rs, crates/lash-postgres-store/src/postgres/schema.rs.

lash-s3-store

May store and retrieve attachment bytes through the core attachment-store contract; it must never become the authority for attachment metadata, manifests, reference counts, session state, or runtime commits, all of which remain in RuntimePersistence (unenforced). It may depend on lash-core but not on a SQL store, protocol, provider, or facade. Anchors: crates/lash-s3-store/src/lib.rs, crates/lash-s3-store/Cargo.toml, ADR 0028.

lash-restate

Must adapt the core effect-controller and process-driver seams to Restate; it must not become a second turn machine, session store, or protocol implementation (unenforced). Restate owns in-flight continuation through stable journal keys and durable waits, while Lash commits final session state through turn-commit idempotency; endpoint, replay-corpus, and tool-context conformance tests exercise that split. Anchors: crates/lash-restate/src/lib.rs, crates/lash-restate/src/controller/, ADR 0045.

Facade And Protocols

The facade is the supported host surface; protocol crates plug behavior into core.

lash

Must remain the single promised host package and the only path examples use for runtime embedding; it may compose and re-export internal crates but must not create a second home for any public name. scripts/check_facade_only_examples.py rejects facade bypasses, scripts/check_facade_external_types.py rejects unreviewed third-party signature leaks, and the facade UI tests gate deliberately absent paths. Anchors: crates/lash/src/lib.rs, ADR 0051, ADR 0079.

lash-protocol-rlm

May own RLM response classification, trajectory history, prompt rendering, stream masking, repair/stall policy, dialect selection, and the protocol driver; it must not own durable commit, provider transport, generic process lifecycle, or Lashlang VM semantics (unenforced). Standard and TypeScript/Lashlang RLM behavior must remain expressed through the protocol scenario and cell-conformance suites. Anchors: crates/lash-protocol-rlm/src/lib.rs, crates/lash-protocol-rlm/src/scenario_contracts.rs, ADR 0061.

lash-protocol-standard

May own native provider tool-call driving, assistant-message weaving, and the Standard-only batch tool; it must not own provider wire formats, tool implementations, persistence, or final turn commit (unenforced). Its deterministic protocol contract must remain in crates/lash-protocol-standard/src/scenario_contracts.rs, not in core or the simulation harness. Anchors: crates/lash-protocol-standard/src/lib.rs, crates/lash-protocol-standard/Cargo.toml, ADR 0050.

Plugins And Tools

These crates register behavior through core contracts; none may take ownership of the runtime that invokes it.

lash-plugin-mcp

Must expose MCP servers as ordinary Lash tool providers and keep one connection pool per LashCore; it must not add an alternate tool-execution path, session persistence, or per-session stdio process pool (unenforced). Streamable HTTP credentials are static host-supplied headers: this crate must not silently enable rmcp OAuth or token refresh, and its lifecycle/policy tests exercise those boundaries. Anchors: crates/lash-plugin-mcp/src/lib.rs, crates/lash-plugin-mcp/src/pool.rs.

lash-plugin-process-controls

May register only the session process-list and process-cancel control tools over core/tool-support contracts; it must not implement process scheduling, leases, persistence, or protocol-specific copies of those controls (unenforced). Protocol crates consume the registered tools and must not absorb their behavior. Anchors: crates/lash-plugin-process-controls/src/lib.rs, crates/lash-plugin-process-controls/Cargo.toml.

lash-plugin-tool-output-budget

May project a truncated model-visible result and spill the full text to its non-durable temporary directory; it must not change the underlying tool outcome, execute tools, write durable session state, or own general context compaction (unenforced). Budget behavior must remain a plugin contribution, not a branch in core or a concrete tool. Anchors: crates/lash-plugin-tool-output-budget/src/lib.rs, crates/lash-plugin-tool-output-budget/Cargo.toml.

lash-llm-tools

May implement focused LLM-backed tools through core's direct-completion seam; llm_query must not use tools, inspect files, or acquire context beyond its explicit task and inputs, and this crate must not construct a provider transport or child runtime (unenforced). Model and generation policy come from the current session unless the host supplies an explicit override. Anchors: crates/lash-llm-tools/src/lib.rs, crates/lash-llm-tools/Cargo.toml.

lash-tool-support

Must remain shared scaffolding for tool schemas, bindings, and static providers; it must not contain a concrete user-visible tool, tool-catalog policy, provider client, or runtime orchestration (unenforced). Concrete tool crates may depend on it; it must not depend on them. Anchors: crates/lash-tool-support/src/lib.rs, crates/lash-tool-support/src/static_provider.rs, crates/lash-tool-support/Cargo.toml.

lash-tools

May implement the built-in shell and web tool families over lash-tool-support; local grep, file indexing, product filesystem policy, provider selection, and runtime persistence must remain outside this crate (unenforced). The standard-stack tests additionally enforce that the shipped bundle contains neither grep nor host filesystem tools. Anchors: crates/lash-tools/src/lib.rs, crates/lash-standard-plugins/src/lib.rs, docs/architecture/modules.html.

lash-standard-plugins

Must compose existing plugin/tool factories rather than implement runtime, protocol, provider, or store mechanisms (unenforced). Web tools must remain opt-in on an explicit Tavily key, and standard_stack_does_not_install_cli_local_grep plus standard_stack_does_not_install_host_filesystem_tools enforce that host-local capabilities do not leak into the default stack. Anchors: crates/lash-standard-plugins/src/lib.rs, crates/lash-standard-plugins/Cargo.toml.

lash-subagents

May define subagent capability selection and register orchestration/leaf tools, but child execution must use core session and tool-access contracts; this crate must not create an independent runtime, provider client, persistence model, or protocol implementation (unenforced). Capability and parent authority must remain explicit inputs to the plugin factory. Anchors: crates/lash-subagents/src/lib.rs, crates/lash-subagents/src/capability.rs, crates/lash-subagents/Cargo.toml.

Language And Dialect

The language owns deterministic compile/execute semantics; the dialect front-end lowers into that shared model.

lash-regress

Must remain the maintained regress fork with deterministic fuel/step-budget instrumentation and anchored matching; it must not depend on any Lash runtime, protocol, provider, store, or tool crate (unenforced). Upstream license, attribution, source notices, and the pinned provenance commit must remain intact. Anchors: crates/lash-regress/PROVENANCE.md, crates/lash-regress/Cargo.toml, crates/lash-regress/src/lib.rs.

lashlang

May own the Lashlang AST, parser, linker, compiler, VM, continuation/value semantics, artifacts, and workflow graph; external work must cross ExecutionHost::perform, so the crate must not call providers, tools, SQL/S3 stores, or host UI directly (unenforced). Protocol trajectory and core process scheduling must remain outside the language. Anchors: crates/lashlang/src/lib.rs, crates/lashlang/src/runtime/, ADR 0060.

lash-typescript

Must remain a TypeScript dialect front-end whose only Lash workspace dependency is lashlang, lowers into the shared Lash AST/program model, and returns stable named diagnostics; SWC must stay confined to adapter and must not leak into the public contract (unenforced). Runtime effects, protocol policy, providers, and persistence must not enter this crate. Anchors: crates/lash-typescript/src/lib.rs, crates/lash-typescript/Cargo.toml, ADR 0062 and ADR 0064.

Verification Harnesses

Harnesses may depend broadly to test production crates; production crates must never depend on harness behavior.

lash-sim

Must remain a deterministic, non-published verification harness: it may compose production crates, scripted provider wires, generated schedules, faults, oracles, and replay artifacts, but it must not define runtime semantics that production code consumes. publish = false enforces the shipping boundary, and schema_congruence_registry_matches_both_backends makes this crate the gate site for declared SQLite/Postgres shape parity. Anchors: crates/lash-sim/Cargo.toml, crates/lash-sim/src/lib.rs, ADR 0009.

lash-perf

Must remain a developer-only measurement harness: it may depend broadly on production crates, but production crates must not depend on it or change semantics to satisfy a benchmark (unenforced). It must never ship as a runtime library; publish = false enforces the package boundary. Anchors: crates/lash-perf/src/lib.rs, crates/lash-perf/Cargo.toml, CONTEXT.md.

read on ·