Atomically advance both the per-client and legacy session read frontiers.
Neither value changes when validation or persistence fails.
One viewer’s stored state for one session.
A terminal’s current composer and the shared value it originally inherited.
The inherited value is retired on detach, never replaced by client-local text.
One relay page being applied inside a single write transaction. The relay
retains everything past the last acknowledgement, so a page that fails
part-way rolls back to the previous durable frontier and is simply
redelivered. Only a committed page may be acknowledged.
Apply one relay page in a single transaction. fill feeds the page’s
events through ProjectionPage::apply; the projection changes and the
event frontier commit together only when fill succeeds, so callers may
acknowledge the page’s last ordinal to the relay after this returns.
Load only the durable prompt queues without deserializing transcript rows.
Dashboard startup uses this path so work is proportional to queued prompts,
not to the complete retained conversation history.
Load only the projection fields needed by dashboard session summaries.
Transcript bodies for tools, plans, thoughts, and old messages stay in
SQLite, which keeps dashboard startup independent of transcript size.
Where a session stands turn by turn: what is running now, and how the last
finished prompt ended. Returns None when the session has no projection
row. The API’s wait loop reads this for sessions whose actor is gone.
Record that the managed target of an otherwise live session is definitively
gone. A verified checkpoint keeps the session recoverable as an error on the
dashboard; without one, the session is lost. The state predicate keeps a
late poll result from overwriting a concurrent lifecycle transition.
Read only the projection’s event frontier. Deciding whether a stored
projection already matches an archive costs one row this way, instead of
deserializing every transcript item to compare two integers.
Explicitly restore a detached draft into its session composer. This is the
only operation that merges client-local draft state back into the legacy
session field, and the transaction marks the source draft recovered at the
same durable boundary.
Recover lifecycle rows stranded by a process exit during checkpoint
creation. This must be called once by the top-level controller process
while it owns the controller-store guard, not by per-operation reloads.
Rewrite a configured profile id in every persisted session in one SQLite
transaction. Configuration is stored separately, so the controller owns
coordinating this update with the matching config-map rename.
Replace a session’s durable prompt queue without touching its transcript or
event frontier. Resume uses this when it keeps the stored projection but
still has to drop the queue the archive carried.
Replace one host’s remembered mount sources with exactly this list, so the
dashboard can forget a directory the user no longer wants suggested.
What each workspace last chose for a second opinion.
Update only the fields a lifecycle transition owns on a session that
already exists. Everything else — display titles, checkpoints, container
settings, and attached directories — stays with its own writer.
Persist one operational session without rewriting unrelated controller
state. Dashboard lifecycle jobs use this path so independent jobs can
commit concurrently without restoring stale copies of other sessions.
Change only whether the resume dialog hides this session. Archiving is a
display choice, so it has its own writer and never rewrites lifecycle,
checkpoint, or title columns another task owns.
Change only the per-session container provisioning inputs: the size
overrides and the attached directories. Everything else the session row
owns is left to its own writer.
Overwrite the unsent chat input carried across a detach. Unlike the read
receipt this is not monotonic: a draft can shrink, and an empty string
clears it.