From afa4f4c660b5200e1395a47ee4adb9e9583f8adc Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Tue, 18 Aug 2026 23:12:58 -0700 Subject: [PATCH] fix: 7 GitHub-adjacent tests no longer fail on developer machines Three local-environment leaks made tests red locally while green on CI: - tests/conftest.py: blank HERMES_REAL_HOME and TERMINAL_HOME_MODE per test. The terminal tool injects both into subprocess envs, so any pytest run launched from a Hermes session inherits them and the hermes_constants home-resolution helpers prefer HERMES_REAL_HOME over the monkeypatched HOME (4 failures in test_subprocess_home_isolation.py). - test_modal_sandbox_fixes.py: reset the import-time _YOLO_MODE_FROZEN flag and pin approval mode to manual in _isolate_approval_state(). HERMES_YOLO_MODE=1 in the launching shell froze True at collection time and every guard auto-approved (2 failures). - test_noninteractive_git.py: strip GIT_ASKPASS/VS Code askpass vars in the fail-fast clone E2E. noninteractive_git_env() intentionally keeps a working askpass helper, but this test asserts the no-helper path; under VS Code the helper blocks on the editor until the 30s timeout (1 failure). Verified: all 49 tests in the three files pass both in a plain dev shell (with HERMES_YOLO_MODE=1, HERMES_REAL_HOME, and VS Code askpass set) and inside an unshare -rn network namespace. --- tests/conftest.py | 6 ++++++ tests/hermes_cli/test_noninteractive_git.py | 12 +++++++++++- tests/tools/test_modal_sandbox_fixes.py | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index a1d0a034c5..00644ab7e6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -264,6 +264,12 @@ _HERMES_BEHAVIORAL_VARS = frozenset({ "HERMES_VOICE", "HERMES_VOICE_TTS", "HERMES_YOLO_MODE", + # Injected into subprocess envs by the terminal tool (_make_run_env), so + # any test run launched FROM a Hermes agent session inherits them and + # hermes_constants home-resolution helpers prefer them over monkeypatched + # HOME (test_subprocess_home_isolation red locally, green on CI). + "HERMES_REAL_HOME", + "TERMINAL_HOME_MODE", "HERMES_INTERACTIVE", "HERMES_QUIET", "HERMES_TOOL_PROGRESS", diff --git a/tests/hermes_cli/test_noninteractive_git.py b/tests/hermes_cli/test_noninteractive_git.py index 1150ab6111..2b8e48b814 100644 --- a/tests/hermes_cli/test_noninteractive_git.py +++ b/tests/hermes_cli/test_noninteractive_git.py @@ -84,6 +84,16 @@ def test_git_clone_against_auth_remote_fails_fast(tmp_path: Path): thread.start() try: t0 = time.monotonic() + env = noninteractive_git_env() + # noninteractive_git_env deliberately leaves GIT_ASKPASS/SSH_ASKPASS + # alone so a user's WORKING helper can still authenticate. This test + # asserts the no-helper fail-fast path, so strip them — otherwise a + # dev shell's VS Code askpass helper (GIT_ASKPASS=...askpass.sh) + # blocks waiting on the editor and the clone times out locally. + for var in ("GIT_ASKPASS", "SSH_ASKPASS", "VSCODE_GIT_ASKPASS_NODE", + "VSCODE_GIT_ASKPASS_MAIN", "VSCODE_GIT_ASKPASS_EXTRA_ARGS", + "VSCODE_GIT_IPC_HANDLE"): + env.pop(var, None) proc = subprocess.run( ["git", "clone", f"http://127.0.0.1:{port}/private.git", str(tmp_path / "dest")], @@ -91,7 +101,7 @@ def test_git_clone_against_auth_remote_fails_fast(tmp_path: Path): text=True, timeout=30, stdin=subprocess.DEVNULL, - env=noninteractive_git_env(), + env=env, ) elapsed = time.monotonic() - t0 assert proc.returncode != 0 diff --git a/tests/tools/test_modal_sandbox_fixes.py b/tests/tools/test_modal_sandbox_fixes.py index 6238f4710e..89878150dc 100644 --- a/tests/tools/test_modal_sandbox_fixes.py +++ b/tests/tools/test_modal_sandbox_fixes.py @@ -391,10 +391,19 @@ class TestDockerHostBindApproval: config permanently allowlists e.g. "delete in root path" the guard under test silently approves and the assertions flip. CI never has such an allowlist, making this a local-only flake. + + Same import-time freeze applies to ``_YOLO_MODE_FROZEN``: it reads + HERMES_YOLO_MODE off the environment when the module is imported at + collection time, before conftest's per-test env blanking runs. A test + run launched from a --yolo Hermes session (or any shell exporting + HERMES_YOLO_MODE=1) freezes True and every guard auto-approves. + Reset it explicitly so the tests exercise the guard, not the bypass. """ import tools.approval as A monkeypatch.setattr(A, "_permanent_approved", set()) monkeypatch.setattr(A, "_session_approved", {}) + monkeypatch.setattr(A, "_YOLO_MODE_FROZEN", False) + monkeypatch.setattr(A, "_get_approval_mode", lambda: "manual") def test_host_bound_docker_requires_approval(self, monkeypatch): """Host-bound Docker dangerous command escalates instead of bypassing."""