Skip to content

Sessions & strands

  • A strand is Ka’s session: one append-only JSONL file whose replay reproduces engine state. ka agent never writes strand files; only the engine does.
  • A ka agent session is the durable handle for a conversation thread: a ka agent id bound to exactly one strand at a time (by id and path), plus a workspace and a status.

The lineage moves to a new strand only on /new, fork, or transfer.

Ka accepts one prompt per session at a time; a prompt sent while a cycle is running is silently dropped. ka agent therefore never submits directly:

  1. An inbound message (Telegram or console) is written to SQLite first, then enqueued.
  2. The queue drains one item at a time; the next item is submitted only after the engine reports idle.
  3. The span from submit to idle is one ka agent turn, with usage and cost recorded at the end.

Consequences you can observe: a crash between message arrival and dispatch re-delivers at least once (consumers are idempotent), and a restart never loses queued messages.

Sessions resume lazily: the first inbound message after a daemon, worker, or machine restart spawns a worker pointed at the session’s recorded strand path. A session whose strand file does not exist yet (Ka appends it only after the first completed turn) is reopened as new.

One subtlety makes resume safe: a resumed strand restores model and mode only from mid-session change records, so it can come back model-less or in a looser mode than configured. After every attach, the worker re-asserts set_mode and set_model before the first submit. Policy cannot loosen across a restart.

The transient state of an active session (the in-flight cycle, a pending ask, streaming handles, the worker pid) lives in memory; the parts needed for recovery (queue, turn status, pending approvals) are persisted. The rest is rebuilt or declared lost on restart: unknown state is reported, never guessed.