- Case ID
- #8016
- Severity
- CRIT
- Decision
- BLOCK
- Agent
- Aider
- Category
- Shell Safety
Correction note (2026-10-13). An earlier version of this article said a Zig/Rust AST engine evaluates the rule and that blocked actions are written to a file named
~/.ssg/audit.log. The rule engine is written in Go. The local audit log is theaudit_logtable in~/.sigmashake/rules.db, andssg audit searchreads it. The per-call timings and latency figures that appeared in this article had no benchmark behind them and were removed. Sample output in this article is illustrative, not a recorded run. The only published measurement is p50 0.39 ms and p99 1.91 ms (sigmashake-bench daemon-socket run, 2026-06-10, ssg 0.29.156, n=500). Sub-2 ms evaluation is a design target. The local audit log records decisions on a best-effort basis: entries can be dropped if the daemon queue is full, and old rows are deleted at the row caps. It is local, not append-only, and not immutable.ssg evalreads the tool call as JSON on stdin and has no --content, --content-file, --file or positional form.
Describe the task
You're using Aider to clean up stale build artifacts in your monorepo. The agent is working inside packages/legacy-api/dist/ — but it miscalculates the working directory and constructs the path as an absolute root reference. Before you can intervene, it attempts:
rm -rf /
This is the classic "rm disaster" — an agent operating without human confirmation with unchecked shell access. SigmaShake's no-rm-rf rule catches it the moment the tool call is evaluated, before execution begins.
# illustrative sample output
[BLOCK] bash › rm -rf / — rule: no-rm-rf
Give SSG context
SigmaShake evaluates Aider's bash tool calls via the SSG MCP Server integration for Aider sessions before they ever reach your shell.
Required context
A .sigmashake/rules/bash.rules file in your project root:
rule no-rm-rf {
enabled true
priority 100
severity error
DENY execution
IF command STARTS_WITH "rm -rf"
MESSAGE "Destructive recursive delete blocked. Use a scoped path."
}
Optional context
Add a custom MESSAGE to guide the agent toward a safe alternative:
rule no-rm-rf-guided {
enabled true
priority 100
severity error
DENY execution
IF command STARTS_WITH "rm -rf"
MESSAGE "Blocked: rm -rf is not allowed. Target a specific subdirectory like 'dist/' instead."
}
What SSG does
SSG evaluates the incoming tool call against your rule file using its Go rule engine. The match is deterministic — no LLM in the loop, no probability. On a match, SSG returns a DENY decision and surfaces it as a tool error. Aider reads the message and can retry with a safe alternative.
Ask the agent to retry with a scoped path
After the block, guide Aider with the error context:
The recursive delete was blocked. Please delete only dist/ relative to the current package path.
The agent reformulates. rm -rf packages/legacy-api/dist/ doesn't match STARTS_WITH "rm -rf /" so it proceeds normally.
See the block in your audit dashboard
Blocked actions are recorded on a best-effort basis in the local audit log (the audit_log table in ~/.sigmashake/rules.db). List blocked calls with ssg audit search --decision block --since 24h, or run ssg dashboard to see a live web UI showing blocked commands and the rule that fired.
Upgrade from DENY to ASK for team workflows
Your security team may prefer human approval over a hard block:
rule confirm-rm-rf {
enabled true
priority 100
severity warning
ASK execution
IF command STARTS_WITH "rm -rf"
PROMPT "This will recursively delete files. Are you sure?"
MESSAGE "This will recursively delete files. Are you sure?"
}
How your rule syntax shapes enforcement
STARTS_WITH is stricter than CONTAINS — using CONTAINS "rm -rf" would also catch occurrences inside echo strings or comments. For shell commands, STARTS_WITH is usually the right choice. Test with echo '{"tool":"Bash","input":{"command":"rm -rf /tmp/test"}}' | ssg eval before shipping.
Check the rule against your environment
If your build pipeline legitimately uses rm -rf on scoped paths, add an EXCEPT clause or use a more specific condition. Always validate with ssg lint .sigmashake/rules/ after editing.