fix: scope plugin manager by resolved hermes home (keyed cache) - #63702
fix: scope plugin manager by resolved hermes home (keyed cache)#63702terry197913 wants to merge 1 commit into
Conversation
fix: remove .codegraph artifacts from commit
teknium1
left a comment
There was a problem hiding this comment.
Thanks for identifying a real multi-profile seam: current main's gateway scopes each multiplexed turn with set_hermes_home_override() (gateway/run.py:1441-1472), while hermes_cli/plugins.py:2029-2037 still has a single manager.
Problems
- The proposed cache does not isolate plugin registrations.
PluginContext.register_tool()writes to the process-globaltools.registry.registry(hermes_cli/plugins.py:428-442), which holds one entry per name (tools/registry.py:389-448);register_platform()also writes to the global platform registry (hermes_cli/plugins.py:963-978,gateway/platform_registry.py:231-248). Loading profile B can therefore replace or block profile A registrations despite separate managers. - The added regressions assert only context-engine/private-skill state (
tests/hermes_cli/test_plugins.py:2074-2087,2151-2157). They do not cover global tool/platform dispatch or return from B to A after module eviction.
Suggested changes
- Scope or activate the registration lifecycle along with the manager, then add A→B→A integration coverage for same-named profile-local tools and platforms plus a runtime relative import.
Automated hermes-sweeper review.
| # key the cache by the *resolved* home path so re-entering a previously | ||
| # seen profile reuses its manager (and picks up any modules it already | ||
| # imported) instead of rebuilding from scratch every switch. | ||
| _plugin_managers_by_home: Dict[Path, PluginManager] = {} |
There was a problem hiding this comment.
This cache isolates only PluginManager-owned fields. PluginContext.register_tool() still mutates the process-global tools.registry.registry, and register_platform() mutates the global platform registry. Loading profile B can therefore overwrite or reject profile A registrations even when the managers differ; the registration lifecycle must be profile-safe too.
| assert engine_a is not None | ||
| assert engine_b is not None | ||
| assert manager_a is not manager_b | ||
| assert engine_a is not engine_b |
There was a problem hiding this comment.
This proves distinct manager/engine objects only. Please add an A→B→A regression that registers and dispatches profile-specific tools/platforms through their real global registries; otherwise the remaining cross-profile registration bleed is untested.
Summary
Fix plugin manager cache to be scoped by resolved
HERMES_HOMEpath, preventing cross-profile plugin state bleed in multi-profile VPS environments.Root cause: Plugin manager was a process-global singleton. When multiple Hermes profiles (Luna / Apollo / Hephaestus) ran on the same VPS, the first profile to load a plugin (e.g.
hermes-lcmcontext engine) cached its instance. Subsequent profiles then received the wrong plugin instance, leading to incorrectlcm.dband other profile-specific state being shared.Fix (3 parts):
_plugin_home_key()+ keyed_plugin_managers_by_homecache (ContextVar-aware) — multi-profile gateway isolation_make_plugin_dir()test helper now acceptshome=for per-profile isolation_clear_plugin_submodules()evictshermes_plugins.{slug}.*fromsys.moduleson reload and import failureAdds regression tests:
test_profile_isolation_separate_managers_and_statetest_force_rediscover_clears_all_cachesVerification: 118 plugin tests pass.
Opened by Luna (kanban-assigned Hephaestus task). Branch:
luna/pr-28109-profile-isolation-fixonterry197913/hermes-agent.