From 495c3733d8cedca83f741560623d5efd86f2ab03 Mon Sep 17 00:00:00 2001 From: Dusk <135010814+Dusk1e@users.noreply.github.com> Date: Fri, 5 Jun 2026 02:31:01 +0300 Subject: [PATCH] fix(config): bridge docker_volumes and docker_forward_env in config set (#38611) Co-authored-by: Ben Barclay --- hermes_cli/config.py | 5 +++ tests/tools/test_terminal_config_env_sync.py | 47 +++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/hermes_cli/config.py b/hermes_cli/config.py index a6948c23f..d0b4493dd 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -5958,6 +5958,11 @@ def set_config_value(key: str, value: str): "terminal.docker_persist_across_processes": "TERMINAL_DOCKER_PERSIST_ACROSS_PROCESSES", "terminal.docker_orphan_reaper": "TERMINAL_DOCKER_ORPHAN_REAPER", "terminal.docker_env": "TERMINAL_DOCKER_ENV", + # JSON-valued keys (terminal_tool parses these via json.loads). The user + # passes JSON on the CLI, so str(value) below already yields valid JSON — + # same as terminal.docker_env. cli.py and gateway/run.py bridge these too. + "terminal.docker_volumes": "TERMINAL_DOCKER_VOLUMES", + "terminal.docker_forward_env": "TERMINAL_DOCKER_FORWARD_ENV", # terminal.cwd intentionally excluded — CLI resolves at runtime, # gateway bridges it in gateway/run.py. Persisting to .env causes # stale values to poison child processes. diff --git a/tests/tools/test_terminal_config_env_sync.py b/tests/tools/test_terminal_config_env_sync.py index 161318434..a3b9b14dd 100644 --- a/tests/tools/test_terminal_config_env_sync.py +++ b/tests/tools/test_terminal_config_env_sync.py @@ -156,14 +156,15 @@ def test_cli_and_gateway_env_maps_agree(): def test_save_config_set_supports_critical_bridged_keys(): """``hermes config set terminal.X true`` must propagate to .env for - known-critical keys. This used to be an all-keys invariant but several - pre-existing terminal keys (ssh_*, docker_forward_env, docker_volumes) - aren't in _config_to_env_sync and are instead handled via the separate - api_keys TERMINAL_SSH_* fallback path or user-edits-yaml-directly. + known-critical keys. This used to be an all-keys invariant but the SSH + terminal keys (ssh_*) aren't in _config_to_env_sync and are instead + handled via the separate api_keys TERMINAL_SSH_* fallback path or + user-edits-yaml-directly. Until those gaps are audited and fixed, pin the specific keys that are - load-bearing for the docker backend's ownership flag so the bug we just - fixed cannot silently regress. + load-bearing for the docker backend so the bugs we fixed cannot silently + regress. (docker_volumes / docker_forward_env, previously listed here as + gaps, are now bridged — see the dedicated tests below.) """ save_keys = _save_config_env_sync_keys() required = { @@ -260,3 +261,37 @@ def test_docker_orphan_reaper_is_bridged_everywhere(): assert "docker_orphan_reaper" in _gateway_env_map_keys() assert "docker_orphan_reaper" in _save_config_env_sync_keys() assert "TERMINAL_DOCKER_ORPHAN_REAPER" in _terminal_tool_env_var_names() + + +def test_docker_volumes_is_bridged_everywhere(): + """Regression pin for ``terminal.docker_volumes`` being silently dropped by + ``hermes config set``. + + The JSON list of ``host:container`` bind mounts was bridged by cli.py and + gateway/run.py and consumed by terminal_tool (via json.loads), but was + missing from set_config_value's _config_to_env_sync. So + ``hermes config set terminal.docker_volumes '["/host:/workspace"]'`` wrote + config.yaml yet left the running process's TERMINAL_DOCKER_VOLUMES stale — + the mounts didn't apply until a full restart. Same four-site bridge + invariant as docker_env / docker_run_as_host_user. + """ + assert "docker_volumes" in _cli_env_map_keys() + assert "docker_volumes" in _gateway_env_map_keys() + assert "docker_volumes" in _save_config_env_sync_keys() + assert "TERMINAL_DOCKER_VOLUMES" in _terminal_tool_env_var_names() + + +def test_docker_forward_env_is_bridged_everywhere(): + """Regression pin for ``terminal.docker_forward_env`` — the sibling gap to + docker_volumes. + + The JSON list of host env-var names forwarded into the container was + bridged by cli.py and gateway/run.py and consumed by terminal_tool (via + json.loads), but missing from set_config_value's _config_to_env_sync, so + ``hermes config set terminal.docker_forward_env '["GITHUB_TOKEN"]'`` had no + effect on the running process until restart. + """ + assert "docker_forward_env" in _cli_env_map_keys() + assert "docker_forward_env" in _gateway_env_map_keys() + assert "docker_forward_env" in _save_config_env_sync_keys() + assert "TERMINAL_DOCKER_FORWARD_ENV" in _terminal_tool_env_var_names()