From b0350365829ee67aee0cd40e7cb04774c57dab27 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 19 Aug 2026 17:33:10 -0700 Subject: [PATCH] fix(cli): /yolo reports locked-ON under process-frozen YOLO instead of a false OFF --- cli.py | 17 +++++++++++++++++ tests/cli/test_cli_yolo_toggle.py | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/cli.py b/cli.py index 1f1ebd45f5..d41ad55877 100644 --- a/cli.py +++ b/cli.py @@ -12672,11 +12672,28 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): """ from hermes_cli.colors import Colors as _Colors from tools.approval import ( + _YOLO_MODE_FROZEN, disable_session_yolo, enable_session_yolo, is_session_yolo_enabled, ) + # Process-level YOLO (--yolo flag / HERMES_YOLO_MODE at startup) is + # frozen into tools.approval at import time and cannot be disabled by + # the session toggle. Before this guard, /yolo printed "YOLO mode OFF — + # dangerous commands will require approval" while every command kept + # auto-approving (the frozen flag short-circuits the approval gate + # ahead of the session check) — a false safety claim. Say the truth + # instead of toggling a bypass that has no effect. + if _YOLO_MODE_FROZEN: + _cprint( + f" ⚡ YOLO is {_Colors.BOLD}{_Colors.RED}locked ON{_Colors.RESET}" + " for this process (started with --yolo / HERMES_YOLO_MODE)." + " /yolo cannot disable it — restart without the flag to" + " re-enable approvals." + ) + return + session_key = self.session_id or "default" # ``getattr`` guard: tests exercise this method unbound against a # minimal stand-in object (see tests/cli/test_cli_yolo_toggle.py); diff --git a/tests/cli/test_cli_yolo_toggle.py b/tests/cli/test_cli_yolo_toggle.py index 43dc6793c3..637ac7083f 100644 --- a/tests/cli/test_cli_yolo_toggle.py +++ b/tests/cli/test_cli_yolo_toggle.py @@ -138,6 +138,27 @@ class TestIsSessionYoloActiveHelper: with patch.object(approval_module, "_YOLO_MODE_FROZEN", True): assert HermesCLI._is_session_yolo_active(stand_in) is True + def test_toggle_under_frozen_yolo_reports_locked_and_stays_on(self): + """With process-level YOLO frozen ON, /yolo must NOT claim approvals + are back. Pre-fix, the second toggle printed "YOLO mode OFF — + dangerous commands will require approval" while the frozen flag kept + auto-approving everything — a false safety claim.""" + stand_in = _make_stand_in() + + printed = [] + with patch.object(approval_module, "_YOLO_MODE_FROZEN", True): + with patch("cli._cprint", side_effect=lambda msg: printed.append(msg)): + HermesCLI._toggle_yolo(stand_in) + HermesCLI._toggle_yolo(stand_in) + + # Still effectively ON, and no session-level state was flipped. + assert HermesCLI._is_session_yolo_active(stand_in) is True + assert not approval_module.is_session_yolo_enabled(SESSION_KEY) + + joined = "\n".join(printed) + assert "locked ON" in joined + assert "will require approval" not in joined + class TestToggleYoloEndToEnd: """End-to-end: a dangerous command must auto-approve through the same