Marketplace dcg
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.
git clone https://github.com/aiskillstore/marketplace
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/dicklesworthstone/dcg" ~/.claude/skills/aiskillstore-marketplace-dcg && rm -rf "$T"
skills/dicklesworthstone/dcg/SKILL.mdDCG — Destructive Command Guard
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.
Why This Exists
AI coding agents are powerful but fallible. They can accidentally run destructive commands:
- "Let me clean up the build artifacts" →
(typo)rm -rf ./src - "I'll reset to the last commit" →
(destroys uncommitted changes)git reset --hard - "Let me fix the merge conflict" →
(discards all modifications)git checkout -- . - "I'll clean up untracked files" →
(permanently deletes untracked files)git clean -fd
DCG intercepts dangerous commands before execution and blocks them with a clear explanation, giving you a chance to stash your changes first.
Critical Design Principles
1. Whitelist-First Architecture
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
2. Fail-Safe Defaults (Default-Allow)
Unrecognized commands are allowed by default. This ensures:
- The hook never breaks legitimate workflows
- Only known dangerous patterns are blocked
- New git commands work until explicitly categorized
3. Zero False Negatives Philosophy
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.
What It Blocks
Git Commands That Destroy Uncommitted Work
| Command | Reason |
|---|---|
| Destroys uncommitted changes |
| Destroys uncommitted changes |
| Discards file modifications |
(without ) | Discards uncommitted changes |
| Permanently deletes untracked files |
Git Commands That Destroy Remote History
| Command | Reason |
|---|---|
/ | Overwrites remote commits |
| Force-deletes without merge check |
Git Commands That Destroy Stashed Work
| Command | Reason |
|---|---|
| Permanently deletes a stash |
| Permanently deletes all stashes |
Filesystem Commands
| Command | Reason |
|---|---|
(outside , , ) | Recursive deletion is dangerous |
What It ALLOWS
Safe operations pass through silently:
Always Safe Git Operations
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
Explicitly Safe Patterns
| Pattern | Why Safe |
|---|---|
| Creating new branches |
| Creating orphan branches |
| Unstaging only, doesn't touch working tree |
| Short flag for staged |
/ | Preview mode, no actual deletion |
| Temp directories are ephemeral |
| Shell variable forms |
Safe Alternative: --force-with-lease
--force-with-leasegit push --force-with-lease # ALLOWED - refuses if remote has unseen commits git push --force # BLOCKED - can overwrite others' work
Modular Pack System
DCG uses a modular "pack" system to organize patterns by category:
Core Packs (Always Enabled)
| Pack | Description |
|---|---|
| Destructive git commands |
| Dangerous rm -rf outside temp |
Database Packs
| Pack | Description |
|---|---|
| DROP/TRUNCATE in PostgreSQL |
| DROP/TRUNCATE in MySQL/MariaDB |
| dropDatabase, drop() |
| FLUSHALL/FLUSHDB |
| DROP in SQLite |
Container Packs
| Pack | Description |
|---|---|
| docker system prune, docker rm -f |
| docker-compose down --volumes |
| podman system prune |
Kubernetes Packs
| Pack | Description |
|---|---|
| kubectl delete namespace |
| helm uninstall |
| kustomize delete patterns |
Cloud Provider Packs
| Pack | Description |
|---|---|
| Destructive AWS CLI commands |
| Destructive gcloud commands |
| Destructive az commands |
Infrastructure Packs
| Pack | Description |
|---|---|
| terraform destroy |
| Dangerous ansible patterns |
| pulumi destroy |
System Packs
| Pack | Description |
|---|---|
| dd, mkfs, fdisk operations |
| Dangerous chmod/chown patterns |
| systemctl stop/disable patterns |
Other Packs
| Pack | Description |
|---|---|
| Extra paranoid git protections |
| npm unpublish, cargo yank |
Configuring Packs
# ~/.config/dcg/config.toml [packs] enabled = [ "database.postgresql", "containers.docker", "kubernetes", # Enables all kubernetes sub-packs ]
Environment Variables
| Variable | Description |
|---|---|
| Enable packs (comma-separated) |
| Disable packs/sub-packs |
| Verbose output |
| Color mode |
| Bypass DCG entirely (escape hatch) |
Installation
Quick Install (Recommended)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/master/install.sh?$(date +%s)" | bash # Easy mode: auto-update PATH curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/master/install.sh?$(date +%s)" | bash -s -- --easy-mode # System-wide (requires sudo) curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/master/install.sh?$(date +%s)" | sudo bash -s -- --system
From Source (Requires Rust Nightly)
cargo +nightly install --git https://github.com/Dicklesworthstone/destructive_command_guard
Prebuilt Binaries
Available for: Linux x86_64, Linux ARM64, macOS Intel, macOS Apple Silicon, Windows
Claude Code Configuration
Add to
~/.claude/settings.json:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "dcg" } ] } ] } }
Important: Restart Claude Code after adding the hook.
How It Works
Processing Pipeline
┌─────────────────────────────────────────────────────────────────┐ │ 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)
Stage 1: JSON Parsing
- Reads hook input from stdin
- Validates Claude Code's
formatPreToolUse - Non-Bash tools immediately allowed
Stage 2: Command Normalization
- Strips absolute paths:
→/usr/bin/git statusgit status - Preserves argument paths
Stage 3: Quick Rejection Filter
- SIMD-accelerated substring search for "git" or "rm"
- Commands without these bypass regex entirely (99%+ of commands)
Stage 4: Pattern Matching
- Safe patterns checked first (short-circuit on match → allow)
- Destructive patterns checked second (match → deny)
- No match → default allow
Exit Codes
| Code | Meaning |
|---|---|
| Command is safe, proceed |
| Command is blocked, do not execute |
CLI Usage
Test commands manually:
# Show version with build metadata dcg --version # Test a command echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
Example Block Message
════════════════════════════════════════════════════════════════════════ 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. ════════════════════════════════════════════════════════════════════════
Contextual Suggestions
| Command Type | Suggestion |
|---|---|
, | "Consider using 'git stash' first" |
| "Use 'git clean -n' first to preview" |
| "Consider using '--force-with-lease'" |
| "Verify the path carefully before running manually" |
Edge Cases Handled
Path Normalization
/usr/bin/git reset --hard # Blocked /usr/local/bin/git checkout -- . # Blocked /bin/rm -rf /home/user # Blocked
Flag Ordering Variants
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.
Shell Variable Expansion
rm -rf $TMPDIR/build # Allowed (temp) rm -rf ${TMPDIR}/build # Allowed rm -rf "$TMPDIR/build" # Allowed rm -rf "${TMPDIR:-/tmp}/build" # Allowed
Staged vs Worktree Restore
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)
Performance Optimizations
DCG is designed for zero perceived latency:
| Optimization | Technique |
|---|---|
| Lazy Static | Regex patterns compiled once via |
| SIMD Quick Reject | crate for CPU vector instructions |
| Early Exit | Safe match returns immediately |
| Zero-Copy JSON | operates on input buffer |
| Zero-Allocation | for path normalization |
| Release Profile | , LTO, single codegen unit |
Result: Sub-millisecond execution for typical commands.
Pattern Counts
| Type | Count |
|---|---|
| Safe patterns (whitelist) | 34 |
| Destructive patterns (blacklist) | 16 |
Security Considerations
What DCG Protects Against
- Accidental data loss from
orgit checkout --git reset --hard - Remote history destruction from force pushes
- Stash loss from
git stash drop/clear - Filesystem accidents from
outside temp directoriesrm -rf
What DCG Does NOT Protect Against
- Malicious actors (can bypass the hook)
- Non-Bash commands (Python/JavaScript file writes, API calls)
- Committed but unpushed work
- Commands inside scripts (
contents not inspected)./deploy.sh
Threat Model
DCG assumes the AI agent is well-intentioned but fallible. It catches honest mistakes, not adversarial attacks.
Troubleshooting
Hook not blocking commands
- Verify
has hook configuration~/.claude/settings.json - Restart Claude Code
- Test manually:
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
Hook blocking safe commands
- Check if there's an edge case not covered
- File a GitHub issue
- Temporary bypass:
or run command manuallyDCG_BYPASS=1
FAQ
Q: Why block
but allow git branch -D
?git branch -d
Lowercase
-d only deletes branches fully merged. Uppercase -D force-deletes regardless of merge status, potentially losing commits.
Q: Why is
allowed?git push --force-with-lease
Force-with-lease refuses to push if the remote has commits you haven't seen, preventing accidental overwrites.
Q: Why block all
outside temp directories?rm -rf
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.
Integration with Flywheel
| 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 |