6.9 Background intelligence

OwnSona is more than a passive store: it learns from use and keeps itself coherent. The mechanisms split cleanly into two groups by what they depend on.

6.9.1 Always-on, embeddings-only learning

These need no extra configuration and never make a generative-LLM call.

Salience and reinforcement

Every memory carries a learned salience weight (seeded from importance). reinforce — and confirm, which counts as positive feedback — moves it by a reward-modulated rule, salience <- clamp((1 - lambda)*salience + eta*reward). Recall multiplies salience into its ranking. There is no time-based decay: the (1 - lambda) term is update smoothing applied only on a feedback event, never with the clock. A memory is never demoted for being old — only feedback and explicit correction change its standing.

Contextual ranking

Beyond the global salience scalar, each memory learns a context_vector — a reward-weighted centroid of the query embeddings it was reinforced as helpful for (fed by reinforce’s optional query). Recall adds a term for how close the current query is to that centroid, so a memory surfaces for the kinds of questions it has proven useful on. A row with no learned context contributes nothing extra, so this is dormant until taught.

Conflict surfacing

On a new remember, and on demand via find_conflicts, the server flags active memories that are semantically close and share a tag — possible contradictions. This is pure embedding + tag-overlap math; the server never judges whether two facts truly conflict.

The recall ranking blend is cosine * (1 + w_s*salience + w_c*context_match) with recency as a tiebreaker, computed in MemoryRepository.findRanked. The reported score stays raw cosine, so min_score keeps its meaning.

6.9.2 The generative seam

A second, optional vendor seam, ai.ownsona.llm.GenerativeProvider, sits beside the embedding provider and is configured independently (LLM_* keys; see Generative LLM keys). Design invariant: a generative LLM may be used for background / maintenance work, but never on the synchronous recall/remember path, and the server runs fully without it. When LLM_API_KEY is unset the seam is not constructed and everything below stays off.

6.9.3 The background jobs

Scheduled by Kiss Cron (backend/CronTasks/crontab), each off by default and gated as described in Learning and background-job keys.

Consolidation (the “sleep” job)

ConsolidationJob clusters near-duplicate memories, asks the LLM to merge each cluster into one canonical fact, stores it, and supersedes the originals (recoverable soft-delete + replaced_by_id). A second, separately-gated pass resolves same-topic contradictions by keeping the current fact and superseding the stale ones. Clusters containing a keep='Y' memory are skipped entirely.

Relation-graph extraction

GraphExtractionJob asks the LLM to pull (subject, predicate, object) triples from each memory (once) into the memory_relations table. query_relations then answers multi-hop questions by breadth-first traversal of that graph — with no LLM call at query time.

Every destructive action these jobs take is a recoverable soft-delete, never a hard delete, and they are cost-bounded (a fixed per-run cap on LLM calls, and zero calls when there is nothing to do).