/SKILL.md
Destructive Command Guard - High-performance Rust hook for Claude Code that blocks dangerous commands before execution. SIMD-accelerated, modular pack system, whitelist-first architecture. Essential safety layer for agent workflows.
npx skillsauth add dicklesworthstone/destructive_command_guard dcgInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A high-performance Claude Code hook that intercepts and blocks destructive commands before they execute. Written in Rust with SIMD-accelerated filtering for sub-millisecond latency.
AI coding agents are powerful but fallible. They can accidentally run destructive commands:
rm -rf ./src (typo)git reset --hard (destroys uncommitted changes)git checkout -- . (discards all modifications)git clean -fd (permanently deletes untracked files)DCG intercepts dangerous commands before execution and blocks them with a clear explanation, giving you a chance to stash your changes first.
Safe patterns are checked before destructive patterns. This ensures explicitly safe commands are never accidentally blocked:
git checkout -b feature → Matches SAFE "checkout-new-branch" → ALLOW
git checkout -- file.txt → No safe match, matches DESTRUCTIVE → DENY
Unrecognized commands are allowed by default. This ensures:
The pattern set prioritizes never allowing dangerous commands over avoiding false positives. A few extra prompts for manual confirmation are acceptable; lost work is not.
| Command | Reason |
|---------|--------|
| git reset --hard | Destroys uncommitted changes |
| git reset --merge | Destroys uncommitted changes |
| git checkout -- <file> | Discards file modifications |
| git restore <file> (without --staged) | Discards uncommitted changes |
| git clean -f | Permanently deletes untracked files |
| Command | Reason |
|---------|--------|
| git push --force / -f | Overwrites remote commits |
| git branch -D | Force-deletes without merge check |
| Command | Reason |
|---------|--------|
| git stash drop | Permanently deletes a stash |
| git stash clear | Permanently deletes all stashes |
| Command | Reason |
|---------|--------|
| rm -rf (outside /tmp, /var/tmp, $TMPDIR) | Recursive deletion is dangerous |
Safe operations pass through silently:
git status, git log, git diff, git add, git commit, git push, git pull, git fetch, git branch -d (safe delete with merge check), git stash, git stash pop, git stash list
| Pattern | Why Safe |
|---------|----------|
| git checkout -b <branch> | Creating new branches |
| git checkout --orphan <branch> | Creating orphan branches |
| git restore --staged <file> | Unstaging only, doesn't touch working tree |
| git restore -S <file> | Short flag for staged |
| git clean -n / --dry-run | Preview mode, no actual deletion |
| rm -rf /tmp/* | Temp directories are ephemeral |
| rm -rf $TMPDIR/* | Shell variable forms |
--force-with-leasegit push --force-with-lease # ALLOWED - refuses if remote has unseen commits
git push --force # BLOCKED - can overwrite others' work
DCG uses a modular "pack" system to organize patterns by category:
| Pack | Description |
|------|-------------|
| core.git | Destructive git commands |
| core.filesystem | Dangerous rm -rf outside temp |
| Pack | Description |
|------|-------------|
| database.postgresql | DROP/TRUNCATE in PostgreSQL |
| database.mysql | DROP/TRUNCATE in MySQL/MariaDB |
| database.mongodb | dropDatabase, drop() |
| database.redis | FLUSHALL/FLUSHDB |
| database.sqlite | DROP in SQLite |
| Pack | Description |
|------|-------------|
| containers.docker | docker system prune, docker rm -f |
| containers.compose | docker-compose down --volumes |
| containers.podman | podman system prune |
| Pack | Description |
|------|-------------|
| kubernetes.kubectl | kubectl delete namespace |
| kubernetes.helm | helm uninstall |
| kubernetes.kustomize | kustomize delete patterns |
| Pack | Description |
|------|-------------|
| cloud.aws | Destructive AWS CLI commands |
| cloud.gcp | Destructive gcloud commands |
| cloud.azure | Destructive az commands |
| Pack | Description |
|------|-------------|
| infrastructure.terraform | terraform destroy |
| infrastructure.ansible | Dangerous ansible patterns |
| infrastructure.pulumi | pulumi destroy |
| Pack | Description |
|------|-------------|
| system.disk | dd, mkfs, fdisk operations |
| system.permissions | Dangerous chmod/chown patterns |
| system.services | systemctl stop/disable patterns |
| Pack | Description |
|------|-------------|
| strict_git | Extra paranoid git protections |
| package_managers | npm unpublish, cargo yank |
# ~/.config/dcg/config.toml
[packs]
enabled = [
"database.postgresql",
"containers.docker",
"kubernetes", # Enables all kubernetes sub-packs
]
| Variable | Description |
|----------|-------------|
| DCG_PACKS="containers.docker,kubernetes" | Enable packs (comma-separated) |
| DCG_DISABLE="kubernetes.helm" | Disable packs/sub-packs |
| DCG_VERBOSE=1 | Verbose output |
| DCG_COLOR=auto\|always\|never | Color mode |
| DCG_BYPASS=1 | Bypass DCG entirely (escape hatch) |
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | bash
# Easy mode: auto-update PATH
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | bash -s -- --easy-mode
# System-wide (requires sudo)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | sudo bash -s -- --system
cargo +nightly install --git https://github.com/Dicklesworthstone/destructive_command_guard
Available for: Linux x86_64, Linux ARM64, macOS Intel, macOS Apple Silicon, Windows
Add to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "dcg"
}
]
}
]
}
}
Important: Restart Claude Code after adding the hook.
┌─────────────────────────────────────────────────────────────────┐
│ Claude Code │
│ Agent executes `rm -rf ./build` │
└─────────────────────┬───────────────────────────────────────────┘
│
▼ PreToolUse hook (stdin: JSON)
┌─────────────────────────────────────────────────────────────────┐
│ dcg │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Parse │───▶│ Normalize │───▶│ Quick Reject │ │
│ │ JSON │ │ Command │ │ Filter │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ┌───────────────────────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Pattern Matching │ │
│ │ 1. Check SAFE_PATTERNS (whitelist) ──▶ Allow if match │ │
│ │ 2. Check DESTRUCTIVE_PATTERNS ──────▶ Deny if match │ │
│ │ 3. No match ────────────────────────▶ Allow (default) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────┬───────────────────────────────────────────┘
│
▼ stdout: JSON (deny) or empty (allow)
PreToolUse format/usr/bin/git status → git status| Code | Meaning |
|------|---------|
| 0 | Command is safe, proceed |
| 2 | Command is blocked, do not execute |
Test commands manually:
# Show version with build metadata
dcg --version
# Test a command
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
════════════════════════════════════════════════════════════════════════
BLOCKED dcg
────────────────────────────────────────────────────────────────────────
Reason: git reset --hard destroys uncommitted changes. Use 'git stash' first.
Command: git reset --hard HEAD~1
Tip: If you need to run this command, execute it manually in a terminal.
Consider using 'git stash' first to save your changes.
════════════════════════════════════════════════════════════════════════
| Command Type | Suggestion |
|-------------|------------|
| git reset, git checkout -- | "Consider using 'git stash' first" |
| git clean | "Use 'git clean -n' first to preview" |
| git push --force | "Consider using '--force-with-lease'" |
| rm -rf | "Verify the path carefully before running manually" |
/usr/bin/git reset --hard # Blocked
/usr/local/bin/git checkout -- . # Blocked
/bin/rm -rf /home/user # Blocked
rm -rf /path # Combined flags
rm -fr /path # Reversed order
rm -r -f /path # Separate flags
rm --recursive --force /path # Long flags
All variants are handled.
rm -rf $TMPDIR/build # Allowed (temp)
rm -rf ${TMPDIR}/build # Allowed
rm -rf "$TMPDIR/build" # Allowed
rm -rf "${TMPDIR:-/tmp}/build" # Allowed
git restore --staged file.txt # Allowed (unstaging only)
git restore -S file.txt # Allowed (short flag)
git restore file.txt # BLOCKED (discards changes)
git restore --worktree file.txt # BLOCKED (explicit worktree)
git restore -S -W file.txt # BLOCKED (includes worktree)
DCG is designed for zero perceived latency:
| Optimization | Technique |
|--------------|-----------|
| Lazy Static | Regex patterns compiled once via LazyLock |
| SIMD Quick Reject | memchr crate for CPU vector instructions |
| Early Exit | Safe match returns immediately |
| Zero-Copy JSON | serde_json operates on input buffer |
| Zero-Allocation | Cow<str> for path normalization |
| Release Profile | opt-level="z", LTO, single codegen unit |
Result: Sub-millisecond execution for typical commands.
| Type | Count | |------|-------| | Safe patterns (whitelist) | 34 | | Destructive patterns (blacklist) | 16 |
git checkout -- or git reset --hardgit stash drop/clearrm -rf outside temp directories./deploy.sh contents not inspected)DCG assumes the AI agent is well-intentioned but fallible. It catches honest mistakes, not adversarial attacks.
~/.claude/settings.json has hook configurationecho '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcgDCG_BYPASS=1 or run command manuallyQ: Why block git branch -D but allow git branch -d?
Lowercase -d only deletes branches fully merged. Uppercase -D force-deletes regardless of merge status, potentially losing commits.
Q: Why is git push --force-with-lease allowed?
Force-with-lease refuses to push if the remote has commits you haven't seen, preventing accidental overwrites.
Q: Why block all rm -rf outside temp directories?
Recursive forced deletion is extremely dangerous. A typo or wrong variable can delete critical files. Temp directories are designed to be ephemeral.
Q: What if I really need to run a blocked command?
DCG instructs the agent to ask for permission. Run the command manually in a separate terminal after making a conscious decision.
| Tool | Integration | |------|-------------| | Claude Code | Native PreToolUse hook | | Agent Mail | Agents can report blocked commands to coordinator | | BV | Flag tasks that repeatedly trigger DCG | | CASS | Search DCG block patterns across sessions | | RU | DCG protects agent-sweep from destructive commits |
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.