- Promote [Unreleased] CHANGELOG entries to [3.8.0] (2026-04-05) - Add Shell Danger Detection section to docs/api/tui.md covering ShellDangerLevel, DangerousPattern, ShellSafetyService, and SafetyCheckResult with full API reference and usage examples - Add InvariantService section to docs/api/core.md documenting the new DI-registered singleton, its methods, and emitted events - Update docs/architecture.md Plan Lifecycle section to document invariant reconciliation as a phase transition gate - Update README.md Highlights with shell danger detection, inline permission questions, invariant reconciliation, UKO provenance tracking, and JSON-RPC 2.0 A2A wire format - Create docs/modules/shell-safety.md with full module guide covering purpose, key classes, built-in patterns, custom pattern registration, TUI integration, and testing guidance ISSUES CLOSED: #1003 #997 #1391 #1004 #891 #1501 #1577 #1941 #2334
4.4 KiB
Shell Safety Module
Package: cleveragents.tui.shell_safety
The shell safety module protects users from accidentally executing dangerous
commands in the TUI shell mode (! prefix). It provides a configurable
pattern registry, a danger-level classification system, and an application
service that integrates with the TUI warning overlay.
Purpose
When a user types !<command> in the TUI, the ShellSafetyService checks
the command against a registry of known-dangerous patterns before the
subprocess is spawned. Commands that match a pattern at or above the
configured block_level are blocked; commands below that level surface a
warning overlay that the user must acknowledge before proceeding.
Key Classes
ShellDangerLevel
Four-level IntEnum severity scale:
LOW (1) < MEDIUM (2) < HIGH (3) < CRITICAL (4)
Numeric comparisons work naturally: level >= ShellDangerLevel.HIGH.
DangerousPattern
Immutable frozen dataclass describing a single dangerous pattern:
DangerousPattern(
name="fork_bomb",
pattern=r":\(\)\s*\{",
level=ShellDangerLevel.CRITICAL,
description="Fork bomb — exhausts process table and crashes the system.",
)
DangerousPatternDetector
Maintains the registry of DangerousPattern objects and provides
check_first(command) → DangerousCommandWarning | None to return the
highest-severity matching pattern.
ShellSafetyService
High-level application service used by the TUI:
from cleveragents.tui.shell_safety import ShellSafetyService, ShellDangerLevel
# Default: block MEDIUM and above automatically
service = ShellSafetyService()
# Custom: only block CRITICAL; show overlay for HIGH and below
service = ShellSafetyService(block_level=ShellDangerLevel.CRITICAL)
# Custom: delegate all decisions to a callback
def my_callback(warning):
# Return True to allow, False to block
return warning.danger_level < ShellDangerLevel.HIGH
service = ShellSafetyService(warn_callback=my_callback)
result = service.check_command("rm -rf /")
if not result.allowed:
print(f"Blocked: {result.warning.description}")
DangerousCommandWarning
Value object returned when a dangerous pattern is matched:
| Attribute | Type | Description |
|---|---|---|
command |
str |
The original command text |
pattern |
DangerousPattern |
The matched pattern |
danger_level |
ShellDangerLevel |
Convenience alias for pattern.level |
message |
str |
Human-readable warning message |
Built-in Pattern Categories
| Category | Example patterns | Default level |
|---|---|---|
| Recursive deletion | rm -rf /, rm -rf ~ |
CRITICAL |
| Disk-level writes | dd if=, mkfs, shred |
CRITICAL |
| Fork bombs | `:(){ : | :& };:` |
| Privilege escalation | sudo su, chmod 777 / |
HIGH |
| Network exfiltration | curl | sh, wget | bash |
HIGH |
| Reverse shells | nc -e /bin/sh, bash -i >& /dev/tcp |
HIGH |
| Dangerous redirects | > /dev/sda, > /etc/passwd |
HIGH |
| Credential exposure | env | curl, cat ~/.ssh/id_rsa | nc |
MEDIUM |
Adding Custom Patterns
from cleveragents.tui.shell_safety import (
DangerousPattern,
ShellDangerLevel,
ShellSafetyService,
)
custom = DangerousPattern(
name="drop_database",
pattern=r"DROP\s+DATABASE",
level=ShellDangerLevel.HIGH,
description="Drops an entire database — irreversible.",
case_sensitive=False,
)
service = ShellSafetyService(extra_patterns=[custom])
Integration with the TUI
The TUI wires ShellSafetyService into the shell input handler. When
check_command() returns allowed=False, the TUI displays a
DangerousCommandWarningOverlay widget with the warning message and danger
level. The user must explicitly confirm before the command is executed.
For commands that are blocked outright (above block_level with no
callback), the overlay displays a non-dismissable error and the command is
never executed.
Testing
The shell safety module is fully covered by BDD scenarios in
features/shell_safety.feature. All pattern matching is deterministic and
does not require a running TUI, making it straightforward to test in
isolation:
from cleveragents.tui.shell_safety import ShellSafetyService
service = ShellSafetyService()
assert not service.is_safe("rm -rf /")
assert service.is_safe("ls -la")