fix(hindsight): corrupt config.json falls through to the legacy file and env, as before
read_json_or_empty returns {} for malformed JSON; returning that directly from
_load_config made a corrupt profile config.json yield an empty (silently
unconfigured) mapping where the pre-dedup loop kept walking to the legacy
file and then the env branch. Only a non-empty parsed object is now returned.
This commit is contained in:
@@ -235,8 +235,9 @@ def _load_config() -> dict:
|
||||
"""$HERMES_HOME/hindsight/config.json (profile-scoped), else ~/.hindsight/config.json
|
||||
(legacy, shared), else environment variables."""
|
||||
for path in (get_hermes_home() / "hindsight" / "config.json", Path.home() / ".hindsight" / "config.json"):
|
||||
if path.exists():
|
||||
return read_json_or_empty(path)
|
||||
# A corrupt (or empty) file falls through to the next source, as before the dedup.
|
||||
if path.exists() and (data := read_json_or_empty(path)):
|
||||
return data
|
||||
# Mode, bank (the data partition), endpoint and retain shaping are per-profile .env values like
|
||||
# the key beside them: read through the secret scope so a multiplexed secondary never inherits
|
||||
# the default profile's bank/mode. Tuning knobs (timeouts, budget) stay process-global.
|
||||
|
||||
@@ -1540,6 +1540,23 @@ def test_save_config_sets_owner_only_permissions(tmp_path):
|
||||
assert mode == 0o600, f"Expected 0o600 (owner-only), got {oct(mode)}"
|
||||
|
||||
|
||||
def test_load_config_corrupt_profile_file_falls_through_to_env(tmp_path, monkeypatch):
|
||||
"""A corrupt $HERMES_HOME/hindsight/config.json is not the config: the loader falls through
|
||||
(legacy file, then env) instead of returning an empty, silently-unconfigured mapping."""
|
||||
home = tmp_path / "home"
|
||||
(home / "hindsight").mkdir(parents=True)
|
||||
(home / "hindsight" / "config.json").write_text("{not json", encoding="utf-8")
|
||||
monkeypatch.setenv("HERMES_HOME", str(home))
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path / "nohome")
|
||||
monkeypatch.setenv("HINDSIGHT_MODE", "local")
|
||||
monkeypatch.setenv("HINDSIGHT_BANK_ID", "from-env")
|
||||
|
||||
cfg = _load_config()
|
||||
|
||||
assert cfg["mode"] == "local"
|
||||
assert cfg["banks"]["hermes"]["bankId"] == "from-env"
|
||||
|
||||
|
||||
class TestLoadSimpleEnv:
|
||||
def test_bom_first_key_is_recognized(self, tmp_path):
|
||||
"""A Notepad-edited .env carries a BOM; the first key must still parse
|
||||
|
||||
Reference in New Issue
Block a user