diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 8748db2cb13..7bbec92cf62 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -847,6 +847,15 @@ def ensure_hermes_home(): any files created (e.g. SOUL.md) are group-writable (0660). """ home = get_hermes_home() + # Named profiles must be created explicitly (e.g. ``hermes profile create``). + # If a stale process keeps running after the profile was renamed/deleted, + # silently mkdir-ing the old HERMES_HOME would resurrect an empty skeleton + # and make the deleted profile reappear in Desktop/profile lists. + if home.parent.name == "profiles" and not home.exists(): + raise FileNotFoundError( + f"Named profile home does not exist: {home}. " + "Create the profile explicitly before using it." + ) if is_managed(): old_umask = os.umask(0o007) try: diff --git a/tests/hermes_cli/test_config.py b/tests/hermes_cli/test_config.py index 41eef04a1ba..37740c2ea75 100644 --- a/tests/hermes_cli/test_config.py +++ b/tests/hermes_cli/test_config.py @@ -89,6 +89,22 @@ class TestEnsureHermesHome: ensure_hermes_home() assert soul_path.read_text(encoding="utf-8") == mixed + def test_existing_named_profile_still_bootstraps_subdirs(self, tmp_path): + profile_home = tmp_path / ".hermes" / "profiles" / "coder" + profile_home.mkdir(parents=True) + with patch.dict(os.environ, {"HERMES_HOME": str(profile_home)}): + ensure_hermes_home() + assert (profile_home / "cron").is_dir() + assert (profile_home / "sessions").is_dir() + assert (profile_home / "memories").is_dir() + + def test_missing_named_profile_is_not_recreated(self, tmp_path): + profile_home = tmp_path / ".hermes" / "profiles" / "coder" + with patch.dict(os.environ, {"HERMES_HOME": str(profile_home)}): + with pytest.raises(FileNotFoundError, match="Named profile home does not exist"): + ensure_hermes_home() + assert not profile_home.exists() + class TestLoadConfigDefaults: def test_returns_defaults_when_no_file(self, tmp_path):