Skip to main content

Module session_journal

Module session_journal 

Source
Expand description

Task 35 — opt-in session journal + periodic atomic snapshots (spec §9.8; decision record: docs/decisions/T35-session-journal-opt-in.md).

The DEFAULT persistence (SessionPersistence::Json) is byte-for-byte the legacy path: every save atomically rewrites sessions/<id>.json. The opt-in Journal mode is purely ADDITIVE: the snapshot file keeps the unchanged legacy Session schema, and an append-only sessions/<id>.journal (JSONL, schema v1) carries the deltas since the snapshot, so a steady-state save costs O(delta) instead of O(total history).

Replay is IDEMPOTENT by construction — msg records carry absolute history indices (i == len appends, i < len skips, i > len stops at the last consistent prefix) and meta records only apply when their updated_at is not older than the loaded state. Torn tails (kill during append), stale journals (kill between snapshot and journal reset), and manual journal deletion therefore all recover to a consistent session.

Everything here writes through the T4 private_fs helpers: 0700 dirs, 0600 files, symlink-refusing, atomic snapshot replacement, synced appends.

Structs§

JournalMetaTail
Freshest journaled metadata, read from a bounded tail window — lets session listings stay accurate without parsing the full journal.
SaveReceipt
Machine-readable receipt for benchmarks and delta-proportionality tests.
SessionDirEntry
One strictly-resolved directory entry for session listings.

Enums§

SaveMode
How a save landed on disk.
SessionPersistence
Which on-disk persistence strategy Session::save uses.

Constants§

JOURNAL_SCHEMA_VERSION
Journal record schema version (line-level "v" field).
JOURNAL_SNAPSHOT_MIN_BYTES
Journal size floor before a periodic snapshot is forced.
JOURNAL_SNAPSHOT_RATIO
A snapshot is due when the journal outgrows snapshot / RATIO (bounded write amplification: large sessions stretch the threshold proportionally).
MAX_PERSISTED_READ_BYTES
Hard cap on any single persisted-session artifact read (snapshot or journal). Reads are bounded on the OPENED handle; an artifact past the cap is refused rather than slurped.

Functions§

delete_session_files_in_dir
Remove a session’s snapshot AND journal (compaction rollback, retention). Idempotent — missing files are not errors.
journal_meta_tail
Freshest meta record from a bounded journal tail window, for listing freshness without a full journal read. None when no journal, no complete supported-version meta record, or a refused (non-confined) artifact — a symlinked journal discloses nothing.
journal_path
sessions/<id>.journal — single-extension name so the session id stays the file stem (chain-head protection and retention pair on the stem).
load_session_in_dir
Load <id>.json and, when a journal exists, replay it idempotently. Old-format sessions (no journal) load exactly as before; a session with a torn or stale journal recovers to its last consistent state. Both reads are confined nofollow bounded handle reads (fix1 I1).
save_session_in_dir
Persist session into dir under the given persistence mode.
session_dir_entries
Enumerate the sessions dir through the SAME strict handle resolution as every other T35 operation (fix2): handle-relative readdir + fstatat(AT_SYMLINK_NOFOLLOW) — a symlinked ancestor refuses, a missing dir lists empty, and entry mtimes are of the entries themselves, never symlink targets.
snapshot_due
Snapshot threshold: journal bytes ≥ max(256 KiB, snapshot / 4).