pub trait MemorySync: Send + Sync {
// Required methods
fn append_knowledge<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
body: &'life2 str,
kind: NoteKind,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn pull_knowledge<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<SyncedFact>, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
}Expand description
A sink that mirrors remembered facts into CAR’s synced oplog
(Surface::Knowledge) so the assistant’s memory can converge across a user’s
devices. Supplied ONLY in the daemon-attached car do --serve process, which
reaches the daemon’s single oplog owner over WS; None for one-shot car do,
so the standalone CLI never becomes a second writer to the lock-guarded oplog.
The write is best-effort: a sync failure must never fail the local remember.
Required Methods§
Sourcefn append_knowledge<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
body: &'life2 str,
kind: NoteKind,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn append_knowledge<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
subject: &'life1 str,
body: &'life2 str,
kind: NoteKind,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Append a remembered fact to the knowledge oplog. The fact is
content-addressed by its {subject, body, kind} payload (no explicit id),
so on the grow-only Knowledge tier each distinct value is its own
immutable entity: an edit is a NEW op (both survive the fold), and an
identical re-remember dedups. The read side (Self::pull_knowledge)
converges a subject to its newest-by-HLC body. subject is normalized
(trimmed) to match the local store’s entity boundary.
kind is part of the content address, and that is a deliberate
migration decision (car#665). Adding it changes the address of a fact
that was already synced under the old {subject, body} payload, so such
a fact re-remembered after the upgrade folds as a second entity rather
than deduping against the first. That is harmless here because
Self::pull_knowledge reduces newest-per-subject before anything sees
the facts: both entities share a subject, the kinded one carries the
later HLC, and the reduce keeps it. So the duplicate never reaches a
reader — it only costs one extra op on a tier that is grow-only by
design (an edit already appends). The alternative — inferring a kind on
the receiving side from a locally-known preference with the same subject
— would leave the wire lossy and only work when the same rule had been
set on both devices, which is exactly the case that needs no fixing.
Sourcefn pull_knowledge<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<SyncedFact>, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn pull_knowledge<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<SyncedFact>, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Pull peer-synced knowledge facts — the read side — already reduced to
newest-per-subject. Best-effort: an Err means “no peer facts available
right now”, never a failure; recall degrades to local memory. The impl
pumps the oplog then reads the folded Knowledge facts, reducing
newest-per-subject by LAST-in-ascending-hlc order.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".