Background maintenance, triggered by events.
The reasoner is the background engine that keeps memory healthy. It consolidates duplicates, archives low-value topics, and does its work after the client response has already returned — so maintenance never adds latency to the request path.
Policy in the research sense is event → condition → action: an event (ingest complete, query complete, cron tick, memory pressure) schedules work; conditions read Dt and Pt; actions update Dt (merge, archive, future summarize/detach) without new agent-facing routes. The shipped reasoner wires a small fixed set of handlers to that pattern. See GEM state and High-level API flow.
Design intent
Stable API, evolving policy
Client-facing semantics stay stable while retention policy evolves independently inside the reasoner.
Lightweight heuristics
Bounded, explainable heuristics for cleanup — not opaque models in the hot path.
Off the critical path
Runs as a FastAPI background task after the response is sent, so requests never wait on maintenance.
Events the reasoner listens to
| Event | Forget | Revise |
|---|---|---|
ingest_complete |
Runs when topic count is at or above the soft limit. | Runs duplicate detection when the store has topics. |
query_complete |
Runs when topic count is at or above the soft limit. | Skipped. |
cron |
Runs when topic count is at or above the soft limit. | Runs duplicate detection when the store has topics. |
memory_pressure |
Always runs — pressure bypasses the count gate. | Skipped. |
Decision flow
The reasoner returns a ReasonerResult listing which revise and forget actions it took.
What each action does
| Action | Behavior | Effect |
|---|---|---|
| Forget by salience | Scans non-archived topics and archives those whose salience is below the threshold. | Marks the topic archived and halves its salience; excluded from default retrieval. |
| Revise duplicates | Finds topic pairs with identical non-empty titles and merges them. | Transfers edges and missing fields onto the surviving topic; removes the duplicate. |
Toward declarative policy
Today's reasoner logic is implemented in code. The direction of travel is a declarative policy engine: rules expressed as event + condition + action triples that operators can tune without touching code. This is on the roadmap; see the configuration reference for current knobs.
Operational notes
- Large ingest bursts trigger cleanup soon after writes, because
ingest_completefires on every ingest call. - Duplicate detection today is title-only. Upstream naming hygiene matters.
- To disable maintenance, skip the reasoner invocation in route handlers or guard it with your own condition.