Skip to content

fix(memory): profile-scoped memory isolation and clone support#4845

Merged
teknium1 merged 1 commit intomainfrom
hermes/hermes-3eaaba2c
Apr 3, 2026
Merged

fix(memory): profile-scoped memory isolation and clone support#4845
teknium1 merged 1 commit intomainfrom
hermes/hermes-3eaaba2c

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented Apr 3, 2026

Summary

Three fixes for memory + profile isolation bugs:

1. Dynamic memory directory resolution (memory_tool.py)

MEMORY_DIR was a module-level constant cached at import time. If HERMES_HOME changed after import (edge case but architecturally fragile), all memory reads/writes would go to the wrong profile. Now get_memory_dir() resolves dynamically via get_hermes_home() on every call. Internal MemoryStore methods (load_from_disk, _path_for, save_to_disk) use it directly. The old MEMORY_DIR constant is kept as a backward-compatible alias.

2. Clone includes memory files (profiles.py)

profile create --clone copied config.yaml, .env, and SOUL.md but NOT MEMORY.md/USER.md. These curated memory files are just as much part of the agent's identity as SOUL.md. New _CLONE_SUBDIR_FILES list handles subdirectory files.

3. Holographic plugin $HERMES_HOME expansion (holographic/__init__.py)

The db_path config value only expanded ~ via Path.expanduser(). Users following the docstring (db_path: $HERMES_HOME/memory_store.db) got a literal $HERMES_HOME string. Now initialize() expands both $HERMES_HOME and ${HERMES_HOME} to the active profile directory.

4. Gateway flush updated (gateway/run.py)

The memory flush path now uses get_memory_dir() instead of importing the cached MEMORY_DIR constant.

Files changed

  • tools/memory_tool.pyget_memory_dir() function, internal usages updated
  • hermes_cli/profiles.py_CLONE_SUBDIR_FILES, clone logic
  • plugins/memory/holographic/__init__.py — $HERMES_HOME expansion in db_path
  • gateway/run.py — use get_memory_dir()
  • tests/tools/test_memory_tool.py — mock get_memory_dir
  • tests/gateway/test_flush_memory_stale_guard.py — mock get_memory_dir

Test plan

  • 170 memory/profile tests pass (0 failures)
  • E2E verified: dynamic resolution, profile clone with memories, holographic $HERMES_HOME expansion

Three fixes for memory+profile isolation bugs:

1. memory_tool.py: Replace module-level MEMORY_DIR constant with
   get_memory_dir() function that calls get_hermes_home() dynamically.
   The old constant was cached at import time and could go stale if
   HERMES_HOME changed after import. Internal MemoryStore methods now
   call get_memory_dir() directly. MEMORY_DIR kept as backward-compat
   alias.

2. profiles.py: profile create --clone now copies MEMORY.md and USER.md
   from the source profile. These curated memory files are part of the
   agent's identity (same as SOUL.md) and should carry over on clone.

3. holographic plugin: initialize() now expands $HERMES_HOME and
   ${HERMES_HOME} in the db_path config value, so users can write
   'db_path: $HERMES_HOME/memory_store.db' and it resolves to the
   active profile directory, not the default home.

Tests updated to mock get_memory_dir() alongside the legacy MEMORY_DIR.
@teknium1 teknium1 merged commit 8a38462 into main Apr 3, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant