dcg について
DCGは、Claude Code向けのコマンド保護フックで、破壊的なコマンドを実行前に検知して遮断します。コーディングエージェントによる誤操作を減らしたい開発者向けで、安全パターンを先に判定し、未分類のコマンドは既定で許可します。
主な機能
- 01既知の破壊的コマンドを遮断
- 02安全パターンを優先し、未一致のコマンドは既定で許可
- 03カテゴリ別のルールパックを有効化・設定
- 04遮断理由と状況に応じた提案を表示
- 05Git、ファイルシステム、データベースなどのコマンドを保護
活用シーン
- 01エージェントによる誤った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 — Destructive Command Guard
実行前に破壊的なコマンドを検知してブロックする、高性能な Claude Code フックです。Rust で記述され、SIMD によるフィルタリングでサブミリ秒のレイテンシを実現します。
これが必要な理由
AI コーディングエージェントは強力ですが、間違いを犯すこともあります。誤って破壊的なコマンドを実行する可能性があります。
- 「ビルド成果物を片付けます」 →
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/* | シェル変数の形式です |
安全な代替手段:--force-with-lease
git push --force-with-lease # ALLOWED - refuses if remote has unseen commits
git push --force # BLOCKED - can overwrite others' work
モジュール式パックシステム
DCG は、パターンをカテゴリ別に整理するモジュール式の「パック」システムを使用します。
コアパック(常に有効)
| パック | 説明 |
|---|---|
core.git | 破壊的な git コマンド |
core.filesystem | 一時ディレクトリ以外での危険な rm -rf |
データベースパック
| パック | 説明 |
|---|---|
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 の解析
- 標準入力からフックの入力を読み取ります
- Claude Code の
PreToolUse形式を検証します - Bash 以外のツールは直ちに許可されます
ステージ 2:コマンドの正規化
- 絶対パスを取り除きます:
/usr/bin/git status→git status - 引数内のパスは保持します
ステージ 3:簡易拒否フィルター
- 「git」または「rm」の部分文字列を SIMD で高速検索します
- これらを含まないコマンドは正規表現の検査を完全に省略します(コマンドの 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
すべてのバリエーションに対応しています。
シェル変数の展開
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 による高速な除外判定 | CPU のベクトル命令に memchr クレートを使用 |
| 早期終了 | 安全な一致が見つかると直ちに返す |
| ゼロコピー JSON | serde_json が入力バッファーを直接処理 |
| ゼロアロケーション | パスの正規化に Cow<str> を使用 |
| リリースプロファイル | opt-level="z"、LTO、単一のコード生成単位 |
結果: 一般的なコマンドをミリ秒未満で実行します。
パターン数
| 種類 | 数 |
|---|---|
| 安全なパターン(許可リスト) | 34 |
| 破壊的なパターン(拒否リスト) | 16 |
セキュリティに関する考慮事項
DCG が防止するもの
git checkout --やgit reset --hardによる誤ったデータ損失- 強制プッシュによるリモート履歴の破壊
git stash drop/clearによるスタッシュの損失- 一時ディレクトリ外での
rm -rfによるファイルシステム上の事故
DCG が防止しないもの
- 悪意ある攻撃者(フックを回避できます)
- Bash 以外のコマンド(Python/JavaScript によるファイル書き込み、API 呼び出し)
- コミット済みだがプッシュされていない作業
- スクリプト内のコマンド(
./deploy.shの内容は検査されません)
脅威モデル
DCG は、AI エージェントが善意を持っているものの、間違いを犯す可能性があることを前提としています。悪意ある攻撃ではなく、うっかりしたミスを検出します。
トラブルシューティング
フックがコマンドをブロックしない場合
~/.claude/settings.jsonにフック設定があることを確認します- Claude Code を再起動します
- 手動でテストします:
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
フックが安全なコマンドをブロックする場合
- カバーされていないエッジケースがないか確認します
- GitHub の issue を作成します
- 一時的に回避するには、
DCG_BYPASS=1を設定するか、コマンドを手動で実行します
FAQ
Q: なぜ git branch -D はブロックし、git branch -d は許可するのですか?
小文字の -d は、完全にマージ済みのブランチのみを削除します。大文字の -D はマージ状態にかかわらず強制削除するため、コミットが失われる可能性があります。
Q: なぜ git push --force-with-lease は許可されているのですか?
force-with-lease は、確認していないコミットがリモートにある場合にプッシュを拒否し、誤った上書きを防ぎます。
Q: なぜ一時ディレクトリ外では、すべての rm -rf をブロックするのですか?
再帰的な強制削除は非常に危険です。タイプミスや誤った変数によって、重要なファイルが削除される可能性があります。一時ディレクトリは、短期間で破棄されることを前提に設計されています。
Q: ブロックされたコマンドをどうしても実行する必要がある場合はどうすればよいですか?
DCG は、エージェントに許可を求めるよう指示します。よく考えたうえで決断し、別のターミナルでコマンドを手動実行してください。
Flywheel との統合
| ツール | 統合 |
|---|---|
| Claude Code | ネイティブの PreToolUse フック |
| Agent Mail | エージェントはブロックされたコマンドをコーディネーターに報告できます |
| BV | DCG が繰り返し作動するタスクにフラグを付けます |
| CASS | セッション全体から DCG のブロックパターンを検索します |
| RU | DCG は、破壊的なコミットから agent-sweep を保護します |