pub struct Store { /* private fields */ }Expand description
A Roteiro graph store backed by a single SQLite database.
Implementations§
Source§impl Store
impl Store
Sourcepub fn open(path: &Path) -> Result<Self, StoreError>
pub fn open(path: &Path) -> Result<Self, StoreError>
Open (creating if absent) a store at path and apply pending migrations.
§Errors
Returns StoreError::Sqlite if the database cannot be opened or a
migration fails.
Sourcepub fn open_in_memory() -> Result<Self, StoreError>
pub fn open_in_memory() -> Result<Self, StoreError>
Sourcepub fn schema_version(&self) -> Result<u32, StoreError>
pub fn schema_version(&self) -> Result<u32, StoreError>
The schema version this store has been migrated to: the highest v for
which every migration 1..=v is recorded as applied.
Not the maximum recorded version. Migrations are selected by set
membership rather than > MAX(version) (see [crate::migrations]), so a
store can hold a gap — one written by a build that knew a higher
migration but not a lower one. For a store recorded as 1..11, 13, the
maximum is 13 while none of migration 12’s schema is present; reporting 13
would be a higher number than the truth. The contiguous prefix reports 11,
which is the version the store can actually be relied on to provide.
The gap is transient in practice — the next Store::open repairs it —
but this must not answer wrongly in the window where it exists, which is
exactly the window in which someone is debugging.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn build_schema_version() -> u32
pub fn build_schema_version() -> u32
The highest schema version this build knows how to apply — the
binary’s half of the comparison Store::schema_ahead makes.
Sourcepub fn schema_ahead(&self) -> Result<Option<SchemaAhead>, StoreError>
pub fn schema_ahead(&self) -> Result<Option<SchemaAhead>, StoreError>
Some when this store was written by a newer build: it records
migrations this binary has never heard of. None — the ordinary case —
when the store is level with this build or behind it.
Call this before rewriting a graph (sync, reconcile, rebuild). Do not
call it to gate reads: an older binary’s reads are sound, which is the
whole reason this is not checked in Store::open (issue #342).
§Which version this compares, and why it is not Store::schema_version
It compares the set of recorded versions against the migrations this
build carries, so it answers has anything newer than me written here?
Store::schema_version answers a different question — the highest
gap-free version, a floor describing what a reader may rely on — and
using it here would let the bug through: a store recorded 1..=13, 15,
read by a build that knows 13, has a gap-free version of 13, so
schema_version() > build is false while migration 15’s schema sits in
the file and a newer build plainly assembled the graph.
Conflating the two situations would also misreport both, so it does not.
A gap — a store missing a lower migration this build knows — is not
a store from the future, and Store::open has already repaired it by
applying the missing migration before this can be called. What is left is
only ever a version no build of this vintage could have written.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn node_count(&self) -> Result<u64, StoreError>
pub fn node_count(&self) -> Result<u64, StoreError>
Sourcepub fn edge_count(&self) -> Result<u64, StoreError>
pub fn edge_count(&self) -> Result<u64, StoreError>
Sourcepub fn upsert_node(&self, node: &Node) -> Result<(), StoreError>
pub fn upsert_node(&self, node: &Node) -> Result<(), StoreError>
Insert or update a node, keyed by its natural Node::key.
§Errors
Returns StoreError::Json if meta cannot be serialized, or
StoreError::Sqlite on write failure.
Sourcepub fn insert_edge(&self, edge: &Edge) -> Result<(), StoreError>
pub fn insert_edge(&self, edge: &Edge) -> Result<(), StoreError>
Insert an edge. Both endpoints must already resolve to nodes.
§Errors
Returns StoreError::InvalidEdge if the provenance/confidence
invariant is violated, StoreError::UnknownNode if an endpoint key is
absent, or StoreError::Sqlite on write failure.
Sourcepub fn apply_factset(&mut self, facts: &FactSet) -> Result<(), StoreError>
pub fn apply_factset(&mut self, facts: &FactSet) -> Result<(), StoreError>
Apply a fact set atomically: all nodes are upserted, then all edges are inserted, in a single transaction. On any error nothing is committed.
§Errors
Returns the first error encountered (see Store::upsert_node and
Store::insert_edge); the transaction is rolled back.
Sourcepub fn sync_state(&self) -> Result<Option<String>, StoreError>
pub fn sync_state(&self) -> Result<Option<String>, StoreError>
The HEAD tree id recorded at the last successful Store::rebuild, if
any. Used by the sync engine to detect an unchanged tree.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn sync_env(&self) -> Result<Option<String>, StoreError>
pub fn sync_env(&self) -> Result<Option<String>, StoreError>
The extractor environment recorded with the last committed [sync],
None if unset (a legacy row, or the last sync was a worktree/index
preview). The incremental committed sync compares this to the current
env and falls back to a full re-extraction when they differ.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn set_sync_env(&self, env: &str) -> Result<(), StoreError>
pub fn set_sync_env(&self, env: &str) -> Result<(), StoreError>
Record the extractor environment for the current synced tree. Called by a
committed sync right after it writes the tree, so a later sync can decide
whether the incremental fast path is sound. A no-op if no tree is recorded.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn synced_worktree(&self) -> Result<Option<String>, StoreError>
pub fn synced_worktree(&self) -> Result<Option<String>, StoreError>
Which working tree this graph was assembled from, or None when the store
has never been synced or predates the column (issue #330).
graph.db is an assembled view of one tree, so a store that came to
describe a different tree — restored from a backup, copied along with a
.git directory, or reached after a layout change — would otherwise
answer confidently about the wrong one: sync reporting “up to date”
against a state id belonging to someone else’s tree, check validating a
tree nobody is looking at. None reads as “unknown” and is adopted
rather than treated as a mismatch, so an existing store is never rebuilt
merely for predating the stamp.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn set_synced_worktree(&self, worktree: &str) -> Result<(), StoreError>
pub fn set_synced_worktree(&self, worktree: &str) -> Result<(), StoreError>
Stamp this graph as assembled from worktree. Called by every sync entry
point right after it writes the tree state, so the two always agree about
whose tree the state describes. A no-op if no tree is recorded.
Unlike Store::set_sync_env’s value, this survives a tree write: it
identifies the store, not the tree, and a new commit does not move the
graph to a different working tree.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn rebuild(
&mut self,
facts: &FactSet,
tree: Option<&str>,
) -> Result<(), StoreError>
pub fn rebuild( &mut self, facts: &FactSet, tree: Option<&str>, ) -> Result<(), StoreError>
Atomically replace the entire graph with facts, recording tree as the
synced state (or clearing it when tree is None). All existing nodes
and edges are deleted first, so the store reflects exactly the given fact
set.
Passing None records no synced tree — distinct from an empty string —
so Store::sync_state returns None and a later sync will not
spuriously short-circuit.
§Errors
Returns the first error encountered (see Store::apply_factset); on any
error nothing is committed.
Sourcepub fn reconcile(
&mut self,
facts: &FactSet,
tree: Option<&str>,
) -> Result<(), StoreError>
pub fn reconcile( &mut self, facts: &FactSet, tree: Option<&str>, ) -> Result<(), StoreError>
Bring the store to exactly facts (as Store::rebuild does) but writing
only what differs instead of wiping and reinserting the whole graph —
the git-style “write only the delta”. Unchanged node rows (which carry the
heavy JSON meta) and unchanged edge rows are left untouched; only removed
rows are deleted and new/changed rows written. The final state — nodes,
edges, and sync_state — is identical to rebuild(facts, tree).
Leaving unchanged edges in place means their row ids do not match a cold
rebuild’s — which is safe because every edge query is content-ordered
((src, dst, kind, provenance), see Store::all_edges), never by row
id. So an incrementally reconciled store and a fresh rebuild return every
query identically; the delta is invisible above the storage layer.
§Errors
Returns StoreError on a query failure; the transaction is rolled back.
Sourcepub fn get_node(&self, key: &str) -> Result<Option<Node>, StoreError>
pub fn get_node(&self, key: &str) -> Result<Option<Node>, StoreError>
Fetch a node by its natural key.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt if a stored value cannot be decoded.
Sourcepub fn all_keys(&self) -> Result<Vec<String>, StoreError>
pub fn all_keys(&self) -> Result<Vec<String>, StoreError>
Every node key in the store, ordered. Useful for whole-graph exports.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn export_factset(&self) -> Result<FactSet, StoreError>
pub fn export_factset(&self) -> Result<FactSet, StoreError>
Dump the entire graph as a single FactSet, with nodes and edges in a
deterministic order — suitable for a portable, content-stable artifact.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn nodes_by_kind(&self, kind: &NodeKind) -> Result<Vec<Node>, StoreError>
pub fn nodes_by_kind(&self, kind: &NodeKind) -> Result<Vec<Node>, StoreError>
All nodes of a given kind.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn nodes_by_kind_named(
&self,
kind: &NodeKind,
name_lower: &str,
) -> Result<Vec<Node>, StoreError>
pub fn nodes_by_kind_named( &self, kind: &NodeKind, name_lower: &str, ) -> Result<Vec<Node>, StoreError>
Nodes of a given kind whose name equals name_lower case-insensitively,
ordered by key. Narrows a lookup at the SQL layer — using the kind index and
filtering name in-query — so only matching rows are decoded, never every
node of that kind. Used by the cross-repo follow bridge to fetch just the
candidate struct(s) for a config section rather than scanning all structs.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn config_keys(&self) -> Result<Vec<ConfigKey>, StoreError>
pub fn config_keys(&self) -> Result<Vec<ConfigKey>, StoreError>
Every config_key node’s flattened setting (ADR-0009), read back out of
the graph as crate::ConfigKeys — the graph-native source the cross-repo
link matcher (roteiro links --infer) consumes, so it never re-parses
config files. Ordered by node key (deterministic). A node missing the
key/path a well-formed config_key carries is skipped defensively.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn nodes_by_path(&self, path: &str) -> Result<Vec<Node>, StoreError>
pub fn nodes_by_path(&self, path: &str) -> Result<Vec<Node>, StoreError>
Every node whose source path is path, ordered by key — the file node
plus the symbols and markers defined in it. Used to scope a change to the
graph (e.g. roteiro review).
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn nodes_by_provenance(
&self,
provenance: Provenance,
) -> Result<Vec<Node>, StoreError>
pub fn nodes_by_provenance( &self, provenance: Provenance, ) -> Result<Vec<Node>, StoreError>
Every node produced by a given layer, ordered by key. The incremental
sync loads the Derived layer to reconstruct the extraction graph
without re-reading every blob.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn all_nodes(&self) -> Result<Vec<Node>, StoreError>
pub fn all_nodes(&self) -> Result<Vec<Node>, StoreError>
Every node in the store, ordered by key. Unlike Store::export_factset
this decodes no edges, so it is cheap for node-only scans (e.g. search).
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on decode failure.
Sourcepub fn all_edges(&self) -> Result<Vec<Edge>, StoreError>
pub fn all_edges(&self) -> Result<Vec<Edge>, StoreError>
Every edge in the store, with endpoints resolved to their node keys. Used
by Store::reconcile to diff the edge set.
Ordered by the edge’s content — (src key, dst key, kind, provenance),
the table’s unique tuple — not by row id. This makes the order a function
of the graph, not of insertion history, so an incrementally
reconciled store and a cold rebuild
return edges identically. (The same reason node scans order by key.)
§Errors
Returns StoreError::Sqlite or StoreError::Corrupt on failure.
Sourcepub fn edges_from(&self, key: &str) -> Result<Vec<Edge>, StoreError>
pub fn edges_from(&self, key: &str) -> Result<Vec<Edge>, StoreError>
Edges whose source is the node with the given key, in content order
((dst key, kind, provenance) — src is fixed). Content-ordered rather
than by row id so the result is history-independent; see Store::all_edges.
§Errors
Returns StoreError::Sqlite or StoreError::Corrupt on failure.
Sourcepub fn edges_to(&self, key: &str) -> Result<Vec<Edge>, StoreError>
pub fn edges_to(&self, key: &str) -> Result<Vec<Edge>, StoreError>
Edges whose destination is the node with the given key, in content order
((src key, kind, provenance) — dst is fixed). See Store::all_edges.
§Errors
Returns StoreError::Sqlite or StoreError::Corrupt on failure.
Sourcepub fn edges_by_provenance(
&self,
provenance: Provenance,
) -> Result<Vec<Edge>, StoreError>
pub fn edges_by_provenance( &self, provenance: Provenance, ) -> Result<Vec<Edge>, StoreError>
All edges with the given provenance, in content order
((src key, dst key, kind) — provenance is fixed). See Store::all_edges.
§Errors
Returns StoreError::Sqlite or StoreError::Corrupt on failure.
Sourcepub fn delete_edges_by_provenance(
&self,
provenance: Provenance,
) -> Result<u64, StoreError>
pub fn delete_edges_by_provenance( &self, provenance: Provenance, ) -> Result<u64, StoreError>
Delete all edges with the given provenance, returning how many were
removed. Used to re-derive a whole provenance class authoritatively (e.g.
inferred edges when re-running inference with different parameters).
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn delete_edges_by_src_ref(&self, src_ref: &str) -> Result<u64, StoreError>
pub fn delete_edges_by_src_ref(&self, src_ref: &str) -> Result<u64, StoreError>
Delete all edges carrying the given src_ref, returning how many were
removed. Lets one producer of inferred edges (e.g. the embedding layer,
or a Graphify import) re-derive its own edges authoritatively without
touching edges another producer contributed.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn apply_import_layer(
&mut self,
src_ref: &str,
facts: &FactSet,
) -> Result<ImportApplied, StoreError>
pub fn apply_import_layer( &mut self, src_ref: &str, facts: &FactSet, ) -> Result<ImportApplied, StoreError>
Apply an import layer to the live graph and persist it durably under
src_ref, validating as it goes: this ref’s prior edges are cleared
(an authoritative re-import), the layer’s nodes are upserted, and each
edge is applied only if both endpoints resolve. Dangling edges — cross-
references to code that is not present — are dropped, and only the
validated (trimmed) layer is persisted, so stale data is never stored.
This is the “validate on import” half; Store::reapply_imports is the
“validate on sync” half, re-checking layers against the rebuilt graph.
§Errors
Returns StoreError::Json if facts cannot be (de)serialized,
StoreError::InvalidEdge on a malformed edge, or StoreError::Sqlite
on write failure.
Sourcepub fn delete_import(&self, src_ref: &str) -> Result<bool, StoreError>
pub fn delete_import(&self, src_ref: &str) -> Result<bool, StoreError>
Remove the persisted import layer for src_ref, returning whether one
existed. Does not remove edges already in the live graph (use
Store::delete_edges_by_src_ref for that).
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn import_refs(&self) -> Result<Vec<String>, StoreError>
pub fn import_refs(&self) -> Result<Vec<String>, StoreError>
The src_refs of all persisted import layers, ordered.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn reapply_imports(&mut self) -> Result<ImportApplied, StoreError>
pub fn reapply_imports(&mut self) -> Result<ImportApplied, StoreError>
Re-apply every persisted import layer on top of the current graph and re-validate it: all import nodes are upserted first (so cross-layer and self references resolve), then each edge is applied; an edge whose endpoint is now absent — a cross-reference to code a sync removed — is pruned from the persisted layer, not merely skipped. So the durable store keeps only still-correct data. Idempotent; safe to run after each rebuild.
§Errors
Returns StoreError::Json if a stored layer cannot be (de)serialized,
or StoreError::Sqlite on write failure.
Sourcepub fn neighbors(
&self,
key: &str,
dir: Direction,
) -> Result<Vec<Node>, StoreError>
pub fn neighbors( &self, key: &str, dir: Direction, ) -> Result<Vec<Node>, StoreError>
Neighbouring nodes reachable from key in the given direction. Returns
an empty vector if the node does not exist.
§Errors
Returns StoreError::Sqlite, StoreError::Json, or
StoreError::Corrupt on failure.
Sourcepub fn context_cache_get(
&self,
key: &str,
) -> Result<Option<(String, String)>, StoreError>
pub fn context_cache_get( &self, key: &str, ) -> Result<Option<(String, String)>, StoreError>
Fetch the cached context bundle for key as (fingerprint, json), if
present. The caller compares the fingerprint to the node’s current one to
decide whether the entry is fresh (see crate::context).
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn context_cache_fingerprint(
&self,
key: &str,
) -> Result<Option<String>, StoreError>
pub fn context_cache_fingerprint( &self, key: &str, ) -> Result<Option<String>, StoreError>
Fetch just the cached fingerprint for key, without reading the (larger)
JSON payload — for a cheap freshness check.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn context_cache_put(
&self,
key: &str,
fingerprint: &str,
json: &str,
) -> Result<(), StoreError>
pub fn context_cache_put( &self, key: &str, fingerprint: &str, json: &str, ) -> Result<(), StoreError>
Store (or replace) the cached context bundle for key.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn context_cache_delete(&self, key: &str) -> Result<bool, StoreError>
pub fn context_cache_delete(&self, key: &str) -> Result<bool, StoreError>
Delete the cached context entry for key, returning whether one existed.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn context_cache_keys(&self) -> Result<Vec<String>, StoreError>
pub fn context_cache_keys(&self) -> Result<Vec<String>, StoreError>
Every key with a cached context entry, ordered. Used to prune entries for nodes that no longer exist.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn replace_findings_layer(
&mut self,
run: &AnalysisRun,
findings: &[Finding],
) -> Result<FindingsApplied, StoreError>
pub fn replace_findings_layer( &mut self, run: &AnalysisRun, findings: &[Finding], ) -> Result<FindingsApplied, StoreError>
Replace the findings layer run.layer wholesale, atomically: the
previous run for that layer and every finding row it owned are deleted,
then this run and its findings are written. A finding that has since been
fixed therefore disappears instead of lingering, and re-ingesting an
unchanged report is idempotent — the store ends up with the same rows and
no growth.
The owned-record cleanup is explicit rather than inherited. The import
path (Store::apply_import_layer) deletes a layer’s edges but leaves its
obsolete nodes behind; copying that shape here would silently orphan
findings, so the previous run’s rows are deleted by hand and counted in
FindingsApplied::removed. The schema’s ON DELETE CASCADE is kept as
defence in depth, not as the mechanism.
findings must carry distinct FindingKeys: a
duplicate identity is a producer bug and is rejected by the unique index
inside the transaction, so nothing is committed. Callers that parse
untrusted reports should reject duplicates earlier, with a better message.
§Errors
Returns StoreError::Json if the run’s command policy or a finding’s
meta cannot be serialized, or StoreError::Sqlite on write failure. On
any error the transaction is rolled back and the previous layer survives
intact.
Sourcepub fn delete_findings_layer(
&mut self,
layer: &str,
) -> Result<Option<usize>, StoreError>
pub fn delete_findings_layer( &mut self, layer: &str, ) -> Result<Option<usize>, StoreError>
Delete a findings layer and every finding row it owns, returning how many
findings went with it, or None if the layer was not live.
§Errors
Returns StoreError::Sqlite on write failure; nothing is committed on
error.
Sourcepub fn findings_layers(
&self,
analyzer: Option<&str>,
) -> Result<Vec<FindingsLayer>, StoreError>
pub fn findings_layers( &self, analyzer: Option<&str>, ) -> Result<Vec<FindingsLayer>, StoreError>
Every live findings layer with its findings, ordered by layer key and, in
each layer, by finding key. Pass analyzer to narrow to one analyzer.
§Errors
Returns StoreError::Sqlite on query failure, StoreError::Json if a
stored policy or meta cannot be decoded, or StoreError::Corrupt on an
unrecognised stored token.
Sourcepub fn finding_count(&self) -> Result<u64, StoreError>
pub fn finding_count(&self) -> Result<u64, StoreError>
Number of findings currently stored, across every layer.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn analysis_run_count(&self) -> Result<u64, StoreError>
pub fn analysis_run_count(&self) -> Result<u64, StoreError>
Number of live analysis runs — one per findings layer.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn record_media_content(
&mut self,
write: &MediaWrite<'_>,
) -> Result<bool, StoreError>
pub fn record_media_content( &mut self, write: &MediaWrite<'_>, ) -> Result<bool, StoreError>
Write one generated-content record, returning true if a row was written.
Keyed by (blob_id, producer). A record for that exact pair already
present is left alone and false is returned — which is what makes
media build incremental and a second run free. A different producer is
a new row beside it, never an overwrite: that is the point of keying on the
producer identity, so a better model’s description can be compared with the
one it replaces and a distrusted producer can be dropped wholesale.
MediaWrite::replace (only media build --force) is the one path that
overwrites, and only for the identical producer.
§Errors
Returns StoreError::Sqlite on a write failure; the transaction is
rolled back.
Sourcepub fn has_media_record(
&self,
blob_id: &str,
producer: &str,
) -> Result<bool, StoreError>
pub fn has_media_record( &self, blob_id: &str, producer: &str, ) -> Result<bool, StoreError>
Whether a record already exists for exactly this (blob, producer).
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn media_records(
&self,
filter: &MediaFilter<'_>,
) -> Result<Vec<MediaRecord>, StoreError>
pub fn media_records( &self, filter: &MediaFilter<'_>, ) -> Result<Vec<MediaRecord>, StoreError>
Stored records matching filter, ordered by (producer, blob id).
§Errors
Returns StoreError::Sqlite on query failure, or
StoreError::Corrupt if a row carries an unknown modality token.
Sourcepub fn clear_media_content(
&mut self,
producer: Option<&str>,
) -> Result<usize, StoreError>
pub fn clear_media_content( &mut self, producer: Option<&str>, ) -> Result<usize, StoreError>
Discard records — all of them, or only those written by producer.
Returns how many rows went.
Nothing in the graph is touched: dropping a model you no longer trust must not cost you a re-sync.
§Errors
Returns StoreError::Sqlite on a write failure.
Sourcepub fn media_content_count(&self) -> Result<u64, StoreError>
pub fn media_content_count(&self) -> Result<u64, StoreError>
Number of generated-content records currently stored.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn media_producer_summaries(
&self,
) -> Result<Vec<ProducerSummary>, StoreError>
pub fn media_producer_summaries( &self, ) -> Result<Vec<ProducerSummary>, StoreError>
One summary per producer that owns records, ordered by producer id.
§Errors
Returns StoreError::Sqlite on query failure, or
StoreError::Corrupt if a row carries an unknown modality token.
Sourcepub fn described_media_blobs(
&self,
kind: MediaKind,
) -> Result<BTreeSet<String>, StoreError>
pub fn described_media_blobs( &self, kind: MediaKind, ) -> Result<BTreeSet<String>, StoreError>
The blob ids that have at least one record carrying generated text
for kind. A blob the pre-generation gate refused is not described, so it
is not here — see Store::gated_media_blobs.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn gated_media_blobs(
&self,
kind: MediaKind,
) -> Result<BTreeSet<String>, StoreError>
pub fn gated_media_blobs( &self, kind: MediaKind, ) -> Result<BTreeSet<String>, StoreError>
The blob ids the pre-generation gate refused for
kind — silent clips, blank images — each of which has a record naming
the value that refused it.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn orphan_media_records(
&self,
present: &BTreeSet<String>,
) -> Result<Vec<MediaRecord>, StoreError>
pub fn orphan_media_records( &self, present: &BTreeSet<String>, ) -> Result<Vec<MediaRecord>, StoreError>
Records whose blob is no longer anywhere in present. Exposed so a caller
can see what a tree change has orphaned; nothing deletes them implicitly,
because a record is expensive to reproduce and a blob can return.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn record_memory(
&mut self,
write: &MemoryWrite<'_>,
) -> Result<i64, MemoryError>
pub fn record_memory( &mut self, write: &MemoryWrite<'_>, ) -> Result<i64, MemoryError>
Record one memory, returning its id — the monotonic generation it was written at.
The anchor’s blob and path, and the sync_state tree witness, are
captured here, from the graph, so a caller cannot record evidence the
node never carried. An anchor key naming no node is accepted and reads
back as crate::AnchorState::Vanished.
MemoryWrite::supersedes records the supersession explicitly, in the
same transaction as the successor: either both land or neither does.
§Errors
Returns MemoryError::InvalidScope / MemoryError::InvalidBody /
MemoryError::InvalidConfidence for a record that could not be recalled,
MemoryError::NotFound or MemoryError::AlreadySuperseded for a bad
supersession target, or MemoryError::Store on a write failure — in
every case with nothing committed.
Sourcepub fn memory_records(
&self,
filter: &MemoryFilter<'_>,
) -> Result<Vec<MemoryRecord>, StoreError>
pub fn memory_records( &self, filter: &MemoryFilter<'_>, ) -> Result<Vec<MemoryRecord>, StoreError>
Memory records matching filter, newest generation first.
Live records only unless MemoryFilter::include_superseded is set: a
superseded record drops out immediately and regardless of age, because the
test is a recorded pointer and not a clock.
Each record’s crate::AnchorState is computed against the current
graph on every call and is never stored.
§Errors
Returns StoreError::Sqlite on query failure, or StoreError::Corrupt
if a row carries an unknown kind token.
Sourcepub fn memory_record(&self, id: i64) -> Result<Option<MemoryRecord>, StoreError>
pub fn memory_record(&self, id: i64) -> Result<Option<MemoryRecord>, StoreError>
One memory record by id, or None if there is no such record.
§Errors
Returns StoreError::Sqlite on query failure, or StoreError::Corrupt
if the row carries an unknown kind token.
Sourcepub fn memory_listing(
&self,
filter: &MemoryFilter<'_>,
) -> Result<MemoryListing, StoreError>
pub fn memory_listing( &self, filter: &MemoryFilter<'_>, ) -> Result<MemoryListing, StoreError>
A MemoryListing: the records matching filter, plus the whole store’s
live and superseded counts, so an empty result is legible as nothing
matched rather than nothing is stored.
§Errors
Returns StoreError::Sqlite on query failure, or StoreError::Corrupt
if a row carries an unknown kind token.
Sourcepub fn forget_memory(
&mut self,
id: i64,
) -> Result<Option<MemoryForgotten>, StoreError>
pub fn forget_memory( &mut self, id: i64, ) -> Result<Option<MemoryForgotten>, StoreError>
The only way a memory record is ever removed. Deletes it, and returns
None if there was no such record.
Episodic memory is unbounded and never auto-evicted — no sweep, no TTL, no capacity bound reaches this table — so an explicit call is the whole reclamation story. It is also the privacy story: memory has no redaction chokepoint, so a record that captured a token or a customer name is removed by asking.
Anything the deleted record had superseded becomes live again and is
named in MemoryForgotten::restored: leaving it superseded would hide it
on the authority of a record that no longer exists.
§Errors
Returns StoreError::Sqlite on a write failure; the transaction is
rolled back.
Sourcepub fn memory_counts(&self) -> Result<(u64, u64), StoreError>
pub fn memory_counts(&self) -> Result<(u64, u64), StoreError>
How many memory records are stored, as (live, superseded).
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn recall_memory(
&self,
opts: &RecallOptions<'_>,
) -> Result<Recall, StoreError>
pub fn recall_memory( &self, opts: &RecallOptions<'_>, ) -> Result<Recall, StoreError>
Ranked recall: the live records that match opts, scored
base_confidence × anchor_penalty × decay(age) and ordered best first.
Every term is computed here, at retrieval time, and written to no column (ADR-0013). A stored score that decayed would rewrite the store on every read and would be wrong in between, making recall depend on when you last looked. Three consequences follow, and each is a promise:
- This call mutates nothing. Recall over an unchanged store and an
unchanged tree is idempotent, which is what makes
crate::Decay::Nonebyte-identical across runs. - A superseded record is never returned, immediately and regardless of age: the test is a recorded pointer, not a clock.
- A record whose anchor no longer resolves is still returned, demoted and labelled. Drift ranks it down; nothing deletes it.
§Errors
Returns StoreError::Sqlite on query failure, or StoreError::Corrupt
if a row carries an unknown kind token.
Sourcepub fn agent_cache_put(&self, write: &CacheWrite<'_>) -> Result<(), StoreError>
pub fn agent_cache_put(&self, write: &CacheWrite<'_>) -> Result<(), StoreError>
Write (or replace) one cache entry.
The payload size is computed here and the anchor’s blob is captured from the graph here, so the sweep can order and total the tier without reading it, and a caller cannot record evidence a node never carried.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn agent_cache_get(
&self,
key: &str,
) -> Result<Option<CacheEntry>, StoreError>
pub fn agent_cache_get( &self, key: &str, ) -> Result<Option<CacheEntry>, StoreError>
Read one cache entry back, recording the access — hits increments and
last_used advances.
This is the one read in the memory store that writes, and what it writes is
the cache’s own bookkeeping: those two columns exist to be moved by exactly
this, and a hit counter nothing increments is a column that lies. It
touches nothing outside agent_cache, so Store::recall_memory — the
read whose reproducibility is promised — stays free of it.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn agent_cache_entries(&self) -> Result<Vec<CacheEntry>, StoreError>
pub fn agent_cache_entries(&self) -> Result<Vec<CacheEntry>, StoreError>
Every cache entry, ordered by key, without recording an access: inspecting a cache is not using it.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn agent_cache_forget(&self, key: &str) -> Result<bool, StoreError>
pub fn agent_cache_forget(&self, key: &str) -> Result<bool, StoreError>
Delete one cache entry, returning whether there was one.
§Errors
Returns StoreError::Sqlite on write failure.
Sourcepub fn agent_cache_stats(
&self,
budget_bytes: u64,
) -> Result<CacheStats, StoreError>
pub fn agent_cache_stats( &self, budget_bytes: u64, ) -> Result<CacheStats, StoreError>
What the cache tier holds, against budget_bytes.
§Errors
Returns StoreError::Sqlite on query failure.
Sourcepub fn sweep_agent_cache(
&mut self,
budget_bytes: u64,
) -> Result<CacheSweep, StoreError>
pub fn sweep_agent_cache( &mut self, budget_bytes: u64, ) -> Result<CacheSweep, StoreError>
Sweep the cache tier down to budget_bytes, evicting oldest-first on
(anchor_valid ASC, last_used ASC), and advance the generation.
Called at the maintenance seam (beside refresh_contexts) and never on
the read path, so an ordinary query never mutates the store. Three things
are never evicted: anything episodic — structurally, there is no column to
grip it by; an entry written in the current generation whose anchor still
applies, which is the session’s own work; and the most-recently-used entry,
always, even if it alone exceeds the budget.
That last pair means a sweep can legitimately finish still over budget.
CacheSweep::over_budget reports it rather than leaving a bound that
silently failed to bind.
§Errors
Returns StoreError::Sqlite on failure; the transaction is rolled back.
Sourcepub fn orphan_finding_count(&self) -> Result<u64, StoreError>
pub fn orphan_finding_count(&self) -> Result<u64, StoreError>
Findings whose owning run no longer exists. Always 0 in a healthy store;
exposed so layer replacement can be asserted to clean up its own records
rather than orphaning them.
§Errors
Returns StoreError::Sqlite on query failure.