Skip to content

#395 — Reflection Items Lack Resolution Mechanism #447

@jlin53882

Description

@jlin53882

Problem

The reflection pipeline is unidirectional: extract → store → decay → inject. There is no resolve → invalidate → suppress path.

Once a reflection item is written, it continues to be injected into every new session until maxAgeDays naturally expires (45 days for invariant items by default). When a problem is solved, the stale derived lessons about that problem keep being injected, occupying the injection budget and blocking relevant items.

Example:

  • Session A: Rerank misconfiguration problem occurs → 6 derived lessons extracted
  • Session B: Rerank is confirmed working
  • Sessions C, D, E...: The 6 stale items continue to be injected on every new session, for up to 45 days

Proposed Solution: Option A — resolvedAt field + manual resolve tool

1. Add resolvedAt to ReflectionItemMetadata

interface ReflectionItemMetadata {
  // ... existing fields ...
  resolvedAt?: number;      // Unix timestamp when marked resolved
  resolvedBy?: string;    // agentId that marked it resolved
  resolutionNote?: string; // optional note
}

2. Add filterByResolved() in reflection recall

In reflection-recall.ts, after filterByMaxAge:

function filterByResolved(items: ReflectionItem[]): ReflectionItem[] {
  return items.filter(item => item.metadata.resolvedAt === undefined);
}

This applies to all injection paths (derived-focus and inherited-rules) since they all consume the same recall output.

3. Add memory_reflection_resolve tool

memory_reflection_resolve({
  query?: string,    // BM25 match — resolves all matching items
  id?: string,       // Direct ID match — resolves one specific item
  note?: string      // Optional resolution note
})

Flow:

  1. If id provided → directly resolve by ID
  2. If query provided → bm25Search() for semantic match → resolve all results
  3. Set resolvedAt = Date.now(), resolvedBy, optional note
  4. Return "resolved N items"

Why Option A over Option B/C?

Option Effort Risk
A — resolvedAt + tool Low Minimal — existing fields unchanged, new field is additive
B — Cross-pipeline suppression Medium Needs semantic similarity classification; high complexity for unclear accuracy
C — Full status schema Medium-High Requires schema migration; most robust but overkill for the problem

Option A requires no schema migration and solves the core issue.

Questions for Author

  1. Does the resolvedAt field approach work for your use case?
  2. Should resolving an item automatically resolve all items with the same strictKey?
  3. Should there be a memory_reflection_list tool to let agents review their reflection items before resolving?

Related: #395

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions