pub struct MemoryStore { /* private fields */ }Expand description
The LMDB environment containing all 14 galaxy sub-databases plus 4 index DBs.
Implementations§
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn probe_write_lock(store_root: &Path) -> Result<()>
pub fn probe_write_lock(store_root: &Path) -> Result<()>
Probe whether another process holds the LMDB writer lock on this store.
LMDB’s write env-open falls back to a blocking shared lock when the
exclusive writer lock is held, then opens data.mdb for writing
anyway and wedges on its internal mutex — wm grimoire/wm status
hung forever against a live store until a SIGKILL (9.1.6). Callers
that need exclusive access probe first and fail loudly instead of
deadlocking.
The probe is a non-blocking fcntl(F_SETLK, F_WRLCK) over the whole
lock.mdb (record locks overlap LMDB’s byte-range writer lock), so
it never blocks and never mutates the store.
Returns Ok(()) when the writer lock is free, Err(WouldBlock)
when another process holds it.
Sourcepub fn open(path: impl AsRef<Path>, map_size: usize) -> Result<Self>
pub fn open(path: impl AsRef<Path>, map_size: usize) -> Result<Self>
Open or create an LMDB store at the given path.
At-rest mode comes from the environment (WM_AT_REST_MODE, default
off) — see Self::open_with_at_rest. off is a provable no-op:
no keyring DBI is created and no key files are written. A
set-but-unrecognized WM_AT_REST_MODE value refuses the open
(fail-closed).
On Unix, the store directory is created with mode 0o700 (owner-only access) if it does not already exist. Existing directories are left untouched.
Sourcepub fn open_with_at_rest(
path: impl AsRef<Path>,
map_size: usize,
at_rest_config: &AtRestConfig,
) -> Result<Self>
pub fn open_with_at_rest( path: impl AsRef<Path>, map_size: usize, at_rest_config: &AtRestConfig, ) -> Result<Self>
Open or create an LMDB store with an explicit at-rest configuration.
Q39 slice A: when the mode is keyfile/passphrase, the store’s
keyring DBI is read (or initialized as meta + rk:check + 16
wrapped galaxy DEKs, all in one transaction) and the DEKs are
unwrapped at open. Records stay plaintext in slice A.
Sourcepub fn at_rest_status(&self) -> AtRestStatus
pub fn at_rest_status(&self) -> AtRestStatus
At-rest disclosure status (Q39 slice A): keyring meta only — the RK is
never resolved here, and nothing is created or written. Absent means
plaintext pass-through.
Sourcepub const fn at_rest_state(&self) -> Option<&AtRestState>
pub const fn at_rest_state(&self) -> Option<&AtRestState>
Unlocked keyring state for a writable at-rest store (slice B seam);
None for plaintext-pass-through stores and all read paths.
Sourcepub const fn keyring_db(&self) -> Option<Database>
pub const fn keyring_db(&self) -> Option<Database>
Keyring DBI handle when the store has one (None for plaintext
pass-through stores and on read paths where the DBI is absent).
Slice-B migration reads/writes its ledger through this handle.
Sourcepub fn open_readonly_bounded(
path: impl AsRef<Path>,
timeout: Duration,
) -> Result<Option<Self>>
pub fn open_readonly_bounded( path: impl AsRef<Path>, timeout: Duration, ) -> Result<Option<Self>>
Bounded env open for inspection paths (9.1.6).
LMDB env opens can block forever: against a live writer the
exclusive-lock fallback wedges on an internal mutex, and a crashed
server can leave the lock file’s in-file mutex locked so even
read-only opens hang. Inspection callers (status, doctor, grimoire)
must never hang — run the open on a worker thread and give up after
timeout, returning Ok(None) so the caller degrades loudly
instead of deadlocking.
Sourcepub fn open_default_bounded(
path: impl AsRef<Path>,
timeout: Duration,
) -> Result<Option<Self>>
pub fn open_default_bounded( path: impl AsRef<Path>, timeout: Duration, ) -> Result<Option<Self>>
Bounded writable env open for exclusive-access paths (9.1.6).
See Self::open_readonly_bounded for the wedge rationale; write
paths bail with an actionable message on timeout instead of hanging.
Sourcepub fn default_map_size() -> usize
pub fn default_map_size() -> usize
Default LMDB map size for this platform (WM_DEFAULT_MAP_SIZE
overrides). See Self::open_default for the platform rationale.
Sourcepub fn open_default(path: impl AsRef<Path>) -> Result<Self>
pub fn open_default(path: impl AsRef<Path>) -> Result<Self>
Open with the default map size.
4 GB on Unix: LMDB truncates the data file sparsely (ftruncate), so
reservation costs nothing until pages are written. On Windows NTFS
materializes the file at full map size immediately — a 4 GB default
would allocate 4 GB on disk per store the moment it opens — so the
Windows default is smaller; pass an explicit size to open() for
large stores. (Auto-grow on MapFull is a planned follow-up.)
Sourcepub fn open_readonly(path: impl AsRef<Path>) -> Result<Self>
pub fn open_readonly(path: impl AsRef<Path>) -> Result<Self>
Open an existing LMDB store without creating a directory, database, or writable LMDB environment. This is the preservation boundary used by read-only evaluator servers: an incomplete or incompatible store must fail closed for the caller to investigate, never be initialized or repaired in place.
Sourcepub fn open_inspection(path: impl AsRef<Path>) -> Result<Self>
pub fn open_inspection(path: impl AsRef<Path>) -> Result<Self>
Open an existing store for inspection without taking any lock
(MDB_NOLOCK | MDB_RDONLY), 9.1.6.
Read-only env opens still block forever in two real situations:
a live writer holds the exclusive lock (lmdb-master falls back to a
blocking shared-lock wait), and a crashed server can leave the lock
file’s in-file mutex wedged so every open hangs. Inspection paths
(status, doctor, grimoire) never need the lock file — no locks, no
reader slots, no mutex — just an mmap read of the store. The store
must exist and be schema-complete (same strict refusal as
Self::open_readonly); torn-meta-page reads are theoretically
possible mid-write and acceptable for display counts.
Sourcepub fn ensure_schema(path: impl AsRef<Path>) -> Result<Vec<String>>
pub fn ensure_schema(path: impl AsRef<Path>) -> Result<Vec<String>>
Complete a store’s schema in place: create any galaxy, index, or named database this build expects but an older store lacks, then let the caller reopen normally. Returns the database names that were missing.
Restores from older builds can be byte-exact yet not openable (found
2026-09-14: a 9.0.0 backup lacked cold_storage). This is the only
in-place repair path; open_readonly deliberately stays strict so
preservation callers see an incomplete store instead of a silent fix.
The at-rest keyring DBI is not required schema (Q39 slice A
decision): legacy stores and strict reads stay working, and this
function neither creates nor repairs a keyring.
Sourcepub const fn with_entry_limit(self, limit: usize) -> Self
pub const fn with_entry_limit(self, limit: usize) -> Self
Set a per-galaxy entry limit for DoS prevention.
When set, put will reject writes that would exceed the limit.
This prevents a single galaxy from exhausting the LMDB map.
Sourcepub const fn env(&self) -> &Environment
pub const fn env(&self) -> &Environment
Get the LMDB environment handle.
Sourcepub fn mutation_count(&self) -> u64
pub fn mutation_count(&self) -> u64
Monotonic counter of successful mutations since this handle was opened (puts, deletes, clears, raw writes). Used by the dispatch pipeline’s write-audit journal to detect actual store writes.
Sourcepub const fn semantic_encoder(&self) -> &SemanticEncoder
pub const fn semantic_encoder(&self) -> &SemanticEncoder
Get the semantic encoder.
Sourcepub fn episodic_sidecar_health(&self) -> Result<(u64, bool)>
pub fn episodic_sidecar_health(&self) -> Result<(u64, bool)>
Read-only health probe for the derived episodic sidecar (H2,
2026-09-19 review): (authoritative indexable record count, sidecar empty?).
count > 0 && sidecar_empty is the signature of a failed or
never-run sidecar rebuild — the raw lane is canonical, the term
postings are a reconstructible view. Callers (doctor) grade that
DEGRADED instead of reporting a healthy store. Private /
model-excluded records deliberately have no postings, so only
indexable records count. Unlike Self::episodic, this never
triggers the once-per-process rebuild and never writes.
Sourcepub fn episodic_record_count(&self) -> Result<u64>
pub fn episodic_record_count(&self) -> Result<u64>
Authoritative episodic record count without triggering the
once-per-process sidecar rebuild (read-only; for inspection paths
such as wm doctor, which must diagnose, not silently repair).
Sourcepub fn episodic(&self) -> EpisodicStore<'_>
pub fn episodic(&self) -> EpisodicStore<'_>
Open the v6 lossless episodic record view.
Sourcepub fn set_episodic_embedder(&self, embedder: Arc<dyn Embedder + Send + Sync>)
pub fn set_episodic_embedder(&self, embedder: Arc<dyn Embedder + Send + Sync>)
Attach an embedder for episodic vector reranking.
Sourcepub fn set_episodic_aliases(&self, aliases: AdaptiveAliases)
pub fn set_episodic_aliases(&self, aliases: AdaptiveAliases)
Attach adaptive aliases for episodic key expansion.
Sourcepub fn set_episodic_enrichment(&self, enrichment: VocabularyEnrichment)
pub fn set_episodic_enrichment(&self, enrichment: VocabularyEnrichment)
Attach vocabulary enrichment for episodic index-time term expansion.
Sourcepub fn galaxy_db(&self, galaxy: Galaxy) -> Result<Database>
pub fn galaxy_db(&self, galaxy: Galaxy) -> Result<Database>
Get a named database handle for a galaxy.
Sourcepub fn put(&self, galaxy: Galaxy, memory: &Memory) -> Result<()>
pub fn put(&self, galaxy: Galaxy, memory: &Memory) -> Result<()>
Store a memory in the given galaxy. Keyed by memory.metadata.id. Also updates all secondary indexes.
Returns a clear error if the per-galaxy entry limit is exceeded or if the LMDB map is full.
Sourcepub fn put_session_turn<F>(
&self,
session_id: &str,
build: F,
) -> Result<(u64, Memory)>
pub fn put_session_turn<F>( &self, session_id: &str, build: F, ) -> Result<(u64, Memory)>
Atomically allocate the next per-session turn sequence and store the turn in one LMDB write transaction (H1, 2026-09-20 review).
The review reproduced duplicate sequences under concurrent writers:
allocation was read-count-then-write (load_turns().len() + 1),
outside the serialization boundary. The counter lives in the
session_sequences DBI and is incremented inside the record’s
transaction, so N concurrent writers get exactly 1..=N unique,
contiguous sequences with no burned numbers (a crash before commit
rolls back both the counter and the record).
build runs with the allocated sequence while the transaction is
open and returns the record to store — this keeps the sequence inside
the record’s own content truthful (the turn schema carries it)
without a second write transaction.
Returns (sequence, stored_memory).
Sourcepub fn last_session_sequence(&self, session_id: &str) -> Result<Option<u64>>
pub fn last_session_sequence(&self, session_id: &str) -> Result<Option<u64>>
Last allocated turn sequence for a session, read from the counter
(no scan). None when the session has no allocated sequence yet, or
when the store predates the session_sequences DBI.
Sourcepub fn mark_index_pending(
&self,
galaxy: &str,
memory_id: &str,
at_ms: i64,
) -> Result<()>
pub fn mark_index_pending( &self, galaxy: &str, memory_id: &str, at_ms: i64, ) -> Result<()>
Record a memory whose write-time Tantivy indexing failed (the writer
lock was held by another process). The next writable context drains
the ledger with crate::reindex::drain_index_pending instead of
leaving the user to discover silent index drift later (2026-09-21
reviewer finding).
Sourcepub fn index_pending_entries(&self) -> Result<Vec<(String, String, i64)>>
pub fn index_pending_entries(&self) -> Result<Vec<(String, String, i64)>>
Pending-index entries as (memory_id, galaxy, at_ms), oldest first.
A legacy store without the DBI reads as an empty ledger.
Sourcepub fn count_index_pending(&self) -> Result<usize>
pub fn count_index_pending(&self) -> Result<usize>
Number of pending-index entries (0 for a legacy store without the DBI).
Sourcepub fn clear_index_pending(&self, ids: &[String]) -> Result<usize>
pub fn clear_index_pending(&self, ids: &[String]) -> Result<usize>
Clear the given pending-index ids (idempotent). Returns how many rows existed and were removed.
Sourcepub fn clear_all_index_pending(&self) -> Result<usize>
pub fn clear_all_index_pending(&self) -> Result<usize>
Clear every pending-index entry (after a full successful reindex); returns the count that was cleared.
Sourcepub fn get(&self, galaxy: Galaxy, id: Uuid) -> Result<Option<Memory>>
pub fn get(&self, galaxy: Galaxy, id: Uuid) -> Result<Option<Memory>>
Retrieve a memory by ID from the given galaxy.
Sourcepub fn find_across_galaxies(&self, id: Uuid) -> Result<Option<(Galaxy, Memory)>>
pub fn find_across_galaxies(&self, id: Uuid) -> Result<Option<(Galaxy, Memory)>>
Retrieve a memory by ID searching across all memory galaxies (S9 cross-galaxy traversal).
Cross-galaxy associations and edges reference galaxy-blind UUIDs. This searches through all memory galaxies in canonical order and returns the first matching (Galaxy, Memory) pair, or None if not found.
Sourcepub fn delete(&self, galaxy: Galaxy, id: Uuid) -> Result<bool>
pub fn delete(&self, galaxy: Galaxy, id: Uuid) -> Result<bool>
Delete a memory by ID from the given galaxy. Returns true if a key was removed. Also removes all secondary index entries for the memory.
Sourcepub fn scan(&self, galaxy: Galaxy, limit: usize) -> Result<Vec<Memory>>
pub fn scan(&self, galaxy: Galaxy, limit: usize) -> Result<Vec<Memory>>
Scan up to limit memories from the given galaxy (unordered by LMDB page layout).
Sourcepub fn scan_all(&self, galaxy: Galaxy) -> Result<Vec<Memory>>
pub fn scan_all(&self, galaxy: Galaxy) -> Result<Vec<Memory>>
Scan every memory in the galaxy (unordered by LMDB page layout).
Used by maintenance tooling (e.g. index rebuild). The full galaxy is
materialized in memory — prefer Self::scan for bounded reads.
Sourcepub fn scan_all_strict(&self, galaxy: Galaxy) -> Result<Vec<Memory>>
pub fn scan_all_strict(&self, galaxy: Galaxy) -> Result<Vec<Memory>>
Maintenance scan that refuses to omit an undecodable source record. Use before replacing derived indexes; a tolerant scan is not a complete authoritative snapshot when any record fails decoding.
Sourcepub fn count_by_tag(&self, galaxy: Galaxy, tag: &str) -> Result<usize>
pub fn count_by_tag(&self, galaxy: Galaxy, tag: &str) -> Result<usize>
Count entries in a galaxy carrying a tag, using the tag index (no
record decoding). wm status uses this to report logical sessions
(records tagged start) instead of every turn/checkpoint record
stored in the Sessions galaxy.
Sourcepub fn clear_galaxy(&self, galaxy: Galaxy) -> Result<usize>
pub fn clear_galaxy(&self, galaxy: Galaxy) -> Result<usize>
Clear all memories from a galaxy in a single transaction. Returns the number of entries cleared. Also removes all secondary index entries.
Sourcepub fn batch_put(&self, galaxy: Galaxy, memories: &[Memory]) -> Result<usize>
pub fn batch_put(&self, galaxy: Galaxy, memories: &[Memory]) -> Result<usize>
Put multiple memories into a galaxy in a single transaction. Returns the number of memories written.
Sourcepub fn get_raw(&self, galaxy: Galaxy, key: &[u8]) -> Result<Option<Vec<u8>>>
pub fn get_raw(&self, galaxy: Galaxy, key: &[u8]) -> Result<Option<Vec<u8>>>
Get raw key-value bytes (for advanced use cases).
Sourcepub fn put_raw(&self, galaxy: Galaxy, key: &[u8], val: &[u8]) -> Result<()>
pub fn put_raw(&self, galaxy: Galaxy, key: &[u8], val: &[u8]) -> Result<()>
Put raw key-value bytes (for advanced use cases).
Sourcepub fn delete_raw(&self, galaxy: Galaxy, key: &[u8]) -> Result<bool>
pub fn delete_raw(&self, galaxy: Galaxy, key: &[u8]) -> Result<bool>
Delete raw key-value bytes (for advanced use cases). Returns true if a key was removed.
Sourcepub fn put_raw_batch(
&self,
galaxy: Galaxy,
entries: &[(&[u8], &[u8])],
) -> Result<()>
pub fn put_raw_batch( &self, galaxy: Galaxy, entries: &[(&[u8], &[u8])], ) -> Result<()>
Batch multiple raw key-value writes in a single LMDB transaction. All writes succeed or fail atomically.
Sourcepub fn put_raw_batch_untracked(
&self,
galaxy: Galaxy,
entries: &[(&[u8], &[u8])],
) -> Result<()>
pub fn put_raw_batch_untracked( &self, galaxy: Galaxy, entries: &[(&[u8], &[u8])], ) -> Result<()>
Batch multiple raw key-value writes without advancing the mutation counter.
For governance bookkeeping (karma chain, write-audit journal): these writes are metadata about dispatches, not memory mutations. Letting them tick the counter attributes a whole batch flush to whichever dispatch happens to be in flight when the threshold trips — the 2026-08-28 restore-drill false-positive class (“read-only” tools flagged with the previous batch’s size as their write delta).
Sourcepub fn find_by_content_hash(
&self,
galaxy: Galaxy,
hash: &str,
) -> Result<Option<Uuid>>
pub fn find_by_content_hash( &self, galaxy: Galaxy, hash: &str, ) -> Result<Option<Uuid>>
Check if a memory with the same content hash already exists in the galaxy. Uses the content_hash index for O(1) lookup. Returns the existing memory’s ID if found.
Sourcepub fn find_by_content_hash_scan(
&self,
galaxy: Galaxy,
hash: &str,
) -> Result<Option<Uuid>>
pub fn find_by_content_hash_scan( &self, galaxy: Galaxy, hash: &str, ) -> Result<Option<Uuid>>
Scan-based content hash lookup (O(n) fallback, used for testing index correctness).
Sourcepub fn put_dedup(&self, galaxy: Galaxy, memory: &Memory) -> Result<Uuid>
pub fn put_dedup(&self, galaxy: Galaxy, memory: &Memory) -> Result<Uuid>
Store a memory with content-hash deduplication. If a memory with the same content already exists in the galaxy, returns the existing memory’s ID without creating a duplicate.
Sourcepub fn put_batch(&self, galaxy: Galaxy, memories: &[Memory]) -> Result<()>
pub fn put_batch(&self, galaxy: Galaxy, memories: &[Memory]) -> Result<()>
Store multiple memories in a single LMDB transaction (batch write). All writes and index updates succeed or fail atomically.
Sourcepub fn query(&self, galaxy: Galaxy, query: &MemoryQuery) -> Result<Vec<Memory>>
pub fn query(&self, galaxy: Galaxy, query: &MemoryQuery) -> Result<Vec<Memory>>
Query memories in a galaxy with filtering. Uses secondary indexes when the query is a pure single-dimension filter (single tag, importance range, or time range with no other filters). Falls back to scan for complex multi-dimensional queries.
Sourcepub fn put_semantic(&self, galaxy: Galaxy, memory: &mut Memory) -> Result<()>
pub fn put_semantic(&self, galaxy: Galaxy, memory: &mut Memory) -> Result<()>
Store a memory with semantically-derived 5D coordinates.
Replaces the SHA-256 hash-based Coordinate5D::encode() with
anchor-based TF projection. The memory’s coord5d field is updated
with semantically meaningful x/y/z values before storage.
Sourcepub fn find_similar(
&self,
galaxy: Galaxy,
query_text: &str,
limit: usize,
) -> Result<Vec<(Memory, f32)>>
pub fn find_similar( &self, galaxy: Galaxy, query_text: &str, limit: usize, ) -> Result<Vec<(Memory, f32)>>
Find memories in a galaxy with content semantically similar to the query text.
Encodes the query text into a 5D coordinate and scans the galaxy, returning memories sorted by semantic distance (nearest first).
Sourcepub fn put_embedding(&self, memory_id: Uuid, embedding: &[f32]) -> Result<()>
pub fn put_embedding(&self, memory_id: Uuid, embedding: &[f32]) -> Result<()>
Store an embedding vector for a memory in the Embeddings galaxy. Keyed by the memory’s UUID.
Sourcepub fn get_embedding(&self, memory_id: Uuid) -> Result<Option<Vec<f32>>>
pub fn get_embedding(&self, memory_id: Uuid) -> Result<Option<Vec<f32>>>
Retrieve an embedding vector for a memory from the Embeddings galaxy.
Sourcepub fn delete_embedding(&self, memory_id: Uuid) -> Result<bool>
pub fn delete_embedding(&self, memory_id: Uuid) -> Result<bool>
Delete an embedding vector from the Embeddings galaxy.
Sourcepub fn put_embedding_cache(
&self,
cache_key: &str,
embedding: &[f32],
) -> Result<()>
pub fn put_embedding_cache( &self, cache_key: &str, embedding: &[f32], ) -> Result<()>
Store a cached embedding under a caller-computed cache key (embedder namespace + content hash). Vectors for the same content differ across models, so the key must carry the namespace.
Sourcepub fn put_embedding_cache_batch(
&self,
entries: &[(String, Vec<f32>)],
) -> Result<()>
pub fn put_embedding_cache_batch( &self, entries: &[(String, Vec<f32>)], ) -> Result<()>
Batched cache write: one transaction for the whole ingest chunk.
Sourcepub fn get_embedding_cache(&self, cache_key: &str) -> Result<Option<Vec<f32>>>
pub fn get_embedding_cache(&self, cache_key: &str) -> Result<Option<Vec<f32>>>
Look up a cached embedding. Ok(None) = miss; the caller embeds.
Sourcepub fn get_embedding_cache_batch(
&self,
keys: &[String],
) -> Result<Vec<Option<Vec<f32>>>>
pub fn get_embedding_cache_batch( &self, keys: &[String], ) -> Result<Vec<Option<Vec<f32>>>>
Batched lookup: one read transaction for the whole ingest chunk.
Result aligns 1:1 with keys.
Sourcepub fn embedding_cache_count(&self) -> Result<u64>
pub fn embedding_cache_count(&self) -> Result<u64>
Number of cached vectors (doctor / honesty surfaces).
Sourcepub fn record_revision(
&self,
galaxy: Galaxy,
id: MemoryId,
old_hash: &str,
new_hash: &str,
actor: RevisionActor,
) -> Result<MemoryRevision>
pub fn record_revision( &self, galaxy: Galaxy, id: MemoryId, old_hash: &str, new_hash: &str, actor: RevisionActor, ) -> Result<MemoryRevision>
Append one content revision to a memory’s chain. Seq is derived from the current chain tail (append-only by convention); the write bumps the store mutation counter so dispatch windows attribute it.
Sourcepub fn revisions(
&self,
galaxy: Galaxy,
id: MemoryId,
) -> Result<Vec<MemoryRevision>>
pub fn revisions( &self, galaxy: Galaxy, id: MemoryId, ) -> Result<Vec<MemoryRevision>>
Full revision chain for a memory, ordered by seq. Empty for memories never content-updated (or pre-S11c).
Sourcepub fn verify_revision_chain(
&self,
galaxy: Galaxy,
id: MemoryId,
current_hash: &str,
) -> Result<RevisionChainReport>
pub fn verify_revision_chain( &self, galaxy: Galaxy, id: MemoryId, current_hash: &str, ) -> Result<RevisionChainReport>
Walk one memory’s revision chain and grade it against the memory’s current content hash (seq continuity, hash linkage, head match).
Sourcepub fn record_attestation(
&self,
galaxy: Galaxy,
id: MemoryId,
entry: &RecordAttestation,
) -> Result<()>
pub fn record_attestation( &self, galaxy: Galaxy, id: MemoryId, entry: &RecordAttestation, ) -> Result<()>
Record one creation attestation for a memory. Upsert by key
(att:{galaxy}:{memory_id}): re-attestation overwrites, which is
safe because attestation covers the creation event and memory ids
are unique per create. The write bumps the mutation counter like
every other store mutation.
Sourcepub fn attestation(
&self,
galaxy: Galaxy,
id: MemoryId,
) -> Result<Option<RecordAttestation>>
pub fn attestation( &self, galaxy: Galaxy, id: MemoryId, ) -> Result<Option<RecordAttestation>>
This memory’s creation attestation, if the creating dispatch signed one (key-available creates only — absence is honest, not an error).
Sourcepub fn scan_attestations(&self) -> Result<Vec<RecordAttestation>>
pub fn scan_attestations(&self) -> Result<Vec<RecordAttestation>>
Every attestation in the store (for wm anchor). Bounded walk —
corrupt data can never spin this loop.
Sourcepub fn verify_attestation(
&self,
galaxy: Galaxy,
id: MemoryId,
) -> Result<AttestationReport>
pub fn verify_attestation( &self, galaxy: Galaxy, id: MemoryId, ) -> Result<AttestationReport>
Grade one memory’s attestation: presence, signature validity, and
whether the attested hash still matches the live content hash.
A content update after creation flips matches_head to false by
design — updates are covered by the revisions chain, not by
re-attestation.
Sourcepub fn attestation_sweep(
&self,
) -> Result<Vec<(RecordAttestation, AttestationReport)>>
pub fn attestation_sweep( &self, ) -> Result<Vec<(RecordAttestation, AttestationReport)>>
Grade every attestation in the store (for wm anchor). Entries
whose galaxy/id no longer parse are reported as broken — never
skipped silently.
Sourcepub fn put_cold_record(&self, record: &ColdRecord) -> Result<()>
pub fn put_cold_record(&self, record: &ColdRecord) -> Result<()>
Store a compressed cold record in the cold_storage DBI.
Sourcepub fn get_cold_record(&self, id: MemoryId) -> Result<Option<ColdRecord>>
pub fn get_cold_record(&self, id: MemoryId) -> Result<Option<ColdRecord>>
Retrieve a compressed cold record by memory id.
Sourcepub fn delete_cold_record(&self, id: MemoryId) -> Result<bool>
pub fn delete_cold_record(&self, id: MemoryId) -> Result<bool>
Delete a cold record from the cold storage DBI (used when thawing back to hot).
Sourcepub fn count_cold(&self, galaxy: Option<Galaxy>) -> Result<usize>
pub fn count_cold(&self, galaxy: Option<Galaxy>) -> Result<usize>
Count cold records in the cold storage database, optionally filtered by galaxy.
Sourcepub fn list_cold_records(
&self,
galaxy: Option<Galaxy>,
limit: usize,
) -> Result<Vec<ColdRecordSummary>>
pub fn list_cold_records( &self, galaxy: Option<Galaxy>, limit: usize, ) -> Result<Vec<ColdRecordSummary>>
List cold records (summaries) with optional galaxy filter and limit.
Sourcepub fn query_cold_records(
&self,
query: &ColdQuery,
) -> Result<Vec<ColdRecordSummary>>
pub fn query_cold_records( &self, query: &ColdQuery, ) -> Result<Vec<ColdRecordSummary>>
Query cold records matching a ColdQuery filter.
Sourcepub fn find_cold_matching(
&self,
terms: &[String],
galaxy: Option<Galaxy>,
limit: usize,
max_scan: usize,
) -> Result<ColdDiscoveryOutcome>
pub fn find_cold_matching( &self, terms: &[String], galaxy: Option<Galaxy>, limit: usize, max_scan: usize, ) -> Result<ColdDiscoveryOutcome>
Bounded, identity-bound cold discovery.
Scans at most max_scan cold records (LMDB cold_storage DBI),
filters by galaxy when given, decompresses each candidate, verifies
the id/galaxy/content-hash chain, applies visibility (private never
surfaces; superseded/non-current records are skipped), and returns
up to limit full cold records whose content or tags contain every
query term (case-insensitive). Nothing is thawed or mutated.
Sourcepub fn find_cold_matching_eligible(
&self,
terms: &[String],
galaxy: Option<Galaxy>,
limit: usize,
max_scan: usize,
eligible: impl Fn(&Memory) -> bool,
) -> Result<ColdDiscoveryOutcome>
pub fn find_cold_matching_eligible( &self, terms: &[String], galaxy: Option<Galaxy>, limit: usize, max_scan: usize, eligible: impl Fn(&Memory) -> bool, ) -> Result<ColdDiscoveryOutcome>
Apply caller eligibility to verified payloads before consuming result capacity. Rejected matches still consume the bounded scan budget.
Sourcepub fn freeze_to_cold(
&self,
search: Option<&SearchEngine>,
memory_id: MemoryId,
distance: f32,
factors: OuterRimFactors,
digest_id: Option<MemoryId>,
notes: Option<String>,
codec: CompressionCodec,
) -> Result<ColdRecord>
pub fn freeze_to_cold( &self, search: Option<&SearchEngine>, memory_id: MemoryId, distance: f32, factors: OuterRimFactors, digest_id: Option<MemoryId>, notes: Option<String>, codec: CompressionCodec, ) -> Result<ColdRecord>
Freeze an active hot memory into the compressed cold archive.
Non-destructive: preserves complete metadata, vector clocks, content, embeddings,
and provenance. The memory transitions to Tier::Archival, is stored in cold_storage_db,
is deindexed from Tantivy (if search provided), and is removed from the active hot galaxy.
Sourcepub fn thaw_from_cold(
&self,
search: Option<&SearchEngine>,
memory_id: MemoryId,
) -> Result<Memory>
pub fn thaw_from_cold( &self, search: Option<&SearchEngine>, memory_id: MemoryId, ) -> Result<Memory>
Thaw a memory from compressed cold storage back into the hot active tier.
Zero data loss: restores the original memory with all fields, transitions tier
back to Tier::Episodic, bumps access/recall count, updates accessed_at,
stores into the hot galaxy, and reindexes into Tantivy search (if provided).
Auto Trait Implementations§
impl !Freeze for MemoryStore
impl !RefUnwindSafe for MemoryStore
impl !UnwindSafe for MemoryStore
impl Send for MemoryStore
impl Sync for MemoryStore
impl Unpin for MemoryStore
impl UnsafeUnpin for MemoryStore
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
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