Tiered Episodic Degradation

Mnemosyne (since v2.3) supports three-tier degradation so episodic memories persist indefinitely without bloat. Old memories never get deleted, they gracefully fade into compact, lower-priority signals that still surface when the query really matters.

Tier Definitions

  • Tier 1 (hot, 0 to 30 days): Full detail, 1.0x recall weight. These are your working, active memories.
  • Tier 2 (warm, 30 to 180 days): LLM-compressed summary, roughly 400 characters. Half the recall weight.
  • Tier 3 (cold, 180+ days): Entity-extracted signal, roughly 200 to 300 characters. Quarter the recall weight.

The Degradation Flow

flowchart LR
    T1[Tier 1: Full Detail] -->|30+ days, LLM compress| T2[Tier 2: Summary ~400 chars]
    T2 -->|180+ days, entity extract| T3[Tier 3: Key Signal ~250 chars]
    T3 -.->|"4x stronger match needed"| Recall[Recall Engine]

How It Works

Degradation runs automatically at the end of each sleep() cycle, right after consolidation completes. No separate cron jobs, no manual pruning.

Tier 1 to Tier 2

Memories older than the configured threshold (default 30 days) get compressed by a local LLM into a roughly 400-character summary. If no LLM is available, the system falls back to keeping the raw text so nothing is lost.

Tier 2 to Tier 3

Memories older than 180 days undergo deep signal extraction via _extract_key_signal(). Instead of naive first-N-characters trimming, this function scores every sentence by entity density: proper nouns, acronyms, security terms, tech stack keywords, and urgency markers. It keeps the highest-scoring sentences until the character budget is full. A memory where the critical fact is buried in the last sentence preserves that sentence instead of only the boring first one.

Recall Weight Multipliers

  • Tier 3 memories need roughly 4x stronger semantic match to surface compared to Tier 1
  • Tier 2 memories need roughly 2x stronger match
  • Old memories stay out of your way unless the query is genuinely relevant

Configuration

All knobs are environment variables:

MNEMOSYNE_TIER2_DAYS=30        # Days before tier 1 -> 2
MNEMOSYNE_TIER3_DAYS=180       # Days before tier 2 -> 3
MNEMOSYNE_TIER1_WEIGHT=1.0     # Recall multiplier for tier 1
MNEMOSYNE_TIER2_WEIGHT=0.5     # Recall multiplier for tier 2
MNEMOSYNE_TIER3_WEIGHT=0.25    # Recall multiplier for tier 3
MNEMOSYNE_DEGRADE_BATCH=100    # Max rows per cycle
MNEMOSYNE_SMART_COMPRESS=1     # Enable entity-aware extraction
MNEMOSYNE_TIER3_MAX_CHARS=300  # Max chars for tier 3

Python API

from mnemosyne import Mnemosyne

mem = Mnemosyne(session_id="default")

# Run degradation manually
result = mem.degrade_episodic()
print(result)  # {"tier1_to_tier2": 5, "tier2_to_tier3": 12}

# Dry run to preview
dry = mem.degrade_episodic(dry_run=True)

# During sleep, degradation runs automatically
result = mem.sleep()
print(result["degradation"])  # {"tier1_to_tier2": 3, "tier2_to_tier3": 8}

Design Intent

Marketing truth: "Mnemosyne remembers what I told it a year ago." Tier 3 memories are still queryable, just at reduced priority.

Engineering reality: Cold memories do not clutter everyday context. They only surface with very strong semantic matches.

Zero maintenance: No manual pruning scripts, no cron jobs. The system degrades itself during sleep cycles.

Backward compatible: Existing databases work without migration. Old rows default to Tier 1.

Smart Compression Detail

The _extract_key_signal() function scores every sentence by signal density:

  • Acronyms (XKCD, API, AWS): +3
  • Known tech terms (Docker, Python, Rust): +4
  • Security terms (password, token, encrypt): +3
  • Infrastructure terms (production, deploy, database): +2
  • Urgency signals (critical, breaking, incident): +3
  • Preference markers (prefers, uses, likes): +2

Sentences are ranked by total score, top scorers kept until character budget is exhausted. A critical security finding in the final paragraph gets preserved, not truncated.

Why not just first N characters? Naive truncation assumes importance lives at the top. Real conversations bury critical facts deep. Smart compression finds the signal no matter where it hides.

Sleep Integration

degrade_episodic() runs at the end of both sleep() and sleep_all_sessions(), after consolidation. Stats included under the "degradation" key.

How It Compares

  • vs Vector DB TTL: Automatic degradation vs manual cleanup. No data loss vs hard deletion after expiry.
  • vs Full-text pruning: Smart entity-aware extraction vs naive first-N-characters. Critical sentences survive.
  • vs Archive-only approaches: Tier 3 remains queryable at reduced weight vs moved to cold storage, unsearchable.