Design: Memory Groom

Memory Groom turns verified graph relations into a stable, first-person view without creating a second store for facts.

Why Memories exists#

Library, Graph, and Memories are different objects, not two filters on one list:

SurfaceObjectJob
LibraryDocumentsProvenance / ingest (“what was said / synced”)
GraphFull entity–relation neighborhoodWorld model explorer
MemoriesGroomed first-person cards“What we believe about you” — review & forget

Ontology is a write-side vocabulary (preferred types/predicates for extract; grows on invent). It is not the Memories visibility gate.

One card per subject#

Memories shows one row per subject (You, a pet, a person, a project), not one row per triple.

  • Title: available immediately from graph structure; optional LLM compaction improves it when fresh.
  • Detail: supporting facts still listed; forget is per-fact (underlying triples).
  • Graph: unchanged full edge set.

Schedule#

LayerWhenMechanism
Structural groomEvery GET /v1/thoughts (+ after chat remember)Sync: reachability, denylist, collapse, subject cards, deterministic titles
LLM compactionAfter remember marks multi-fact subjects dirtyEvent memory.subject.dirty → tension memory_subject_dirty → workflow memory_groom (needs Once/Always approval first)
Entity wiki summariesSame memory_groom run, only when neighborhood ≥ threshold & staleentity.wiki.summary:{id} keyed by edge fingerprint

Structural work is never behind tension. Compaction stores titles in kv (memory.card.summary:{subject}) keyed by fact fingerprint; stale fingerprints fall back to structural titles and set needs_compaction.

Reachability & noise#

  1. Owner as src/dst, plus durable attributes of entities linked by any durable outbound edge.
  2. Thin noise denylist (is_durable_thought_predicate).
  3. First-person: skip other-person → you and org → you inbound.

Non-goals#

  • Ontology-as-allowlist for Memories
  • Growing animal/breed string lists as the Memories gate
  • Putting cheap structural groom behind a workflow queue