You are reading Nightly documentation for 0.12.4.dev0+g50bde75.

This documentation may describe behavior that differs from Stable.

Open Stable documentation

Documentation version

0.12.4.dev0+g50bde75 · Nightly

Memory

Memory

Holaryn Agent keeps a durable local memory: everything it remembers lands in a database on your machine, searchable by keyword and — once you enable a real embedder — by meaning. No memory ever leaves your machine unless you point it at your own server.

How recall works

Recall is hybrid: every query runs two searches and merges the ranked results.

Leg Machinery Finds
Keyword SQLite full-text search (FTS5) Memories containing the query's words
Semantic An embedder + a vector index (sqlite-vec by default) Memories that mean what the query means, even with no shared words

The agent uses two tools against this store: remember (request promotion of an entity or episodic fact into an explicit scope) and recall (search one authorized scope). Both are ordinary tools under the autonomy policy, in the memory.write / memory.read categories. Session context is not saved merely because the model saw it; a matching automatic-saving policy can save, queue for review, or pause the promotion.

Every recall is explainable. The store records the structured/hybrid path, candidate ids and versions, keyword/vector/recency/confidence/provenance/pin/conflict score components, result and token budgets, and why each candidate was included or omitted. It retains only a query digest—not the prompt—and bounds this diagnostic history to 500 decisions.

Why recalled assertions are not automatically evidence

Holaryn tracks who wrote a memory separately from what kind of document the memory claims to
describe. A conclusion saved by the agent is sealed as a model assertion, defaults to the review
queue, and has capped confidence. Approval allows recall but does not certify the conclusion.
Team-member assertions and memories created before this provenance contract are treated the same
way for grounding: they can tell the agent what was said before, but they receive no citation id
and cannot serve as proof of their own claims.

A factual memory gets a validated citation only when a trusted importer independently records the
source and its revision. Operator-authored commitments, decisions, instructions, preferences, and
procedures can also be cited within the operator-intent domain. Pinning, confidence, repetition,
or labeling an assertion as a file never promotes it. In Settings, every result remains
inspectable and shows its evidence class and provenance contribution even when it is
attribution-only.

Memory blocks: always-present notes

Alongside searchable memory, the agent curates named markdown blocks that are injected into the system preamble of every new session — never subject to retrieval, simply always there. Three tools manage them: memory_pin(name, content) creates or replaces a block, memory_append(name, content) adds a line, and memory_unpin(name) deletes one. Budgets force curation: 4,000 characters per block, 12,000 injected in total.

Each block is one plain markdown file under <state dir>/memory-blocks/<name>.md — you can read and edit them with any text editor; edits take effect at the next session.

Embedders: from keyword-only to semantic

Out of the box the agent runs on the hash embedder: deterministic token hashing with zero dependencies and zero network — but no semantic recall. The agent warns you once per session:

memory is using the default hash embedder; for semantic recall, install
holaryn-agent[fastembed] or configure Ollama embeddings

Pick a real embedder in Settings → Memory (or via HOLARYN_EMBEDDER):

Choice What it is Semantic recall
hash (default) Token hashing; no downloads, no network, ever No
fastembed Local in-process embeddings; one-time model download (~70 MB default model), fully offline after that Yes
ollama A running Ollama server's embedding endpoint Yes
custom Your own module:attribute implementing the Embedder protocol Up to you

fastembed needs the optional extra — install it with the one-click Install button on the
Memory page, holaryn memory install-extra fastembed, or uv sync --extra fastembed from an
authorized source checkout. The default model is BAAI/bge-small-en-v1.5 (full registry names
required); for Ollama the default is nomic-embed-text, which you must ollama pull first
(HOLARYN_EMBED_MODEL and HOLARYN_OLLAMA_HOST configure both).

There is never a silent fallback: selecting an embedder that cannot run fails with an instruction telling you how to fix it.

The mismatch guard and reindexing

The store records which embedder built the vector index. If the active embedder no longer matches (you switched embedders or models), semantic recall is disabled — never mixed with incompatible vectors — until you reindex. Your memories are never lost: text is the source of truth; vectors are derived data.

Run a reindex after any embedder change, from Settings → Memory or the CLI:

holaryn memory status     # active vs recorded embedder, match state, vector counts
holaryn memory reindex    # re-embed everything with the active embedder
holaryn memory install-extra fastembed|qdrant|postgres|mariadb

Reindexing is idempotent and safe to run at any time.

Reviewing and controlling memory

Settings → Memory is the operator view. In addition to store/embedder status and search, it provides:

  • filters for scope and lifecycle state, a review queue, and keyboard-native batch approval, archive, pin, and unpin;
  • writer provenance, evidence class, grounding eligibility, confidence, consent, sensitivity, retention, conflicts, immutable version history, and retrieval score reasons;
  • edit-as-new-version, pin/unpin, archive/activate, conflict/supersession links, verified deletion, and source-wide forget;
  • atomic verified JSON export into the state directory's exports folder; and
  • automatic-saving rules by exact/wildcard scope, category, and source type: Save automatically, Require review, or Pause saving.

Pending-review and archived records are stored but never recalled. Superseded records are marked stale and deindexed; conflicting active records remain visible with uncertainty rather than silently replacing one another. Editing reindexes the new version. Deletion removes primary, keyword, and vector representations before leaving a digest-only tombstone; if the vector backend cannot confirm its delete operation, the primary record is preserved and the operation fails.

Scopes never bleed into one another: personal, project/profile, team:<id>, and organization-managed scopes are exact retrieval boundaries. A prior export is an external copy, so later source-forget cannot erase JSON that an operator moved or backed up elsewhere.

See the explainable-memory architecture and recovery contract for score formulas, promotion precedence, completion reports, and deliberate v0.7.9 boundaries.

Bigger setups: server databases

Defaults are a single local SQLite file — zero setup, right for one machine. Two panels in Settings → Memory scale beyond that:

  • Memory database — point at a PostgreSQL server (with pgvector) or MariaDB 11.7+ to share one durable memory across several Holaryn instances. Install the matching extra (holaryn-agent[postgres] or holaryn-agent[mariadb]), enter the server URL without a password, and set the password in the write-only field (or HOLARYN_MEMORY_DB_PASSWORD) — it is never written to a config file. Exactly one backend is active at a time; switching starts with an empty memory, and every instance sharing a database must use the same embedder.
  • Vector database — episodes and entities always live in the memory database; this panel only chooses where search vectors go. Default is local sqlite-vec; pick Qdrant server (extra: holaryn-agent[qdrant], API key via HOLARYN_QDRANT_API_KEY) for large memories or shared infrastructure. If the vector server is unreachable, memory keeps working with keyword-only recall and heals on the next reindex.

Troubleshooting

Symptom Likely cause Fix
Recall feels like plain text search Still on hash Pick fastembed or Ollama, then reindex
"embedder mismatch" in status Changed embedder/model without reindexing holaryn memory reindex
fastembed import error Extra not installed Install button, holaryn memory install-extra fastembed, or pip
Ollama connection error Server down, wrong host, or model not pulled Start Ollama, check the host field, ollama pull <model>
Vector count is 0 after switching Index not rebuilt Reindex
A memory is not recalled It is pending review, archived, stale, in another scope, or over the retrieval budget Inspect its state and latest decision in Settings → Memory
Edit or batch action reports a version conflict Another action created a newer immutable version Refresh the list/detail and retry against the new version
Delete/forget fails while using Qdrant The vector backend did not complete deletion Restore the backend connection, then retry; Holaryn keeps the primary record rather than claiming completion