Skip to content

ForeverAngry/rig-memory-policy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rig-memory-policy

Crates.io Documentation CI

Backend-agnostic memory-policy primitives shared across Rig memory-store adapters (e.g. rig-memvid and future SQLite / LanceDB / Qdrant / filesystem backends).

This crate has no dependency on memvid-core or any specific storage engine. Adapters wrap these primitives in their own backend-specific code.

Public surface

  • dedup — in-process content-hash dedup for hooks/compactors that must satisfy rig::memory::{DemotionHook, Compactor}'s idempotency contract on (conversation_id, messages).
  • metadata — typed envelope (FrameMetadata + FrameKind) written into a backend's per-entry metadata map so downstream tools (evals, memory inspectors, RAG pipelines) can reason about the lifecycle that produced each entry.
  • store — small capability traits (TextWriter + Committable) for hooks, compactors, and adapters that need to write text and explicitly flush it without depending on a concrete storage backend.
  • inmem — deterministic no-disk lexical reference store (Episode, InMemoryStore, InMemoryHit) for tests, examples, offline modes, and backend-neutral fixtures.
  • scope — normalized exact and hierarchical scope matching helpers for backend isolation, tenant boundaries, and provenance projection.
  • retention — deterministic keep/drop/defer decisions over decoded frame metadata plus backend-provided sequence numbers, timestamps, and retention labels.
  • error::PolicyError — neutral error type shared by the helpers above.

Adapter pattern

Backend crates keep ownership of their storage-specific APIs while leaning on these shared primitives for policy-level behaviour. For example, rig-memvid wraps Memvid's .mv2 archive format, but re-exports this crate's dedup, metadata, in-memory, and text-write capability surfaces to preserve its historic public paths.

New backend-neutral code should prefer importing directly from rig-memory-policy:

use rig_memory_policy::{Episode, InMemoryStore};

#[derive(Clone)]
struct Finding {
    summary: String,
}

impl Episode for Finding {
    fn summary(&self) -> &str {
        &self.summary
    }
}

# async fn run() -> Result<(), rig_memory_policy::PolicyError> {
let store = InMemoryStore::<Finding>::new();
store
    .append(Finding {
        summary: "scheduled maintenance".into(),
    })
    .await?;
let hits = store.retrieve_similar("maintenance", 5).await?;
assert_eq!(hits.len(), 1);
# Ok(()) }

Existing rig-memvid callers can continue using rig_memvid::inmem::* and the top-level rig_memvid::{Episode, InMemoryStore, InMemoryHit} re-exports; those are compatibility shims over this crate.

Retention and scope policies

Backends can evaluate retention decisions without adopting a shared storage trait. Decode a frame's FrameMetadata, attach any backend-local facts (such as sequence numbers or write timestamps), and run it through a pure RetentionPolicy before compaction, deletion, or archival.

use rig_memory_policy::{
  FrameKind, FrameMetadata, RetentionCandidate, RetentionDecision,
  RetentionPolicy, Scope,
};

let metadata = FrameMetadata {
  schema_version: 1,
  kind: FrameKind::CompactionSummary,
  conversation_id: "conv-1".into(),
  chat_role: "assistant".into(),
  dedup_key: "abc".into(),
  scope: Some("tenant-a/project-1".into()),
};

let policy = RetentionPolicy::new()
  .keep_summaries()
  .drop_outside_scope(Some(Scope::new("tenant-a/project-1")))
  .drop_written_before(1_700_000_000_000)
  .default_decision(RetentionDecision::Drop);

let decision = policy.evaluate(
  RetentionCandidate::new(&metadata).with_written_at_unix_ms(1_600_000_000_000),
);
assert_eq!(decision, RetentionDecision::Keep);

The policy helpers intentionally use primitive caller-supplied timestamps and string-backed labels. That keeps the crate runtime-agnostic and avoids baking one backend's storage model into the shared contract.

Status

  • Crate version: 0.2.1.
  • Rust edition: 2024.
  • MSRV: 1.89.
  • Runtime stance: runtime-agnostic library. The only runtime dependencies are pure-Rust utility crates (blake3, serde, serde_json, thiserror, tracing); tokio is not in [dependencies].
  • Scope stance: backend-neutral. The crate must not depend on memvid-core, rig-compose, rig-resources, rig-mcp, rig-memvid, or rig-retrieval-evals so every memory-store backend can consume it.
  • Stability: the Phase 1 public surface listed above is considered stable for 0.2.x. New backend-neutral capabilities land as additive modules; breaking changes go through a minor-version bump and are flagged in CHANGELOG.md.

See ROADMAP.md for the published Phase 1 surface and Phase 2 candidates.

License

MIT

About

Backend-agnostic memory-policy primitives for Rig memory-store adapters

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors