Skip to main content
This page is the canonical settled-state 0.5 contract for session and runtime behavior.

Ownership model

Meerkat has one canonical semantic path:
  • runtime-backed surfaces own keep_alive, Queue/Steer routing, comms drain lifecycle, external-event admission, and request/turn commit semantics
  • SessionService is the substrate lifecycle seam used by those surfaces
  • EphemeralSessionService / build_ephemeral_service remain valid for testing, embedded use, and WASM internals, but they are not the primary product path and do not own runtime semantics
The runtime-backed path is:
Surface -> RuntimeSessionAdapter -> SessionService -> AgentFactory::build_agent()
Direct substrate usage is intentionally narrower:
  • Queue-only turns
  • no runtime-owned keep_alive
  • no Steer/render-metadata semantics
  • no runtime ingress/admission ownership

Agent construction contract

Agent construction is centralized in AgentFactory::build_agent().
  • Surfaces pass per-request build data in-band via CreateSessionRequest.build (SessionBuildOptions).
  • No out-of-band staging lock is used.
  • FactoryAgentBuilder maps SessionBuildOptions to AgentBuildConfig.
  • Session metadata persists realm context and durable session identity:
    • realm_id
    • instance_id
    • backend
    • config_generation
    • durable LLM identity
    • keep_alive
    • visible comms identity metadata such as comms_name and peer_meta

Session lifecycle and turn semantics

create_session

create_session(req) builds the agent and optionally runs the first turn.
  • Returns RunResult with session_id.
  • InitialTurnPolicy::RunImmediately executes the first turn inline (default).
  • InitialTurnPolicy::Defer registers the session without running a turn.
Create has a commit boundary:
  • pre-commit failure: side-effect free; no committed session identity
  • post-commit first-turn failure: return session identity and keep the session resumable
Committed create failure must not be silently rewritten to “cancelled” or cleaned up as unpublished work.

start_turn

start_turn(id, req) executes a new turn on an existing session.
  • At most one in-flight turn per session.
  • Concurrent attempts return SESSION_BUSY.
  • Committed success must not be rewritten to cancellation.
  • Runtime-backed surfaces may hot-swap supported live settings on an existing session where the surface contract says that is allowed.

Deferred first-turn system prompt override

Rust supports system_prompt on StartTurnRequest only for a deferred session’s first turn.
  • deferred + first turn: allowed
  • existing history/messages: rejected
This keeps Rust aligned with the 0.5 runtime contract instead of implying arbitrary mid-session prompt replacement.

interrupt

interrupt(id) cancels an in-flight turn.
  • If no turn is running: SESSION_NOT_RUNNING.

read and list

  • read(id) and list(query) are non-blocking with respect to in-flight turns.
  • Persistent services can include durable sessions from the realm backend.
  • Presence in list() is not the same as “live session exists”; runtime-owned seams must answer liveness.

read_history

read_history(id, query) returns the last committed transcript snapshot for a session.
  • Messages are returned oldest-to-newest.
  • offset and limit apply from the start of the full transcript.
  • Active sessions do not expose in-flight partial output through history reads.
  • Archived sessions remain readable when the underlying service/backend supports archived snapshots.

archive

  • Removes session from live runtime.
  • Persistent behavior depends on service/store implementation.

Keep-alive contract

keep_alive is a runtime/session concept, not an old “host mode” execution path. Rules:
  • create / run omitted => default false
  • continue / resume omitted => inherit persisted session intent
  • explicit keep_alive override is a session/runtime mutation once validated
  • invalid keep_alive + comms configuration is rejected before any stateful work
  • once validated, an explicit keep_alive mutation may commit independently of turn success
keep_alive=true requires usable comms identity/config on the surfaces that expose it.

External events

External events are queue-only runtime-backed inputs.
  • they are admitted into runtime ingress
  • they do not invent a second direct execution path
  • “turn-boundary inbox draining” is not the primary mental model for 0.5

Explicit override semantics

Where the surface supports omission vs explicit override, these are distinct facts:
  • omit / inherit
  • disable / false
  • set / concrete value
When all three meanings matter, the wire/API must preserve that distinction. Typed optional fields and override masks are preferred over default-value folklore.

Realm contract

Sessions are realm-scoped.
  • Same realm_id: shared visibility and config context.
  • Different realm_id: strict isolation.
  • Backend is pinned per realm via realm_manifest.json.

Compaction contract

Compaction is optional and non-fatal.
  • Triggered by token thresholds and turn guards.
  • On failure, emits CompactionFailed and continues with uncompacted history.
  • Compaction usage counts toward run budgets.

Durability

Ephemeral mode

No durability across process restart.

Persistent mode

Durability follows the active realm backend (sqlite, redb, or jsonl).
  • Completed turns are persisted.
  • Crash during in-flight turn may lose only that turn.
  • SQLite-backed realms are the default persistent mode and support normal same-realm multi-process workflows.
Persistent session metadata is the source of truth for resumed durable session behavior unless an interactive surface supplies an explicit typed override.

Config concurrency contract

Config runtime uses generation CAS.
  • config/get returns current generation.
  • config/set and config/patch can specify expected_generation.
  • Mismatches fail deterministically with generation conflict.

Data governance

No automatic sensitive-data redaction is applied to session content or tool payloads. Encrypt storage at rest externally if required by your environment.

See also