Class: ClaudeMemory::Observe::Reflector
- Inherits:
-
Object
- Object
- ClaudeMemory::Observe::Reflector
- Defined in:
- lib/claude_memory/observe/reflector.rb
Overview
Deterministic, free (no LLM) Reflector for the episodic observation log.
Runs inside Sweep, which fires on PreCompact and SessionEnd — Claude Code’s context-pressure lifecycle events. That is the analog of Mastra’s token-threshold-triggered reflection: “reflect when memory gets big” maps onto “reflect when the session is about to compact”, without a wall-clock timer (Claude Code has no cron hook) and without extra API cost.
Two passes, both provenance-preserving (tombstone, never hard-delete):
- dedupe: collapse near-duplicate active observations (same scope) into
the newest, linking losers via consolidated_into. Similarity is decided
by an injected matcher (default: lexical token-overlap, #73) so the
promotion gate can actually accumulate corroboration — exact-string
matching never folded varied wording, leaving every observation at
corroboration 1 (the 2026-06-23 audit finding).
- expire_stale_info: retire info-level (🟢 / priority 3) observations
older than the TTL to bound context size. Important (🔴) and maybe
(🟡) are never expired — only the lowest-signal tier ages out.
Semantic consolidation (“combine related items, surface patterns”) is deliberately NOT here — it needs the LLM and lands in the Phase-4 Claude-as-reflector pass. This pass is pure Ruby so it can run shell-side in the sweep hook for free.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- DEFAULT_INFO_TTL_DAYS =
30
Instance Method Summary collapse
-
#initialize(store, info_ttl_days: DEFAULT_INFO_TTL_DAYS, matcher: TokenOverlapMatcher.new) ⇒ Reflector
constructor
A new instance of Reflector.
-
#reflect! ⇒ Result
Number of observations deduped and expired.
Constructor Details
#initialize(store, info_ttl_days: DEFAULT_INFO_TTL_DAYS, matcher: TokenOverlapMatcher.new) ⇒ Reflector
Returns a new instance of Reflector.
38 39 40 41 42 |
# File 'lib/claude_memory/observe/reflector.rb', line 38 def initialize(store, info_ttl_days: DEFAULT_INFO_TTL_DAYS, matcher: TokenOverlapMatcher.new) @store = store @info_ttl_days = info_ttl_days @matcher = matcher end |
Instance Method Details
#reflect! ⇒ Result
Returns number of observations deduped and expired.
45 46 47 48 49 50 51 52 53 |
# File 'lib/claude_memory/observe/reflector.rb', line 45 def reflect! deduped = 0 expired = 0 @store.db.transaction do deduped = dedupe expired = expire_stale_info end Result.new(deduped: deduped, expired: expired) end |