Skip to main content

App

Struct App 

Source
pub struct App { /* private fields */ }
Expand description

An open Memnite instance: the event log + its SQLite projection.

Implementations§

Source§

impl App

Source

pub fn open(data_dir: impl AsRef<Path>) -> Result<Self, CliError>

Open (creating if needed) a Memnite data dir: <dir>/log/ + <dir>/memnite.db.

Source

pub fn add( &self, spec: AddSpec, root: &Path, ctx: &EventCtx, ) -> Result<MemoryRow, CliError>

Create a memory: stamp anchor hashes from root, append a MemoryAdded event to the log, and project it. Returns the projected MemoryRow.

Source

pub fn session_summary( &self, summary: String, project: String, scope: Scope, ctx: &EventCtx, ) -> Result<MemoryRow, CliError>

Persist a session summary as a memory (mem_type = "session_summary"). Model-driven: the caller passes the distilled text. Plain add — summaries accumulate as history (no topic_key upsert).

Source

pub fn get(&self, memory_id: &str) -> Result<Option<MemoryRow>, CliError>

Fetch one memory by id.

Source

pub fn rebuild(&self) -> Result<usize, CliError>

Rebuild the projection from the full log. Returns the event count folded.

Source

pub fn search( &self, query: impl Into<SearchQuery>, ) -> Result<Vec<MemoryRow>, CliError>

Full-text search over memories, narrowed by optional filters. User text is sanitized into FTS5 syntax; a blank query returns no results. Accepts anything convertible into SearchQuery (e.g. a plain &str).

Source

pub fn list_stale(&self) -> Result<Vec<MemoryRow>, CliError>

All memories currently marked stale.

Source

pub fn delete(&self, memory_id: &str, ctx: &EventCtx) -> Result<(), CliError>

Tombstone a memory (append a MemoryDeleted event). Errors if the id is unknown. Re-deleting an already-deleted memory is a no-op (delete is terminal in the fold), so no duplicate event is appended.

Source

pub fn mark(&self, memory_id: &str, ctx: &EventCtx) -> Result<(), CliError>

Mark a memory as reviewed: append a MemoryReviewed event, resetting its decay clock (updated_ts) without changing its status. Errors NotFound if the id is unknown or already deleted (a tombstone cannot be reviewed).

Source

pub fn review_list( &self, now: &str, project: Option<&str>, mem_type: Option<&str>, ) -> Result<Vec<MemoryRow>, CliError>

Live memories whose decay verdict (given now, an RFC3339 timestamp) is NeedsReview, optionally narrowed by exact project / mem_type. Read-time only — nothing is written and the log is untouched.

Source

pub fn relate( &self, from_id: &str, to_id: &str, spec: RelationSpec, ctx: &EventCtx, ) -> Result<(), CliError>

Assert a relation from_id → to_id. Appends a RelationAsserted event and projects it. Both memories must exist, be live (not deleted), and differ. spec.judged_by records who classified it (“agent” for interactive/manual, an engine name for the judge).

Source

pub fn relations_for( &self, memory_id: &str, ) -> Result<Vec<RelationRow>, CliError>

Relation edges touching a memory (as source or target).

Source

pub fn list_relations(&self) -> Result<Vec<RelationRow>, CliError>

Every relation edge.

Source

pub fn find_candidates( &self, memory_id: &str, limit: u32, ) -> Result<Vec<MemoryRow>, CliError>

Candidate memories worth relating to memory_id: FTS over its title within the same project + scope, excluding self / deleted / already-related pairs. Uses OR-match (broad recall). Returns up to limit rows. Callers treat a failure as “no candidates” (non-blocking) at the surface layer.

Source

pub fn conflicts_scan( &self, judge: impl Fn(&MemoryView, &MemoryView) -> Result<Verdict, JudgeError>, judged_by: &str, since: Option<String>, limit: u32, ctx: &EventCtx, ) -> Result<ScanSummary, CliError>

Batch scan: for each live memory, find candidates and ask the injected judge to classify each pair. Non-not_conflict verdicts are asserted as RelationAsserted events stamped with judged_by (provenance is the caller’s, never a hardcoded literal — keeps the audit trail honest under a swapped judge). Judge errors are swallowed per pair (never abort); the first one is sampled into ScanSummary::first_error.

since limits the scan to memories updated at/after it. It must be the same RFC3339 form as the stored updated_ts — the comparison is lexical, so a differently-formatted timestamp will filter incorrectly.

Source

pub fn check( &self, root: &Path, ctx: &EventCtx, ) -> Result<CheckSummary, CliError>

Run the staleness checker over every anchored, non-deleted memory. When a memory’s verdict changes its status, append the verdict event and project it. Memories without anchors (nothing to verify) are skipped.

Source

pub fn context( &self, project: &str, limit: u32, ) -> Result<Vec<MemoryRow>, CliError>

Recent memories for a project (newest-updated first, deleted excluded).

Source

pub fn timeline(&self, memory_id: &str) -> Result<Vec<EventMetaRow>, CliError>

Event history of one memory, oldest first.

Source

pub fn doctor(&self) -> Result<DoctorReport, CliError>

Compare the log fold against the projection and report divergences. A clean projection (after any normal op, since each op projects incrementally) returns zero mismatches and cursor_ok == true.

Source

pub fn update( &self, memory_id: &str, patch: UpdatePatch, root: &Path, ctx: &EventCtx, ) -> Result<MemoryRow, CliError>

Update a memory by patch: emits a sparse MemoryPatched delta containing only the fields patch provides — untouched fields are left None and carry no value over the wire, enabling field-level LWW merge downstream (see memnite_core::replay). The LOG FOLD (not the projection) is only consulted to validate the memory exists and is not deleted; it is not used to fill in omitted fields. Anchors in the patch are re-hashed from root; omitted anchors are left untouched. Errors if the id is unknown. Returns the new projected row.

Source

pub fn import(&self, reader: impl BufRead) -> Result<ImportSummary, CliError>

Import an NDJSON event bundle: append only events whose event_id is not already in the local log (dedup), then rebuild the projection from the full log. Rebuild — not incremental apply — because imported events may carry a lamport below the local max and must be re-folded in (lamport, event_id) order. Corrupt lines are skipped and counted.

Source

pub fn export( &self, since: Option<u64>, writer: impl Write, ) -> Result<usize, CliError>

Write the event log as an NDJSON bundle (one event per line), sorted by (lamport, event_id) for deterministic, diff-friendly bundles. With since, only events whose lamport >= since are written. Returns the number of events written.

Source

pub fn ingest( &self, source: &dyn IngestSource, root: &Path, project: &str, ctx: &EventCtx, ) -> Result<IngestSummary, CliError>

Ingest memories from any IngestSource (source-agnostic). Each item gets a deterministic memory_id (mem_ing_<source>_<key-slug>); a new id is added, a changed one (by projected title/body/type/topic) is updated, an unchanged one is skipped. Idempotent.

Auto Trait Implementations§

§

impl !Freeze for App

§

impl !RefUnwindSafe for App

§

impl !Sync for App

§

impl !UnwindSafe for App

§

impl Send for App

§

impl Unpin for App

§

impl UnsafeUnpin for App

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V