test(config): pin load_env's dotenv inline-comment semantics

load_env now tokenizes through agent.secret_scope.load_env_file, which
strips an unquoted ` # ...` tail (dotenv standard; the behaviour the
profile secret scope already had). Pin both halves of the rule so the
value-semantics change is a stated contract, not an accident: unquoted
`abc #123` -> `abc`, quoted `"abc #123"` -> `abc #123`. Hermes' own
writer (_quote_env_value) quotes any value containing `#`, so saved
secrets round-trip.
This commit is contained in:
teknium1
2026-09-12 23:44:37 -07:00
committed by Teknium
parent 9401cc1643
commit 2ef929dfe0

View File

@@ -405,6 +405,21 @@ class TestSaveAndLoadRoundtrip:
assert config_path.read_text(encoding="utf-8") == original
assert list((tmp_path / "backups" / "config").glob("config.yaml.corrupt.*"))
class TestLoadEnvInlineComments:
def test_unquoted_hash_is_a_comment_quoted_hash_is_data(self, tmp_path):
"""load_env is the one dotenv reader (agent.secret_scope.load_env_file): an unquoted ` #...` tail
is a comment, a quoted value keeps its hash. Hermes' own writer (_quote_env_value) always quotes
values containing `#`, so a saved secret round-trips."""
from hermes_cli.config import invalidate_env_cache
(tmp_path / ".env").write_text('PASSWORD=abc #123\nPASSWORD2="abc #123"\n', encoding="utf-8")
with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}):
invalidate_env_cache()
env = load_env()
assert env["PASSWORD"] == "abc"
assert env["PASSWORD2"] == "abc #123"
class TestSaveEnvValueSecure:
def test_secure_save_returns_metadata_only(self, tmp_path):