
Dcg
- 23 installs
- 416 repo stars
- Updated August 5, 2026
- boshu2/agentops
DCG is a Claude Code skill that blocks destructive commands like rm -rf and git reset --hard and steers the agent to a safe alternative or a human-approved override.
About
DCG is a destructive-command guard that blocks dangerous shell, git, database, filesystem, and Kubernetes commands and offers a safe alternative for each. When an agent hits a block it explains why, suggests a recoverable variant such as git stash for git reset --hard, and only surfaces a human-approved allow-once code when no alternative exists. It is context-aware, so rm -rf ./build is allowed while rm -rf / is blocked.
- Blocks destructive shell, git, DB, and k8s commands with a safe alternative for each
- Context-aware: rm -rf ./build allowed, rm -rf / blocked
- Human-only allow-once codes: 4 hex chars, 24h expiry, bound to command and directory
Dcg by the numbers
- 23 all-time installs (skills.sh)
- Ranked #1,564 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
dcg capabilities & compatibility
Free; configured via .dcg.toml and DCG_* environment variables, no API keys required.
- Capabilities
- dependency update safety
- Works with
- docker · kubernetes · postgres · aws
- Use cases
- security audit · devops
- Pricing
- Free
What dcg says it does
Blocks are checkpoints, not errors. A safe alternative almost always exists.
**Context-aware:** `rm -rf ./build` allowed, `rm -rf /` blocked.
**Allow-once codes** — 4 hex chars, 24h expiry, bound to exact command+directory
npx skills add https://github.com/boshu2/agentops --skill dcgAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 416 |
| Last updated | August 5, 2026 |
| Repository | boshu2/agentops ↗ |
What it does
Handle blocked destructive commands and configure agent safety guardrails against rm -rf, git reset --hard, DROP DATABASE, and kubectl delete.
Who is it for?
Teams running coding agents that need mechanical guardrails against irreversible shell, git, and database commands.
When should I use this skill?
When dcg blocks rm -rf, git reset --hard, DROP DATABASE, or kubectl delete, or when configuring agent safety guardrails.
What you get
Destructive commands are mechanically blocked at a checkpoint with a safe alternative surfaced before any override is mentioned.
By the numbers
- 49+ rule packs available
- sub-millisecond latency
- allow-once codes are 4 hex chars with 24h expiry
Files
<!-- TOC: Core Insight | THE EXACT WORKFLOW | Quick Reference | Safe Alternatives | What Gets Blocked | Anti-Patterns | Configuration | References -->
DCG: When You Get Blocked
Core Insight: Blocks are checkpoints, not errors. A safe alternative almost always exists. Find it before mentioning override.
Quick Navigation
| I need to... | Go to |
|---|---|
| Handle a block right now | THE EXACT WORKFLOW |
| Find a safe alternative | Safe Alternatives |
| See all CLI commands | COMMANDS.md |
| Enable more rule packs | PACKS.md |
| Configure per-project | CONFIG.md |
| Debug hook issues | TROUBLESHOOTING.md |
---
THE EXACT WORKFLOW
When blocked, follow this sequence every time:
1. Run `dcg explain "cmd"` → Understand why (see trace)
2. Check Safe Alternatives table → Use if exists (DON'T mention override)
3. No alternative? → Explain risk clearly, let human decide
4. Human approves? → THEY run: dcg allow-once CODENever: Ask for override first. Never retry silently. Never circumvent.
Example block output:
BLOCKED: git reset --hard HEAD
Rule: core.git:reset-hard
Reason: Discards uncommitted changes permanently
Allow-once code: ab12
Safer alternative: git stashGood response:
"I wanted to discard changes butgit reset --hardwas blocked. Let me usegit stashinstead—recoverable if needed." [proceeds with stash]
Safe Alternatives
| Blocked | Use Instead | Why |
|---|---|---|
git reset --hard | git stash | Recoverable |
git checkout -- file | git stash push file | Preserves changes |
git push --force | git push --force-with-lease | Checks remote unchanged |
git clean -fd | git clean -fdn (preview) | Shows what would delete |
git stash drop | git stash list first | Verify which stash |
rm -rf /path | rm -ri /path or verify path | Interactive/confirm |
kubectl delete namespace | kubectl delete -l app=X | Selective deletion |
DROP DATABASE | Backup first | Human approves |
docker system prune -a | docker system df first | See what's used |
Quick Reference
dcg doctor # Health check — hook registered?
dcg explain "cmd" # WHY is it blocked? (with trace)
dcg test "cmd" # Would this be blocked? (dry-run)
dcg allow-once CODE # Human approves (THEY run this)
dcg packs # List available rule packs
dcg scan --staged # Pre-commit: scan for issues---
What Gets Blocked
| Category | Patterns | Safe Variants |
|---|---|---|
| Git destructive | reset --hard, checkout -- | stash, restore --staged |
| Git history | push --force, branch -D | --force-with-lease, -d |
| Git stash | stash drop, stash clear | stash list first |
| Filesystem | rm -rf (dangerous paths) | /tmp/* allowed |
| Database | DROP, TRUNCATE, DELETE w/o WHERE | Add WHERE clause |
| K8s | delete namespace, delete --all | -l label selector |
Context-aware: rm -rf ./build allowed, rm -rf / blocked.
`dcg explain` example (7-step pipeline):
$ dcg explain "git reset --hard HEAD"
BLOCKED by core.git:reset-hard
Evaluation trace:
1. Config allow overrides: no match
2. Config block overrides: no match
3. Heredoc detection: not applicable
4. Quick reject: triggered (contains "reset")
5. Context sanitization: no changes
6. Normalization: git reset --hard HEAD
7. Pack evaluation:
- Safe patterns: no match
- Destructive: MATCH "reset --hard"
Suggestion: Use `git stash` to preserve changesAnti-Patterns
❌ "Command blocked. Run dcg allow-once ab12" → Find alternative first!
❌ *Retrying silently or circumventing* → Always acknowledge blocks
❌ Treating blocks as errors → They're checkpoints
❌ Asking user to allow-once without explaining → They need contextConfiguration
# .dcg.toml — enable rule packs per-project
[packs]
enabled = ["database.postgresql", "kubernetes.kubectl", "cloud.aws"]
[overrides]
allow_patterns = ["rm -rf ./node_modules"] # Project-specific safeEnvironment variables:
DCG_PACKS="containers.docker,kubernetes"— Enable packsDCG_DISABLE="kubernetes.helm"— Disable specific packsDCG_BYPASS=1— Escape hatch (human-only)
Key Facts
- 49+ rule packs available (database, containers, k8s, cloud, etc.)
- Sub-millisecond latency — won't slow your workflow
- Fail-open on timeout — if DCG hangs, command runs (with warning)
- Heredoc scanning — inline scripts (
bash -c,python -c) are analyzed - Allow-once codes — 4 hex chars, 24h expiry, bound to exact command+directory
The Incident That Started It All
On December 17, 2025, an AI agent rangit checkout --on files containing hours of uncommitted work. The files were recovered viagit fsck --lost-found, but it proved: instructions don't prevent execution—mechanical enforcement does.
---
Validation
# Quick health check
dcg doctor | head -20
# Test if a command would be blocked
dcg test "git reset --hard HEAD"
# Should show: WOULD BE BLOCKED---
Scripts
| Script | Usage |
|---|---|
./scripts/validate-dcg.sh | Full installation validation |
---
References
- COMMANDS.md — Full CLI reference with
dcg explain,dcg scan - PACKS.md — 49+ rule pack system (database, k8s, cloud, etc.)
- CONFIG.md — Configuration, agent profiles, heredoc settings
- SCENARIOS.md — Detailed examples with good/bad responses
- PHILOSOPHY.md — Why DCG works this way
- TROUBLESHOOTING.md — Common issues and fixes
DCG Commands Reference
Command Overview
| Command | Purpose | When to Use |
|---|---|---|
dcg doctor | Verify installation | Hook not working |
dcg explain "cmd" | Understand why blocked | After any block |
dcg test "cmd" | Dry-run evaluation | Before risky commands |
dcg allow-once CODE | Temporary exception | Human approves |
dcg allowlist add | Permanent exception | Recurring safe ops |
dcg allowlist list | Show exceptions | Audit allowlist |
dcg packs | List available packs | See what's enabled |
dcg scan | Scan repository | Pre-commit checks |
dcg update | Self-update | Get latest rules |
---
dcg doctor
Verify DCG installation and hook registration.
$ dcg doctor
DCG Doctor
══════════════════════════════════════════════════
Binary:
✓ dcg version 0.8.2 (built 2025-01-15)
✓ Located at /usr/local/bin/dcg
Hook Registration:
✓ Claude Code hook registered in ~/.config/claude-code/settings.json
✓ Hook path: /usr/local/bin/dcg hook
Configuration:
✓ User config: ~/.config/dcg/config.toml
✓ Project config: .dcg.toml (not found - using defaults)
Packs:
✓ Core packs loaded: core.git, core.filesystem
✓ Optional packs: 0 enabled
Status: All checks passedUse when: Hook doesn't seem to be working, commands aren't being blocked.
---
dcg explain "command"
Show exactly why a command is blocked/allowed with full evaluation trace.
$ dcg explain "git reset --hard HEAD"
BLOCKED by core.git:reset-hard
Evaluation trace (7-step pipeline):
Step 1. Config allow overrides ... no match
Step 2. Config block overrides ... no match
Step 3. Heredoc detection ....... not applicable
Step 4. Quick reject ............ triggered (pattern: "reset")
Step 5. Context sanitization .... no changes
Step 6. Normalization ........... "git reset --hard HEAD"
Step 7. Pack evaluation:
- Safe patterns ........ no match
- Destructive patterns . MATCH "reset --hard"
Rule details:
Pack: core.git
Rule ID: reset-hard
Severity: high
Reason: Discards all uncommitted changes permanently
Suggestion: Use `git stash` to preserve changes before resetting$ dcg explain "git checkout -b feature"
ALLOWED
Evaluation trace (7-step pipeline):
Step 4. Quick reject ............ no trigger
Step 7. Pack evaluation:
- Safe patterns ........ MATCH "checkout -b" (creating branch)
No block - command is safe.Use when: You want to understand WHY something was blocked before deciding next steps.
---
dcg test "command"
Dry-run evaluation without executing.
$ dcg test "rm -rf /home/user/project"
WOULD BE BLOCKED
Rule: core.filesystem:rm-rf-dangerous
Reason: Recursive deletion of non-temporary path
$ dcg test "rm -rf ./build"
WOULD BE ALLOWED
Context: Relative path in current directory considered safeUse when: Checking before running something you're unsure about.
---
dcg allow-once CODE
Create temporary exception for a blocked command.
$ dcg allow-once ab12
Exception created:
Command: git reset --hard HEAD
Directory: /home/user/project
Expires: 2025-01-16T10:30:00Z (24 hours)
Run the command again within 24 hours to execute.Characteristics:
- Code is 4 hex characters (cryptographically bound to command + directory)
- Expires after 24 hours
- Single use per command instance
- Stored in
~/.config/dcg/pending_exceptions.jsonl - Logged to
~/.config/dcg/audit.log
Critical: The HUMAN runs this command, not the agent. Agent should never execute dcg allow-once.
---
dcg allowlist
Manage permanent exceptions.
# Add allowlist entry
$ dcg allowlist add core.git:reset-hard -r "CI cleanup requires this"
# Add with scope
$ dcg allowlist add core.filesystem:rm-rf-dangerous \
--path "/home/user/project/build" \
-r "Build directory cleanup"
# List entries
$ dcg allowlist list
┌──────────────────────────────────┬────────────────────────────┬─────────────────────────┐
│ Rule ID │ Scope │ Reason │
├──────────────────────────────────┼────────────────────────────┼─────────────────────────┤
│ core.git:reset-hard │ global │ CI cleanup requires │
│ core.filesystem:rm-rf-dangerous │ /home/user/project/build │ Build directory cleanup │
└──────────────────────────────────┴────────────────────────────┴─────────────────────────┘
# Remove entry
$ dcg allowlist remove core.git:reset-hardLayered allowlists (highest to lowest priority): 1. .dcg/allowlist.toml — Project-level 2. ~/.config/dcg/allowlist.toml — User-level 3. /etc/dcg/allowlist.toml — System-level
---
dcg packs
List available and enabled rule packs.
$ dcg packs
Core (always enabled):
✓ core.git - Destructive git commands
✓ core.filesystem - Dangerous file operations
Optional (49 available):
Database: postgresql, mysql, mongodb, redis, sqlite
Containers: docker, compose, podman
Kubernetes: kubectl, helm, kustomize
Cloud: aws, azure, gcp
Storage: s3, gcs, azure_blob, minio
...
Currently enabled: core.git, core.filesystem
$ dcg packs --verbose
# Shows all patterns in each pack---
dcg scan
Scan repository for destructive commands in scripts and config files.
# Scan entire repo
$ dcg scan
Scanning 142 files...
FINDINGS:
┌─────────────────────────────────┬──────────┬─────────────────────────────────┐
│ File │ Line │ Issue │
├─────────────────────────────────┼──────────┼─────────────────────────────────┤
│ scripts/deploy.sh │ 45 │ git reset --hard (core.git) │
│ .github/workflows/ci.yml │ 23 │ rm -rf / (core.filesystem) │
│ Makefile │ 67 │ DROP DATABASE (database.*) │
└─────────────────────────────────┴──────────┴─────────────────────────────────┘
Found 3 issues in 3 files.
# Scan only staged files
$ dcg scan --staged
# Scan specific path
$ dcg scan --path scripts/
# Scan with SARIF output (for CI)
$ dcg scan --format sarif > results.sarifSupported file types:
| Type | Contexts Scanned |
|---|---|
Shell scripts (.sh) | All executable lines |
| Dockerfile | RUN instructions |
| GitHub Actions | run: fields |
| GitLab CI | script:, before_script:, after_script: |
| Makefile | Recipe lines |
| Docker Compose | command:, entrypoint: |
Install Pre-commit Hook
$ dcg scan install-pre-commit
Installed pre-commit hook at .git/hooks/pre-commit
Staged files will be scanned before each commit.---
dcg update
Self-update to latest version.
$ dcg update
Current version: 0.8.1
Latest version: 0.8.2
Downloading...
Verifying signature...
Installing...
Updated to 0.8.2---
Output Formats
All commands support --format:
dcg explain "cmd" --format json # Machine-readable
dcg explain "cmd" --format text # Human-readable (default)
dcg scan --format sarif # SARIF for CI integration---
Environment Variables
| Variable | Purpose | Example |
|---|---|---|
DCG_PACKS | Enable packs | "database.postgresql,kubernetes" |
DCG_DISABLE | Disable packs | "kubernetes.helm" |
DCG_BYPASS | Skip all checks | 1 (human-only escape hatch) |
DCG_VERBOSE | Verbosity (0-3) | 2 |
DCG_FORMAT | Default output | json |
DCG_CONFIG | Config file path | /path/to/config.toml |
DCG Configuration Reference
Configuration Hierarchy
Settings are loaded in this order (highest to lowest priority):
1. Environment Variables (DCG_* prefix) 2. Explicit Config File (DCG_CONFIG env var) 3. Project Config (.dcg.toml in repo root) 4. User Config (~/.config/dcg/config.toml) 5. System Config (/etc/dcg/config.toml) 6. Compiled Defaults
---
Environment Variables
| Variable | Purpose | Example |
|---|---|---|
DCG_PACKS | Enable optional packs | "database.postgresql,kubernetes" |
DCG_DISABLE | Disable specific packs | "kubernetes.helm" |
DCG_BYPASS | Skip all checks (escape hatch) | 1 |
DCG_VERBOSE | Verbosity level | 0-3 |
DCG_FORMAT | Default output format | text, json, sarif |
DCG_CONFIG | Explicit config path | /path/to/config.toml |
---
Project Config (.dcg.toml)
# Pack configuration
[packs]
enabled = [
"database.postgresql",
"kubernetes.kubectl",
"cloud.aws"
]
# Override patterns (evaluated before packs)
[overrides]
allow_patterns = [
"rm -rf ./node_modules",
"rm -rf ./build",
"git clean -fd ./generated"
]
block_patterns = [
"rm -rf /custom/dangerous/path"
]
# Heredoc scanning configuration
[heredoc]
enabled = true
max_size_bytes = 1048576 # 1MB
max_lines = 10000
tier2_budget_ms = 200
tier3_budget_ms = 5000
# Supported languages for AST analysis
languages = ["bash", "python", "ruby", "javascript", "typescript", "go", "php"]---
Agent-Specific Profiles
Configure different trust levels and rules per agent:
# Claude Code - high trust, additional allowlist
[agents.claude-code]
trust_level = "high"
additional_allowlist = [
"npm run build",
"cargo build --release"
]
# Gemini CLI - medium trust
[agents.gemini-cli]
trust_level = "medium"
# Unknown agents - paranoid mode
[agents.unknown]
trust_level = "low"
extra_packs = ["paranoid"]Trust Levels
| Level | Behavior |
|---|---|
high | Core packs only, faster evaluation |
medium | Standard evaluation (default) |
low | Extra scrutiny, more packs enabled |
---
Allowlist Configuration
Project-Level Allowlist (.dcg/allowlist.toml)
[[rules]]
id = "core.git:reset-hard"
reason = "CI cleanup requires hard reset"
expires = "2025-12-31" # Optional expiration
[[rules]]
id = "core.filesystem:rm-rf-dangerous"
path = "./build" # Scope to specific path
reason = "Build directory cleanup"User-Level Allowlist (~/.config/dcg/allowlist.toml)
[[rules]]
id = "containers.docker:system-prune"
reason = "Regular Docker cleanup on dev machine"---
Heredoc Three-Tier Architecture
DCG scans inline scripts (bash -c, python -c, heredocs) with progressive depth:
Tier 1: Trigger Detection (<5μs)
- Ultra-fast RegexSet screening
- Detects heredoc operators (
<<EOF,<<'EOF') - Detects inline script flags (
python -c,bash -c,ruby -e)
Tier 2: Content Extraction (<200μs)
- Parse heredoc body between delimiters
- Bounded by
max_size_bytesandmax_lines - Budget controlled by
tier2_budget_ms
Tier 3: AST Pattern Matching (<5ms)
- Parse with language-specific grammars (tree-sitter/ast-grep)
- Match structural patterns for destructive operations
- Budget controlled by
tier3_budget_ms
Fail-open behavior: If any tier exceeds its budget, remaining tiers are skipped and command is ALLOWED with a warning logged.
Tune Heredoc Settings
[heredoc]
# Increase for large scripts
max_size_bytes = 2097152 # 2MB
# Increase budgets if seeing "budget exceeded" warnings
tier2_budget_ms = 500
tier3_budget_ms = 10000
# Disable for performance (not recommended)
enabled = false---
CI Integration
GitHub Actions
- name: DCG Pre-commit Scan
run: dcg scan --git-diff origin/main..HEAD --fail-on errorPre-commit Hook
# Install hook
dcg scan install-pre-commit
# Hook checks staged files before each commit
# Blocks commit if destructive patterns foundGitLab CI
dcg-scan:
script:
- dcg scan --format sarif > dcg-results.sarif
artifacts:
reports:
sast: dcg-results.sarif---
Hook Protocol
DCG integrates with Claude Code via the PreToolUse hook:
Registration (~/.config/claude-code/settings.json)
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "dcg hook"
}]
}]
}
}Input (JSON on stdin)
{
"tool_name": "Bash",
"tool_input": {"command": "git reset --hard"}
}Deny Response (JSON on stdout)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "BLOCKED by dcg: ...",
"allowOnceCode": "ab12",
"ruleId": "core.git:reset-hard"
}
}Allow Response
Exit code 0 with no output.
DCG Rule Packs
DCG uses a modular pack system with 49+ rule packs organized by domain.
Core Packs (Always Enabled)
These cannot be disabled—they catch the most common destructive patterns.
core.git
| Pattern | Blocked | Safe Alternative |
|---|---|---|
git reset --hard | Yes | git stash |
git checkout -- <file> | Yes | git stash push <file> |
git clean -f | Yes | git clean -n (dry-run) |
git push --force | Yes | git push --force-with-lease |
git branch -D | Yes | git branch -d (checks merge) |
git stash drop | Yes | git stash list first |
git stash clear | Yes | Review stashes first |
Safe patterns (allowed):
git checkout -b— Creating branchesgit restore --staged— Unstaging filesgit clean -n/--dry-run— Preview modegit push --force-with-lease— Safe force push
core.filesystem
| Pattern | Blocked | Condition |
|---|---|---|
rm -rf / | Yes | Always |
rm -rf /* | Yes | Always |
rm -rf ~ | Yes | Always |
rm -rf /home | Yes | System paths |
rm -rf /path | Depends | Non-temp paths blocked |
Safe patterns (allowed):
rm -rf /tmp/*— Temp directoryrm -rf /var/tmp/*— Temp directoryrm -rf $TMPDIR/*— User temprm -rf ./build— Relative paths in project
---
Optional Packs by Category
Enable with DCG_PACKS or in .dcg.toml:
[packs]
enabled = ["database.postgresql", "kubernetes.kubectl", "cloud.aws"]Database Packs
| Pack | Blocks | Examples |
|---|---|---|
database.postgresql | Data destruction | DROP DATABASE, TRUNCATE, DELETE w/o WHERE |
database.mysql | Data destruction | DROP, TRUNCATE, unsafe deletes |
database.mongodb | Collection drops | db.dropDatabase(), db.collection.drop() |
database.redis | Data wipes | FLUSHALL, FLUSHDB, DEBUG SEGFAULT |
database.sqlite | File deletion | .backup overwrites, DROP TABLE |
Container Packs
| Pack | Blocks | Examples |
|---|---|---|
containers.docker | System prune | docker system prune -a, docker rm -f $(...) |
containers.compose | Stack destruction | docker-compose down -v --rmi all |
containers.podman | Same as docker | Pod and container mass deletion |
Kubernetes Packs
| Pack | Blocks | Examples |
|---|---|---|
kubernetes.kubectl | Namespace/cluster | delete namespace, delete --all, drain --force |
kubernetes.helm | Release destruction | helm uninstall, helm delete --purge |
kubernetes.kustomize | Dangerous applies | delete -k without confirmation |
Cloud Provider Packs
| Pack | Blocks | Examples |
|---|---|---|
cloud.aws | Resource destruction | aws ec2 terminate-instances, aws s3 rb --force |
cloud.azure | Resource groups | az group delete, az vm delete |
cloud.gcp | Project/instance | gcloud projects delete, instance termination |
Storage Packs
| Pack | Blocks | Examples |
|---|---|---|
storage.s3 | Bucket destruction | aws s3 rb, aws s3 rm --recursive |
storage.gcs | Bucket destruction | gsutil rm -r, gsutil rb |
storage.azure_blob | Container deletion | az storage container delete |
storage.minio | S3-compatible ops | mc rb --force |
Infrastructure Packs
| Pack | Blocks | Examples |
|---|---|---|
infrastructure.terraform | State destruction | terraform destroy, terraform state rm |
infrastructure.ansible | Dangerous playbooks | File deletion tasks, service stops |
infrastructure.pulumi | Stack destruction | pulumi destroy, pulumi stack rm |
CI/CD Packs
| Pack | Blocks | Examples |
|---|---|---|
cicd.github_actions | Workflow deletion | Dangerous run: commands in workflows |
cicd.gitlab_ci | Pipeline destruction | Risky script: blocks |
cicd.circleci | Config issues | Destructive commands in jobs |
cicd.jenkins | Pipeline risks | Shell steps with dangerous commands |
Secrets Management Packs
| Pack | Blocks | Examples |
|---|---|---|
secrets.vault | Secret deletion | vault kv delete, vault secrets disable |
secrets.aws_secrets | Secret destruction | aws secretsmanager delete-secret |
secrets.doppler | Config deletion | doppler configs delete |
secrets.onepassword | Vault destruction | op vault delete |
Messaging Packs
| Pack | Blocks | Examples |
|---|---|---|
messaging.kafka | Topic deletion | kafka-topics.sh --delete |
messaging.rabbitmq | Queue/exchange | rabbitmqctl delete_queue |
messaging.nats | Stream deletion | nats stream delete |
messaging.sqs_sns | Queue destruction | aws sqs delete-queue |
Search & Analytics Packs
| Pack | Blocks | Examples |
|---|---|---|
search.elasticsearch | Index deletion | DELETE /index, _delete_by_query |
search.algolia | Index clear | clearObjects, deleteIndex |
search.meilisearch | Index destruction | Index deletion APIs |
search.opensearch | Same as ES | Index and alias deletion |
Monitoring Packs
| Pack | Blocks | Examples |
|---|---|---|
monitoring.datadog | Monitor deletion | API calls to delete monitors |
monitoring.prometheus | Rule deletion | Recording rule destruction |
monitoring.splunk | Index deletion | Index and data destruction |
monitoring.newrelic | Alert deletion | Policy and condition removal |
monitoring.pagerduty | Service deletion | Escalation policy destruction |
Backup Packs
| Pack | Blocks | Examples |
|---|---|---|
backup.restic | Snapshot deletion | restic forget --prune |
backup.borg | Archive deletion | borg delete, borg prune |
backup.rclone | Remote deletion | rclone delete, rclone purge |
backup.velero | Backup destruction | velero backup delete |
Platform Packs
| Pack | Blocks | Examples |
|---|---|---|
platform.github | Repo destruction | gh repo delete |
platform.gitlab | Project deletion | glab project delete |
DNS Packs
| Pack | Blocks | Examples |
|---|---|---|
dns.cloudflare | Zone destruction | cloudflare dns delete |
dns.route53 | Record deletion | aws route53 change-resource-record-sets DELETE |
Payment Packs
| Pack | Blocks | Examples |
|---|---|---|
payment.stripe | Customer/sub deletion | API calls to delete customers |
payment.braintree | Transaction voids | Refund and void operations |
payment.square | Payment cancellation | Payment and customer deletion |
Load Balancer Packs
| Pack | Blocks | Examples |
|---|---|---|
lb.elb | LB destruction | aws elb delete-load-balancer |
lb.haproxy | Config destruction | Runtime API deletions |
lb.nginx | Config issues | Dangerous reload patterns |
lb.traefik | Dynamic config | Router and service deletion |
CDN Packs
| Pack | Blocks | Examples |
|---|---|---|
cdn.cloudflare_workers | Worker deletion | wrangler delete |
cdn.cloudfront | Distribution deletion | aws cloudfront delete-distribution |
cdn.fastly | Service destruction | Service and VCL deletion |
API Gateway Packs
| Pack | Blocks | Examples |
|---|---|---|
api.apigee | Proxy deletion | API proxy and product deletion |
api.aws | Gateway destruction | aws apigateway delete-rest-api |
api.kong | Route deletion | Service and route destruction |
---
Enabling Packs
Via Environment Variable
export DCG_PACKS="database.postgresql,kubernetes.kubectl,cloud.aws"Via Project Config (.dcg.toml)
[packs]
enabled = [
"database.postgresql",
"database.mysql",
"kubernetes.kubectl",
"kubernetes.helm",
"cloud.aws",
"storage.s3"
]Via User Config (~/.config/dcg/config.toml)
[packs]
enabled = ["containers.docker", "platform.github"]Disabling Specific Packs
# Disable helm even if kubernetes is enabled
export DCG_DISABLE="kubernetes.helm"---
Pack Inspection
# List all packs
dcg packs
# Show patterns in a pack
dcg packs --verbose database.postgresql
# Check which packs would match a command
dcg explain "kubectl delete namespace prod"DCG Philosophy
The Core Asymmetry
Execute "rm -rf /": 0.001 seconds
Recover from it: impossibleDCG exists because the cost of a false negative (destructive command runs) far exceeds the cost of a false positive (safe command blocked for 30 seconds).
Mechanical Enforcement vs Instructions
AGENTS.md says "don't run destructive commands" → Agent might ignore
DCG blocks destructive commands before execution → Physically impossible to runInstructions in AGENTS.md are suggestions. DCG is enforcement. This is the key differentiator.
Why Pre-Execution Blocking
Your Decision → DCG Hook → Shell → Kernel
↑
Intercept HERE- No partial execution
- No cleanup needed
- Clear audit trail
Alternatives (backups, permissions, monitoring) all act too late.
Human Context You Lack
When blocked, you're being told "get human confirmation" because they know:
- Production vs test environment
- Whether uncommitted changes matter
- Who else is working on this branch
- Actual blast radius
Why Patterns, Not AI
| Property | Pattern Matching |
|---|---|
| Speed | <2ms |
| Determinism | Same input → same result |
| Auditability | Exact pattern visible |
| Predictability | No model variance |
Allow-Once Codes
ALLOW-24H CODE: [12345]- Cryptographically bound to exact command + directory
- Time-limited, single-use, logged
- Human explicitly accepts responsibility
Why Never Circumvent
1. Your context may be incomplete 2. Human loses visibility 3. Erodes trust in all your actions
Correct response: explain why you think it's safe, let human decide.
Design Principles
| Principle | Meaning |
|---|---|
| Fail-closed on match | Pattern hits → block |
| Fail-open on error | DCG breaks → allow |
| Fail-open on timeout | >200ms → allow + warning |
| Fast safe path | Most commands <1ms |
| Human override | Never permanent, just confirmed |
Performance Contract
Latency Tiers:
| Tier | Stage | Target | Panic Threshold |
|---|---|---|---|
| 0 | Quick Reject | <1μs | >50μs |
| 1 | Normalization | <5μs | >100μs |
| 2 | Safe Pattern Check | <50μs | >500μs |
| 3 | Destructive Pattern Check | <50μs | >500μs |
| 4 | Heredoc Extraction | <1ms | >20ms |
| 5 | Heredoc Evaluation | <2ms | >30ms |
| 6 | Full Pipeline | <5ms | >50ms |
Absolute Max: 200ms (fail-open threshold)
SIMD Optimizations:
memchrcrate for fast substring searchAho-Corasickfor multi-pattern keyword matchingLazyLockfor one-time pattern compilationSmallVecfor stack-allocated collections
DCG will never significantly slow your workflow. If something goes wrong, commands run (with warnings logged).
You can always run dcg explain "command" to see exactly why something was blocked.
DCG makes you more useful: humans trust you more when safety rails exist.
DCG Scenarios
Quick reference for handling common blocks.
---
1. Git Reset — Use Alternative
Blocked: git reset --hard HEAD
❌ "Command blocked. Run dcg allow-once 12345."
✓ "Blocked because it destroys uncommitted work. Using git stash instead—recoverable if needed."
git stash -m "experimental changes"---
2. Force Push — Use Safer Flag
Blocked: git push --force origin feature-branch
✓ "Using --force-with-lease instead—checks remote hasn't changed since fetch."
git push --force-with-lease origin feature-branch---
3. rm -rf Typo — DCG Saved You
Blocked: rm -rf /home/user/project/ (meant ./build)
DCG caught the typo. Correct the path:
rm -rf ./build # Safe path, won't be blocked---
4. DROP DATABASE — Human Decision
Blocked: DROP DATABASE test_db;
✓ "Blocked as safety measure. Since this is a test database, you can approve with dcg allow-once 12345, or I can show contents first."
Approve for: Test/dev databases, known context Don't approve for: Production, unrecognized names, uncertainty
---
5. K8s Namespace — Show Contents First
Blocked: kubectl delete namespace staging
✓ "Namespace deletion removes ALL resources. Let me show what's there first:"
kubectl get all -n stagingThen human can approve or you can delete selectively with -l app=X.
---
6. Documented Procedure Requires It
Blocked: git reset --hard origin/main (per cleanup docs)
✓ "Procedure requires this. Blocked because it discards local changes. Approve with dcg allow-once 12345 if no local work to keep."
Even documented procedures deserve checkpoints—docs may be outdated.
---
7. False Positive
Blocked: rm -rf ./node_modules (unusual config)
✓ "This is typically safe—might be a false positive. Options: 1. dcg allow-once 12345 for this instance 2. Add allowlist entry if recurring"
Suggest allowlist only for genuinely safe, recurring operations.
---
Anti-Patterns
| Don't | Why |
|---|---|
| Retry silently | Human loses visibility |
| Ask for override first | Find alternatives first |
| Treat blocks as errors | They're checkpoints |
| Circumvent detection | Defeats safety system |
DCG Troubleshooting
Quick Diagnostics
dcg doctor # First step for any issue---
Common Issues
1. Commands Not Being Blocked
Symptom: Destructive commands run without DCG intercepting.
Diagnose:
$ dcg doctor
Hook Registration:
✗ Claude Code hook NOT registeredFix:
# Re-register hook
dcg install
# Verify
dcg doctorOther causes:
DCG_BYPASS=1is set → unset it- Command uses absolute path
/usr/bin/git→ DCG normalizes these, check config - Running in a context where hooks don't apply
2. False Positives (Safe Command Blocked)
Symptom: rm -rf ./node_modules blocked when it shouldn't be.
Diagnose:
$ dcg explain "rm -rf ./node_modules"
BLOCKED by core.filesystem:rm-rf-dangerous
Evaluation trace:
...
Step 6. Normalization: rm -rf /home/user/project/node_modules
Step 7. Pack evaluation: MATCH (non-temp path)Fix options:
1. Project allowlist (recommended):
# .dcg.toml
[overrides]
allow_patterns = ["rm -rf ./node_modules"]2. One-time allow:
# Human runs this
dcg allow-once ab123. Permanent allowlist:
dcg allowlist add core.filesystem:rm-rf-dangerous \
--path "$PWD/node_modules" \
-r "Package cleanup"3. Hook Timeout / Slow Performance
Symptom: Commands hang for 200ms before running.
Diagnose:
$ time dcg test "git status"
real 0m0.250s # Should be <5msPossible causes:
- Complex heredoc scanning taking too long
- Config file parsing issues
- Disk I/O problems
Fix:
# Check heredoc settings
grep -i heredoc ~/.config/dcg/config.toml
# Reduce heredoc limits if needed
# In config.toml:
[heredoc]
max_size_bytes = 524288 # 512KB instead of 1MB
max_lines = 5000 # Reduce from 10000Note: DCG is fail-open. If it exceeds 200ms deadline, command runs with warning.
4. Allow-Once Code Not Working
Symptom: dcg allow-once ab12 says "Invalid code" or exception doesn't apply.
Causes: 1. Code expired (24h limit) 2. Different directory — codes are bound to exact directory 3. Command changed — even whitespace matters
Diagnose:
$ dcg allow-once ab12
Error: Exception not found or expired
Details:
- Code 'ab12' was valid for: git reset --hard HEAD
- In directory: /home/user/other-project
- Current directory: /home/user/this-projectFix: Re-run the blocked command to get a fresh code for current context.
5. Pack Not Loading
Symptom: Database commands not blocked despite enabling pack.
Diagnose:
$ dcg packs
Currently enabled: core.git, core.filesystem
# database.postgresql not showing
$ echo $DCG_PACKS
# Empty or missing postgresqlFix:
# Environment variable
export DCG_PACKS="database.postgresql"
# Or in .dcg.toml
[packs]
enabled = ["database.postgresql"]Verify:
$ dcg explain "DROP DATABASE test"
BLOCKED by database.postgresql:drop-database6. Heredoc/Inline Script Not Scanned
Symptom: Destructive command in heredoc runs without block.
# This should be caught
bash -c "rm -rf /important"Diagnose:
$ dcg explain 'bash -c "rm -rf /important"'
ALLOWED
Evaluation trace:
Step 3. Heredoc detection: triggered (bash -c)
Step 3a. Tier 1: Pattern match ✓
Step 3b. Tier 2: Content extraction ✓
Step 3c. Tier 3: AST parsing... SKIPPED (budget exceeded)Cause: Heredoc budget exceeded, fell back to allow.
Fix:
# .dcg.toml - increase heredoc budget
[heredoc]
tier2_budget_ms = 500 # Default 200
tier3_budget_ms = 10000 # Default 50007. Config Not Being Applied
Symptom: .dcg.toml settings ignored.
Diagnose:
$ dcg doctor
Configuration:
✓ User config: ~/.config/dcg/config.toml
✗ Project config: .dcg.toml (parse error line 15)Common config errors:
# BAD: Wrong TOML syntax
[packs]
enabled = "postgresql" # Should be array
# GOOD:
[packs]
enabled = ["database.postgresql"]
# BAD: Invalid pack name
enabled = ["postgres"] # Should be "database.postgresql"
# GOOD:
enabled = ["database.postgresql"]Verify config:
# TOML syntax check
cat .dcg.toml | python3 -c "import sys,tomli;tomli.loads(sys.stdin.read())"8. Agent Bypassing DCG
Symptom: Agent uses workarounds like:
- Breaking command across lines
- Using aliases
- Calling absolute paths
DCG handles these: Command normalization strips sudo, env, aliases, and absolute paths.
If still bypassed: 1. Check DCG version is current: dcg update 2. Report bypass pattern to DCG maintainers 3. Add custom block pattern:
[overrides]
block_patterns = ["the-bypass-pattern"]---
Hook Protocol Issues
Claude Code Hook Not Receiving Input
Check hook is registered:
cat ~/.config/claude-code/settings.json | jq '.hooks'Expected:
{
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "dcg hook"}]
}]
}Hook Returns Wrong Format
DCG hook protocol:
Input (stdin):
{"tool_name": "Bash", "tool_input": {"command": "git reset --hard"}}Deny output (stdout):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "BLOCKED: ...",
"allowOnceCode": "ab12"
}
}Allow: Exit 0 with no output.
---
Getting Help
1. Check version: dcg --version 2. Run diagnostics: dcg doctor 3. Explain specific command: dcg explain "the-command" 4. Check logs: ~/.config/dcg/dcg.log (if verbose enabled)
Report issues: Include output of dcg doctor and dcg explain "command".
#!/usr/bin/env bash
# Validate DCG installation and configuration
set -euo pipefail
echo "=== DCG Installation Validation ==="
# Check if dcg is installed
if ! command -v dcg &> /dev/null; then
echo "ERROR: dcg not found in PATH"
echo "Install from: https://github.com/anthropics/destructive-command-guard"
exit 1
fi
echo "✓ dcg binary found: $(command -v dcg)"
# Check version
DCG_VERSION=$(dcg --version 2>&1 | awk '/dcg v/ { for (i = 1; i <= NF; i++) if ($i ~ /^v[0-9]/) { print $i; exit } }')
if [[ -z "$DCG_VERSION" ]]; then
DCG_VERSION="unknown"
fi
echo "✓ Version: $DCG_VERSION"
# Check if hook is installed
if dcg doctor &> /dev/null; then
echo "✓ Hook installed correctly"
else
echo "⚠ Hook may not be installed. Run: dcg install"
fi
# Test pattern detection
echo ""
echo "=== Pattern Detection Tests ==="
test_command() {
local cmd="$1"
local expected="$2"
local result
if dcg test "$cmd" &> /dev/null; then
result="allow"
else
result="block"
fi
if [ "$result" = "$expected" ]; then
echo "✓ '$cmd' → $result (expected)"
else
echo "✗ '$cmd' → $result (expected: $expected)"
return 1
fi
}
# Commands that SHOULD be blocked
test_command "rm -r""f /" "block"
test_command "rm -rf ./build" "block"
test_command "git reset --hard HEAD" "block"
test_command "DROP DATABASE production" "block"
# Commands that SHOULD be allowed
test_command "git status" "allow"
test_command "find . -maxdepth 1 -type d" "allow"
test_command "ls -la" "allow"
echo ""
echo "=== Configuration ==="
# Check for project config
if [ -f ".dcg.toml" ]; then
echo "✓ Project config found: .dcg.toml"
else
echo "○ No project config (.dcg.toml)"
fi
# Check for allowlist
if [ -f ".dcg/allowlist.toml" ]; then
echo "✓ Allowlist found: .dcg/allowlist.toml"
else
echo "○ No allowlist (.dcg/allowlist.toml)"
fi
echo ""
echo "=== Validation Complete ==="
DCG Skill Self-Test
Validate trigger phrases and skill functionality.
Trigger Test Cases
Each phrase should trigger this skill. Test by pasting into Claude Code:
Direct triggers (high confidence)
1. "DCG blocked my command, what do I do?" 2. "git reset --hard was blocked" 3. "rm -rf got blocked by dcg" 4. "How do I allow a blocked command?" 5. "Configure dcg for my project" 6. "kubectl delete namespace was blocked"
Intent-based triggers (should trigger)
7. "My destructive command was blocked" 8. "How do I bypass dcg safely?" 9. "Set up safety guardrails for agents" 10. "DROP DATABASE got blocked" 11. "Why did dcg block git push --force?" 12. "Configure agent safety rules"
Tool-specific triggers
13. "dcg explain isn't working" 14. "How do I use dcg allow-once?" 15. "Enable more dcg packs" 16. "dcg doctor shows an error"
Should NOT trigger
- "Search for dangerous code patterns" (code search)
- "Review this bash script for issues" (code review)
- "What git commands are dangerous?" (general git help)
- "How do I reset my git branch?" (git help, not dcg-specific)
---
Validation
Quick Smoke Test
# 1. Validate dcg installation
dcg doctor
# 2. Test explain command
dcg explain "git reset --hard HEAD"
# 3. Test dry-run
dcg test "rm -rf /home"
# 4. Verify skill structure
ls -la /cs/dcg/
ls -la /cs/dcg/references/Manual Validation
# Should show BLOCKED
dcg test "git reset --hard HEAD"
# Should show ALLOWED
dcg test "git checkout -b new-branch"
# Should show packs
dcg packs---
Expected Skill Behavior
When triggered, the skill should:
1. Provide THE EXACT WORKFLOW — The 4-step response sequence 2. Check Safe Alternatives first — Before mentioning override 3. Use `dcg explain` — To understand why blocked 4. Never ask for override first — Find alternative or explain risk 5. Human runs allow-once — Agent never runs this command
---
Common Failure Modes
| Failure | Cause | Fix |
|---|---|---|
| Skill doesn't trigger | Vague query | Use explicit "dcg blocked", "command blocked" |
| Hook not working | Not registered | Run dcg doctor, check Claude Code settings |
| Commands not blocked | Wrong hook path | Verify dcg hook in settings.json |
| Allow-once fails | Wrong directory | Codes are directory-bound; re-run blocked command |
---
Good vs Bad Responses
Good Response to Block
"I wanted to discard changes butgit reset --hardwas blocked. Let me rundcg explainto understand why... The reason is it destroys uncommitted work. I'll usegit stashinstead—it's recoverable if needed."
Bad Response to Block
"Command blocked. Run dcg allow-once ab12 to proceed."Why bad: Didn't look for alternative first, didn't explain risk.
Related skills
FAQ
How should an agent react to a DCG block?
Run dcg explain to understand it, use a safe alternative if one exists without mentioning override, and otherwise explain the risk and let a human run allow-once.
Does DCG slow down my workflow?
No. It runs at sub-millisecond latency and fails open on timeout, so a hung check lets the command run with a warning.