Skip to main content

lean_ctx/core/value/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Value surface: makes what lean-ctx did visible outside the dashboard —
3//! subtly, outside the model's context, and with every number provable.
4//!
5//! * [`snapshot`] — a tiny per-session file the MCP server keeps current, so
6//!   status lines and prompt segments render in microseconds without touching
7//!   the ledger.
8//! * [`mod@format`] — the shared renderers (one dim line; the branded status line).
9//! * [`host`] — which agent process a session serves, so concurrent agents in
10//!   one project each see their own numbers.
11//! * [`proof`] — recomputes each number from the hash-chained savings ledger
12//!   and audit trail and verifies both chains (`lean-ctx value`).
13//! * [`recap`] — when a host hook speaks up (turn and session recaps, weekly
14//!   digest), always as a user-only message, never into the model's context.
15//! * [`milestones`] — a native desktop notification ([`notify`]) when a
16//!   verified lifetime threshold is first crossed; at most one a day.
17
18pub mod format;
19pub mod host;
20pub mod milestones;
21pub mod notify;
22pub mod proof;
23pub mod recap;
24pub mod snapshot;
25
26use std::sync::RwLock;
27
28static CURRENT_SESSION: RwLock<Option<String>> = RwLock::new(None);
29
30/// Marks `id` as the session this process is serving. Ledger events and
31/// security events recorded afterwards commit it into their hashes.
32pub fn set_current_session(id: &str) {
33    if id.is_empty() {
34        return;
35    }
36    if let Ok(mut guard) = CURRENT_SESSION.write()
37        && guard.as_deref() != Some(id)
38    {
39        *guard = Some(id.to_string());
40    }
41}
42
43/// The session this process is serving, if it is an MCP server that has
44/// handled a tool call. `None` for CLI, hook and proxy processes.
45pub fn current_session() -> Option<String> {
46    CURRENT_SESSION.read().ok().and_then(|guard| guard.clone())
47}
48
49/// Whether any value display is on (`[value_display] mode`, overridable via
50/// `LEAN_CTX_VALUE_DISPLAY`). The proof chains are written regardless; this
51/// only gates the display snapshot and the user-facing channels.
52pub fn display_enabled() -> bool {
53    crate::core::config::Config::load_arc()
54        .value_display
55        .effective_mode()
56        != crate::core::config::ValueDisplayMode::Off
57}