From 79799c80f576f111b92cedfcfbdbecee950cdff8 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 25 May 2026 04:06:43 -0700 Subject: [PATCH] test(approval): patch _YOLO_MODE_FROZEN directly in test_yolo_overrides_cron_deny The test set HERMES_YOLO_MODE=1 via monkeypatch.setenv, expecting check_dangerous_command() to honor yolo and bypass cron_mode=deny. But tools.approval._YOLO_MODE_FROZEN is intentionally frozen at module import time (security: prevents prompt-injection runtime escalation). When CI imports the module BEFORE the test sets the env, the frozen value stays False and the yolo bypass never activates. Local runs missed this because the conftest leaked a non-empty HERMES_YOLO_MODE into the import-time env. CI's clean-env path exposed the bug deterministically on test (3) / test (4) shards. Fix: patch the module attribute directly via mock.patch.object so the test simulates process-startup-with-yolo regardless of import order. The behavior under test (yolo bypasses cron_mode=deny for non-hardline commands) is unchanged; the security invariant (_YOLO_MODE_FROZEN can't be set at runtime by skills) is preserved. Reproduced locally with: env -i HOME=$HOME PATH=$PATH python3 -m pytest tests/tools/test_cron_approval_mode.py -o 'addopts=' -v Without the fix: 1 failed, 23 passed. With the fix: 24 passed. --- tests/tools/test_cron_approval_mode.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/tools/test_cron_approval_mode.py b/tests/tools/test_cron_approval_mode.py index 3826813157a..8aae20659a6 100644 --- a/tests/tools/test_cron_approval_mode.py +++ b/tests/tools/test_cron_approval_mode.py @@ -240,8 +240,18 @@ class TestCronModeInteractions: monkeypatch.delenv("HERMES_INTERACTIVE", raising=False) monkeypatch.delenv("HERMES_GATEWAY_SESSION", raising=False) + # _YOLO_MODE_FROZEN is frozen at module import time (security: prevents + # prompt injection from runtime-setting HERMES_YOLO_MODE). When the + # test process imports tools.approval BEFORE this test sets the env, + # the frozen value is False and yolo-bypass paths don't activate. + # Patch the module attribute directly to simulate process-startup + # with HERMES_YOLO_MODE=1. from unittest.mock import patch as mock_patch - with mock_patch("tools.approval._get_cron_approval_mode", return_value="deny"): + import tools.approval + with ( + mock_patch.object(tools.approval, "_YOLO_MODE_FROZEN", True), + mock_patch("tools.approval._get_cron_approval_mode", return_value="deny"), + ): # Use a dangerous-but-not-hardline command — `rm -rf /` is now # hardline-blocked regardless of yolo (see test_hardline_blocklist.py). result = check_dangerous_command("rm -rf /tmp/stuff", "local")