diff --git a/tests/tools/test_skills_guard.py b/tests/tools/test_skills_guard.py index 530d42aeb97..e2cc1c84e79 100644 --- a/tests/tools/test_skills_guard.py +++ b/tests/tools/test_skills_guard.py @@ -152,6 +152,31 @@ class TestShouldAllowInstall: ) assert allowed is False assert "Blocked" in reason + # Error message MUST explain why --force didn't work, not invite a retry. + assert "does not override" in reason + assert "Use --force to override" not in reason + + def test_force_does_not_override_dangerous_for_trusted_message(self): + f = [Finding("x", "critical", "c", "f", 1, "m", "d")] + allowed, reason = should_allow_install( + self._result("trusted", "dangerous", f), force=True + ) + assert allowed is False + assert "does not override" in reason + assert "Use --force to override" not in reason + + def test_non_dangerous_block_keeps_force_hint(self): + # When --force CAN override the block, the error message must still + # point to it. Use builtin trust + dangerous to land in the block + # branch without triggering the dangerous-specific message. + f = [Finding("x", "high", "network", "f", 1, "m", "d")] + # Construct a path where decision == block but verdict != dangerous. + # community + caution = block per current INSTALL_POLICY. + allowed, reason = should_allow_install( + self._result("community", "caution", f), force=False + ) + assert allowed is False + assert "Use --force to override" in reason def test_force_does_not_override_dangerous_for_trusted(self): f = [Finding("x", "critical", "c", "f", 1, "m", "d")] diff --git a/tools/skills_guard.py b/tools/skills_guard.py index 2375a8e09a7..28d29daa5c6 100644 --- a/tools/skills_guard.py +++ b/tools/skills_guard.py @@ -674,6 +674,13 @@ def should_allow_install(result: ScanResult, force: bool = False) -> Tuple[bool, f"{len(result.findings)} findings)" ) + # Dangerous verdicts cannot be overridden by --force (community/trusted); + # other blocks can. + if result.verdict == "dangerous" and result.trust_level in ("community", "trusted"): + return False, ( + f"Blocked ({result.trust_level} source + dangerous verdict, " + f"{len(result.findings)} findings). --force does not override a dangerous verdict." + ) return False, ( f"Blocked ({result.trust_level} source + {result.verdict} verdict, " f"{len(result.findings)} findings). Use --force to override."