docs: shell safety API, invariant reconciliation architecture, new feature highlights #3476

Merged
freemo merged 1 commits from docs/shell-safety-invariant-reconciliation-2026-04-05 into master 2026-04-05 21:06:58 +00:00
2 changed files with 111 additions and 3 deletions
+71 -3
View File
@@ -293,7 +293,8 @@ from cleveragents.tui.shell_safety import ShellDangerLevel
| `HIGH` | 3 | High risk — significant, hard-to-reverse damage (e.g. `dd if=`, `mkfs`) |
| `CRITICAL` | 4 | Critical risk — can destroy the system or create a fork bomb (e.g. `rm -rf /`, `:(){ :\|:& };:`) |
Numeric comparisons work naturally: `level >= ShellDangerLevel.HIGH`.
Because `ShellDangerLevel` is an `IntEnum`, numeric comparisons work
naturally: `level >= ShellDangerLevel.HIGH`.
---
@@ -302,7 +303,6 @@ Numeric comparisons work naturally: `level >= ShellDangerLevel.HIGH`.
```python
from cleveragents.tui.shell_safety import DangerousPattern
pattern = DangerousPattern(
name="rm_rf_root",
pattern=r"rm\s+-[rRfF]*\s+/",
level=ShellDangerLevel.CRITICAL,
@@ -324,6 +324,54 @@ Immutable frozen dataclass describing a single dangerous shell pattern.
---
### Built-in Patterns (`DEFAULT_PATTERNS`)
```python
from cleveragents.tui.shell_safety.pattern_registry import DEFAULT_PATTERNS
```
The default pattern set covers the most common dangerous shell operations:
| Name | Level | Trigger |
|------|-------|---------|
| `rm_rf_root` | CRITICAL | `rm -rf /` |
| `rm_rf_wildcard` | CRITICAL | `rm -rf /*` or similar |
| `fork_bomb` | CRITICAL | `:(){ :|:& };:` |
| `dd_if_device` | HIGH | `dd if=` |
| `mkfs` | HIGH | `mkfs` |
| `shred_device` | HIGH | `shred /dev/` or `shred --remove` |
| `chmod_777` | MEDIUM | `chmod 777` |
| `sudo_rm` | MEDIUM | `sudo rm` |
| `wget_pipe_sh` | MEDIUM | `wget … \| sh` |
| `curl_pipe_sh` | MEDIUM | `curl … \| sh` |
| `wget_pipe_bash` | MEDIUM | `wget … \| bash` |
| `curl_pipe_bash` | MEDIUM | `curl … \| bash` |
| `git_push_force` | LOW | `git push --force` |
| `chmod_recursive_permissive` | LOW | `chmod -R 6xx/7xx` |
---
### `DangerousPatternDetector`
```python
from cleveragents.tui.shell_safety import DangerousPatternDetector
detector = DangerousPatternDetector()
warning = detector.check_first("rm -rf /")
# → DangerousCommandWarning or None
```
Checks a command string against all registered patterns and returns the
first match as a `DangerousCommandWarning`, or `None` if the command is safe.
| Method | Description |
|--------|-------------|
| `check_first(command) → DangerousCommandWarning \| None` | Return the first matching warning |
| `check_all(command) → list[DangerousCommandWarning]` | Return all matching warnings |
| `add_pattern(pattern)` | Register an additional `DangerousPattern` |
---
### `ShellSafetyService`
```python
@@ -353,7 +401,11 @@ Application service that checks shell commands before execution.
| `check_command(command)` | `SafetyCheckResult` | Check a command and return a structured result |
| `is_safe(command)` | `bool` | Convenience wrapper — returns `True` if the command passes |
**`SafetyCheckResult`** attributes:
**`SafetyCheckResult`** — import path and attributes:
```python
from cleveragents.tui.shell_safety.safety_service import SafetyCheckResult
```
| Attribute | Type | Description |
|-----------|------|-------------|
@@ -361,6 +413,22 @@ Application service that checks shell commands before execution.
| `warning` | `DangerousCommandWarning \| None` | Warning if a dangerous pattern matched, otherwise `None` |
| `allowed` | `bool` | `True` if the command is allowed to proceed |
**Example — custom block level and callback:**
```python
from cleveragents.tui.shell_safety import ShellSafetyService, ShellDangerLevel
def my_callback(warning):
# Show a UI prompt; return True to allow, False to block
return ask_user(f"⚠️ {warning.message}. Proceed?")
service = ShellSafetyService(
block_level=ShellDangerLevel.HIGH,
warn_callback=my_callback,
)
result = service.check_command("sudo rm /etc/hosts")
```
**Built-in pattern categories:**
- Destructive filesystem operations (`rm -rf`, `shred`, `wipe`)
+40
View File
@@ -219,6 +219,46 @@ Key UKO capabilities:
---
## Invariant Reconciliation
The **Invariant Reconciliation Actor** (`builtin/invariant-reconciliation`)
is automatically invoked at the start of the Strategize, Execute, and Apply
phase transitions by `PlanLifecycleService`.
**Reconciliation algorithm** (spec §1944019600):
1. Collect invariants from four scopes: global, project, action, plan.
2. Group by normalised text (case-insensitive, stripped).
3. Detect conflicts between invariants at different scopes.
4. Resolve using specificity: `plan > action > project > global`.
Exception: `non_overridable` global invariants always win.
5. Record an `invariant_enforced` decision for each active invariant.
6. Return a reconciled `InvariantSet`.
**Failure behaviour:**
- Reconciliation failures block the phase transition with
`ReconciliationBlockedError` and emit an `INVARIANT_VIOLATED` event.
- Post-correction reconciliation runs via `CORRECTION_APPLIED` event
subscription (best-effort; does not block correction completion).
**DI registration:** `InvariantService` is registered as a Singleton
provider in the DI container.
```python
from cleveragents.actor.reconciliation import InvariantReconciliationActor
actor = InvariantReconciliationActor(
invariant_service=container.invariant_service(),
decision_service=container.decision_service(),
)
result = actor.run(plan_id="...", project_name="...", action_name="...")
# result.reconciled_set — effective InvariantSet
# result.conflicts — list[ConflictRecord] with resolution details
```
---
## A2A Protocol Boundary
All CLI, TUI, and server interactions cross the A2A boundary