fix(honcho): inherit identity-mapping config in cloned profile blocks

PR #27371 added host-scoped userPeerAliases, runtimePeerPrefix, and
pinPeerName, but the cloned-profile allowlist in
plugins/memory/honcho/cli.py::clone_honcho_for_profile() omitted them.
A new profile created via 'hermes honcho setup' or similar would
silently drop the operator's identity-mapping config, causing gateway
users to resolve to raw runtime IDs and fragmenting Honcho memory
across an unintended set of peers.

Add the three keys to the allowlist and a regression test class
covering all three plus the unset case.
This commit is contained in:
erosika 2026-05-21 22:15:14 +00:00 committed by kshitij
parent 30b391ab36
commit 00e6830204
2 changed files with 94 additions and 3 deletions

View file

@ -40,12 +40,18 @@ def clone_honcho_for_profile(profile_name: str) -> bool:
if new_host in hosts:
return False # already exists
# Clone settings from default block, override identity fields
# Clone settings from default block, override identity fields.
# Identity-mapping keys (pinPeerName, userPeerAliases, runtimePeerPrefix)
# carry the operator's runtime-to-peer routing intent from #27371.
# Without them in this allowlist, a cloned profile would silently lose
# the mapping and gateway users would resolve to raw runtime IDs,
# fragmenting Honcho memory across an unintended set of peers.
new_block = {}
for key in ("recallMode", "writeFrequency", "sessionStrategy",
"sessionPeerPrefix", "contextTokens", "dialecticReasoningLevel",
"dialecticDynamic", "dialecticMaxChars", "messageMaxChars",
"dialecticMaxInputChars", "saveMessages", "observation"):
"dialecticMaxInputChars", "saveMessages", "observation",
"pinPeerName", "userPeerAliases", "runtimePeerPrefix"):
val = default_block.get(key)
if val is not None:
new_block[key] = val

View file

@ -153,4 +153,89 @@ class TestCmdStatus:
out = capsys.readouterr().out
assert "FAILED (Invalid API key)" in out
assert "Connection... OK" not in out
assert "Connection... OK" not in out
class TestCloneHonchoForProfile:
"""Regression tests for clone_honcho_for_profile identity-key carryover.
PR #27371 added userPeerAliases, runtimePeerPrefix, and pinPeerName as
host-scoped identity-mapping config. These keys must survive profile
cloning, otherwise a new profile silently fragments memory by resolving
gateway users to raw runtime IDs instead of operator-declared peers.
"""
def _setup_clone_env(self, monkeypatch, tmp_path, cfg):
import plugins.memory.honcho.cli as honcho_cli
cfg_path = tmp_path / "config.json"
cfg_path.write_text("{}")
monkeypatch.setattr(honcho_cli, "_read_config", lambda: cfg)
monkeypatch.setattr(honcho_cli, "_config_path", lambda: cfg_path)
monkeypatch.setattr(honcho_cli, "_local_config_path", lambda: cfg_path)
monkeypatch.setattr(honcho_cli, "_ensure_peer_exists", lambda host_key=None: True)
written = {}
def _write(c, path=None):
written["cfg"] = c
monkeypatch.setattr(honcho_cli, "_write_config", _write)
return honcho_cli, written
def test_user_peer_aliases_carry_into_cloned_profile(self, monkeypatch, tmp_path):
cfg = {
"apiKey": "***",
"hosts": {
"hermes": {
"userPeerAliases": {"86701400": "eri", "discord-491827364": "eri"},
"peerName": "eri",
},
},
}
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
ok = honcho_cli.clone_honcho_for_profile("coder")
assert ok is True
new_block = written["cfg"]["hosts"]["hermes.coder"]
assert new_block["userPeerAliases"] == {"86701400": "eri", "discord-491827364": "eri"}
def test_runtime_peer_prefix_carries_into_cloned_profile(self, monkeypatch, tmp_path):
cfg = {
"apiKey": "***",
"hosts": {
"hermes": {
"runtimePeerPrefix": "telegram_",
"peerName": "eri",
},
},
}
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
ok = honcho_cli.clone_honcho_for_profile("coder")
assert ok is True
new_block = written["cfg"]["hosts"]["hermes.coder"]
assert new_block["runtimePeerPrefix"] == "telegram_"
def test_pin_peer_name_carries_into_cloned_profile(self, monkeypatch, tmp_path):
cfg = {
"apiKey": "***",
"hosts": {
"hermes": {
"pinPeerName": True,
"peerName": "eri",
},
},
}
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
ok = honcho_cli.clone_honcho_for_profile("coder")
assert ok is True
new_block = written["cfg"]["hosts"]["hermes.coder"]
assert new_block["pinPeerName"] is True
def test_unset_identity_keys_do_not_appear_in_cloned_profile(self, monkeypatch, tmp_path):
cfg = {
"apiKey": "***",
"hosts": {"hermes": {"peerName": "eri"}},
}
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
ok = honcho_cli.clone_honcho_for_profile("coder")
assert ok is True
new_block = written["cfg"]["hosts"]["hermes.coder"]
assert "userPeerAliases" not in new_block
assert "runtimePeerPrefix" not in new_block
assert "pinPeerName" not in new_block