fix(honcho): every honcho.json writer holds _refresh_lock and reads strictly

The CLI's _write_config took only the best-effort file lock, so an in-process
refresh thread could still interleave with a command's read-modify-write. The
dashboard's Honcho save (_write_provider_honcho) still seeded its whole-file
rewrite from a tolerant reader, so a honcho.json that exists but does not parse
was replaced by the active host's block alone from the UI - the same bug class
this PR closes on the CLI and refresh paths. `hermes profile create --clone`
swallowed the new ConfigWriteRefused as "plugin not installed".

One parametrized test covers the web writer for the corrupt and parseable cases.
This commit is contained in:
kshitijk4poor
2026-09-12 22:35:12 +05:30
committed by kshitij
parent 56231e51ad
commit 24b33d42e0
4 changed files with 49 additions and 9 deletions
+10 -4
View File
@@ -245,11 +245,17 @@ def _profile_create(args):
_print_channel_clone_notice(name, source_label, clone_channels, "--clone-all" if clone_all else "--clone")
# Auto-clone Honcho config for the new profile (only with clone operations)
try:
from plugins.memory.honcho.cli import clone_honcho_for_profile
if clone_honcho_for_profile(name):
print(f"Honcho config cloned (peer: {name})")
from plugins.memory.honcho.cli import ConfigWriteRefused, clone_honcho_for_profile
except Exception:
pass # Honcho plugin not installed or not configured
clone_honcho_for_profile = None # Honcho plugin not installed
if clone_honcho_for_profile is not None:
try:
if clone_honcho_for_profile(name):
print(f"Honcho config cloned (peer: {name})")
except ConfigWriteRefused as e:
print(f"Honcho config not cloned: {e}")
except Exception:
pass # Honcho not configured
else:
# Fresh profiles only: clones already carry the source's (user-curated) skills.
result = seed_profile_skills(profile_dir)