Dynamic Salience Scoring
Overview
Dynamic Salience Scoring adjusts memory relevance based on access patterns instead of static importance. Memories that are frequently recalled or recently used score higher; older, unused memories fade in relevance. This mimics biological memory (“use it or lose it”) and keeps the vector space focused on active context.
The Problem
Previously, memory importance was static (set at creation time). Memories from months ago were treated equally with fresh ones unless manually decayed or searched by date. Over time, the vector space became cluttered with irrelevant facts.
The Solution
The system now applies three mechanisms:
- Access Boost — Frequently recalled facts score higher
- Time Decay — Older, unused memories fade in relevance
- Hebbian Reinforcement — Co-recalled memories get stronger associations
How It Works
1. Access Boost
Every time a memory is recalled (via memory_recall or auto-recall):
recall_countandaccess_countare incrementedlast_accessed(epoch) andlast_accessed_at(ISO 8601) are set to the current time
The effective importance score is boosted by:
boost = 1 + 0.1 * log(recall_count + 1)
So a fact recalled 100 times gets roughly a 46% boost over one never recalled.
Where access is tracked:
FactsDB.search()— all returned factsFactsDB.lookup()— all returned factsmemory_recallby id — when fetching a specific memory- Auto-recall — all injected memories (full, short, minimal, progressive, progressive_hybrid)
2. Time Decay
The score is multiplied by a decay factor based on (now - last_accessed):
decay = 1 / (1 + days_since_access / 30)
Default half-life is 30 days: after 30 days without access, salience halves. If last_accessed is null, last_confirmed_at or created_at is used.
3. Hebbian Reinforcement
When two or more memories are recalled together in the same session, the system creates or strengthens RELATED_TO links between them. Co-recalled facts become associated in the graph, enabling graph traversal to surface related context.
When Hebbian linking runs:
memory_recallreturns 2+ results- Auto-recall injects 2+ memories (any format)
Requires graph.enabled (default true).
Configuration
No separate config is required. Dynamic salience uses:
graph.enabled— must be true for Hebbian reinforcement (default true)
Salience scoring (access boost + time decay) always runs on search and lookup.
Database Schema
| Column | Type | Description |
|---|---|---|
recall_count | INTEGER | Number of times the fact was recalled |
last_accessed | INTEGER | Epoch seconds of last recall (null if never) |
access_count | INTEGER | Number of times the fact was recalled (for salience scoring) |
last_accessed_at | TEXT | ISO 8601 timestamp of last recall |
The initial columns were added by migration migrateAccessTracking(). Migration migrateAccessCountAndLastAccessedAt() (#237) adds access_count and last_accessed_at, backfilling from the original columns for compatibility.
Related Docs
- GRAPH-MEMORY.md —
RELATED_TOlinks and graph traversal - DEEP-DIVE.md — Search scoring and access tracking
- DYNAMIC-DERIVED-DATA.md — Derived fields index
- DECAY-AND-PRUNING.md — TTL and expiry
Inspiration
- neural-memory — Hebbian learning
- engram-memory — Salience decay
See issue #5.