SessionService. The public facade
meerkat::AgentBuilder still routes through AgentFactory, but defaults to
StandaloneEphemeral and does not acquire service-owned persistence, recovery,
auth leases, scheduling, or wake coordination automatically.
Lifecycle
Only one turn can run on a session at a time. A competing start fails with
SESSION_BUSY; Meerkat does not silently queue it. Use runtime ingress,
scheduling, comms handling modes, or an application queue when queued delivery
is part of the product contract.
Transcript Contract
The durable transcript is typed and ordered:Systemis an ordinary instruction and may appear at any transcript position.SystemNoticeis runtime-authored structured metadata for comms, tools, MCP, auth, jobs, and other lifecycle facts.Usermessages carry a typed role: conversational input, a compaction summary, or host-attached injected context.- Assistant messages keep ordered content and tool-call blocks.
- Tool-result rows keep the results of executed tool calls.
Context And System Updates
injected_context on create and turn requests is host-attached ambient
context. Each item becomes a typed injected-context user-channel row immediately
before that turn’s conversational user message. These rows are excluded from
semantic-memory indexing and do not masquerade as ordinary user requests.
transient_turn_context is a different, request-only runtime input. Its exact
bytes stay with the pending input for crash retry, but it is never appended to
the Session transcript or rewrite history, or included in compaction or
structured-output extraction. At an authorized foreground model-request
boundary, temporary injected-context User rows are appended at the current
request tail: caller context first, then accepted steers. This needs no
conversational-row anchor and does not change the durable injected_context
before-user rule above. A deferred create cannot carry it because no runtime
input exists yet; attach it to the eventual turn.
The JSON-RPC session/inject_context method is a separate compatibility
surface: it appends durable system context with a source and optional
idempotency key for a later turn.
At create time, SystemPromptOverride keeps inherit, set, and disable as three
different facts. A set value materializes an ordinary ordered System row;
disable suppresses the config, project-instruction, and built-in prompt sources
for that build rather than encoding an empty instruction.
System-prompt update APIs use keyed, versioned System rows. The newest
version of a key is active at the model boundary, while prior revisions remain
in the audited transcript. Unkeyed system messages remain ordinary ordered
events.
Persistent JSON-RPC sessions also expose append-audited transcript revision
methods:
session/rewrite_transcriptsession/transcript_revisionsession/transcript_revisionssession/restore_transcript_revision
Session Metadata
Persisted metadata carries the facts needed to resume consistently:- model, provider, provider parameters, and optional self-hosted server
- max-token and structured-output policy
- tool intent, comms identity, and keep-alive intent
- realm, instance, pinned backend, and config generation
- structural auth binding, without credential material
- typed mob-member binding when a mob runtime owns the session
Persistence Profiles
Backends are selected once per realm and pinned inrealm_manifest.json.
Persistent stores own the physical current head. Runtime machines authorize
lifecycle transitions and recovery commits, but the in-memory
Session
object does not independently certify that its bytes are the durable head.
Events And History
History reads return committed transcript rows, not partial in-flight output. When installed, persistent event audit projection uses a dedicated unbounded subscription, so a slow UI subscriber cannot drop its projector input. The audit log is asynchronous derived state, not session commit authority. Bounded interactive subscribers can receive a typedStreamTruncated(StreamLagged) marker and should refresh state or history
instead of assuming they observed every presentation event.
Archiving is a lifecycle visibility change, not a transcript deletion.
Persistent history remains readable after archive. The memory profile retains
a final read-only state view but cannot provide persistent archived history.
Recovery Holds
Meerkat never guesses across ambiguous durable evidence. Resume can be refused with one of three stable codes while the stored content remains intact:
These are preservation states, not proof that the transcript was erased.
Inspect the owning realm and runtime before attempting repair.
Cross-Surface Visibility
See Realms for identity and root resolution.
