Skip to main content

zeph_session/
lib.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Conversation-session persistence, event-log replay, and fork engine for Zeph.
5//!
6//! `zeph-session` implements spec-068: an append-only JSONL event log (the source of truth for
7//! a conversation), a metadata index over the existing `acp_sessions` table, a deterministic
8//! [`replay::ReplayEngine`], and the [`condenser::Condenser`] contract for durable context
9//! condensation. It is consumed by `zeph-core` (agent-loop `SessionSink` wiring, `zeph serve`
10//! per-session actors) and `zeph-acp` (session load/list/fork/resume handlers thinned to
11//! delegate here).
12//!
13//! # Architectural placement
14//!
15//! `zeph-session` mirrors the append-only journal design of `zeph-durable`
16//! (sequential event ordering, a single-writer actor model) but is a **separate** crate: the two
17//! operate at different abstraction levels (task/step effect-idempotency vs. conversation
18//! semantics) and use different storage formats (`SQLite`-backed opaque payloads vs. JSONL
19//! domain-typed events). `zeph-session` MUST NOT depend on `zeph-durable`, and vice versa
20//! (spec-068 §3, §15 NEVER; INV-1 in spec-064).
21//!
22//! # Module map
23//!
24//! - [`error`] — the crate-wide [`error::SessionError`].
25//! - [`event`] — the [`event::SessionEvent`] tagged enum and its [`event::SessionEventEnvelope`]
26//!   on-disk wrapper. Reuses `zeph_llm::provider::MessagePart` and
27//!   `zeph_common::memory::AnchoredSummary` rather than redefining them.
28//! - [`log`] — [`log::SessionEventLog`]: the append-only JSONL writer/reader, including the
29//!   INV-SP-2 torn-append truncation logic.
30//! - [`store`] — [`store::SessionStore`]: CRUD over the `acp_sessions` metadata index (spec §5).
31//! - [`replay`] — [`replay::ReplayEngine`]: deterministic fold of an event log into agent-ready
32//!   messages. Never calls the LLM or a tool executor.
33//! - [`condenser`] — the [`condenser::Condenser`] trait contract and the INV-SP-4 non-overlap
34//!   guard.
35//! - [`llm_condenser`] — [`llm_condenser::LlmCondenser`]: the default `Condenser` implementation,
36//!   reusing `zeph_context::summarization::summarize_structured`.
37//! - [`fork`] — [`fork::ForkEngine`]: eager-copy session forking (spec §7).
38//!
39//! The `zeph-core` `SessionActor` integration (`zeph serve`, spec §9) lands in a later phase of
40//! the implementation plan (`specs/068-session-persistence/plan.md`).
41
42pub mod condenser;
43pub mod error;
44pub mod event;
45pub mod fork;
46pub mod llm_condenser;
47pub mod log;
48pub mod replay;
49pub mod store;
50
51pub use condenser::{CondensationResult, Condenser};
52pub use error::SessionError;
53pub use event::{CompactionTier, SessionEvent, SessionEventEnvelope};
54pub use fork::{ForkEngine, ForkResult};
55pub use llm_condenser::LlmCondenser;
56pub use log::SessionEventLog;
57pub use replay::{ReconstructedState, ReplayEngine};
58pub use store::{SessionFilter, SessionMetadata, SessionStatus, SessionStore};
59
60/// The on-disk directory for one session's event log and blobs, per spec §4.1:
61/// `<data_dir>/sessions/<session_id>/`.
62///
63/// # Examples
64///
65/// ```
66/// use std::path::Path;
67///
68/// let dir = zeph_session::session_dir(Path::new(".zeph/sessions"), "abc-123");
69/// assert_eq!(dir, Path::new(".zeph/sessions/sessions/abc-123"));
70/// ```
71#[must_use]
72pub fn session_dir(data_dir: &std::path::Path, session_id: &str) -> std::path::PathBuf {
73    data_dir.join("sessions").join(session_id)
74}