kiromi-ai-memory 0.2.2

Local-first multi-tenant memory store engine: Markdown/text content on object storage, metadata in SQLite, plugin-shaped embedder/storage/metadata, hybrid text+vector search.
Documentation
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Live observer stream. Sibling to the audit log: the audit log is the
//! historical record (queryable via SQL); this is the push side
//! (subscribe via `Memory::subscribe`).
//!
//! Cheap to add (an empty subscriber list is free) and unlocks replication,
//! live UI, external indexers, and webhooks in future slices without engine
//! changes.
//!
//! Events are emitted **after** the SQL transaction commits. Slow subscribers
//! do not slow appends — the broadcast channel is lossy: lagged subscribers
//! receive `RecvError::Lagged(n)` and continue.
//!
//! See spec § 18.5.

use crate::memory::MemoryId;
use crate::partition::PartitionPath;
use crate::summarizer::SummaryStyle;
use crate::summary::{SummaryId, SummarySubject};

/// One push-side event.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum MemoryEvent {
    /// `Memory::append` succeeded and the SQL transaction committed.
    Appended {
        /// Memory id.
        id: MemoryId,
        /// Partition the memory was written to.
        partition: PartitionPath,
        /// Server-clock timestamp (unix millis).
        ts_ms: i64,
    },
    /// `Memory::delete` succeeded.
    Deleted {
        /// Memory id soft-deleted.
        id: MemoryId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::delete_partition` succeeded.
    PartitionDeleted {
        /// Partition path under which all live memories were tombstoned.
        partition: PartitionPath,
        /// How many rows the call tombstoned.
        count: u64,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::add_link` succeeded.
    LinkAdded {
        /// Source memory.
        src: MemoryId,
        /// Destination memory.
        dst: MemoryId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::remove_link` succeeded.
    LinkRemoved {
        /// Source memory.
        src: MemoryId,
        /// Destination memory.
        dst: MemoryId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::attach_summary` succeeded — Plan 9 first-class summary.
    SummaryAttached {
        /// Summary id.
        id: SummaryId,
        /// What the summary attaches to.
        subject: SummarySubject,
        /// Style preset.
        style: SummaryStyle,
        /// 1-indexed version.
        version: u32,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::delete_summary` succeeded — Plan 9 summary tombstoned.
    SummaryDeleted {
        /// Summary id.
        id: SummaryId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// A subject's `summary_stale` flag flipped on. Emitted by `Memory::append`,
    /// `Memory::delete`, `Memory::delete_partition`, and
    /// `Memory::mark_partition_stale`.
    SummaryNeeded {
        /// Subject whose summary is now stale.
        subject: SummarySubject,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::snapshot` succeeded — Plan 12 point-in-time freeze.
    SnapshotTaken {
        /// Snapshot id.
        id: crate::snapshot::SnapshotId,
        /// `audit_log.seq` at snapshot time.
        seq: i64,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::regenerate_embeddings` succeeded — Plan 12 atomic shard
    /// swap. Reserved for Phase E; the variant is added now so consumers
    /// can match on it without breakage when the implementation lands.
    EmbeddingsRegenerated {
        /// Number of memories re-embedded.
        count: u64,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::restore` succeeded — Plan 12 hard rollback to a snapshot.
    Restored {
        /// Snapshot the live set was rolled back to.
        snapshot_id: crate::snapshot::SnapshotId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// `Memory::migrate_scheme` succeeded — Plan 12 partition scheme
    /// evolution; memory blobs were moved + indices rebuilt.
    SchemeMigrated {
        /// Memories whose `partition_path` changed.
        memories_moved: u64,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// Plan 15: `Memory::set_validity` succeeded — bi-temporal validity
    /// columns updated.
    ValidityUpdated {
        /// Memory id whose validity range moved.
        id: MemoryId,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
    /// Plan 16: `Memory::evolve` succeeded — atomic batch update was
    /// committed.
    Evolved {
        /// Memory whose arrival triggered the evolution (if any).
        trigger: Option<MemoryId>,
        /// How many ops applied.
        applied: u64,
        /// New audit-log seq.
        audit_seq: i64,
        /// Server-clock timestamp.
        ts_ms: i64,
    },
}

/// Default capacity for the per-`Memory` broadcast channel.
pub const DEFAULT_EVENT_CAPACITY: usize = 1024;