*** Settings *** Documentation Integration coverage for TUI shell safety wiring and safeguards. Resource ${CURDIR}/common.resource Suite Setup Setup Test Environment With Database Isolation Suite Teardown Cleanup Test Environment *** Variables *** ${TIMEOUT} 45s *** Test Cases *** Shell Safety Service Blocks Denied Command [Documentation] ShellSafetyService verdict should block commands even when heuristics allow them. [Tags] tui shell_safety regression ${script}= Catenate SEPARATOR=\n ... import os ... from cleveragents.tui.input.modes import InputModeRouter ... from cleveragents.tui.shell_safety import ShellSafetyService ... from cleveragents.tui.shell_safety.warning import DangerousCommandWarning ... ... warnings: list[DangerousCommandWarning] = [] ... ... def warn_callback(warning: DangerousCommandWarning) -> bool: ... ${SPACE * 4}warnings.append(warning) ... ${SPACE * 4}return False ... ... router = InputModeRouter(lambda cmd: "handled", shell_safety=ShellSafetyService(warn_callback=warn_callback)) ... os.environ.pop("CLEVERAGENTS_ALLOW_DANGEROUS_SHELL", None) ... result = router.process("!chmod -R 777 /tmp/test-shell-safety") ... assert result.shell_warning is not None, "Shell safety warning should be surfaced" ... assert warnings and warnings[0].command == "chmod -R 777 /tmp/test-shell-safety" ... assert result.shell_result is not None, "Shell result should be populated" ... assert result.shell_result.exit_code == 1, f"Expected blocked exit code, got {result.shell_result.exit_code}" ... assert "blocked" in result.shell_result.stderr.lower(), result.shell_result.stderr ... print("blocked-ok") ${result}= Run Process ${PYTHON} -c ${script} ... timeout=${TIMEOUT} on_timeout=kill ... env:PYTHONPATH=${CURDIR}/../src Should Be Equal As Integers ${result.rc} 0 Shell safety blocking script failed: ${result.stderr} Should Contain ${result.stdout} blocked-ok Shell Confirm Callback Gates All Commands [Documentation] run_shell_command must respect confirm callback regardless of built-in heuristics. [Tags] tui shell_safety regression ${script}= Catenate SEPARATOR=\n ... from cleveragents.tui.input.shell_exec import run_shell_command ... ... counter = {"count": 0} ... ... def deny(command: str) -> bool: ... ${SPACE * 4}counter["count"] += 1 ... ${SPACE * 4}return False ... ... result = run_shell_command("chmod -R 777 /tmp/test-shell-safety", confirm_dangerous=deny) ... assert counter["count"] == 1, f"Expected confirm to be invoked once, got {counter['count']}" ... assert result.exit_code == 1, f"Expected blocked exit code, got {result.exit_code}" ... assert "blocked" in result.stderr.lower(), result.stderr ... print("confirm-gate-ok") ${result}= Run Process ${PYTHON} -c ${script} ... timeout=${TIMEOUT} on_timeout=kill ... env:PYTHONPATH=${CURDIR}/../src Should Be Equal As Integers ${result.rc} 0 Shell confirm gate script failed: ${result.stderr} Should Contain ${result.stdout} confirm-gate-ok