DCG: Destructive Command Guard — Safety Philosophy and Design Principles
Research Date: 2026-01-26 Source URL: https://x.com/doodlestein/status/2015510232869245033
Reference URLs
- Original X Post - Jeffrey Emanuel
- DCG Agent Skills Documentation
- Agentic Coding Flywheel TL;DR
- GitHub Repository - destructive_command_guard
- SafeExec - Agentify Command Guard
- Project CodeGuard
Summary
DCG (Destructive Command Guard) is a high-performance Rust-based safety tool developed by Jeffrey Emanuel that intercepts and blocks dangerous shell commands before execution in Claude Code workflows. The tool represents a systematic approach to AI agent safety, prioritizing prevention of data loss through a whitelist-first architecture with SIMD-accelerated pattern matching for sub-millisecond latency.
DCG operates on three critical design principles: whitelist-first architecture (safe patterns checked before destructive ones), fail-safe defaults (unrecognized commands allowed by default), and zero false negatives philosophy (prioritizing blocking all dangerous commands over avoiding false positives). The tool integrates natively with Claude Code via PreToolUse hooks and forms part of a broader “Agentic Coding Flywheel” ecosystem of 14 interconnected tools for multi-agent AI coding workflows.
This analysis examines DCG’s safety philosophy, design principles, detailed pattern matching implementation, integration patterns, and comparative analysis with similar safety tools in the AI coding agent ecosystem.
Safety Philosophy
Threat Model: Well-Intentioned but Fallible Agents
DCG’s fundamental assumption is that AI coding agents are well-intentioned but fallible. The tool protects against honest mistakes rather than adversarial attacks. This distinction shapes every design decision:
| Threat Type | Protection Level | Rationale |
|---|---|---|
| Accidental commands | Full protection | Primary use case: typos, misunderstandings |
| Malicious actors | Not protected | Can bypass hooks; requires different security |
| Non-Bash commands | Not protected | Python/JS file operations outside scope |
| Scripted commands | Not protected | ./deploy.sh contents not inspected |
The threat model acknowledges that perfect security is impossible—malicious actors can always bypass hooks, and non-shell operations require different protection mechanisms. DCG focuses on the high-probability, high-impact scenario: an AI agent making an honest mistake that destroys uncommitted work.
Zero False Negatives Philosophy
DCG explicitly prioritizes never allowing dangerous commands over avoiding false positives. This philosophy accepts that occasional manual confirmation prompts are preferable to allowing work to be destroyed. The trade-off calculation:
- Cost of false positive: User must manually run command (minor inconvenience)
- Cost of false negative: Permanent data loss (catastrophic)
The tool errs on the side of caution, blocking commands that might be safe in specific contexts but are dangerous in general. For example, git reset --hard is always blocked, even though it might be safe if the user has no uncommitted changes—the tool cannot reliably determine this without complex git state analysis.
Fail-Safe Defaults: Default-Allow Architecture
Despite the zero false negatives philosophy, DCG uses a default-allow approach for unrecognized commands. This ensures:
- Legitimate workflows remain unbroken: New git commands or tools work until explicitly categorized
- Only known dangerous patterns are blocked: The tool doesn’t attempt to guess what might be dangerous
- Explicit safety over implicit restrictions: Users can trust that if DCG doesn’t block something, it’s been explicitly evaluated
This creates a tension between safety and usability that DCG resolves through comprehensive pattern coverage rather than broad restrictions.
Design Principles
Principle 1: Whitelist-First Architecture
Safe patterns are checked before destructive patterns. This ordering ensures that explicitly safe commands are never accidentally blocked:
Example: git checkout -b feature matches the safe “checkout-new-branch” pattern and is allowed immediately, without checking destructive patterns. If safe patterns were checked second, a hypothetical destructive pattern matching “checkout” might incorrectly block this safe operation.
Principle 2: Path Normalization
Commands are normalized before pattern matching to handle absolute paths and various command invocation styles:
| Input | Normalized Output | Rationale |
|---|---|---|
/usr/bin/git status | git status | Strip absolute paths |
/usr/local/bin/git reset --hard | git reset --hard | Preserve arguments, normalize path |
/bin/rm -rf /home/user | rm -rf /home/user | Extract command name |
This normalization ensures that pattern matching works regardless of how the command is invoked—whether through PATH resolution, absolute paths, or system-specific binary locations.
Principle 3: SIMD-Accelerated Quick Rejection
Before expensive regex pattern matching, DCG performs a SIMD-accelerated substring search for “git” or “rm”. Commands without these keywords bypass regex entirely, handling 99%+ of commands in microseconds:
This optimization ensures that DCG adds negligible latency to the vast majority of commands while still providing comprehensive protection for dangerous operations.
Detailed Pattern Matching Examples
Git Command Patterns
Safe Patterns (Whitelist)
DCG maintains 34 safe patterns that are checked first:
| Pattern | Example Command | Why Safe |
|---|---|---|
git checkout -b <branch> | git checkout -b feature | Creates new branch, no data loss |
git checkout --orphan | git checkout --orphan main | Creates orphan branch |
git restore --staged | git restore --staged file | Unstaging only, preserves worktree |
git restore -S <file> | git restore -S file.txt | Short flag for staged-only |
git clean -n | git clean -n | Dry-run mode, preview only |
git clean --dry-run | git clean --dry-run | Explicit dry-run flag |
Pattern Matching Logic:
// Pseudo-code representation
safe_patterns = [
r"^git checkout -b \S+", // New branch creation
r"^git checkout --orphan \S+", // Orphan branch
r"^git restore --staged", // Unstaging only
r"^git restore -S", // Short staged flag
r"^git clean -(n|--dry-run)", // Preview mode
// ... 29 more patterns
]
destructive_patterns = [
r"^git reset --hard", // Destroys uncommitted changes
r"^git reset --merge", // Destroys uncommitted changes
r"^git checkout -- \S+", // Discards file modifications
r"^git restore(?!.*--staged)(?!.*-S)", // Restore without staged flag
r"^git clean -f", // Force clean untracked files
r"^git push --force", // Overwrites remote history
r"^git push -f", // Short force flag
r"^git branch -D", // Force delete branch
r"^git stash drop", // Permanently deletes stash
r"^git stash clear", // Deletes all stashes
// ... 6 more patterns
]
Destructive Patterns (Blacklist)
DCG blocks 16 destructive git patterns:
Commands That Destroy Uncommitted Work:
| Command Pattern | Example | Blocked Because |
|---|---|---|
git reset --hard | git reset --hard HEAD~1 | Permanently discards uncommitted changes |
git reset --merge | git reset --merge | Abandons merge, loses uncommitted work |
git checkout -- <file> | git checkout -- file.txt | Discards modifications to file |
git restore <file> | git restore file.txt | Restores file, discarding changes |
git clean -f | git clean -f | Permanently deletes untracked files |
git clean --force | git clean --force | Explicit force flag |
Edge Case Handling:
The git restore command demonstrates sophisticated pattern matching:
Commands That Destroy Remote History:
| Command Pattern | Example | Blocked Because |
|---|---|---|
git push --force | git push --force origin main | Overwrites remote commits |
git push -f | git push -f | Short flag for force push |
git branch -D | git branch -D feature | Force-deletes without merge check |
Safe Alternative: git push --force-with-lease is explicitly allowed because it refuses to push if the remote has commits you haven’t seen, preventing accidental overwrites.
Commands That Destroy Stashed Work:
| Command Pattern | Example | Blocked Because |
|---|---|---|
git stash drop | git stash drop | Permanently deletes a stash |
git stash clear | git stash clear | Permanently deletes all stashes |
Safe Alternative: git stash (create), git stash pop (apply and remove), and git stash list (view) are all allowed.
Filesystem Command Patterns
Recursive Deletion Protection
DCG blocks rm -rf operations outside temporary directories:
| Command Pattern | Example | Status | Rationale |
|---|---|---|---|
rm -rf /tmp/* | rm -rf /tmp/build | ALLOWED | Temp directories are ephemeral |
rm -rf $TMPDIR/* | rm -rf $TMPDIR/build | ALLOWED | Shell variable temp directories |
rm -rf ${TMPDIR}/build | rm -rf ${TMPDIR}/build | ALLOWED | Variable expansion variants |
rm -rf /home/user/project | rm -rf /home/user/project | BLOCKED | Outside temp, dangerous |
rm -rf ./src | rm -rf ./src | BLOCKED | Could be typo, blocks all non-temp |
Flag Ordering Variants:
DCG handles all common flag ordering patterns:
| Variant | Pattern Recognition |
|---|---|
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 normalized and checked against the same pattern.
Modular Pack System
DCG uses a modular “pack” system to organize patterns by category, allowing users to enable only relevant protections:
Core Packs (Always Enabled)
| Pack | Patterns Covered |
|---|---|
core.git | Destructive git commands |
core.filesystem | Dangerous rm -rf outside temp |
Database Packs
| Pack | Destructive Operations Blocked |
|---|---|
database.postgresql | DROP DATABASE, TRUNCATE TABLE |
database.mysql | DROP DATABASE, TRUNCATE TABLE |
database.mongodb | dropDatabase(), collection.drop() |
database.redis | FLUSHALL, FLUSHDB |
database.sqlite | DROP TABLE, DROP INDEX |
Container Packs
| Pack | Destructive Operations Blocked |
|---|---|
containers.docker | docker system prune, docker rm -f |
containers.compose | docker-compose down —volumes |
containers.podman | podman system prune |
Kubernetes Packs
| Pack | Destructive Operations Blocked |
|---|---|
kubernetes.kubectl | kubectl delete namespace |
kubernetes.helm | helm uninstall |
kubernetes.kustomize | kustomize delete patterns |
Cloud Provider Packs
| Pack | Destructive Operations Blocked |
|---|---|
cloud.aws | Destructive AWS CLI commands |
cloud.gcp | Destructive gcloud commands |
cloud.azure | Destructive az commands |
Configuration Example:
# ~/.config/dcg/config.toml
[packs]
enabled = [
"database.postgresql",
"containers.docker",
"kubernetes", # Enables all kubernetes sub-packs
]
This modular approach allows developers to enable protections relevant to their stack without unnecessary restrictions.
Integration Examples
Claude Code Integration
DCG integrates natively with Claude Code via PreToolUse hooks:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "dcg"
}
]
}
]
}
}
Processing Pipeline:
Hook Input Format:
{
"tool_name": "Bash",
"tool_input": {
"command": "git reset --hard HEAD~1"
}
}
Hook Output (Blocked):
{
"error": "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."
}
Hook Output (Allowed):
Empty stdout, exit code 0. Claude Code proceeds with command execution.
Integration with Flywheel Ecosystem
DCG integrates with multiple tools in the Agentic Coding Flywheel:
Agent Mail Integration
When DCG blocks a command, agents can report the block to a coordinator via Agent Mail:
BV (Beads Viewer) Integration
Tasks that repeatedly trigger DCG blocks can be flagged in BV for review:
| Metric | Indication |
|---|---|
| High DCG block rate | Task may require manual intervention |
| Repeated patterns | Suggests workflow improvement needed |
| Block frequency | Helps prioritize task complexity |
CASS (Coding Agent Session Search) Integration
DCG block patterns are searchable across sessions:
- Search for “git reset —hard” to find all instances where agents attempted destructive operations
- Analyze patterns to identify common mistakes
- Extract lessons learned for agent prompt improvements
NTM (Named Tmux Manager) Integration
DCG protects all commands in NTM-managed sessions:
Multi-Layer Safety Architecture
DCG works alongside SLB (Simultaneous Launch Button) for layered protection:
| Layer | Tool | Protection Mechanism | Use Case |
|---|---|---|---|
| Layer 1 | DCG | Pattern-based blocking | Prevent accidental execution |
| Layer 2 | SLB | Two-person rule approval | High-risk operations |
Example Workflow:
- DCG blocks
git push --force→ Agent cannot execute - Agent requests manual approval via SLB
- Human reviewer evaluates context
- Approval granted → Command executes with
DCG_BYPASS=1
This layered approach provides defense in depth: DCG catches obvious mistakes, while SLB provides human oversight for edge cases.
Comparison with Similar Safety Tools
SafeExec (Agentify)
Architecture Comparison:
| Aspect | DCG | SafeExec |
|---|---|---|
| Language | Rust | Bash |
| Performance | SIMD-accelerated, sub-millisecond | TTY-based, interactive prompt |
| Integration | Claude Code PreToolUse hook | PATH shims, dpkg-divert |
| Bypass difficulty | Easy (environment variable) | Hard (requires absolute paths) |
| Pattern matching | Regex-based, modular packs | String matching, git-specific |
| Default behavior | Default-allow (fail-safe) | Default-block (interactive) |
Design Philosophy Differences:
DCG: Optimized for AI agent workflows with minimal latency. Uses default-allow to avoid breaking legitimate operations. Focuses on known dangerous patterns.
SafeExec: Optimized for human + AI workflows with interactive confirmation. Uses hard-mode installation (dpkg-divert) to catch non-interactive execution. More aggressive blocking.
Use Case Recommendations:
- Choose DCG if: Working primarily with Claude Code, need sub-millisecond latency, want modular pack system, prefer default-allow philosophy
- Choose SafeExec if: Need hard-mode protection against non-interactive execution, want TTY-based confirmation, working with multiple AI agents beyond Claude Code
Project CodeGuard
Scope Comparison:
| Aspect | DCG | Project CodeGuard |
|---|---|---|
| Protection scope | Shell command execution | Code generation + review |
| Stage of protection | Pre-execution (runtime) | Pre-generation + post-generation |
| Threat model | Accidental destructive commands | Security vulnerabilities |
| Pattern type | Command patterns | Code patterns, security rules |
| Integration | Claude Code hooks | Multiple agent translators |
Complementary Use:
DCG and Project CodeGuard address different threat vectors:
DCG: Prevents data loss from destructive commands Project CodeGuard: Prevents security vulnerabilities in generated code
These tools can be used together for comprehensive protection.
SLB (Simultaneous Launch Button)
Approach Comparison:
| Aspect | DCG | SLB |
|---|---|---|
| Approval mechanism | Automatic pattern blocking | Two-person rule (human/AI) |
| Latency | Sub-millisecond | Human-in-the-loop (seconds) |
| Use case | Prevent obvious mistakes | High-stakes operations |
| Bypass | Environment variable | Requires second approval |
| Integration | PreToolUse hook | Command queue system |
Layered Protection Model:
DCG and SLB form complementary layers:
- DCG (Layer 1): Blocks obviously dangerous commands automatically
- SLB (Layer 2): Requires human approval for edge cases that pass DCG
This creates a defense-in-depth strategy where DCG handles the common cases, and SLB provides oversight for ambiguous situations.
Anthropic’s Built-in Safety
Comparison with Claude Code Defaults:
| Aspect | DCG | Claude Code Defaults |
|---|---|---|
| Permission model | Pattern-based blocking | Read-only by default |
| Granularity | Command-level | Tool-level |
| Customization | Modular packs, configurable | Persistent permissions |
| Performance | Sub-millisecond | Native (no overhead) |
| Scope | Shell commands only | All tool operations |
Complementary Relationship:
Claude Code’s read-only defaults provide broad protection, while DCG adds granular command-level safety:
DCG adds an additional safety layer specifically for shell commands, complementing Claude Code’s broader permission system.
Performance Characteristics
Latency Analysis
DCG is optimized for zero perceived latency in AI agent workflows:
| Optimization Technique | Impact | Implementation |
|---|---|---|
| Lazy Static Regex | One-time compilation cost | LazyLock for pattern compilation |
| SIMD Quick Reject | 99%+ commands: ~1μs | memchr crate for vector ops |
| Early Exit | Safe matches: immediate return | Short-circuit on first match |
| Zero-Copy JSON | Avoids allocation overhead | serde_json on input buffer |
| Zero-Allocation | Path normalization via Cow<str> | Borrowed strings where possible |
| Release Profile | Optimized binary size + speed | opt-level="z", LTO, single unit |
Performance Profile:
| Command Type | Latency | Path Through System |
|---|---|---|
| Non-git/rm command | ~1μs | SIMD quick reject → allow |
| Safe git command | ~100-200μs | SIMD → regex safe match → allow |
| Destructive command | ~200-500μs | SIMD → regex destructive match → block |
| Unrecognized git command | ~200-500μs | SIMD → regex (no match) → allow |
These latencies are imperceptible to users and add minimal overhead to Claude Code workflows.
Pattern Matching Efficiency
The whitelist-first architecture ensures that safe commands (the majority) are checked with minimal overhead:
| Pattern Set | Count | Check Order | Typical Match Rate |
|---|---|---|---|
| Safe patterns | 34 | First | ~60% of git commands |
| Destructive patterns | 16 | Second | ~5% of git commands |
| Default allow | N/A | Fallback | ~35% of git commands |
By checking safe patterns first, DCG can short-circuit on the majority of commands without evaluating destructive patterns.
Key Findings
Safety Philosophy Insights
-
Default-allow with comprehensive patterns provides better UX than default-deny: Legitimate workflows remain unbroken while dangerous operations are blocked.
-
Zero false negatives philosophy accepts occasional false positives as preferable to data loss: The cost of manual confirmation is orders of magnitude lower than the cost of lost work.
-
Whitelist-first architecture ensures safe operations are never accidentally blocked: Ordering matters when both safe and destructive patterns could match.
Design Principle Validation
-
SIMD quick rejection handles 99%+ of commands in microseconds: Most commands aren’t git or rm operations, so expensive regex matching is unnecessary.
-
Modular pack system allows targeted protection: Developers can enable only relevant protections (e.g., database packs for backend developers, Kubernetes packs for DevOps).
-
Path normalization ensures consistent pattern matching: Commands work the same whether invoked via PATH, absolute paths, or system-specific locations.
Integration Patterns
-
Native Claude Code integration via PreToolUse hooks provides seamless protection: No manual intervention required, blocks happen automatically.
-
Layered safety architecture with SLB provides defense in depth: DCG handles obvious cases, SLB provides human oversight for edge cases.
-
Ecosystem integration amplifies value: DCG blocks become searchable (CASS), reportable (Mail), and analyzable (BV).
Comparative Analysis Conclusions
-
DCG vs SafeExec: DCG optimized for AI agent latency, SafeExec optimized for human confirmation. Complementary use cases.
-
DCG vs Project CodeGuard: Different threat vectors (data loss vs security vulnerabilities). Can be used together.
-
DCG vs Claude Code defaults: DCG adds granular command-level safety to Claude Code’s tool-level permissions.
References
- DCG Agent Skills Documentation - Comprehensive technical documentation
- Agentic Coding Flywheel TL;DR - Ecosystem context and integration patterns
- GitHub - destructive_command_guard - Source code repository
- SafeExec - Agentify Command Guard - Alternative safety tool comparison
- Project CodeGuard - Security-focused code generation protection
- Original X Post - Jeffrey Emanuel - January 26, 2026