Files

Holographic Memory Provider

Local SQLite fact store with FTS5 search, trust scoring, entity resolution, and HRR-based compositional retrieval.

Requirements

None — uses SQLite (always available). NumPy optional for HRR algebra.

Setup

hermes memory setup    # select "holographic"

Or manually:

hermes config set memory.provider holographic

Config

Config in config.yaml under plugins.hermes-memory-store:

Key Default Description
db_path $HERMES_HOME/memory_store.db SQLite database path
project_scoped false Explicit source-linked current-project candidates; ignores db_path
auto_extract false Auto-extract facts at session end
default_trust 0.5 Default trust score for new facts
hrr_dim 1024 HRR vector dimensions

Tools

Tool Description
fact_store 9 actions: add, search, probe, related, reason, contradict, update, remove, list
fact_feedback Rate facts as helpful/unhelpful (trains trust scores)

Optional Project Scope

Set plugins.hermes-memory-store.project_scoped: true explicitly to opt in. The default legacy mode is unchanged. Project mode resolves the provider's exact current session against the core project scope, never an active-project pointer or tool-supplied session override. Unresolved/ambiguous projects are denied.

Each project uses $HERMES_HOME/holographic/projects/<sha256>.db, with a key derived from resolved profile home, project identity, and the exact current session's user_id read from canonical state.db metadata. NULL has its own tagged sentinel, distinct from empty strings and named users. Custom db_path and the legacy global database are not consulted. A changed session project switches stores on the next tool call. on_session_switch releases the old store and binds the new session under the same lock used by project tools. No global configuration changes. Trusted caller session_id kwargs must match the binding or receive session_changed; model arguments cannot override it. During an asynchronous queued switch, callers must supply that trusted context to fail closed. Direct callers omitting it retain compatibility and cannot detect the not-yet-delivered switch.

Add and reads return fact_ref; update/remove/feedback require this opaque reference, not the local integer fact_id. It binds the profile/project/principal digest, a random persistent store UUID, fact ID and candidate revision hash. The reference is an identifier, not authorization: scope is always resolved from trusted metadata. Content/tags/category updates and source replacement invalidate old references; feedback and retrieval only change ranking and leave references valid. Reopening a store preserves its UUID; rebuilding creates a different UUID even if IDs repeat. Restoring an exact backup restores its UUID and candidate versions too, so references to that exact snapshot can become valid again; there is no external restore counter. Older project-only stores without principal partitioning are not auto-migrated or read.

{"action":"add","content":"Candidate deployment choice","sources":[{"session_id":"original-session-id","message_id":123}]}

For mutation use {"action":"remove","fact_ref":"<returned fact_ref>"} or {"action":"update","fact_ref":"<returned fact_ref>","content":"Revised candidate","sources":[...]}. sources is required for add and content update; source-only updates are supported. content_hash is optional on input and always stored after source verification. Message IDs must be positive integers, supplied hashes must be lowercase SHA-256 hex. The core original-message reader enforces project/principal membership, lifecycle, secret and multimodal filtering. Every linked source must still exist and have the same hash on retrieval. Facts without source links are never returned. Contradiction pairs require both candidates to pass. Fact/entity/vector/source changes share one SQLite transaction; a failed final scope/source check rolls back mutations.

Responses expose identity, scope, assertion: candidate_not_confirmed, and trust_semantics: ranking_only_not_confirmation. A successful add has status: candidate; reads have status: ok with per-item candidate status. Trust scores and feedback are ranking signals, not factual confirmation. Source linkage does not prove that a candidate's wording follows from its source.

Automatic prefetch returns empty in this mode, and built-in memory mirroring and session-end auto-extraction do nothing even if auto_extract is enabled. No automatic LLM calls, external service, legacy migration or conclusion-version engine is added.

Boundaries: source/scope checks are optimistic across the session and project databases, not a distributed transaction. Revoked candidates are retained locally but suppressed from tools; remove also requires a currently valid source, so revoked candidates cannot be purged through these tools (governance limitation). Retrieval applies the existing candidate limits before source filtering, so a page can underfill; it does not claim complete recall: reads explicitly return partial: true and coverage.complete: false. Source edits restored to the exact same safe text/hash become eligible again. The plugin uses this profile's canonical state.db.