# Session storage guide
Durable JSONL events, bounded reads, metadata, scope, retention and export.
## Where to look
| Event kinds and local-only classification | `event.rs` |
| Create/open/list and writer admission | `manager.rs`, `writer.rs` |
| IDs, tolerant reads, append outcomes | `read.rs`, `write.rs` |
| Usage and preferences | `usage.rs`, `usage_recorder.rs`, `preferences.rs` |
| Neutral presentation/history hydration helpers | `chat.rs`; wire pages: `../local_agent/sessions.rs` |
| Sidecars, retention and worktree scope | `metadata.rs`, `prune.rs`, `scope.rs` |
| Preparation/export | `store.rs`, `export.rs`, `export/{discovery,archive}.rs` |
| Rewind forks and retained-prefix checkpoints | `rewind.rs`, `effects.rs`, `task_scope.rs` |
## Local contracts
- Validate IDs before constructing paths; new sessions may lack JSONL until first append. Use `Session::append_with_outcome`; `append_owned_batch` owns validation, redaction, locking, writes, rollback and metadata. Distinguish rolled-back from uncertain outcomes.
- Metadata validates session ID/schema/file length/modification time; stale sidecars rebuild from JSONL. Read limits count original line bytes, tolerant errors expose line numbers/safe errors rather than malformed content, unknown kinds remain readable. Provider replay belongs to context.
- Chat projection reconciles final/chunk output before redaction/chunking, excludes internal prompts/private provider records and summarizes tools without raw bodies. Snapshot IDs are revision-scoped; mutation invalidates wire pages. This is separate from TUI state and provider replay.
- Writer leases differ from retention protection and stay in `Session` clones through cleanup. Lock order: writer → activation → append; nested work reuses admission. Delete sidecars only after successful session deletion.
- Worktree normalization belongs in `scope.rs`, deletion in `prune.rs`. Title records belong here, provider/background work in `../session_titles.rs`; best-effort title/cache failures cannot replace required append outcomes.
- Export owns cancellation and destination validation; no direct archive-write bypass.
- Usage checkpoints cover only removed prefixes. Retain active-run records so suffix snapshots replace partial usage without double counting; missing/unfinished request usage remains incomplete.
- `effects.rs` folds removed-prefix structured mutation evidence into bounded `execution_effects`. Restores/clean diffs/model summaries cannot erase observations; legacy missing evidence is incomplete and shell calls do not prove writes.
- `task_scope.rs` retains original delegated input and acknowledged steering outside summaries. Fold only removed prefixes into versioned checkpoints; missing/invalid required policy blocks execution. Scope caches are derived; validate steering before required append and update only after success.
- Rewind copies ordered prefix before retained prompt into a new fork, remaps top-level session IDs and uses durable batches; never truncates source JSONL. Preserve event-count cutoffs and aggregate prompt numbering. Unsent rewind prompts remain local diagnostic metadata.