mcpField
D
dcg

dcg

github.com/dicklesworthstoneセキュリティ7359 回インストール8 週間前に更新
リポジトリ

dcg について

DCGは、Claude Code向けのコマンド保護フックで、破壊的なコマンドを実行前に検知して遮断します。コーディングエージェントによる誤操作を減らしたい開発者向けで、安全パターンを先に判定し、未分類のコマンドは既定で許可します。

主な機能

  1. 01既知の破壊的コマンドを遮断
  2. 02安全パターンを優先し、未一致のコマンドは既定で許可
  3. 03カテゴリ別のルールパックを有効化・設定
  4. 04遮断理由と状況に応じた提案を表示
  5. 05Git、ファイルシステム、データベースなどのコマンドを保護

活用シーン

  1. 01エージェントによる誤ったgit reset --hardを防止
  2. 02強制プッシュによるリモートコミットの上書きを回避
  3. 03一時ディレクトリ外へのrm -rfを遮断
  4. 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.postgresqlPostgreSQL の DROP/TRUNCATE
database.mysqlMySQL/MariaDB の DROP/TRUNCATE
database.mongodbdropDatabase、drop()
database.redisFLUSHALL/FLUSHDB
database.sqliteSQLite の DROP
コンテナパック
パック説明
containers.dockerdocker system prune、docker rm -f
containers.composedocker-compose down --volumes
containers.podmanpodman system prune
Kubernetes パック
パック説明
kubernetes.kubectlkubectl delete namespace
kubernetes.helmhelm uninstall
kubernetes.kustomizekustomize の削除パターン
クラウドプロバイダーパック
パック説明
cloud.awsAWS CLI の破壊的なコマンド
cloud.gcpgcloud の破壊的なコマンド
cloud.azureaz の破壊的なコマンド
インフラストラクチャパック
パック説明
infrastructure.terraformterraform destroy
infrastructure.ansible危険な ansible パターン
infrastructure.pulumipulumi destroy
システムパック
パック説明
system.diskdd、mkfs、fdisk の操作
system.permissions危険な chmod/chown パターン
system.servicessystemctl stop/disable パターン
その他のパック
パック説明
strict_gitより厳格な git 保護
package_managersnpm 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=1DCG を完全にバイパスします(緊急回避策)

インストール

クイックインストール(推奨)
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 クレートを使用
早期終了安全な一致が見つかると直ちに返す
ゼロコピー JSONserde_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 エージェントが善意を持っているものの、間違いを犯す可能性があることを前提としています。悪意ある攻撃ではなく、うっかりしたミスを検出します。

トラブルシューティング

フックがコマンドをブロックしない場合
  1. ~/.claude/settings.json にフック設定があることを確認します
  2. Claude Code を再起動します
  3. 手動でテストします:echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
フックが安全なコマンドをブロックする場合
  1. カバーされていないエッジケースがないか確認します
  2. GitHub の issue を作成します
  3. 一時的に回避するには、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エージェントはブロックされたコマンドをコーディネーターに報告できます
BVDCG が繰り返し作動するタスクにフラグを付けます
CASSセッション全体から DCG のブロックパターンを検索します
RUDCG は、破壊的なコミットから agent-sweep を保護します

コメント