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.
This commit is contained in:
Teknium
2026-08-18 23:12:58 -07:00
parent 63565fa26b
commit afa4f4c660
3 changed files with 26 additions and 1 deletions
+6
View File
@@ -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",
+11 -1
View File
@@ -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
+9
View File
@@ -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."""