hermes - 💡(How to fix) Fix [Bug] Holographic probe/reason algebraically broken: circular-mean bundle incompatible with phase-subtract unbind

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause


Root Cause

Fix Action

Fix / Workaround

Additional finding: retrieval_count is never incremented during normal tool use. _handle_fact_store dispatches to retriever.search() (no increment), never to store.search_facts() (which does increment). retrieval_count is a dead metric in the current implementation.

RAW_BUFFERClick to expand / collapse

The probe, reason, and related operations in the holographic memory plugin produce near-noise similarity scores due to a fundamental incompatibility between the bundle() implementation (circular mean / FHRR-style) and the algebraic extraction assumed by unbind() (phase subtraction).

The plugin docstring states:

unbind(fact, bind(entity, ROLE_ENTITY)) ≈ content_vector

This property does not hold with the current bundle implementation.


Environment

  • Hermes Agent: v0.12.0 (2026.4.30)
  • Plugin: plugins/memory/holographic, version 0.1.0 (PR #2351, dusterbloom)
  • NumPy: 2.4.4 (present — not a silent-fallback issue)
  • Python: 3.13.5

Reproduction

import sys
sys.path.insert(0, '/opt/hermes/plugins/memory/holographic')
from holographic import encode_atom, encode_text, bind,
unbind, bundle, similarity

dim = 1024
role_c = encode_atom('__hrr_role_content__', dim)
role_e = encode_atom('__hrr_role_entity__', dim)

A = encode_text('test content', dim)
E = encode_atom('larry dehobbit', dim)
A_bound = bind(A, role_c)
E_bound = bind(E, role_e)

bnd = bundle(A_bound, E_bound)
residual = unbind(bnd, E_bound)
print(similarity(residual, A_bound))
# Expected (classical HRR): ~0.8–1.0
# Actual:                    ~0.02  (noise)

Verified on a live instance with 16 stored facts. probe("Larry
 DeHobbit") returns uniform noise scores (~0.259) across all
16 facts, including the one where "Larry DeHobbit" is
correctly registered as an entity.

---
Root Cause

bundle() implements circular mean (FHRR / Fourier HRR style):

def bundle(*vectors):
    complex_sum = np.sum([np.exp(1j * v) for v in vectors],
axis=0)
    return np.angle(complex_sum) % _TWO_PI  # projects onto
unit circle — non-linear

unbind() implements phase subtraction:

def unbind(memory, key):
    return (memory - key) % _TWO_PI

The algebraic extraction property unbind(bundle(bind(A,K), B),
 K) ≈ A only holds when bundle is unnormalized additive
superposition (classical Plate 1995 HRR), because addition is
linear:

unbind(bind(A,K) + B, K) = A + unbind(B, K) ≈ A

The circular mean projects onto the unit circle (magnitude
normalization), breaking linearity. For a 2-element bundle the
 result is analytically:

bundle(bind(A,K), E_bound)(bind(A,K) + E_bound) / 2

unbind(bundle, K) = (A + K + E_bound)/2 − K
                 = (A + E_bound − K) / 2   ≠ A

Confirmed by qFHRR (arxiv:2604.25939): "bundling corresponds
to complex-valued superposition followed by projection onto
the unit circle" — the projection is what breaks algebraic
retrieval.

---
Impact

Operation: fact_store search
Status: ✅ Works — FTS5 + Jaccard dominant
────────────────────────────────────────
Operation: prefetch()
Status: ✅ Works — uses retriever.search()
────────────────────────────────────────
Operation: fact_store probe
Status: ❌ Algebraically broken — noise-level scores
────────────────────────────────────────
Operation: fact_store reason
Status: ⚠️  Algebraically not reliable — may appear to work in
  edge cases (FTS5/Jaccard fallback or agent interpolation),
  but should not be treated as a dependable core path
────────────────────────────────────────
Operation: fact_store related
Status: ❌ Same issue as probe
────────────────────────────────────────
Operation: fact_store contradict
Status: ⚠️ Entity-overlap detection depends on fact_entities
  links; content similarity via HRR vectors is affected

Results from probe and reason can look plausible because
FTS5/Jaccard fallbacks or system-prompt context (built-in
MEMORY.md/USER.md injection) carry the answer — not because
HRR algebraic retrieval is working.

Additional finding: retrieval_count is never incremented
during normal tool use. _handle_fact_store dispatches to
retriever.search() (no increment), never to
store.search_facts() (which does increment). retrieval_count
is a dead metric in the current implementation.

---
Probable Repair Direction (hypothesis — not a proven solution)

The likely fix would be to separate bundle behavior for
algebraic paths (probe/reason/encode_fact) from bank
superposition:

- Algebraic paths: use unnormalized complex addition, operate
in the complex domain for unbind, convert back to phase only
for storage/similarity.
- Bank/representation: keep circular mean for numerical
stability.

This would restore the classical HRR algebraic extraction
guarantee while preserving FHRR's representational properties.
 The exact implementation strategy and tradeoffs would need
validation by the plugin authors.

---
Operational Note

The plugin is stable and useful as a lightweight
search/prefetch layer (FTS5 + Jaccard + weak HRR score
contribution, plus built-in MEMORY.md/USER.md injection). It
should not be relied upon for algebraic entity retrieval
(probe/reason) until this is resolved. For use cases requiring
 reliable semantic recall, embedding-based providers (e.g.
Hindsight) are more appropriate.

---
Related Issues

- #20552 — entity-bound fact retrieval failures (symptom
overlap: probe unreliable → FTS5 fallback visible to users)
- #17350 — silent numpy fallback without warning

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING