Expand description
Agent-anchored session zones (Option E, PR 1 of 2).
A session zone is bound to the agent definition (definition_id),
not the identity bundle the agent currently uses. Two agents that
share an identity bundle keep separate session histories.
§Zone naming
- Active:
agent:<defId>:current - Archived:
agent:<defId>:archive:<unix_ms>
Files inside a zone keep the existing shape:
output.state.json (full UI snapshot) and output (raw NDJSON
stream for crash-recovery replay).
§Migration (migrate_block_zones_v1)
On first srv startup after this PR ships, the per-block zones (the
pre-Option-E layout where each blockId owned its own zone) are
back-filled into the new per-agent layout:
- For each
db_blockrow withmeta.view = "agent"and a non-emptyoutput.state.jsonin its block-keyed zone, copy the contents toagent:<defId>:archive:<block-zone-createdts>. - For each definition, copy the most-recently-modified per-block
snapshot to
agent:<defId>:current. - Write the marker file
<data_dir>/migration_agent_zones_v1.flag.
The migration is read-only against the existing per-block zones — GC of those is a later PR.
See docs/specs/SPEC_CONTINUATION_SESSION_PERSISTENCE_2026_05_23.md.
Structs§
- Archive
Summary - A single archive row. Mirrors the shape of
RecentSessionRow’s preview fields so the frontend can reuse the same row component. - Migration
Stats - Stats from
migrate_block_zones_v1. Logged at INFO at startup. - Template
Promote Stats - Stats from
migrate_promote_template_sessions_v1. Logged at INFO.
Enums§
- Copy
Action 🔒 - Per-file decision inside
move_zone’s retry-aware loop. See the doc comment inmove_zonefor which round each variant addresses.
Constants§
- MIGRATION_
MARKER_ V1 - Marker file name for the per-data-dir one-shot migration gate.
- OUTPUT_
FILE - Raw NDJSON stream for crash-recovery replay.
- SNAPSHOT_
FILE - Full UI snapshot (JSON). Frontend reads this on pane mount.
- TEMPLATE_
PROMOTE_ MARKER_ V1 - Marker file name for the Phase 1 two-tier-picker migration.
Functions§
- agent_
archive_ zone agent:<definition_id>:archive:<ts_ms>.- agent_
current_ zone agent:<definition_id>:current. Panics in debug ifdefinition_idis invalid; callers shouldvalidate_definition_idfirst in release.- append_
session_ output - Append
line(with a trailing newline added if not present) tooutputinagent:<defId>:current. Creates the file if missing. - archive_
session - Archive
agent:<defId>:currenttoagent:<defId>:archive:<now_ms>. - collapse_
preview 🔒 - ensure_
file 🔒 - Ensure a file exists in
zone. No-op when present. - is_
valid_ definition_ id - Returns true if
smatches[A-Za-z0-9_-]+. Rejects empty. - list_
archives - List archive zones for
definition_id, newest first. - migrate_
block_ zones_ v1 - One-shot migration of per-block agent session zones to per-agent
zones. Gated by a marker file under
data_dir; running twice is a no-op. - migrate_
promote_ template_ sessions_ v1 - Phase 1 two-tier picker migration: promote any seeded template that
carries a session zone into a fresh user-owned definition, then move
its
:current+:archive:*zones onto the new definition_id. - move_
zone 🔒 - Move every file in
old_zonetonew_zone, preserving names + bytes. Implemented as read-write-delete because FileStore doesn’t expose a native rename; the cost is bounded by the per-zone file count (1-2 in practice —output.state.json+output). - now_ms 🔒
- read_
archive_ 🔒preview - Pull a small preview + node_count out of an archive’s
output.state.json. Returns("", 0)on any error. - read_
session_ state - Read
output.state.jsonfromagent:<defId>:current. ReturnsOk((None, None))when the zone doesn’t exist — that’s the “fresh agent, nothing to restore” path and is NOT an error. - validate_
and_ current - Convenience: validate + build the current-zone string. Returns
Errwith a stable error prefix on bad input so RPC callers see a consistent message. - write_
session_ state - Write
contenttooutput.state.jsoninagent:<defId>:current. Idempotent — creates the file if missing, overwrites otherwise. - write_
zone_ 🔒file - Write the entire contents of a file in
zone. Creates the file if missing, otherwise replaces all parts atomically (FileStore single-tx).