heyq02/moomem/src does not have a README file

    Clock

    pub(open) trait Clock {
    fn now_ms(self : Self) -> Int64
    }

    时钟抽象。缺省 LogicalClock;测试可注入 FixedClock 精确断言 created_at。

    ConflictJudge

    pub(open) trait ConflictJudge {
    fn judge(self : Self, new_fact : ExtractedFact, candidates : Array[MemoryEntry]) -> Result[Array[ConflictVerdict], MoomemError]
    }

    冲突判定抽象。仅对判定为 Replace / Coexist 的候选返回裁决。

    Embedder

    pub(open) trait Embedder {
    fn embed(self : Self, texts : Array[String]) -> Result[Array[Array[Double]], MoomemError]
    fn dim(self : Self) -> Int
    }

    嵌入服务抽象。生产环境可注入 vcdb 等适配实现。

    Extractor

    pub(open) trait Extractor {
    fn extract(self : Self, user_id : String, text : String) -> Result[Array[ExtractedFact], MoomemError]
    fn mode(self : Self) -> String
    }

    事实提取抽象。结构化提取由宿主实现并注入。

    PersistenceBackend

    pub(open) trait PersistenceBackend {
    fn load(self : Self) -> Result[String?, MoomemError]
    fn save(self : Self, snapshot : String) -> Result[Unit, MoomemError]
    }

    持久化后端抽象。load 返回 None 表示空库(首次打开)。

    MoomemError

    pub(all) suberror MoomemError {
    InvalidUserId(String)
    StoreCorrupted(String)
    IoFailure(String)
    ExtractionFailure(String)
    EmbeddingFailure(String)
    BackendUnsupported(String)
    InvalidOperation(String)
    }

    moomem 全库唯一错误类型。 声明为 suberror:内部实现可用 raise 风格传播,公开 API 统一 Result[T, MoomemError]。
    impl Show for MoomemError

    MoomemError::kind

    fn MoomemError::kind(self : MoomemError) -> String

    错误类别短名(供 metadata / 日志使用)

    MoomemError::message

    fn MoomemError::message(self : MoomemError) -> String

    人类可读的错误消息(含上下文),供宿主程序展示。

    MoomemError::output

    fn MoomemError::output(self : MoomemError, logger : &Logger) -> Unit

    MoomemError::to_string

    fn MoomemError::to_string(self : MoomemError) -> String

    AddSummary

    pub struct AddSummary {
    extracted : Int
    inserted : Int
    duplicates : Int
    superseded : Int
    degraded : Bool
    notes : Array[String]
    }

    add 的返回摘要:提取条数、入库条数、重复、覆盖与降级。
    impl Show for AddSummary

    AddSummary::output

    fn AddSummary::output(self : AddSummary, logger : &Logger) -> Unit

    AddSummary::to_string

    fn AddSummary::to_string(self : AddSummary) -> String

    Config

    pub(all) struct Config {
    embedder : &Embedder?
    extractor : &Extractor?
    judge : &ConflictJudge?
    persistence : &PersistenceBackend?
    clock : &Clock?
    dim : Int
    rrf_k : Int
    recall_candidates : Int
    supersede_threshold : Double
    conflict_candidates : Int
    coexist_band : Double
    backfill : RecallBackfill
    fusion_policy : FusionPolicy
    lexical_floor : Double
    lexical_gap : Double
    vector_weight_when_lexical : Double
    vector_weight_when_semantic : Double
    }

    打开 MemoryStore 的配置。所有注入点均为 Option,None 时使用缺省确定性实现。

    Config::default

    fn Config::default() -> Config

    缺省配置(全部注入点走确定性缺省实现)。

    ConflictDecision

    pub(all) enum ConflictDecision {
    Replace
    Coexist
    Ignore
    } derive(Eq)

    冲突裁决:Replace 触发 supersede;Coexist 并存并标记;Ignore 无裁决。

    ConflictDecision::equal

    ConflictDecision::not_equal

    fn ConflictDecision::not_equal(x : ConflictDecision, y : ConflictDecision) -> Bool

    ConflictDecision::output

    fn ConflictDecision::output(self : ConflictDecision, logger : &Logger) -> Unit

    ConflictDecision::to_string

    fn ConflictDecision::to_string(self : ConflictDecision) -> String

    ConflictVerdict

    pub(all) struct ConflictVerdict {
    existing : MemoryEntry
    decision : ConflictDecision
    }

    单个候选条目的裁决。

    DedupIndex

    type DedupIndex

    按 user 分片的内容指纹索引:user → fingerprint → entry_id。 只登记当前可检索(Active / Unstructured)的条目; supersede / forget 时同步摘除。 Package-private (abstract): host API is MemoryStore only.

    EntryKind

    pub(all) enum EntryKind {
    Fact
    Preference
    Event
    Unstructured
    } derive(Eq)

    条目语义类型(由 Extractor 产出)。
    impl Show for EntryKind

    EntryKind::equal

    fn EntryKind::equal(EntryKind, EntryKind) -> Bool

    EntryKind::not_equal

    fn EntryKind::not_equal(x : EntryKind, y : EntryKind) -> Bool

    EntryKind::output

    fn EntryKind::output(self : EntryKind, logger : &Logger) -> Unit

    EntryKind::to_string

    fn EntryKind::to_string(self : EntryKind) -> String

    EntryStatus

    pub(all) enum EntryStatus {
    Active
    Superseded
    Deleted
    Unstructured
    } derive(Eq)

    条目生命周期状态。 Active / Unstructured 参与检索;Superseded / Deleted 保留于快照可审计但不可检索。
    impl Show for EntryStatus

    EntryStatus::equal

    fn EntryStatus::equal(EntryStatus, EntryStatus) -> Bool

    EntryStatus::not_equal

    fn EntryStatus::not_equal(x : EntryStatus, y : EntryStatus) -> Bool

    EntryStatus::output

    fn EntryStatus::output(self : EntryStatus, logger : &Logger) -> Unit

    EntryStatus::to_string

    fn EntryStatus::to_string(self : EntryStatus) -> String

    ExtractedFact

    pub(all) struct ExtractedFact {
    content : String
    kind : EntryKind
    source_span : String?
    degraded : Bool
    degrade_reason : String?
    }

    提取器产出的一条结构化事实。

    ExtractedFact::output

    fn ExtractedFact::output(self : ExtractedFact, logger : &Logger) -> Unit

    ExtractedFact::to_string

    fn ExtractedFact::to_string(self : ExtractedFact) -> String

    FixedClock

    pub struct FixedClock {
    value : Int64
    }

    固定时钟(测试用):now_ms 恒返回初始值。
    impl Clock for FixedClock

    FixedClock::new

    fn FixedClock::new(value : Int64) -> FixedClock

    FixedClock::now_ms

    fn FixedClock::now_ms(self : FixedClock) -> Int64

    ForgetTarget

    pub(all) enum ForgetTarget {
    ById(String)
    All
    }

    forget 的目标选择:按 id 或清空该 user 全部可检索条目。

    ForgetTarget::output

    fn ForgetTarget::output(self : ForgetTarget, logger : &Logger) -> Unit

    ForgetTarget::to_string

    fn ForgetTarget::to_string(self : ForgetTarget) -> String

    FsBackend

    pub struct FsBackend {
    base_dir : String
    slot : Int
    }

    磁盘后端。目录布局: /moomem/slot{0,1}.jsonl + /moomem/head

    FsBackend::load

    fn FsBackend::load(self : FsBackend) -> Result[String?, MoomemError]

    FsBackend::new

    fn FsBackend::new(path : String) -> FsBackend

    FsBackend::save

    fn FsBackend::save(self : FsBackend, snapshot : String) -> Result[Unit, MoomemError]

    FusionPolicy

    pub(all) enum FusionPolicy {
    EqualRrf
    AdaptiveLexical
    }

    混合检索融合策略。

    FusionPolicy::output

    fn FusionPolicy::output(self : FusionPolicy, logger : &Logger) -> Unit

    FusionPolicy::to_string

    fn FusionPolicy::to_string(self : FusionPolicy) -> String

    HashingEmbedder

    pub struct HashingEmbedder {
    dim : Int
    }

    缺省嵌入器:小写化 → 分词(与 BM25 同一分词器 tokenize)→ 每 token FNV-1a 哈希到 [0, dim) 桶 → 桶内 TF 累加 → L2 归一。 确定性、离线,三后端行为一致。

    HashingEmbedder::dim

    fn HashingEmbedder::dim(self : HashingEmbedder) -> Int

    HashingEmbedder::embed

    fn HashingEmbedder::embed(self : HashingEmbedder, texts : Array[String]) -> Result[Array[Array[Double]], MoomemError]

    HashingEmbedder::new

    fn HashingEmbedder::new(dim : Int) -> Result[HashingEmbedder, MoomemError]

    构造 HashingEmbedder;dim 必须 > 0,否则返回 Err。

    KeywordIndex

    type KeywordIndex

    BM25 索引:按 user 物理分片,维护每 user 的 df 与总词长。 Package-private (abstract): host API is MemoryStore only.

    LogicalClock

    pub struct LogicalClock {
    current : Int64
    }

    逻辑时钟:每次调用单调 +1ms。open 时从快照 header.clock 续接, 测试确定性,生产可注入系统时钟。

    LogicalClock::new

    fn LogicalClock::new(start? : Int64) -> LogicalClock

    LogicalClock::now_ms

    fn LogicalClock::now_ms(self : LogicalClock) -> Int64

    MemoryBackend

    pub struct MemoryBackend {
    snapshot : String?
    simulate_partial_write : Int?
    fail_next_save : Bool
    bytes_written : Int64
    }

    进程内后端。保存完整快照字符串;支持模拟崩溃(半写 / 写失败)。

    MemoryBackend::load

    fn MemoryBackend::load(self : MemoryBackend) -> Result[String?, MoomemError]

    MemoryBackend::new

    MemoryBackend::save

    fn MemoryBackend::save(self : MemoryBackend, snapshot : String) -> Result[Unit, MoomemError]

    MemoryEntry

    pub(all) struct MemoryEntry {
    id : String
    user_id : String
    content : String
    kind : EntryKind
    embedding : Array[Double]
    keywords : Array[String]
    status : EntryStatus
    created_at : Int64
    superseded_by : String?
    seq : Int
    metadata : Map[String, Json]
    }

    最小记忆单元:一条可复用事实。
    impl Show for MemoryEntry

    MemoryEntry::is_recallable

    fn MemoryEntry::is_recallable(self : MemoryEntry) -> Bool

    条目是否可被 recall 返回(Active 与 Unstructured;Superseded/Deleted 不可见)。

    MemoryEntry::output

    fn MemoryEntry::output(self : MemoryEntry, logger : &Logger) -> Unit

    MemoryEntry::to_string

    fn MemoryEntry::to_string(self : MemoryEntry) -> String

    MemoryStore

    pub struct MemoryStore {
    path : String
    embedder : &Embedder
    extractor : &Extractor
    judge : &ConflictJudge
    persistence : &PersistenceBackend
    clock : &Clock
    dim : Int
    rrf_k : Int
    recall_candidates : Int
    supersede_threshold : Double
    conflict_candidates : Int
    coexist_band : Double
    backfill : RecallBackfill
    fusion_policy : FusionPolicy
    lexical_floor : Double
    lexical_gap : Double
    vector_weight_when_lexical : Double
    vector_weight_when_semantic : Double
    entries : Map[String, MemoryEntry]
    by_user : Map[String, Array[String]]
    clock_high : Int64
    next_seq : Int
    gen : Int
    truncated_recovered : Int
    extraction_failures : Int
    last_write_at : Int64
    ever_flushed : Bool
    snapshot_bytes : Int64
    closed : Bool
    // private fields
    }

    记忆库聚合根:索引、条目表常驻内存;持久化仅负责快照落盘(单写者模型)。

    MemoryStore::add

    fn MemoryStore::add(self : MemoryStore, user_id : String, text : String) -> Result[AddSummary, MoomemError]

    写入记忆:校验 → 提取 → 去重 → 冲突 → 嵌入 → 双索引 → supersede → 落盘。

    MemoryStore::close

    fn MemoryStore::close(self : MemoryStore) -> Result[Unit, MoomemError]

    安全关闭:flush 后拒绝一切后续操作。重复 close 为幂等 Ok。

    MemoryStore::export_jsonl

    fn MemoryStore::export_jsonl(self : MemoryStore) -> Result[String, MoomemError]

    全量导出为 JSONL 文本:每行一条 entry 的 JSON,含全部状态(可审计)。 按 seq 升序;不包含快照 header。

    MemoryStore::forget

    fn MemoryStore::forget(self : MemoryStore, user_id : String, target : ForgetTarget) -> Result[Int, MoomemError]

    软删除:状态置 Deleted,索引摘除,快照保留标记。 ById 返回 1/0(目标不存在或不可检索时报 InvalidOperation / 0); All 删除该 user 全部可检索条目并返回条数。

    MemoryStore::import_jsonl

    fn MemoryStore::import_jsonl(self : MemoryStore, jsonl : String) -> Result[(Int, Int), MoomemError]

    从 JSONL 文本导入。导出再导入后,可召回内容等价。 跳过 id 已存在或同 user 内容指纹重复的条目;返回 (导入数, 跳过数)。 恢复条目的状态、双索引与计数器均按导出时语义重建。

    MemoryStore::list_entries

    fn MemoryStore::list_entries(self : MemoryStore, user_id : String) -> Result[Array[MemoryEntry], MoomemError]

    枚举某 user 的全部条目(含 Superseded / Deleted,供审计)。

    MemoryStore::open

    fn MemoryStore::open(path : String, config? : Config) -> Result[MemoryStore, MoomemError]

    打开或创建记忆库。 目录不存在则创建;存在则加载快照并重建索引与计数器。

    MemoryStore::recall

    fn MemoryStore::recall(self : MemoryStore, user_id : String, query : String, top_k? : Int) -> Result[Array[MemoryEntry], MoomemError]

    混合检索:向量 + BM25 双路 → RRF 融合 → 只返回 Active/Unstructured。 嵌入失败时仅 BM25 单路。无结果返回空列表(不编造)。

    MemoryStore::stats

    fn MemoryStore::stats(self : MemoryStore) -> Result[StoreStats, MoomemError]

    运行统计:各状态条目数、快照字节数(逻辑值)、最近写入、恢复截断计数。

    RawExtractor

    pub struct RawExtractor {
    }

    缺省提取器:原文直通(kind=Unstructured)。 空白文本返回 0 条事实,不入库。

    RawExtractor::extract

    fn RawExtractor::extract(_ : RawExtractor, _ : String, text : String) -> Result[Array[ExtractedFact], MoomemError]

    RawExtractor::mode

    fn RawExtractor::mode(_ : RawExtractor) -> String

    RawExtractor::new

    RecallBackfill

    pub(all) enum RecallBackfill {
    NoBackfill
    BackfillRecency
    }

    recall 命中数不足 top_k 时的补齐策略。

    RecallBackfill::output

    fn RecallBackfill::output(self : RecallBackfill, logger : &Logger) -> Unit

    RecallBackfill::to_string

    fn RecallBackfill::to_string(self : RecallBackfill) -> String

    SimilarityJudge

    pub struct SimilarityJudge {
    threshold : Double
    embedder : &Embedder
    coexist_band : Double
    }

    缺省判定器:对每个 candidate 计算 sim = max(cosine(new_fact 嵌入, candidate 嵌入), 关键词 Jaccard) sim >= threshold → Replace [threshold - coexist_band, threshold) → Coexist 否则 → Ignore(不产生裁决)

    SimilarityJudge::judge

    fn SimilarityJudge::judge(self : SimilarityJudge, new_fact : ExtractedFact, candidates : Array[MemoryEntry]) -> Result[Array[ConflictVerdict], MoomemError]

    SimilarityJudge::new

    fn SimilarityJudge::new(threshold : Double, embedder : &Embedder, coexist_band? : Double) -> SimilarityJudge

    StoreStats

    pub struct StoreStats {
    total : Int
    active : Int
    superseded : Int
    deleted : Int
    unstructured : Int
    bytes_on_disk : Int64
    last_write_at : Int64?
    truncated_recovered : Int
    extractor_mode : String
    }

    stats 的返回结构。
    impl Show for StoreStats

    StoreStats::output

    fn StoreStats::output(self : StoreStats, logger : &Logger) -> Unit

    StoreStats::to_string

    fn StoreStats::to_string(self : StoreStats) -> String

    VectorIndex

    type VectorIndex

    向量索引:user_id → (entry_id → 向量)。 Package-private (abstract): host API is MemoryStore only.

    COEXIST_BAND

    let COEXIST_BAND : Double

    SimilarityJudge 的 Coexist 下界间距:[threshold-0.15, threshold)

    CONFLICT_CANDIDATES

    let CONFLICT_CANDIDATES : Int

    add 链路冲突检测的每路候选窗口

    DEFAULT_DIM

    let DEFAULT_DIM : Int

    DEFAULT_LEXICAL_FLOOR

    let DEFAULT_LEXICAL_FLOOR : Double

    adaptive 词法强判定:BM25 top1 下限(独立开发集校准;偏低以覆盖短轮次)

    DEFAULT_LEXICAL_GAP

    let DEFAULT_LEXICAL_GAP : Double

    adaptive 词法强判定:top1 ≥ top2 × gap

    DEFAULT_RECALL_TOP_K

    let DEFAULT_RECALL_TOP_K : Int

    DEFAULT_RRF_K

    let DEFAULT_RRF_K : Int

    DEFAULT_SUPERSEDE_THRESHOLD

    let DEFAULT_SUPERSEDE_THRESHOLD : Double

    DEFAULT_VECTOR_WEIGHT_LEXICAL

    let DEFAULT_VECTOR_WEIGHT_LEXICAL : Double

    adaptive:词法强时向量通道权重(≤0.05 时 recall 走 BM25 单路)

    DEFAULT_VECTOR_WEIGHT_SEMANTIC

    let DEFAULT_VECTOR_WEIGHT_SEMANTIC : Double

    adaptive:词法弱时向量通道权重(近均衡;BM25 top 由 protect_bm25_topk 兜底)

    MAX_EXTRACTION_FAILURES

    let MAX_EXTRACTION_FAILURES : Int

    提取器连续失败降级上限

    MAX_RECALL_TOP_K

    let MAX_RECALL_TOP_K : Int

    MAX_USER_ID_LEN

    let MAX_USER_ID_LEN : Int

    MOOMEM_VERSION

    let MOOMEM_VERSION : String

    库版本号。与 moon.mod 和 package.json 相同,由 bumpp 一起改。 SNAPSHOT_VERSION 是快照格式,不跟着发版号走。

    SNAPSHOT_VERSION

    let SNAPSHOT_VERSION : Int

    快照格式版本(header 中的 "v" 字段)

    default_backend

    fn default_backend(path : String) -> Result[&PersistenceBackend, MoomemError]

    validate_user_id

    fn validate_user_id(user_id : String) -> Result[Unit, MoomemError]

    校验 user_id:非空、≤64 字符、字符集 [A-Za-z0-9_-.],且不为 "." / ".."。