关于 dcg
DCG 是为 Claude Code 编写的命令防护钩子,在危险命令执行前进行拦截,适合希望减少 Agent 意外破坏代码、数据或基础设施的开发者。它采用白名单优先匹配,并以默认放行为未识别命令设定处理方式。
主要功能
- 01拦截已知破坏性命令
- 02安全模式优先匹配,未识别命令默认放行
- 03按类别启用和配置规则包
- 04提供阻止原因和操作建议
- 05支持 Git、文件系统及数据库等命令防护
适用场景
- 01阻止 Agent 误执行 git reset --hard
- 02避免强制推送覆盖远程提交
- 03防止 rm -rf 删除临时目录外文件
- 04配置数据库、容器或云命令的防护规则
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dicklesworthstone/ agent_flywheel_clawdbot_skills_and_integrations --skill dcg安装后在 Claude Code 中输入/dcg确认已加载。
详细介绍
DCG — 破坏性命令防护
一款高性能的 Claude Code 钩子,可在破坏性命令执行前拦截并阻止它们。使用 Rust 编写,并通过 SIMD 加速过滤,实现亚毫秒级延迟。
存在的意义
AI 编码 Agent 功能强大,但也会出错。它们可能会意外运行破坏性命令:
- “我来清理一下构建产物” →
rm -rf ./src(手误) - “我会重置到上一次提交” →
git reset --hard(会销毁未提交的更改) - “我来解决合并冲突” →
git checkout -- .(会丢弃所有修改) - “我会清理未跟踪文件” →
git clean -fd(会永久删除未跟踪的文件)
DCG 会在危险命令执行之前拦截它们,并给出清晰的说明,然后阻止命令执行,让你有机会先暂存更改。
核心设计原则
1. 白名单优先架构
先检查安全模式,再检查破坏性模式。这可确保明确安全的命令不会被意外阻止:
git checkout -b feature → Matches SAFE "checkout-new-branch" → ALLOW
git checkout -- file.txt → No safe match, matches DESTRUCTIVE → DENY
2. 默认安全(默认允许)
默认情况下,允许无法识别的命令。这可确保:
- 钩子不会破坏正常工作流
- 只阻止已知的危险模式
- 新的 git 命令在被明确归类前都可以正常使用
3. 零漏报理念
模式集优先考虑绝不允许危险命令,而非避免误报。多几次需要手动确认的提示可以接受;丢失工作成果则不可接受。
阻止的命令
会破坏未提交工作的 Git 命令
| 命令 | 原因 |
|---|---|
git reset --hard | 会销毁未提交的更改 |
git reset --merge | 会销毁未提交的更改 |
git checkout -- <file> | 会丢弃文件修改 |
git restore <file>(不带 --staged) | 会丢弃未提交的更改 |
git clean -f | 会永久删除未跟踪的文件 |
会破坏远程历史记录的 Git 命令
| 命令 | 原因 |
|---|---|
git push --force / -f | 会覆盖远程提交 |
git branch -D | 未检查合并状态就强制删除分支 |
会破坏暂存工作的 Git 命令
| 命令 | 原因 |
|---|---|
git stash drop | 会永久删除一个暂存 |
git stash clear | 会永久删除所有暂存 |
文件系统命令
| 命令 | 原因 |
|---|---|
rm -rf(在 /tmp、/var/tmp、$TMPDIR 之外) | 递归删除具有危险性 |
允许的命令
安全操作会静默放行:
始终安全的 Git 操作
git status、git log、git diff、git add、git commit、git push、git pull、git fetch、git branch -d(合并检查后安全删除)、git stash、git stash pop、git stash list
明确安全的模式
| 模式 | 安全原因 |
|---|---|
git checkout -b <branch> | 创建新分支 |
git checkout --orphan <branch> | 创建孤儿分支 |
git restore --staged <file> | 仅取消暂存,不会修改工作区 |
git restore -S <file> | 暂存操作的简写标志 |
git clean -n / --dry-run | 预览模式,不会实际删除 |
rm -rf /tmp/* | 临时目录中的内容是临时的 |
rm -rf $TMPDIR/* | Shell 变量形式 |
安全替代方案:--force-with-lease
git push --force-with-lease # ALLOWED - refuses if remote has unseen commits
git push --force # BLOCKED - can overwrite others' work
模块化 Pack 系统
DCG 使用模块化的“pack”系统,按类别组织模式:
核心 Pack(始终启用)
| Pack | 描述 |
|---|---|
core.git | 破坏性 git 命令 |
core.filesystem | 临时目录之外的危险 rm -rf |
数据库 Pack
| Pack | 描述 |
|---|---|
database.postgresql | PostgreSQL 中的 DROP/TRUNCATE |
database.mysql | MySQL/MariaDB 中的 DROP/TRUNCATE |
database.mongodb | dropDatabase、drop() |
database.redis | FLUSHALL/FLUSHDB |
database.sqlite | SQLite 中的 DROP |
容器包
| 包 | 描述 |
|---|---|
containers.docker | docker system prune、docker rm -f |
containers.compose | docker-compose down --volumes |
containers.podman | podman system prune |
Kubernetes 包
| 包 | 描述 |
|---|---|
kubernetes.kubectl | kubectl delete namespace |
kubernetes.helm | helm uninstall |
kubernetes.kustomize | kustomize 删除模式 |
云服务提供商包
| 包 | 描述 |
|---|---|
cloud.aws | 具有破坏性的 AWS CLI 命令 |
cloud.gcp | 具有破坏性的 gcloud 命令 |
cloud.azure | 具有破坏性的 az 命令 |
基础设施包
| 包 | 描述 |
|---|---|
infrastructure.terraform | terraform destroy |
infrastructure.ansible | 危险的 ansible 模式 |
infrastructure.pulumi | pulumi destroy |
系统包
| 包 | 描述 |
|---|---|
system.disk | dd、mkfs、fdisk 操作 |
system.permissions | 危险的 chmod/chown 模式 |
system.services | systemctl stop/disable 模式 |
其他包
| 包 | 描述 |
|---|---|
strict_git | 额外严格的 git 防护 |
package_managers | npm unpublish、cargo yank |
配置包
# ~/.config/dcg/config.toml
[packs]
enabled = [
"database.postgresql",
"containers.docker",
"kubernetes", # Enables all kubernetes sub-packs
]
环境变量
| 变量 | 描述 |
|---|---|
DCG_PACKS="containers.docker,kubernetes" | 启用包(以逗号分隔) |
DCG_DISABLE="kubernetes.helm" | 禁用包/子包 |
DCG_VERBOSE=1 | 详细输出 |
DCG_COLOR=auto|always|never | 颜色模式 |
DCG_BYPASS=1 | 完全绕过 DCG(紧急出口) |
安装
快速安装(推荐)
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
从源代码构建(需要 Rust Nightly)
cargo +nightly install --git https://github.com/Dicklesworthstone/destructive_command_guard
预构建二进制文件
适用于:Linux x86_64、Linux ARM64、macOS Intel、macOS Apple Silicon、Windows
Claude Code 配置
添加到 ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "dcg"
}
]
}
]
}
}
重要: 添加钩子后,请重启 Claude Code。
工作原理
处理流水线
┌─────────────────────────────────────────────────────────────────┐
│ 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)
阶段 1:JSON 解析
- 从 stdin 读取钩子输入
- 验证 Claude Code 的
PreToolUse格式 - 立即允许非 Bash 工具
阶段 2:命令规范化
- 移除绝对路径:
/usr/bin/git status→git status - 保留参数路径
阶段 3:快速拒绝过滤器
- 使用 SIMD 加速的子字符串搜索查找 "git" 或 "rm"
- 不包含这些内容的命令会完全跳过正则表达式处理(99% 以上的命令)
阶段 4:模式匹配
- 优先检查安全模式(匹配时短路 → 允许)
- 然后检查破坏性模式(匹配 → 拒绝)
- 未匹配 → 默认允许
退出代码
| 代码 | 含义 |
|---|---|
0 | 命令安全,可以继续 |
2 | 命令已被阻止,请勿执行 |
CLI 用法
手动测试命令:
# 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.
════════════════════════════════════════════════════════════════════════
上下文建议
| 命令类型 | 建议 |
|---|---|
git reset、git checkout -- | "建议先使用 'git stash'" |
git clean | "先使用 'git clean -n' 预览" |
git push --force | "建议使用 '--force-with-lease'" |
rm -rf | "手动运行前请仔细确认路径" |
已处理的边缘情况
路径规范化
/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
所有变体均已处理。
Shell 变量展开
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 的设计目标是实现零感知延迟:
| 优化 | 技术 |
|---|---|
| 惰性静态变量 | 通过 LazyLock 仅编译一次正则表达式模式 |
| SIMD 快速拒绝 | 使用 memchr crate 执行 CPU 向量指令 |
| 提前退出 | 安全匹配时立即返回 |
| 零拷贝 JSON | serde_json 直接操作输入缓冲区 |
| 零分配 | 使用 Cow<str> 规范化路径 |
| 发布配置 | opt-level="z"、LTO、单个代码生成单元 |
结果: 典型命令的执行时间不到 1 毫秒。
模式数量
| 类型 | 数量 |
|---|---|
| 安全模式(白名单) | 34 |
| 破坏性模式(黑名单) | 16 |
安全注意事项
DCG 防护的情况
- 防止因
git checkout --或git reset --hard导致意外数据丢失 - 防止强制推送破坏远程历史记录
- 防止因
git stash drop/clear导致存储内容丢失 - 防止在临时目录之外执行
rm -rf造成文件系统事故
DCG 无法防护的情况
- 恶意行为者(可以绕过钩子)
- 非 Bash 命令(Python/JavaScript 文件写入、API 调用)
- 已提交但尚未推送的工作
- 脚本内部的命令(不会检查
./deploy.sh的内容)
威胁模型
DCG 假设 AI Agent 出于善意,但难免犯错。它能捕获无心之失,而非对抗性攻击。
故障排除
钩子未拦截命令
- 确认
~/.claude/settings.json中已配置钩子 - 重启 Claude Code
- 手动测试:
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
钩子拦截了安全命令
- 检查是否存在未覆盖的边缘情况
- 提交 GitHub issue
- 临时绕过:使用
DCG_BYPASS=1,或手动运行命令
常见问题
问:为什么拦截 git branch -D,却允许 git branch -d?
小写的 -d 只会删除已完全合并的分支。大写的 -D 无论分支是否已合并都会强制删除,可能导致提交丢失。
问:为什么允许 git push --force-with-lease?
如果远程端存在你尚未看到的提交,--force-with-lease 会拒绝推送,从而防止意外覆盖。
问:为什么拦截临时目录之外的所有 rm -rf?
强制递归删除极其危险。拼写错误或变量错误都可能删除关键文件。临时目录就是为短期使用而设计的。
问:如果我确实需要运行被拦截的命令,该怎么办?
DCG 会指示 Agent 请求许可。在审慎作出决定后,可在单独的终端中手动运行该命令。
与 Flywheel 的集成
| 工具 | 集成方式 |
|---|---|
| Claude Code | 原生 PreToolUse 钩子 |
| Agent Mail | Agent 可向协调器报告被拦截的命令 |
| BV | 标记反复触发 DCG 的任务 |
| CASS | 搜索各会话中的 DCG 拦截模式 |
| RU | DCG 保护 agent-sweep,避免破坏性提交 |