Understanding the Memory Tiers in ai-memory: The M8 Policy Explained
ai-memory organizes all knowledge into four distinct memory tiers—Working, Episodic, Semantic, and Procedural—each with unique retention rules defined by the M8 policy.
The M8 policy governs how the ai-memory system retains and decays information over time. Implemented in the akitaonrails/ai-memory repository, this policy assigns every page in the SQLite-backed wiki to a specific tier that determines its lifecycle, from session-bound working memory to indefinitely persistent semantic knowledge.
The Four Memory Tiers of the M8 Policy
The M8 policy defines four memory tiers with distinct retention behaviors. These tiers are documented in docs/ARCHITECTURE.md at lines 80-88 and implemented across the core storage crates.
Working Memory
Working memory exists only for the current session and receives no decay processing.
- Lifetime: Current session only
- Decay behavior: Hard-drop when the session ends
- Raw observations: Preserved only for forensics
Working memory holds transient, context-specific information that doesn't need to persist beyond the immediate interaction.
Episodic Memory
Episodic memory follows a graduated decay pattern based on salience, access patterns, and time.
- Lifetime: 30 days hot → 180 days cold → eviction
- Decay formula:
salience·exp(−λ·Δt) + σ·log(1+access_count)·exp(−μ·days_since_access)·(1 + breadth_weight·ln(1 + max(distinct_actors−1, 0)))
The episodic tier uses the most complex decay logic in the M8 policy. The formula combines:
- Base salience decay: Exponential time decay with rate
λ - Access count boost: Log-scaled access frequency with decay rate
μ - Breadth weight: Social signal based on distinct actors interacting with the page
These parameters (λ, μ, σ, breadth_weight) are configurable via the [decay] table in ai-memory.toml.
Semantic Memory
Semantic memory persists indefinitely and is only modified through explicit supersession.
- Lifetime: Indefinite
- Decay behavior: None automatic; removed only by M7 LLM rewrite
Semantic pages contain distilled, factual knowledge that shouldn't fade over time. The M7 policy handles supersession—when new information replaces old, the outdated page becomes a tombstone.
Procedural Memory
Procedural memory also persists indefinitely but includes frequency-based decay for unused entries.
- Lifetime: Indefinite
- Decay behavior: Decays only if not re-observed
This tier stores operational knowledge like "how to" procedures, which remain valid until explicitly contradicted or forgotten through disuse.
Protected Pages: Pinned and Reserved Namespaces
Certain pages bypass all decay mechanisms regardless of tier assignment.
- Pinned pages: Marked with
pinned: truein front-matter; immune to all decay _slots/namespace: Reserved directory where pages are permanently retained
These protections ensure critical reference material survives routine maintenance sweeps.
The Forget-Sweep Tool: Enforcing M8 Policy at Runtime
The M8 policy is enforced by the memory_forget_sweep tool, exposed through the MCP server in crates/ai-memory-mcp/src/server.rs (lines 299-306).
During a sweep:
- Episodic pages below the cold threshold become tombstones (
superseded_attimestamp) - Tombstones older than the configured period are permanently removed
- Pinned and
_slots/pages are skipped regardless of scores
The decay implementation lives in crates/ai-memory-store/src/decay.rs, while candidate selection for sweeps occurs in crates/ai-memory-store/src/reader.rs at decay_candidates (lines 3132-3156).
Querying Memory Tiers Programmatically
You can inspect tier assignments through the CLI or Rust client.
CLI Usage
ai-memory memory_query "how to initialize a Rust project" --explain
Output includes tier: "episodic" with the decay-adjusted relevance score.
Rust Client Example
use ai_memory_mcp::client::MemoryClient;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = MemoryClient::new("http://127.0.0.1:49374")?;
let resp = client
.memory_query(
"git branch list".into(),
None,
false,
None,
Some(true),
None,
)
.await?;
for hit in resp.hits {
println!("{} (tier: {})", hit.title, hit.tier);
}
Ok(())
}
Each query automatically increments the access counter, feeding into the episodic decay formula.
Running a Forget Sweep in Rust
use ai_memory_store::writer::WriterHandle;
use ai_memory_store::decay::DecayParams;
async fn run_forget_sweep(writer: WriterHandle) {
let params = DecayParams::default();
writer.memory_forget_sweep(params, dry_run = false).await.unwrap();
}
Integration with M9 and M10 Enhancements
The M8 policy operates alongside newer M9 and M10 columns that add:
- Embedding metadata for vector search
- Salience-derived scoring for improved ranking
These enhancements supplement but don't replace the core tier logic—all four memory tiers function identically regardless of which metadata columns are present.
Summary
- Working: Session-only, hard-dropped on exit
- Episodic: 30-day hot window, 180-day cold retention, complex salience-based decay formula
- Semantic: Indefinite, only removed by M7 LLM supersession
- Procedural: Indefinite, frequency-based decay if unobserved
- Pinned pages and
_slots/namespace are immune to all decay - Configuration lives in
ai-memory.tomlunder[decay] - Core implementation spans
decay.rs,reader.rs, andserver.rs
Frequently Asked Questions
How do I configure decay parameters for episodic memory?
Edit the [decay] table in your ai-memory.toml file. The parameters λ (time decay rate), μ (access decay rate), σ (access boost coefficient), and breadth_weight (social signal multiplier) all control the behavior of the decay formula defined in crates/ai-memory-store/src/decay.rs.
What happens when an episodic page becomes "cold"?
Pages that fall below the cold threshold receive a superseded_at timestamp and become tombstones. If they remain cold for the configured eviction period (default 180 days), the forget-sweep tool permanently removes them. This process is handled in crates/ai-memory-mcp/src/server.rs through the memory_forget_sweep MCP tool.
Can I prevent a page from ever being deleted?
Set pinned: true in the page's front-matter, or store it under the _slots/ namespace. Both mechanisms bypass all decay logic in crates/ai-memory-store/src/reader.rs during sweep candidate selection.
What's the difference between semantic and procedural memory tiers?
Semantic memory contains factual knowledge that never decays automatically—it only changes through explicit M7 LLM rewrites. Procedural memory stores operational knowledge that persists indefinitely but can decay if the page is never re-observed, making it sensitive to usage patterns rather than calendar time.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →