pub struct WorkingMemory { /* private fields */ }Expand description
Key-prefixed scratchpad. Stores (k, v) pairs under {scope_prefix}{k}
as Episodes on the Episode source field.
Implementations§
Source§impl WorkingMemory
impl WorkingMemory
Sourcepub fn new(
lunaris: Arc<Lunaris>,
scope: Scope,
scope_prefix: impl Into<String>,
) -> Self
pub fn new( lunaris: Arc<Lunaris>, scope: Scope, scope_prefix: impl Into<String>, ) -> Self
Construct a new scratchpad bound to scope (RFC 0001 partition key)
and scope_prefix (source-key namespace). The two concepts are
orthogonal: scope partitions the KV / FT keyspace, while
scope_prefix namespaces the source field on each Episode so a
single scope can host multiple WorkingMemory instances (e.g.,
"helios:fs/" vs "chat:user-42/").
Sourcepub async fn write(&self, k: &str, v: Value) -> Result<Lsn, LunarisError>
pub async fn write(&self, k: &str, v: Value) -> Result<Lsn, LunarisError>
Write (k, v) under {scope_prefix}{k} as an Episode.
Sourcepub async fn write_dated(
&self,
k: &str,
v: Value,
t_ref: DateTime<Utc>,
) -> Result<Lsn, LunarisError>
pub async fn write_dated( &self, k: &str, v: Value, t_ref: DateTime<Utc>, ) -> Result<Lsn, LunarisError>
Self::write with the payload’s real-world reference time stamped
as Episode::t_ref.
t_ref is the date the CONTENT is from (a chat session’s date, a
document’s authored date) — distinct from the ingest-time HLC the
clock stamps on bt. Graph-ON ingest threads it into the extraction
prompt as REFERENCE_TIME so extracted valid_from/valid_to
dates are grounded in the content’s timeline instead of the model’s
“today” (Mechanism B, 2026-07-29 LME diagnosis).
Sourcepub async fn read(&self, k: &str) -> Result<Option<Value>, LunarisError>
pub async fn read(&self, k: &str) -> Result<Option<Value>, LunarisError>
Read the value for k scoped under scope_prefix, if present.
Recovers the VERBATIM value from the parent Episode content, NOT from
the lossy chunk text (the markdown chunker’s smart-punctuation pass
rewrites quotes / dashes and corrupts JSON values — see
Self::recover_value).
Sourcepub async fn grep(
&self,
pattern: &str,
) -> Result<Vec<(String, Value)>, LunarisError>
pub async fn grep( &self, pattern: &str, ) -> Result<Vec<(String, Value)>, LunarisError>
Return all (source, value) pairs whose source starts with
{scope_prefix}{pattern}. Values are recovered verbatim from the
parent Episode content (see Self::recover_value).
Sourcepub async fn consolidate(&self) -> Result<ConsolidationReport, LunarisError>
pub async fn consolidate(&self) -> Result<ConsolidationReport, LunarisError>
Phase 9.1 Plan 01 Task 3 — run one consolidation pass scoped to
self.scope_prefix.
§Foreign-event preservation
drain_consolidate_events subscribes to CONSOLIDATE_TOPIC and
consumes ALL pending events for the scope in one pass — it is not
prefix-aware. Without an explicit re-queue step, calling
consolidate_scoped(Some(prefix)) on the drained batch silently drops
the non-matching (“foreign”) events: they are consumed from the
consumer-group queue and never seen by a subsequent pass (ADD task
consolidate-prefix-drop).
Fix: after draining, partition events by
source.starts_with(scope_prefix). Matching events are forwarded to
consolidate_scoped (which therefore receives an already-filtered
batch and must NOT double-filter — hence None prefix in the call).
Foreign events are re-published verbatim to CONSOLIDATE_TOPIC so
that the next consolidate_unfiltered (or the background worker) can
pick them up. A publish error on re-queue is loud-not-fatal: the call
still returns Ok with the matching report (matching consolidation
already happened and its result must not be discarded).
Sourcepub async fn consolidate_unfiltered(
&self,
) -> Result<ConsolidationReport, LunarisError>
pub async fn consolidate_unfiltered( &self, ) -> Result<ConsolidationReport, LunarisError>
Whole-scope variant of Self::consolidate: drains and consolidates
ALL pending events for the scope, ignoring self.scope_prefix.
The drain is scope-wide either way; consolidate_scoped(Some(prefix))
then FILTERS the drained events and the non-matching ones are already
consumed from the queue — dropped, not re-queued. Callers that cannot
tolerate that loss (e.g. the MCP session-handover, which runs
implicitly and must not eat other namespaces’ pending events) use this
variant; it consolidates exactly what the background worker would.
Trait Implementations§
Source§impl Clone for WorkingMemory
impl Clone for WorkingMemory
Source§fn clone(&self) -> WorkingMemory
fn clone(&self) -> WorkingMemory
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for WorkingMemory
impl !UnwindSafe for WorkingMemory
impl Freeze for WorkingMemory
impl Send for WorkingMemory
impl Sync for WorkingMemory
impl Unpin for WorkingMemory
impl UnsafeUnpin for WorkingMemory
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more