Some checks are pending
CI / lint-and-test (push) Waiting to run
* Preserve candidate reasoning and disable automatic chat reinforcement * Retain exact-row guards for combined claim audits
76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
PATCH_PATH = ROOT / "hermes-agent" / "patches" / "enforce_leoclean_learning_policy.py"
|
|
|
|
|
|
def _load_module():
|
|
spec = importlib.util.spec_from_file_location("enforce_leoclean_learning_policy", PATCH_PATH)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def test_learning_policy_disables_automatic_reviews_without_removing_explicit_tools(tmp_path: Path) -> None:
|
|
module = _load_module()
|
|
config_path = tmp_path / "config.yaml"
|
|
original = """model:
|
|
provider: openrouter
|
|
gateway:
|
|
telegram:
|
|
bot_token: private-test-token
|
|
memory:
|
|
memory_enabled: true
|
|
user_profile_enabled: true
|
|
nudge_interval: 10
|
|
skills:
|
|
external_dirs: []
|
|
creation_nudge_interval: 10
|
|
"""
|
|
config_path.write_text(original, encoding="utf-8")
|
|
config_path.chmod(0o600)
|
|
|
|
result, code = module.enforce_policy(config_path)
|
|
|
|
assert code == 0
|
|
assert result["status"] == "updated"
|
|
assert result["policy"] == {
|
|
"memory_nudge_interval": 0,
|
|
"skill_creation_nudge_interval": 0,
|
|
}
|
|
assert "private-test-token" not in json.dumps(result)
|
|
updated = yaml.safe_load(config_path.read_text(encoding="utf-8"))
|
|
assert updated["memory"] == {
|
|
"memory_enabled": True,
|
|
"user_profile_enabled": True,
|
|
"nudge_interval": 0,
|
|
}
|
|
assert updated["skills"] == {"external_dirs": [], "creation_nudge_interval": 0}
|
|
assert updated["gateway"]["telegram"]["bot_token"] == "private-test-token"
|
|
assert config_path.stat().st_mode & 0o777 == 0o600
|
|
assert config_path.with_name(config_path.name + module.BACKUP_SUFFIX).read_text(encoding="utf-8") == original
|
|
|
|
check_result, check_code = module.enforce_policy(config_path, check=True)
|
|
assert check_code == 0
|
|
assert check_result["status"] == "compliant"
|
|
|
|
|
|
def test_learning_policy_check_reports_drift_without_writing(tmp_path: Path) -> None:
|
|
module = _load_module()
|
|
config_path = tmp_path / "config.yaml"
|
|
original = "memory:\n memory_enabled: true\n"
|
|
config_path.write_text(original, encoding="utf-8")
|
|
|
|
result, code = module.enforce_policy(config_path, check=True)
|
|
|
|
assert code == 1
|
|
assert result["status"] == "change_required"
|
|
assert config_path.read_text(encoding="utf-8") == original
|
|
assert not config_path.with_name(config_path.name + module.BACKUP_SUFFIX).exists()
|