[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-Dicklesworthstone--destructive_command_guard":3,"tool-Dicklesworthstone--destructive_command_guard":62},[4,18,26,36,46,54],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",159636,2,"2026-04-17T23:33:34",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":42,"last_commit_at":43,"category_tags":44,"status":17},8272,"opencode","anomalyco\u002Fopencode","OpenCode 是一款开源的 AI 编程助手（Coding Agent），旨在像一位智能搭档一样融入您的开发流程。它不仅仅是一个代码补全插件，而是一个能够理解项目上下文、自主规划任务并执行复杂编码操作的智能体。无论是生成全新功能、重构现有代码，还是排查难以定位的 Bug，OpenCode 都能通过自然语言交互高效完成，显著减少开发者在重复性劳动和上下文切换上的时间消耗。\n\n这款工具专为软件开发者、工程师及技术研究人员设计，特别适合希望利用大模型能力来提升编码效率、加速原型开发或处理遗留代码维护的专业人群。其核心亮点在于完全开源的架构，这意味着用户可以审查代码逻辑、自定义行为策略，甚至私有化部署以保障数据安全，彻底打破了传统闭源 AI 助手的“黑盒”限制。\n\n在技术体验上，OpenCode 提供了灵活的终端界面（Terminal UI）和正在测试中的桌面应用程序，支持 macOS、Windows 及 Linux 全平台。它兼容多种包管理工具，安装便捷，并能无缝集成到现有的开发环境中。无论您是追求极致控制权的资深极客，还是渴望提升产出的独立开发者，OpenCode 都提供了一个透明、可信",144296,1,"2026-04-16T14:50:03",[13,45],"插件",{"id":47,"name":48,"github_repo":49,"description_zh":50,"stars":51,"difficulty_score":32,"last_commit_at":52,"category_tags":53,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",108322,"2026-04-10T11:39:34",[14,15,13],{"id":55,"name":56,"github_repo":57,"description_zh":58,"stars":59,"difficulty_score":32,"last_commit_at":60,"category_tags":61,"status":17},6121,"gemini-cli","google-gemini\u002Fgemini-cli","gemini-cli 是一款由谷歌推出的开源 AI 命令行工具，它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言，它提供了一条从输入提示词到获取模型响应的最短路径，无需切换窗口即可享受智能辅助。\n\n这款工具主要解决了开发过程中频繁上下文切换的痛点，让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用，还是执行复杂的 Git 操作，gemini-cli 都能通过自然语言指令高效处理。\n\n它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口，具备出色的逻辑推理能力；内置 Google 搜索、文件操作及 Shell 命令执行等实用工具；更独特的是，它支持 MCP（模型上下文协议），允许用户灵活扩展自定义集成，连接如图像生成等外部能力。此外，个人谷歌账号即可享受免费的额度支持，且项目基于 Apache 2.0 协议完全开源，是提升终端工作效率的理想助手。",100752,"2026-04-10T01:20:03",[45,13,15,14],{"id":63,"github_repo":64,"name":65,"description_en":66,"description_zh":67,"ai_summary_zh":68,"readme_en":69,"readme_zh":70,"quickstart_zh":71,"use_case_zh":72,"hero_image_url":73,"owner_login":74,"owner_name":75,"owner_avatar_url":76,"owner_bio":77,"owner_company":78,"owner_location":78,"owner_email":78,"owner_twitter":79,"owner_website":80,"owner_url":81,"languages":82,"stars":102,"forks":103,"last_commit_at":104,"license":105,"difficulty_score":32,"env_os":106,"env_gpu":107,"env_ram":107,"env_deps":108,"category_tags":111,"github_topics":112,"view_count":32,"oss_zip_url":78,"oss_zip_packed_at":78,"status":17,"created_at":119,"updated_at":120,"faqs":121,"releases":150},8811,"Dicklesworthstone\u002Fdestructive_command_guard","destructive_command_guard","The Destructive Command Guard (dcg) is for blocking dangerous git and shell commands from being executed by agents.","destructive_command_guard（简称 dcg）是一款专为 AI 编程助手设计的安全防护工具，旨在防止自动化代理执行危险命令导致代码或数据丢失。在使用 Claude Code、GitHub Copilot、Cursor 等 AI 工具时，模型偶尔会误生成如 `rm -rf`、`git reset --hard` 或数据库删除指令，瞬间摧毁数小时的工作成果。dcg 通过在命令执行前进行拦截，精准识别并阻断这些高风险操作，同时提供清晰的解释和更安全的替代建议。\n\n这款工具特别适合依赖 AI 辅助编程的开发者、运维工程师及技术团队。它无需复杂配置即可开箱即用，支持 Git、文件系统以及 AWS、Kubernetes、Docker 等 49 多种环境的安全规则包。技术亮点在于其亚毫秒级的超低延迟过滤能力，采用 SIMD 加速技术，确保在保护安全的同时不影响开发流畅度；此外，它还具备智能上下文感知功能，能区分代码中的危险字符串与实际执行指令，避免误报。无论是本地开发还是 CI\u002FCD 流程，destructive_command_guard 都能为你的项目构建一道坚实的安全防线，","destructive_command_guard（简称 dcg）是一款专为 AI 编程助手设计的安全防护工具，旨在防止自动化代理执行危险命令导致代码或数据丢失。在使用 Claude Code、GitHub Copilot、Cursor 等 AI 工具时，模型偶尔会误生成如 `rm -rf`、`git reset --hard` 或数据库删除指令，瞬间摧毁数小时的工作成果。dcg 通过在命令执行前进行拦截，精准识别并阻断这些高风险操作，同时提供清晰的解释和更安全的替代建议。\n\n这款工具特别适合依赖 AI 辅助编程的开发者、运维工程师及技术团队。它无需复杂配置即可开箱即用，支持 Git、文件系统以及 AWS、Kubernetes、Docker 等 49 多种环境的安全规则包。技术亮点在于其亚毫秒级的超低延迟过滤能力，采用 SIMD 加速技术，确保在保护安全的同时不影响开发流畅度；此外，它还具备智能上下文感知功能，能区分代码中的危险字符串与实际执行指令，避免误报。无论是本地开发还是 CI\u002FCD 流程，destructive_command_guard 都能为你的项目构建一道坚实的安全防线，让 AI 协作更安心。","# dcg (Destructive Command Guard)\n\n\u003Cdiv align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FDicklesworthstone_destructive_command_guard_readme_f3551a4f1c3c.webp\" alt=\"Destructive Command Guard - Protecting your code from accidental destruction\">\n\u003C\u002Fdiv>\n\n\u003Cdiv align=\"center\">\n\n[![Coverage](https:\u002F\u002Fimg.shields.io\u002Fcodecov\u002Fc\u002Fgithub\u002FDicklesworthstone\u002Fdestructive_command_guard?label=coverage)](https:\u002F\u002Fcodecov.io\u002Fgh\u002FDicklesworthstone\u002Fdestructive_command_guard)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\n\u003C\u002Fdiv>\n\nA high-performance hook for AI coding agents that blocks destructive commands before they execute, protecting your work from accidental deletion.\n\n**Supported:** [Claude Code](https:\u002F\u002Fclaude.ai\u002Fcode), [Gemini CLI](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli), [GitHub Copilot CLI](https:\u002F\u002Fdocs.github.com\u002Fen\u002Fcopilot\u002Fconcepts\u002Fagents\u002Fcoding-agent\u002Fabout-hooks), [Cursor IDE](https:\u002F\u002Fcursor.com), [OpenCode](https:\u002F\u002Fopencode.ai) (via [community plugin](https:\u002F\u002Fgithub.com\u002Faspiers\u002Fai-config\u002Fblob\u002Fmain\u002F.config\u002Fopencode\u002Fplugins\u002Fdcg-guard.js)), [Aider](https:\u002F\u002Faider.chat\u002F) (limited—git hooks only), [Continue](https:\u002F\u002Fcontinue.dev) (detection only), [Codex CLI](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex)\n\n\u003Cdiv align=\"center\">\n\u003Ch3>Quick Install\u003C\u002Fh3>\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --easy-mode\n```\n\n\u003Cp>\u003Cem>Works on Linux, macOS, and Windows (WSL). Auto-detects your platform and downloads the right binary.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\n---\n\n## TL;DR\n\n**The Problem**: AI coding agents (Claude, GPT, etc.) occasionally run catastrophic commands like `git reset --hard`, `rm -rf .\u002Fsrc`, or `DROP TABLE users`—destroying hours of uncommitted work in seconds.\n\n**The Solution**: dcg is a high-performance hook that intercepts destructive commands *before* they execute, blocking them with clear explanations and safer alternatives.\n\n### Why Use dcg?\n\n| Feature | What It Does |\n|---------|--------------|\n| **Zero-Config Protection** | Blocks dangerous git\u002Ffilesystem commands out of the box |\n| **49+ Security Packs** | Databases, Kubernetes, Docker, AWS\u002FGCP\u002FAzure, Terraform, and more |\n| **Sub-Millisecond Latency** | SIMD-accelerated filtering—you won't notice it's there |\n| **Heredoc\u002FInline Script Scanning** | Catches `python -c \"os.remove(...)\"` and embedded shell scripts |\n| **Smart Context Detection** | Won't block `grep \"rm -rf\"` (data) but will block `rm -rf \u002F` (execution) |\n| **Scan Mode for CI** | Pre-commit hooks and CI integration to catch dangerous commands in code review |\n| **Fail-Open Design** | Never blocks your workflow due to timeouts or parse errors |\n| **Explain Mode** | `dcg explain \"command\"` shows exactly why something is blocked |\n\n### Quick Example\n\n```bash\n# AI agent tries to run:\n$ git reset --hard HEAD~5\n\n# dcg intercepts and blocks:\n════════════════════════════════════════════════════════════════\nBLOCKED  dcg\n────────────────────────────────────────────────────────────────\nReason:  git reset --hard destroys uncommitted changes\n\nCommand: git reset --hard HEAD~5\n\nTip: Consider using 'git stash' first to save your changes.\n════════════════════════════════════════════════════════════════\n```\n\n### Enable More Protection\n\n```toml\n# ~\u002F.config\u002Fdcg\u002Fconfig.toml\n[packs]\nenabled = [\n    \"database.postgresql\",    # Blocks DROP TABLE, TRUNCATE\n    \"kubernetes.kubectl\",     # Blocks kubectl delete namespace\n    \"cloud.aws\",              # Blocks aws ec2 terminate-instances\n    \"containers.docker\",      # Blocks docker system prune\n]\n```\n\n### Agent-Specific Profiles\n\ndcg automatically detects which AI coding agent is invoking it and can apply\nagent-specific configuration. The `trust_level` field is an **advisory label**\nrecorded in JSON output and logs — it does not directly change rule evaluation.\nBehavioral differences come from the other profile fields:\n\n| Option | Effect |\n|--------|--------|\n| `disabled_packs` | Removes rule packs from evaluation |\n| `extra_packs` | Adds rule packs to evaluation |\n| `additional_allowlist` | Adds command patterns that bypass deny rules |\n| `disabled_allowlist` | When `true`, ignores all allowlist entries |\n\n```toml\n# Trust Claude Code more — wider allowlist, fewer packs\n[agents.claude-code]\ntrust_level = \"high\"\nadditional_allowlist = [\"npm run build\", \"cargo test\"]\ndisabled_packs = [\"kubernetes\"]\n\n# Restrict unknown agents — extra rules, no allowlist bypass\n[agents.unknown]\ntrust_level = \"low\"\nextra_packs = [\"paranoid\"]\ndisabled_allowlist = true\n```\n\nSee [docs\u002Fagents.md](docs\u002Fagents.md) for full documentation on supported agents,\ntrust levels, and configuration options.\n\n---\n\n## Origins & Authors\n\nThis project began as a Python script by Jeffrey Emanuel, who recognized that AI coding agents, while incredibly useful, occasionally run catastrophic commands that destroy hours of uncommitted work. The original implementation was a simple but effective hook that intercepted dangerous git and filesystem commands before execution.\n\n- **[Jeffrey Emanuel](https:\u002F\u002Fgithub.com\u002FDicklesworthstone)** - Original concept and Python implementation ([source](https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fmisc_coding_agent_tips_and_scripts\u002Fblob\u002Fmain\u002FDESTRUCTIVE_GIT_COMMAND_CLAUDE_HOOKS_SETUP.md)); substantially expanded the Rust version with the modular pack system (49+ security packs), heredoc\u002Finline-script scanning, the three-tier architecture, context classification, allowlists, scan mode, and the dual regex engine\n- **[Darin Gordon](https:\u002F\u002Fgithub.com\u002FDowwie)** - Initial Rust port with performance optimizations\n\nThe initial Rust port by Darin maintained pattern compatibility with the original Python implementation while adding sub-millisecond execution through SIMD-accelerated filtering and lazy-compiled regex patterns. Jeffrey subsequently expanded the Rust codebase dramatically to add the features described above.\n\n## Escape Hatch \u002F Bypass\n\nIf dcg is blocking something you genuinely need to run:\n\n| Method | Scope | How |\n|--------|-------|-----|\n| **Env var bypass** | Single command | `DCG_BYPASS=1 \u003Ccommand>` |\n| **Allow-once code** | Single command | Copy the short code from the block message, run `dcg allow-once \u003Ccode>` |\n| **Permanent allowlist** | Rule or command | `dcg allowlist add core.git:reset-hard -r \"reason\"` |\n| **Remove the hook** | All commands | Delete or comment out the dcg entry in `~\u002F.claude\u002Fsettings.json` (or equivalent for your agent) |\n\n`DCG_BYPASS=1` disables all protection for that invocation. Use it sparingly and prefer allowlists for recurring needs.\n\n## Modular Pack System\n\ndcg uses a modular \"pack\" system to organize destructive command patterns by category. Packs can be enabled or disabled in the configuration file.\n\n- Full pack ID index: `docs\u002Fpacks\u002FREADME.md`\n- Canonical descriptions + pattern counts: `dcg packs --verbose`\n\n### Core Packs (enabled by default)\n- `core.filesystem` - Protects against dangerous rm -rf commands outside temp directories\n- `core.git` - Protects against destructive git commands that can lose uncommitted work, rewrite history, or destroy stashes\n\n**Common packs enabled by default:**\n- `database.postgresql` - Protects against destructive PostgreSQL operations\n- `containers.docker` - Protects against destructive Docker operations like system prune\n\n### Storage Packs\n- `storage.s3` - Protects against destructive S3 operations like bucket removal, recursive deletes, and sync --delete.\n- `storage.gcs` - Protects against destructive GCS operations like bucket removal, object deletion, and recursive deletes.\n- `storage.minio` - Protects against destructive MinIO Client (mc) operations like bucket removal, object deletion, and admin operations.\n- `storage.azure_blob` - Protects against destructive Azure Blob Storage operations like container deletion, blob deletion, and azcopy remove.\n\n### Remote Packs\n- `remote.rsync` - Protects against destructive rsync operations like --delete and its variants.\n- `remote.scp` - Protects against destructive SCP operations like overwrites to system paths.\n- `remote.ssh` - Protects against destructive SSH operations like remote command execution and key management.\n\n### Database Packs\n- `database.postgresql` - Protects against destructive PostgreSQL operations like DROP DATABASE, TRUNCATE, and dropdb.\n- `database.mysql` - MySQL\u002FMariaDB guard.\n- `database.mongodb` - Protects against destructive MongoDB operations like dropDatabase, dropCollection, and remove without criteria.\n- `database.redis` - Protects against destructive Redis operations like FLUSHALL, FLUSHDB, and mass key deletion.\n- `database.sqlite` - Protects against destructive SQLite operations like DROP TABLE, DELETE without WHERE, and accidental data loss.\n- `database.supabase` - Protects against destructive Supabase CLI operations including database resets, migration rollbacks, function\u002Fsecret\u002Fstorage deletion, project removal, and infrastructure changes.\n\n### Container Packs\n- `containers.docker` - Protects against destructive Docker operations like system prune, volume prune, and force removal.\n- `containers.compose` - Protects against destructive Docker Compose operations like down -v which removes volumes.\n- `containers.podman` - Protects against destructive Podman operations like system prune, volume prune, and force removal.\n\n### Kubernetes Packs\n- `kubernetes.kubectl` - Protects against destructive kubectl operations like delete namespace, drain, and mass deletion.\n- `kubernetes.helm` - Protects against destructive Helm operations like uninstall and rollback without dry-run.\n- `kubernetes.kustomize` - Protects against destructive Kustomize operations when combined with kubectl delete or applied without review.\n\n### Cloud Provider Packs\n- `cloud.aws` - Protects against destructive AWS CLI operations like terminate-instances, delete-db-instance, and s3 rm --recursive.\n- `cloud.azure` - Protects against destructive Azure CLI operations like vm delete, storage account delete, and resource group delete.\n- `cloud.gcp` - Protects against destructive gcloud operations like instances delete, sql instances delete, and gsutil rm -r.\n\n### CDN Packs\n- `cdn.cloudflare_workers` - Protects against destructive Cloudflare Workers, KV, R2, and D1 operations via the Wrangler CLI.\n- `cdn.cloudfront` - Protects against destructive AWS CloudFront operations like deleting distributions, cache policies, and functions.\n- `cdn.fastly` - Protects against destructive Fastly CLI operations like service, domain, backend, and VCL deletion.\n\n### API Gateway Packs\n- `apigateway.apigee` - Protects against destructive Google Apigee CLI and apigeecli operations.\n- `apigateway.aws` - Protects against destructive AWS API Gateway CLI operations for both REST APIs and HTTP APIs.\n- `apigateway.kong` - Protects against destructive Kong Gateway CLI, deck CLI, and Admin API operations.\n\n### Infrastructure Packs\n- `infrastructure.ansible` - Protects against destructive Ansible operations like dangerous shell commands and unchecked playbook runs.\n- `infrastructure.pulumi` - Protects against destructive Pulumi operations like destroy and up with -y (auto-approve).\n- `infrastructure.terraform` - Protects against destructive Terraform operations like destroy, taint, and apply with -auto-approve.\n\n### System Packs\n- `system.disk` - Protects against destructive disk operations including dd to devices, mkfs, partition table modifications (fdisk\u002Fparted), RAID management (mdadm), btrfs filesystem operations, device-mapper (dmsetup), network block devices (nbd-client), and LVM commands (pvremove, vgremove, lvremove, lvreduce, pvmove).\n- `system.permissions` - Protects against dangerous permission changes like chmod 777, recursive chmod\u002Fchown on system directories.\n- `system.services` - Protects against dangerous service operations like stopping critical services and modifying init configuration.\n\n### CI\u002FCD Packs\n- `cicd.circleci` - Protects against destructive CircleCI operations like deleting contexts, removing secrets, deleting orbs\u002Fnamespaces, or removing pipelines.\n- `cicd.github_actions` - Protects against destructive GitHub Actions operations like deleting secrets\u002Fvariables or using gh api DELETE against \u002Factions endpoints.\n- `cicd.gitlab_ci` - Protects against destructive GitLab CI\u002FCD operations like deleting variables, removing artifacts, and unregistering runners.\n- `cicd.jenkins` - Protects against destructive Jenkins CLI\u002FAPI operations like deleting jobs, nodes, credentials, or build history.\n\n### Secrets Management Packs\n- `secrets.aws_secrets` - Protects against destructive AWS Secrets Manager and SSM Parameter Store operations like delete-secret and delete-parameter.\n- `secrets.doppler` - Protects against destructive Doppler CLI operations like deleting secrets, configs, environments, or projects.\n- `secrets.onepassword` - Protects against destructive 1Password CLI operations like deleting items, documents, users, groups, and vaults.\n- `secrets.vault` - Protects against destructive Vault CLI operations like deleting secrets, disabling auth\u002Fsecret engines, revoking leases\u002Ftokens, and deleting policies.\n\n### Platform Packs\n- `platform.github` - Protects against destructive GitHub CLI operations like deleting repositories, gists, releases, or SSH keys.\n- `platform.gitlab` - Protects against destructive GitLab platform operations like deleting projects, releases, protected branches, and webhooks.\n\n### DNS Packs\n- `dns.cloudflare` - Protects against destructive Cloudflare DNS operations like record deletion, zone deletion, and targeted Terraform destroy.\n- `dns.generic` - Protects against destructive or risky DNS tooling usage (nsupdate deletes, zone transfers).\n- `dns.route53` - Protects against destructive AWS Route53 DNS operations like hosted zone deletion and record set DELETE changes.\n\n### Email Packs\n- `email.mailgun` - Protects against destructive Mailgun API operations like domain deletion, route deletion, and mailing list removal.\n- `email.postmark` - Protects against destructive Postmark API operations like server deletion, template deletion, and sender signature removal.\n- `email.sendgrid` - Protects against destructive SendGrid API operations like template deletion, API key deletion, and domain authentication removal.\n- `email.ses` - Protects against destructive AWS Simple Email Service operations like identity deletion, template deletion, and configuration set removal.\n\n### Feature Flag Packs\n- `featureflags.flipt` - Protects against destructive Flipt CLI and API operations.\n- `featureflags.launchdarkly` - Protects against destructive LaunchDarkly CLI and API operations.\n- `featureflags.split` - Protects against destructive Split.io CLI and API operations.\n- `featureflags.unleash` - Protects against destructive Unleash CLI and API operations.\n\n### Load Balancer Packs\n- `loadbalancer.elb` - Protects against destructive AWS Elastic Load Balancing (ELB\u002FALB\u002FNLB) operations like deleting load balancers, target groups, or deregistering targets from live traffic.\n- `loadbalancer.haproxy` - Protects against destructive HAProxy load balancer operations like stopping the service or disabling backends via runtime API.\n- `loadbalancer.nginx` - Protects against destructive nginx load balancer operations like stopping the service or deleting config files.\n- `loadbalancer.traefik` - Protects against destructive Traefik load balancer operations like stopping containers, deleting config, or API deletions.\n\n### Messaging Packs\n- `messaging.kafka` - Protects against destructive Kafka CLI operations like deleting topics, removing consumer groups, resetting offsets, and deleting records.\n- `messaging.nats` - Protects against destructive NATS\u002FJetStream operations like deleting streams, consumers, key-value entries, objects, and accounts.\n- `messaging.rabbitmq` - Protects against destructive RabbitMQ operations like deleting queues\u002Fexchanges, purging queues, deleting vhosts, and resetting cluster state.\n- `messaging.sqs_sns` - Protects against destructive AWS SQS and SNS operations like deleting queues, purging messages, deleting topics, and removing subscriptions.\n\n### Monitoring Packs\n- `monitoring.datadog` - Protects against destructive Datadog CLI\u002FAPI operations like deleting monitors and dashboards.\n- `monitoring.newrelic` - Protects against destructive New Relic CLI\u002FAPI operations like deleting entities or alerting resources.\n- `monitoring.pagerduty` - Protects against destructive PagerDuty CLI\u002FAPI operations like deleting services and schedules (which can break incident routing).\n- `monitoring.prometheus` - Protects against destructive Prometheus\u002FGrafana operations like deleting time series data or dashboards\u002Fdatasources.\n- `monitoring.splunk` - Protects against destructive Splunk CLI\u002FAPI operations like index removal and REST API DELETE calls.\n\n### Payment Packs\n- `payment.braintree` - Protects against destructive Braintree\u002FPayPal payment operations like deleting customers or cancelling subscriptions via API\u002FSDK calls.\n- `payment.square` - Protects against destructive Square CLI\u002FAPI operations like deleting catalog objects or customers (which can break payment flows).\n- `payment.stripe` - Protects against destructive Stripe CLI\u002FAPI operations like deleting webhook endpoints and customers, or rotating API keys without coordination.\n\n### Search Engine Packs\n- `search.algolia` - Protects against destructive Algolia operations like deleting indices, clearing objects, removing rules\u002Fsynonyms, and deleting API keys.\n- `search.elasticsearch` - Protects against destructive Elasticsearch REST API operations like index deletion, delete-by-query, index close, and cluster setting changes.\n- `search.meilisearch` - Protects against destructive Meilisearch REST API operations like index deletion, document deletion, delete-batch, and API key removal.\n- `search.opensearch` - Protects against destructive OpenSearch REST API operations and AWS CLI domain deletions.\n\n### Backup Packs\n- `backup.borg` - Protects against destructive borg operations like delete, prune, compact, and recreate.\n- `backup.rclone` - Protects against destructive rclone operations like sync, delete, purge, dedupe, and move.\n- `backup.restic` - Protects against destructive restic operations like forgetting snapshots, pruning data, removing keys, and cache cleanup.\n- `backup.velero` - Protects against destructive velero operations like deleting backups, schedules, and locations.\n\n### Other Packs\n- `package_managers` - Protects against dangerous package manager operations like publishing packages and removing critical system packages.\n- `strict_git` - Stricter git protections: blocks all force pushes, rebases, and history rewriting operations.\n\nEnable packs in `~\u002F.config\u002Fdcg\u002Fconfig.toml`:\n\n```toml\n[packs]\nenabled = [\n    # Databases\n    \"database.postgresql\",\n    \"database.redis\",\n    \"database.supabase\",\n\n    # Containers and orchestration\n    \"containers.docker\",\n    \"kubernetes\",  # Enables all kubernetes sub-packs\n\n    # Cloud providers\n    \"cloud.aws\",\n    \"cloud.gcp\",\n\n    # Secrets management\n    \"secrets.aws_secrets\",\n    \"secrets.vault\",\n\n    # CI\u002FCD\n    \"cicd.jenkins\",\n    \"cicd.gitlab_ci\",\n\n    # Messaging\n    \"messaging.kafka\",\n    \"messaging.sqs_sns\",\n\n    # Search engines\n    \"search.elasticsearch\",\n\n    # Backup\n    \"backup.restic\",\n\n    # Platform\n    \"platform.github\",\n\n    # Monitoring\n    \"monitoring.splunk\",\n]\n```\n\n### Custom Packs\n\nCreate your own organization-specific security packs using YAML files. Custom packs let you define patterns for internal tools, deployment scripts, and proprietary systems without modifying dcg.\n\n```toml\n[packs]\ncustom_paths = [\n    \"~\u002F.config\u002Fdcg\u002Fpacks\u002F*.yaml\",      # User packs\n    \".dcg\u002Fpacks\u002F*.yaml\",               # Project-local packs\n]\n```\n\nFor detailed pack authoring guide, schema reference, and examples, see [`docs\u002Fcustom-packs.md`](docs\u002Fcustom-packs.md).\n\nValidate your pack before deployment:\n\n```bash\ndcg pack validate mypack.yaml\n```\n\nHeredoc scanning configuration:\n\n```toml\n[heredoc]\n# Enable scanning for heredocs and inline scripts (python -c, bash -c, etc.).\nenabled = true\n\n# Extraction timeout budget (milliseconds).\ntimeout_ms = 50\n\n# Resource limits for extracted bodies.\nmax_body_bytes = 1048576\nmax_body_lines = 10000\nmax_heredocs = 10\n\n# Optional language filter (scan only these languages). Omit for \"all\".\n# languages = [\"python\", \"bash\", \"javascript\", \"typescript\", \"ruby\", \"perl\", \"go\"]\n\n# Graceful degradation (hook defaults are fail-open).\nfallback_on_parse_error = true\nfallback_on_timeout = true\n```\n\nCLI overrides for heredoc scanning:\n\n- `--heredoc-scan` \u002F `--no-heredoc-scan`\n- `--heredoc-timeout \u003Cms>`\n- `--heredoc-languages \u003Clang1,lang2,...>`\n\nHeredoc documentation:\n\n- `docs\u002Fadr-001-heredoc-scanning.md` (architecture and rationale)\n- `docs\u002Fpatterns.md` (pattern authoring + inventory)\n- `docs\u002Fsecurity.md` (threat model and incident response)\n\n#### Heredoc Three-Tier Architecture\n\nHeredoc and inline script scanning uses a three-tier pipeline designed for performance and accuracy:\n\n```\nCommand Input\n     │\n     ▼\n┌─────────────────┐\n│ Tier 1: Trigger │ ─── No match ──► ALLOW (fast path, \u003C100μs)\n│   (RegexSet)    │\n└────────┬────────┘\n         │ Match\n         ▼\n┌─────────────────┐\n│ Tier 2: Extract │ ─── Error\u002FTimeout ──► ALLOW + fallback check\n│   (\u003C1ms)        │\n└────────┬────────┘\n         │ Success\n         ▼\n┌─────────────────┐\n│ Tier 3: AST     │ ─── No match ──► ALLOW\n│   (\u003C5ms)        │ ─── Match ──► BLOCK\n└─────────────────┘\n```\n\n**Tier 1: Trigger Detection** (\u003C100μs)\n\nUltra-fast regex screening to detect heredoc indicators. Uses a compiled `RegexSet` for O(n) matching against all trigger patterns simultaneously:\n\n```rust\nstatic HEREDOC_TRIGGERS: LazyLock\u003CRegexSet> = LazyLock::new(|| {\n    RegexSet::new([\n        r\"\u003C\u003C-?\\s*(?:['\\x22][^'\\x22]*['\\x22]|[\\w.-]+)\",  \u002F\u002F Heredocs\n        r\"\u003C\u003C\u003C\",                                          \u002F\u002F Here-strings\n        r\"\\bpython[0-9.]*\\b.*\\s+-[A-Za-z]*[ce]\",        \u002F\u002F python -c\u002F-e\n        r\"\\bruby[0-9.]*\\b.*\\s+-[A-Za-z]*e\",             \u002F\u002F ruby -e\n        r\"\\bnode(js)?[0-9.]*\\b.*\\s+-[A-Za-z]*[ep]\",     \u002F\u002F node -e\u002F-p\n        r\"\\b(sh|bash|zsh)\\b.*\\s+-[A-Za-z]*c\",           \u002F\u002F bash -c\n        \u002F\u002F ... more patterns\n    ])\n});\n```\n\nCommands without any trigger patterns skip directly to ALLOW—no further processing needed.\n\n**Tier 2: Content Extraction** (\u003C1ms)\n\nFor commands that trigger, extract the actual content to be evaluated:\n\n- **Heredocs**: `cat \u003C\u003CEOF ... EOF` → extracts body between delimiters\n- **Here-strings**: `cat \u003C\u003C\u003C \"content\"` → extracts quoted content\n- **Inline scripts**: `python -c \"code\"` → extracts the code argument\n\nExtraction is bounded by configurable limits:\n- Maximum body size (default: 1MB)\n- Maximum lines (default: 10,000)\n- Maximum heredocs per command (default: 10)\n- Timeout (default: 50ms)\n\n```rust\npub struct ExtractionLimits {\n    pub max_body_bytes: usize,\n    pub max_body_lines: usize,\n    pub max_heredocs: usize,\n    pub timeout_ms: u64,\n}\n```\n\n**Tier 3: AST Pattern Matching** (\u003C5ms)\n\nExtracted content is parsed using language-specific AST grammars (via tree-sitter\u002Fast-grep) and matched against structural patterns:\n\n```rust\n\u002F\u002F Example: detect subprocess.run with shell=True and rm -rf\nlet pattern = r#\"\n    call_expression {\n        function: attribute { object: \"subprocess\" attr: \"run\" }\n        arguments: argument_list {\n            contains string { contains \"rm -rf\" }\n            contains keyword_argument { keyword: \"shell\" value: \"True\" }\n        }\n    }\n\"#;\n```\n\n**Recursive Shell Analysis**:\n\nWhen extracted content is itself a shell script (e.g., `bash -c \"git reset --hard\"`), Tier 3 recursively extracts inner commands and re-evaluates them through the full pipeline:\n\n```rust\nif content.language == ScriptLanguage::Bash {\n    let inner_commands = extract_shell_commands(&content.content);\n    for inner in inner_commands {\n        \u002F\u002F Re-evaluate inner command against all packs\n        if let Some(result) = evaluate_command(&inner, ...) {\n            if result.decision == Deny {\n                return result; \u002F\u002F Block the outer command\n            }\n        }\n    }\n}\n```\n\nIf you encounter commands that should be blocked, please file an issue.\n\n### Environment Variables\n\nEnvironment variables override config files (highest priority):\n\n- `DCG_PACKS=\"containers.docker,kubernetes\"`: enable packs (comma-separated)\n- `DCG_DISABLE=\"kubernetes.helm\"`: disable packs\u002Fsub-packs (comma-separated)\n- `DCG_VERBOSE=0-3`: verbosity level (0 = quiet, 3 = trace)\n- `DCG_QUIET=1`: suppress non-error output\n- `DCG_COLOR=auto|always|never`: color mode\n- `DCG_NO_COLOR=1`: disable colored output (same as NO_COLOR)\n- `DCG_HIGH_CONTRAST=1`: enable high-contrast output (ASCII borders + monochrome palette)\n- `DCG_FORMAT=text|json|sarif`: default output format (command-specific; SARIF applies to `dcg scan`)\n- `DCG_BYPASS=1`: bypass dcg entirely (escape hatch; use sparingly)\n- `DCG_CONFIG=\u002Fpath\u002Fto\u002Fconfig.toml`: use explicit config file\n- `DCG_HEREDOC_ENABLED=true|false`: enable\u002Fdisable heredoc scanning\n- `DCG_HEREDOC_TIMEOUT=50`: heredoc extraction timeout (milliseconds)\n- `DCG_HEREDOC_TIMEOUT_MS=50`: heredoc extraction timeout (milliseconds)\n- `DCG_HEREDOC_LANGUAGES=python,bash`: filter heredoc languages\n- `DCG_POLICY_DEFAULT_MODE=deny|warn|log`: global default decision mode\n- `DCG_HOOK_TIMEOUT_MS=200`: hook evaluation timeout budget (milliseconds)\n\n### Configuration Hierarchy\n\ndcg supports layered configuration from multiple sources, with higher-priority sources overriding lower ones:\n\n1. Environment Variables (DCG_* prefix)           [HIGHEST PRIORITY]\n2. Explicit Config File (DCG_CONFIG env var)\n3. Project Config (.dcg.toml in repo root)\n4. User Config (~\u002F.config\u002Fdcg\u002Fconfig.toml)\n5. System Config (\u002Fetc\u002Fdcg\u002Fconfig.toml)\n6. Compiled Defaults                              [LOWEST PRIORITY]\n\n### Accessibility & Themes\n\ndcg supports colorblind-safe palettes and high-contrast output. Colors are always paired\nwith symbols\u002Flabels to avoid conveying meaning by color alone.\n\n```toml\n[output]\nhigh_contrast = true       # ASCII borders + black\u002Fwhite palette\n\n[theme]\npalette = \"colorblind\"     # default | colorblind | high-contrast\nuse_unicode = true         # false for ASCII-only\nuse_color = true           # false for monochrome\n```\n\n**Configuration File Locations**:\n\n| Level | Path | Use Case |\n|-------|------|----------|\n| System | `\u002Fetc\u002Fdcg\u002Fconfig.toml` | Organization-wide defaults |\n| User | `~\u002F.config\u002Fdcg\u002Fconfig.toml` | Personal preferences |\n| Project | `.dcg.toml` (repo root) | Project-specific settings |\n| Explicit | `DCG_CONFIG=\u002Fpath\u002Fto\u002Ffile` | Testing or override |\n\n**Merging Behavior**:\n\nConfiguration layers are merged additively, with higher-priority sources overriding specific fields:\n\n```rust\n\u002F\u002F Only fields explicitly set in higher-priority configs override\n\u002F\u002F Missing fields retain values from lower-priority sources\nfn merge_layer(&mut self, other: ConfigLayer) {\n    if let Some(verbose) = other.general.verbose {\n        self.general.verbose = verbose;  \u002F\u002F Override if present\n    }\n    \u002F\u002F Unset fields retain previous values\n}\n```\n\nThis means you can set organization defaults in `\u002Fetc\u002Fdcg\u002Fconfig.toml`, personal preferences in `~\u002F.config\u002Fdcg\u002Fconfig.toml`, and project-specific overrides in `.dcg.toml`—each layer only needs to specify the settings that differ from defaults.\n\n**Project-Specific Pack Configuration**:\n\nThe `[projects]` section allows different pack configurations for different repositories:\n\n```toml\n[projects.\"\u002Fhome\u002Fuser\u002Fwork\u002Fproduction-api\"]\npacks = { enabled = [\"database.postgresql\", \"cloud.aws\"], disabled = [] }\n\n[projects.\"\u002Fhome\u002Fuser\u002Fpersonal\u002Fexperiments\"]\npacks = { enabled = [], disabled = [\"core.git\"] }  # More permissive for experiments\n```\n\n### Fail-Open Philosophy\n\ndcg is designed with a **fail-open** philosophy: when the tool cannot safely analyze a command (due to timeouts, parse errors, or resource limits), it allows the command to proceed rather than blocking it and breaking the user's workflow.\n\n**Why Fail-Open?**\n\n1. **Workflow Continuity**: A blocked legitimate command is more disruptive than a missed dangerous one\n2. **Performance Guarantees**: The hook must never become a bottleneck\n3. **Graceful Degradation**: Partial analysis is better than no analysis\n\n**Fail-Open Scenarios**:\n\n| Scenario | Behavior | Rationale |\n|----------|----------|-----------|\n| Parse error in heredoc | ALLOW + warn | Malformed input shouldn't block work |\n| Extraction timeout | ALLOW + warn | Slow inputs shouldn't hang terminal |\n| Size limit exceeded | ALLOW + fallback check | Large inputs get reduced analysis |\n| Regex engine timeout | ALLOW + warn | Pathological patterns shouldn't block |\n| AST matching error | Skip that heredoc | Continue evaluating other content |\n| Deadline exceeded | ALLOW immediately | Hard cap prevents runaway processing |\n\n**Configurable Strictness**:\n\nFor high-security environments, fail-open can be disabled:\n\n```toml\n[heredoc]\nfallback_on_parse_error = false  # Block on parse errors\nfallback_on_timeout = false      # Block on timeouts\n```\n\nWith strict mode enabled, dcg will block commands when analysis fails, providing detailed error messages explaining why.\n\n**Fallback Pattern Checking**:\n\nEven when full analysis is skipped, dcg performs a lightweight fallback check for critical destructive patterns:\n\n```rust\nstatic FALLBACK_PATTERNS: LazyLock\u003CRegexSet> = LazyLock::new(|| {\n    RegexSet::new([\n        r\"shutil\\.rmtree\",\n        r\"os\\.remove\",\n        r\"fs\\.rmSync\",\n        r\"\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*f\",\n        r\"\\bgit\\s+reset\\s+--hard\\b\",\n        \u002F\u002F ... other critical patterns\n    ])\n});\n```\n\nThis ensures that even oversized or malformed inputs are checked for the most dangerous operations before being allowed.\n\n**Absolute Timeout**:\n\nTo prevent any single command from blocking indefinitely, dcg enforces an absolute maximum processing time of **200ms**. Any command exceeding this threshold is immediately allowed with a warning logged.\n\n## Installation\n\n### Quick Install (Recommended)\n\nThe easiest way to install is using the install script, which downloads a prebuilt binary for your platform:\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --easy-mode\n```\n\nEasy mode auto-detects your platform, downloads the right binary, verifies SHA256 checksums, configures all supported AI agent hooks (Claude Code, Gemini CLI, Copilot CLI, Aider, Codex CLI), and updates your PATH.\n\n**Other options:**\n\nInteractive mode (prompts for each step):\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash\n```\n\nInstall specific version:\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --version v0.1.0\n```\n\nInstall to \u002Fusr\u002Flocal\u002Fbin (system-wide, requires sudo):\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | sudo bash -s -- --system\n```\n\nBuild from source instead of downloading binary:\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --from-source\n```\n\nDownload\u002Finstall only (skip agent hook configuration):\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --no-configure\n```\n\n> **Note:** If you have [gum](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fgum) installed, the installer will use it for fancy terminal formatting.\n\nThe installer also verifies Sigstore cosign bundles when available (falls back to checksum-only), falls back to building from source if no prebuilt is available, and removes the legacy Python predecessor (`git_safety_guard.py`) if present.\n\n\u003Cdetails>\n\u003Csummary>Agent-specific notes\u003C\u002Fsummary>\n\n- **Aider:** No PreToolUse-style interception. The installer enables `git-commit-verify: true` in `~\u002F.aider.conf.yml` so git hooks run. For full protection, install dcg as a [git pre-commit hook](docs\u002Fscan-precommit-guide.md).\n- **Continue:** No shell command interception hooks. The installer detects Continue but cannot auto-configure protection. Use a [git pre-commit hook](docs\u002Fscan-precommit-guide.md) instead.\n- **Codex CLI:** Experimental PreToolUse hooks via `~\u002F.codex\u002Fhooks.json`. Wire format is compatible with Claude Code. Caveat: the model can write scripts to disk to bypass hook-based blocking.\n- **GitHub Copilot CLI:** Hooks are repository-local (`.github\u002Fhooks\u002F*.json`). Run the installer from each repository where you want protection.\n- **OpenCode:** Not auto-configured. Requires a Bun-based plugin with `\"tool.execute.before\"` hook key. A working community plugin: [aspiers\u002Fai-config\u002Fdcg-guard.js](https:\u002F\u002Fgithub.com\u002Faspiers\u002Fai-config\u002Fblob\u002Fmain\u002F.config\u002Fopencode\u002Fplugins\u002Fdcg-guard.js).\n\n\u003C\u002Fdetails>\n\n> **Recommended:** After installing, run `dcg setup` to add a [shell startup check](#hook-silently-removed-recommended-add-shell-startup-check) that warns you if the dcg hook is ever silently removed from `~\u002F.claude\u002Fsettings.json`.\n\n### From source (requires Rust nightly)\n\nThis project uses Rust Edition 2024 features and requires the nightly toolchain. The repository includes a `rust-toolchain.toml` that automatically selects the correct toolchain.\n\n```bash\n# Install Rust nightly if you don't have it\nrustup install nightly\n\n# Install directly from GitHub (package name required due to workspace)\ncargo +nightly install --git https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard destructive_command_guard\n```\n\n### Manual build\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\ncd destructive_command_guard\n# rust-toolchain.toml automatically selects nightly\ncargo build --release\ncp target\u002Frelease\u002Fdcg ~\u002F.local\u002Fbin\u002F\n```\n\n## Updating\n\nRun the built-in updater to re-run the installer for your platform:\n\n```bash\ndcg update\n```\n\nOptional flags mirror the installer scripts (examples):\n\n```bash\ndcg update --version v0.2.7\ndcg update --system\ndcg update --verify\n```\n\nYou can always re-run `install.sh` \u002F `install.ps1` directly if preferred.\n\n### Prebuilt Binaries\n\nPrebuilt binaries are available for:\n- Linux x86_64 (`x86_64-unknown-linux-gnu`)\n- Linux ARM64 (`aarch64-unknown-linux-gnu`)\n- macOS Intel (`x86_64-apple-darwin`)\n- macOS Apple Silicon (`aarch64-apple-darwin`)\n- Windows (`x86_64-pc-windows-msvc`)\n\nDownload from [GitHub Releases](https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Freleases) and verify the SHA256 checksum.\nIf you have cosign installed, each release also includes a Sigstore bundle (`.sigstore.json`) so you can verify provenance with `cosign verify-blob`.\n\n## Uninstalling\n\nRemove dcg and all its hooks from AI agents:\n\n```bash\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Funinstall.sh | bash\n```\n\nThe uninstaller:\n- Removes dcg hooks from Claude Code, Gemini CLI, GitHub Copilot CLI (repo-local), and Aider\n- Removes the dcg binary\n- Removes configuration (`~\u002F.config\u002Fdcg\u002F`) and history (`~\u002F.local\u002Fshare\u002Fdcg\u002F`)\n- Prompts for confirmation before making changes\n\nOptions:\n- `--yes` - Skip confirmation prompt\n- `--keep-config` - Preserve configuration files\n- `--keep-history` - Preserve history database\n- `--purge` - Remove everything (overrides keep flags)\n\n## Claude Code Configuration\n\nAdd to `~\u002F.claude\u002Fsettings.json`:\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"dcg\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n**Important:** Restart Claude Code after adding the hook configuration.\n\n## Gemini CLI Configuration\n\nAdd to `~\u002F.gemini\u002Fsettings.json`:\n\n```json\n{\n  \"hooks\": {\n    \"BeforeTool\": [\n      {\n        \"matcher\": \"run_shell_command\",\n        \"hooks\": [\n          {\n            \"name\": \"dcg\",\n            \"type\": \"command\",\n            \"command\": \"dcg\",\n            \"timeout\": 5000\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n**Important:** Restart Gemini CLI after adding the hook configuration.\n\n## CLI Usage\n\nWhile primarily designed as a hook, the binary supports direct invocation for testing, debugging, and understanding why commands are blocked or allowed.\n\n```bash\n# Show version with build metadata\ndcg --version\n\n# Show help with blocked command categories\ndcg --help\n\n# Test a command manually (pipe JSON to stdin)\necho '{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git reset --hard\"}}' | dcg\n```\n\n### Test Mode (`dcg test`)\n\nUse `dcg test` to evaluate a command **without executing it**. This is useful for CI checks, false-positive debugging, and config validation before rollout.\n\n#### Basic Usage\n\n```bash\n# Basic evaluation (human-readable output)\ndcg test \"rm -rf .\u002Fbuild\"\n\n# Structured output for automation\ndcg test --format json \"kubectl delete namespace prod\" | jq -r .decision\n\n# Use a specific config file\ndcg test --config .dcg.prod.toml \"docker system prune\"\n\n# Temporarily enable extra packs only for this test run\ndcg test --with-packs containers.docker,database.postgresql \"docker system prune\"\n\n# Print full evaluation trace (same engine as `dcg explain`)\ndcg test --explain \"git reset --hard\"\n```\n\n#### Exit Codes\n\n- `0`: command would be allowed\n- `1`: command would be blocked\n\n#### Flags and Options\n\n- `-c, --config \u003CPATH>`: use a specific config file\n- `--with-packs \u003CID1,ID2>`: temporarily enable extra packs\n- `--explain`: print detailed decision trace\n- `-f, --format \u003Cpretty|json|toon>`: output format (default: `pretty`)\n- `--no-color`: disable ANSI color output\n- `--heredoc-scan`: force-enable heredoc\u002Finline-script scanning\n- `--no-heredoc-scan`: force-disable heredoc\u002Finline-script scanning\n- `--heredoc-timeout \u003CMS>`: override heredoc extraction timeout budget\n- `--heredoc-languages \u003CLANG1,LANG2>`: limit heredoc AST scanning languages\n\n#### Output Formats\n\n- `pretty`: human-readable output with command context, matched rule info, and suggestions\n- `json`: structured payload for scripts\u002FCI; includes metadata like `schema_version`, `dcg_version`, `command`, `decision`, rule\u002Fpack fields, and allowlist\u002Fagent context when present\n- `toon`: token-efficient structured encoding of the same payload used by `json` (useful for agent-to-agent\u002Ftool pipelines)\n\n#### CI\u002FCD Integration Examples\n\nFail fast in shell pipelines:\n\n```bash\ndcg test --format json \"rm -rf \u002F\" > \u002Ftmp\u002Fdcg.json\njq -e '.decision == \"allow\"' \u002Ftmp\u002Fdcg.json\n```\n\nMinimal GitHub Actions step:\n\n```yaml\n- name: Validate dangerous command policy\n  run: |\n    ~\u002F.local\u002Fbin\u002Fdcg test --format json \"git reset --hard HEAD~1\" > \u002Ftmp\u002Fdcg-test.json\n    jq -e '.decision == \"allow\"' \u002Ftmp\u002Fdcg-test.json\n```\n\n#### Troubleshooting\n\n- Use `--format json` (or `DCG_FORMAT=json`) for machine parsing.\n- Add `--no-color` if logs or parsers choke on ANSI output.\n- If results differ between environments, check config precedence (`DCG_CONFIG`, project `.dcg.toml`, user\u002Fsystem config).\n- If a command is unexpectedly allowed, inspect active allowlists (`dcg allowlist list`) and enabled packs (`dcg packs --verbose`).\n- For full decision traces, run `dcg test --explain \"\u003Ccommand>\"` (or `dcg explain \"\u003Ccommand>\"`).\n\n### Explain Mode\n\nWhen you need to understand exactly why a command was blocked (or allowed), the `dcg explain` command provides a detailed trace of the decision-making process:\n\n```bash\n# Explain why a command is blocked\ndcg explain \"git reset --hard HEAD\"\n\n# Explain a safe command\ndcg explain \"git status\"\n\n# Explain with verbose timing information\ndcg explain --verbose \"rm -rf \u002Ftmp\u002Fbuild\"\n\n# Output as JSON for programmatic use\ndcg explain --format json \"kubectl delete namespace production\"\n```\n\nJSON output is versioned via `schema_version` (currently 2). v2 adds\n`matched_span`, `matched_text_preview`, and `explanation` in the `match`\nobject when a pattern is detected.\n\n**Example Output**:\n\n```\nCommand: git reset --hard HEAD\nNormalized: git reset --hard HEAD\n\nDecision: BLOCKED\n  Pack: core.git\n  Rule: reset-hard\n  Reason: git reset --hard destroys uncommitted changes\n\nEvaluation Trace:\n  [  0.8μs] Quick reject: passed (contains 'git')\n  [  2.1μs] Normalize: no changes\n  [  5.3μs] Safe patterns: no match (checked 34 patterns)\n  [ 12.7μs] Destructive patterns: MATCH at pattern 'reset-hard'\n  [ 12.9μs] Total time: 12.9μs\n\nSuggestion: Consider using 'git stash' first to save your changes.\n```\n\nThe explain mode shows:\n- **Normalized command**: How dcg sees the command after path normalization\n- **Decision**: Whether the command would be blocked or allowed\n- **Matching rule**: Which pack and pattern triggered the decision\n- **Evaluation trace**: Step-by-step timing of each evaluation stage\n- **Suggestion**: Actionable guidance for safer alternatives\n\nThis is invaluable for debugging false positives, understanding pack coverage, and verifying that custom allowlist entries work as expected.\n\n### Allow-Once (Temporary Exceptions)\n\nSometimes you need to run a blocked command temporarily without permanently modifying your allowlist. The allow-once system provides short codes:\n\n```bash\n# When a command is blocked, dcg outputs a short code\n# BLOCKED: git reset --hard HEAD\n# Allow-once code: ab12\n# To allow this: dcg allow-once ab12\n\n# Use the short code to create a temporary exception\ndcg allow-once ab12\n\n# Or, use --single-use to make the exception one-shot\ndcg allow-once ab12 --single-use\n```\n\n**How Allow-Once Works**:\n\n1. When dcg blocks a command, it generates a short code (currently 4 hex chars; collisions are handled via `--pick` \u002F `--hash`)\n2. The code is tied to the exact command that was blocked\n3. Running `dcg allow-once \u003Ccode>` creates a temporary exception\n4. The exception is stored in `~\u002F.config\u002Fdcg\u002Fpending_exceptions.jsonl`\n5. Exceptions expire after 24 hours (or after first use if `--single-use` is used)\n6. While active, the exception allows the same command in the same directory scope\n\nThis workflow is useful for:\n- One-time administrative operations that are intentionally destructive\n- Migration scripts that need to reset state\n- Emergency fixes where permanent allowlist changes aren't appropriate\n\n**Security Considerations**:\n- Short codes are derived from SHA256 (or optional HMAC-SHA256 when `DCG_ALLOW_ONCE_SECRET` is set)\n- Codes are never logged or transmitted\n- The pending exceptions file is readable only by the current user\n- Expired codes are automatically cleaned up\n\nThe `--version` output includes build metadata for debugging:\n\n```\ndcg 0.1.0\n  Built: 2026-01-07T22:13:10.413872881Z\n  Rustc: 1.94.0-nightly\n  Target: x86_64-unknown-linux-gnu\n```\n\nThis metadata is embedded at compile time via [vergen](https:\u002F\u002Fgithub.com\u002Frustyhorde\u002Fvergen), making it easy to identify exactly which build is running when troubleshooting.\n\n## Repository Scanning\n\nWhile the hook protects **interactive** command execution, teams also need protection against destructive commands that get **committed into repositories**. The `dcg scan` command extracts executable command contexts from files and evaluates them using the same pattern engine.\n\n### What Scan Is (and Is Not)\n\n**What it is:**\n- An extractor-based scanner that understands executable contexts\n- Uses the same evaluator as hook mode for consistency\n- Supports CI integration and pre-commit hooks\n\n**What it is NOT:**\n- A naive grep that matches strings everywhere\n- A replacement for code review\n- A static analysis tool for arbitrary languages\n\nThe key difference from grep: `dcg scan` understands that `\"rm -rf \u002F\"` in a comment is data, not code. It uses extractors that understand file structure (shell scripts, Dockerfiles, GitHub Actions, Makefiles) to find only actually-executed commands.\n\n### Supported File Formats\n\ndcg scan includes specialized extractors for each file format, understanding which parts contain executable commands:\n\n| File Type | Detection | Executable Contexts |\n|-----------|-----------|---------------------|\n| **Shell Scripts** | `*.sh`, `*.bash`, `*.zsh` | All non-comment, non-assignment lines |\n| **Dockerfile** | `Dockerfile`, `*.dockerfile` | `RUN` instructions (shell and exec forms) |\n| **GitHub Actions** | `.github\u002Fworkflows\u002F*.yml` | `run:` fields in steps |\n| **GitLab CI** | `.gitlab-ci.yml` | `script:`, `before_script:`, `after_script:` |\n| **Makefile** | `Makefile` | Tab-indented recipe lines |\n| **Terraform** | `*.tf` | `provisioner` blocks (`local-exec`, `remote-exec`) |\n| **Docker Compose** | `docker-compose.yml`, `compose.yml` | `command:` and `entrypoint:` fields |\n\n**Context-Aware Extraction**:\n\nEach extractor understands its format's semantics:\n\n```yaml\n# GitHub Actions - only 'run:' is extracted\n- name: Build\n  run: |                    # ← Extracted\n    npm install\n    npm run build\n  env:\n    NODE_ENV: production    # ← Skipped (not executable)\n```\n\n```dockerfile\n# Dockerfile - only RUN instructions\nFROM node:18\nCOPY . \u002Fapp                 # ← Skipped\nRUN npm install             # ← Extracted\nRUN [\"node\", \"server.js\"]   # ← Extracted (exec form)\nENV PORT=3000               # ← Skipped\n```\n\n```makefile\n# Makefile - tab-indented lines under targets\nbuild:\n\tnpm install             # ← Extracted (recipe line)\n\tnpm run build           # ← Extracted\nSOURCES = $(wildcard *.js)  # ← Skipped (variable assignment)\n```\n\n**Non-Executable Context Filtering**:\n\nExtractors intelligently skip data-only sections:\n\n- **Shell**: Assignment-only lines (`export VAR=value`)\n- **YAML**: `environment:`, `labels:`, `volumes:`, `variables:` blocks\n- **Terraform**: Everything outside `provisioner` blocks\n- **All formats**: Comments (format-appropriate: `#`, `\u002F\u002F`, etc.)\n\n### Quick Start\n\n```bash\n# Install the pre-commit hook\ndcg scan install-pre-commit\n\n# Or manually run on staged files\ndcg scan --staged\n\n# Scan specific paths\ndcg scan --paths scripts\u002F .github\u002Fworkflows\u002F\n```\n\n### Recommended Rollout Plan\n\n**Start conservative to avoid developer friction:**\n\n```bash\n# Week 1-2: Warn-first with narrow scope\ndcg scan --staged --fail-on error  # Only fail on catastrophic rules\n```\n\nCreate `.dcg\u002Fhooks.toml` with conservative defaults:\n\n```toml\n[scan]\nfail_on = \"error\"          # Only fail on high-confidence catastrophic rules\nformat = \"pretty\"          # Human-readable output\nredact = \"quoted\"          # Hide sensitive strings\ntruncate = 120             # Shorten long commands\n\n[scan.paths]\ninclude = [\n    \".github\u002Fworkflows\u002F**\",  # Start with CI configs\n    \"Dockerfile\",            # Container builds\n    \"Makefile\",              # Build scripts\n]\nexclude = [\n    \"target\u002F**\",\n    \"node_modules\u002F**\",\n    \"vendor\u002F**\",\n]\n```\n\n**Gradual expansion:**\n\n1. **Week 1-2**: Start with workflows\u002FDockerfiles only, `--fail-on error`\n2. **Week 3-4**: Add Makefiles and shell scripts in `scripts\u002F`\n3. **Month 2**: Add `--fail-on warning` after reviewing findings\n4. **Ongoing**: Add new extractors as team confidence grows\n\n### Pre-Commit Integration\n\n#### One-Command Install\n\n```bash\ndcg scan install-pre-commit\n```\n\nThis creates a `.git\u002Fhooks\u002Fpre-commit` that runs `dcg scan --staged`.\n\n#### Manual Setup\n\nIf you prefer manual control or use a hook manager:\n\n```bash\n#!\u002Fbin\u002Fbash\n# .git\u002Fhooks\u002Fpre-commit (or equivalent for your hook manager)\n\nset -e\n\n# Run dcg scan on staged files\ndcg scan --staged --fail-on error\n\n# Add other hooks below...\n```\n\n#### Uninstall\n\n```bash\ndcg scan uninstall-pre-commit\n```\n\nThis only removes hooks installed by dcg (detected via sentinel comment).\n\n### Interpreting Findings\n\nThe output includes:\n\n```\nscripts\u002Fdeploy.sh:42:5: [ERROR] core.git:reset-hard\n  Command: git reset --hard HEAD\n  Reason: git reset --hard destroys uncommitted changes\n  Suggestion: Consider using 'git stash' first to save changes.\n```\n\n- **File:Line:Col**: Location in the source file\n- **Severity**: `ERROR` (catastrophic) or `WARNING` (concerning)\n- **Rule ID**: Stable identifier like `core.git:reset-hard`\n- **Command**: The extracted command (may be redacted\u002Ftruncated)\n- **Reason**: Why this command is flagged\n- **Suggestion**: How to make it safer\n\n### Fixing Findings\n\n#### Option 1: Change the Code (Preferred)\n\nReplace the dangerous command with a safer alternative:\n\n```bash\n# Instead of:\ngit reset --hard\n\n# Use:\ngit stash push -m \"before reset\"\ngit reset --hard\n```\n\n#### Option 2: Understand with Explain\n\nGet detailed analysis:\n\n```bash\ndcg explain \"git reset --hard HEAD\"\n```\n\n#### Option 3: Allowlist (When Intentional)\n\nIf the command is genuinely needed:\n\n```bash\n# Project-level allowlist (committed, code-reviewed)\ndcg allowlist add core.git:reset-hard --reason \"Required for CI cleanup\" --project\n\n# Or for a specific command\ndcg allowlist add-command \"rm -rf .\u002Fbuild\" --reason \"Build cleanup\" --project\n```\n\nThe finding output includes a copy-paste allowlist command for convenience.\nHeredoc rules use stable IDs like `heredoc.python.shutil_rmtree`.\n\n### Privacy and Redaction\n\nScan supports redaction of potentially sensitive content in output. Use `--redact quoted` to hide quoted strings that may contain secrets:\n\n```\n# Original command:\ncurl -H \"Authorization: Bearer $TOKEN\" https:\u002F\u002Fapi.example.com\n\n# With --redact quoted:\ncurl -H \"...\" https:\u002F\u002Fapi.example.com\n```\n\nOptions:\n- `--redact none`: Show full commands (default)\n- `--redact quoted`: Hide quoted strings (recommended for CI logs)\n- `--redact aggressive`: Hide more potential secrets\n\n### Configuration Reference\n\n`.dcg\u002Fhooks.toml` (project-level, committed):\n\n```toml\n[scan]\n# Exit non-zero when findings meet this threshold\nfail_on = \"error\"      # Options: none, warning, error\n\n# Output format\nformat = \"pretty\"      # Options: pretty, json, markdown\n\n# Maximum file size to scan (bytes)\nmax_file_size = 1000000\n\n# Stop after this many findings\nmax_findings = 50\n\n# Redaction level for sensitive content\nredact = \"quoted\"      # Options: none, quoted, aggressive\n\n# Truncate long commands (chars; 0 = no truncation)\ntruncate = 120\n\n[scan.paths]\n# Only scan files matching these patterns\ninclude = [\n    \"scripts\u002F**\",\n    \".github\u002Fworkflows\u002F**\",\n    \"Dockerfile*\",\n    \"Makefile\",\n]\n\n# Skip files matching these patterns\nexclude = [\n    \"target\u002F**\",\n    \"node_modules\u002F**\",\n    \"*.md\",\n]\n```\n\nCLI flags override config file values.\n\n### CI Integration\n\n#### GitHub Actions\n\n```yaml\nname: Security Scan\non: [pull_request]\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Install dcg\n        run: |\n          curl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh\" | bash\n          echo \"$HOME\u002F.local\u002Fbin\" >> $GITHUB_PATH\n\n      - name: Scan changed files\n        run: |\n          dcg scan --git-diff origin\u002F${{ github.base_ref }}..HEAD \\\n            --format markdown \\\n            --fail-on error\n```\n\n#### GitLab CI\n\n```yaml\nscan:\n  stage: test\n  script:\n    - curl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh\" | bash\n    - ~\u002F.local\u002Fbin\u002Fdcg scan --git-diff origin\u002F$CI_MERGE_REQUEST_TARGET_BRANCH_NAME..HEAD --fail-on error\n  rules:\n    - if: $CI_MERGE_REQUEST_ID\n```\n\n### Bypass for Emergencies\n\nIf you need to bypass the pre-commit hook temporarily:\n\n```bash\ngit commit --no-verify -m \"Emergency fix\"\n```\n\nThis is logged and visible in git history. For permanent exceptions, use allowlists instead.\n\n## How It Works\n\nYour AI agent invokes dcg as a PreToolUse hook before executing each shell command. The hook receives the command as JSON on stdin and runs through a four-stage pipeline:\n\n1. **JSON Parsing** -- Validates the hook payload (Claude\u002FGemini\u002FCopilot variants), extracts the command string. Non-shell tools are immediately allowed.\n2. **Normalization** -- Strips absolute paths (`\u002Fusr\u002Fbin\u002Fgit` becomes `git`) while preserving arguments.\n3. **Quick Reject** -- O(n) substring search for keywords like \"git\" or \"rm\". Commands without these substrings skip regex matching entirely (handles 99%+ of non-destructive commands).\n4. **Pattern Matching** -- Safe patterns checked first (match = allow). Destructive patterns checked second (match = deny with explanation). No match on either = allow.\n\nIf blocked, dcg outputs a JSON denial on stdout and a colorful human-readable warning on stderr. If allowed, dcg exits silently (no output). Colors are automatically disabled when stderr is not a TTY.\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│            Claude Code \u002F Gemini CLI \u002F Copilot CLI                │\n│                                                                  │\n│  User: \"delete the build artifacts\"                             │\n│  Agent: executes `rm -rf .\u002Fbuild`                               │\n│                                                                  │\n└─────────────────────┬───────────────────────────────────────────┘\n                      │\n                      ▼ PreToolUse hook (stdin: JSON)\n┌─────────────────────────────────────────────────────────────────┐\n│                     dcg                             │\n│                                                                  │\n│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐       │\n│  │    Parse     │───▶│  Normalize   │───▶│ Quick Reject │       │\n│  │    JSON      │    │   Command    │    │   Filter     │       │\n│  └──────────────┘    └──────────────┘    └──────┬───────┘       │\n│                                                  │               │\n│                      ┌───────────────────────────┘               │\n│                      ▼                                           │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │                   Pattern Matching                        │   │\n│  │                                                           │   │\n│  │   1. Check SAFE_PATTERNS (whitelist) ──▶ Allow if match  │   │\n│  │   2. Check DESTRUCTIVE_PATTERNS ──────▶ Deny if match    │   │\n│  │   3. No match ────────────────────────▶ Allow (default)  │   │\n│  │                                                           │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                                                                  │\n└─────────────────────┬───────────────────────────────────────────┘\n                      │\n                      ▼ stdout: JSON (deny) or empty (allow)\n┌─────────────────────────────────────────────────────────────────┐\n│            Claude Code \u002F Gemini CLI \u002F Copilot CLI                │\n│                                                                  │\n│  If denied: Shows block message, does NOT execute command       │\n│  If allowed: Proceeds with command execution                    │\n│                                                                  │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### Context Classification System\n\nNot every occurrence of a dangerous pattern is actually dangerous. The string `git reset --hard` appearing in a comment, a heredoc body, or a quoted string is fundamentally different from the same string appearing as an executed command. dcg uses a sophisticated context classification system to reduce false positives without compromising safety.\n\n**SpanKind Classification**\n\nEvery token in a command is classified into one of these categories:\n\n| SpanKind | Description | Treatment |\n|----------|-------------|-----------|\n| `Executed` | Command words and unquoted arguments | **MUST check** - highest priority |\n| `InlineCode` | Content inside `-c`\u002F`-e` flags (bash -c, python -c) | **MUST check** - code will be executed |\n| `Argument` | Quoted arguments to known-safe commands | Lower priority, context-dependent |\n| `Data` | Single-quoted strings (shell cannot interpolate) | **Can skip** - treated as literal data |\n| `HeredocBody` | Content inside heredocs | Escalated to Tier 2\u002F3 heredoc scanning |\n| `Comment` | Shell comments (`# ...`) | **Skip** - never executed |\n| `Unknown` | Cannot determine context | Conservative treatment as `Executed` |\n\n**Why Context Matters**\n\nConsider these commands:\n\n```bash\n# Safe: the dangerous pattern is in a comment\necho \"Reminder: never run git reset --hard\"   # git reset --hard destroys changes\n\n# Safe: the dangerous pattern is data being searched for\ngrep \"git reset --hard\" documentation.md\n\n# Safe: the dangerous pattern is in a heredoc being written to a file\ncat \u003C\u003CEOF > safety_guide.md\nWarning: git reset --hard destroys uncommitted changes\nEOF\n\n# DANGEROUS: the pattern will be executed\ngit reset --hard HEAD\n\n# DANGEROUS: the pattern is passed to bash -c for execution\nbash -c \"git reset --hard\"\n```\n\nWithout context classification, the first three examples would trigger false positives. The context classifier analyzes the AST (abstract syntax tree) structure to understand where patterns appear and only flags genuinely dangerous occurrences.\n\n**Implementation Details**\n\nThe context classifier uses a multi-pass approach:\n\n1. **Lexical Analysis**: Identify quoted strings, comments, and heredoc markers\n2. **Structural Analysis**: Build a tree of command structure, identifying pipes, subshells, and command substitutions\n3. **Flag Analysis**: Detect `-c`, `-e`, and similar flags that introduce inline code contexts\n4. **Span Annotation**: Tag each character range with its SpanKind\n\nThis approach achieves a significant reduction in false positives while maintaining the zero-false-negatives philosophy for actual command execution.\n\n## Design Principles\n\n### 1. Whitelist-First Architecture\n\nSafe patterns are checked *before* destructive patterns. This design ensures that explicitly safe commands (like `git checkout -b`) are never accidentally blocked, even if they partially match a destructive pattern (like `git checkout`).\n\n```\ngit checkout -b feature    →  Matches SAFE \"checkout-new-branch\"  →  ALLOW\ngit checkout -- file.txt   →  No safe match, matches DESTRUCTIVE  →  DENY\n```\n\n### 2. Fail-Safe Defaults\n\nThe hook uses a **default-allow** policy for unrecognized commands. This ensures:\n- The hook never breaks legitimate workflows\n- Only *known* dangerous patterns are blocked\n- New git commands are allowed until explicitly categorized\n\n### 3. Zero False Negatives Philosophy\n\nThe pattern set prioritizes **never allowing dangerous commands** over avoiding false positives. A few extra prompts for manual confirmation are acceptable; lost work is not.\n\n### 4. Defense in Depth\n\nThis hook is one layer of protection. It complements (not replaces):\n- Regular commits and pushes\n- Git stash before risky operations\n- Proper backup strategies\n- Code review processes\n\n### 5. Minimal Latency\n\nEvery Bash command passes through this hook. Performance is critical:\n- Lazy-initialized static regex patterns (compiled once, reused)\n- Quick rejection filter eliminates 99%+ of commands before regex\n- No heap allocations on the hot path for safe commands\n- Sub-millisecond execution for typical commands\n\n## Pattern Matching System\n\n### Safe Patterns (Whitelist)\n\nThe safe pattern list contains 34 patterns covering:\n\n| Category | Patterns | Purpose |\n|----------|----------|---------|\n| Branch creation | `checkout -b`, `checkout --orphan` | Creating branches is safe |\n| Staged-only | `restore --staged`, `restore -S` | Unstaging doesn't touch working tree |\n| Dry run | `clean -n`, `clean --dry-run` | Preview mode, no actual deletion |\n| Temp cleanup | `rm -rf \u002Ftmp\u002F*`, `rm -rf \u002Fvar\u002Ftmp\u002F*` | Ephemeral directories are safe |\n| Variable expansion | `rm -rf $TMPDIR\u002F*`, `rm -rf ${TMPDIR}\u002F*` | Shell variable forms |\n| Quoted paths | `rm -rf \"$TMPDIR\u002F*\"` | Quoted variable forms |\n| Separate flags | `rm -r -f \u002Ftmp\u002F*`, `rm -r -f $TMPDIR\u002F*` | Flag ordering variants |\n| Long flags | `rm --recursive --force \u002Ftmp\u002F*`, `$TMPDIR\u002F*` | GNU-style long options |\n\n### Destructive Patterns (Blacklist)\n\nThe destructive pattern list contains 16 patterns covering:\n\n| Category | Pattern | Reason |\n|----------|---------|--------|\n| Work destruction | `reset --hard`, `reset --merge` | Destroys uncommitted changes |\n| File reversion | `checkout -- \u003Cpath>` | Discards file modifications |\n| Worktree restore | `restore` (without --staged) | Discards uncommitted changes |\n| Untracked deletion | `clean -f` | Permanently removes untracked files |\n| History rewrite | `push --force`, `push -f` | Can destroy remote commits |\n| Unsafe branch delete | `branch -D` | Force-deletes without merge check |\n| Stash destruction | `stash drop`, `stash clear` | Permanently deletes stashed work |\n| Filesystem nuke | `rm -rf` (non-temp paths) | Recursive deletion outside temp |\n\n### Pattern Syntax\n\nPatterns use [fancy-regex](https:\u002F\u002Fgithub.com\u002Ffancy-regex\u002Ffancy-regex) for advanced features:\n\n```rust\n\u002F\u002F Negative lookahead: block restore UNLESS --staged is present\nr\"git\\s+restore\\s+(?!--staged\\b)(?!-S\\b)\"\n\n\u002F\u002F Negative lookahead: don't match --force-with-lease\nr\"git\\s+push\\s+.*--force(?![-a-z])\"\n\n\u002F\u002F Character class: match any flag ordering\nr\"rm\\s+-[a-zA-Z]*[rR][a-zA-Z]*f[a-zA-Z]*\"\n```\n\n## Edge Cases Handled\n\n### Path Normalization\n\nCommands may use absolute paths to binaries:\n\n```bash\n\u002Fusr\u002Fbin\u002Fgit reset --hard          # Blocked ✓\n\u002Fusr\u002Flocal\u002Fbin\u002Fgit checkout -- .   # Blocked ✓\n\u002Fbin\u002Frm -rf \u002Fhome\u002Fuser             # Blocked ✓\n```\n\nThe normalizer uses regex to strip paths while preserving arguments:\n\n```bash\ngit add \u002Fusr\u002Fbin\u002Fsomething         # \"\u002Fusr\u002Fbin\u002Fsomething\" is an argument, preserved\n```\n\n### Flag Ordering Variants\n\nThe `rm` command accepts flags in many forms:\n\n```bash\nrm -rf \u002Fpath          # Combined flags\nrm -fr \u002Fpath          # Reversed order\nrm -r -f \u002Fpath        # Separate flags\nrm -f -r \u002Fpath        # Separate, reversed\nrm --recursive --force \u002Fpath    # Long flags\nrm --force --recursive \u002Fpath    # Long flags, reversed\nrm -rf --no-preserve-root \u002F     # Additional flags\n```\n\nAll variants are handled by flexible regex patterns.\n\n### Shell Variable Expansion\n\nTemp directory variables come in multiple forms:\n\n```bash\nrm -rf $TMPDIR\u002Fbuild           # Unquoted, simple\nrm -rf ${TMPDIR}\u002Fbuild         # Unquoted, braced\nrm -rf \"$TMPDIR\u002Fbuild\"         # Quoted, simple\nrm -rf \"${TMPDIR}\u002Fbuild\"       # Quoted, braced\nrm -rf \"${TMPDIR:-\u002Ftmp}\u002Fbuild\" # With default value\n```\n\n### Git Flag Combinations\n\nGit commands can have flags in various positions:\n\n```bash\ngit push --force                  # Blocked ✓\ngit push origin main --force      # Blocked ✓\ngit push --force origin main      # Blocked ✓\ngit push -f                       # Blocked ✓\ngit push --force-with-lease       # Allowed ✓ (safe alternative)\n```\n\n### Staged vs Worktree Restore\n\nThe restore command has nuanced safety:\n\n```bash\ngit restore --staged file.txt           # Allowed ✓ (unstaging only)\ngit restore -S file.txt                 # Allowed ✓ (short flag)\ngit restore file.txt                    # Blocked (discards changes)\ngit restore --worktree file.txt         # Blocked (explicit worktree)\ngit restore --staged --worktree file    # Blocked (includes worktree)\ngit restore -S -W file.txt              # Blocked (includes worktree)\n```\n\n## Performance Optimizations\n\n### Dual Regex Engine Architecture\n\ndcg uses a sophisticated dual-engine regex system that automatically selects the optimal engine for each pattern. This enables both guaranteed performance and advanced pattern matching features.\n\n**The Two Engines**:\n\n| Engine | Crate | Time Complexity | Features | Use Case |\n|--------|-------|-----------------|----------|----------|\n| **Linear** | `regex` | O(n) guaranteed | Basic regex, character classes, alternation | ~85% of patterns |\n| **Backtracking** | `fancy_regex` | O(2^n) worst case | Lookahead, lookbehind, backreferences | ~15% of patterns |\n\n**Automatic Engine Selection**:\n\nWhen a pattern is compiled, dcg analyzes it to determine which engine to use:\n\n```rust\npub enum CompiledRegex {\n    Linear(regex::Regex),           \u002F\u002F O(n) guaranteed, no lookahead\n    Backtracking(fancy_regex::Regex), \u002F\u002F Supports lookahead\u002Flookbehind\n}\n\nimpl CompiledRegex {\n    pub fn new(pattern: &str) -> Result\u003CSelf, Error> {\n        \u002F\u002F Try linear engine first (faster, predictable)\n        if let Ok(re) = regex::Regex::new(pattern) {\n            return Ok(CompiledRegex::Linear(re));\n        }\n        \u002F\u002F Fall back to backtracking for advanced features\n        Ok(CompiledRegex::Backtracking(fancy_regex::Regex::new(pattern)?))\n    }\n}\n```\n\n**Why This Matters**:\n\n1. **Performance predictability**: The linear engine guarantees O(n) matching time, critical for a hook that runs on every command\n2. **Feature completeness**: Some patterns require negative lookahead (e.g., \"match `--force` but not `--force-with-lease`\")\n3. **Automatic optimization**: Pattern authors don't need to think about engine selection—dcg chooses optimally\n\n**Examples of Engine Selection**:\n\n```rust\n\u002F\u002F Linear engine (simple pattern)\nr\"git\\s+reset\\s+--hard\"              \u002F\u002F No advanced features needed\n\n\u002F\u002F Backtracking engine (negative lookahead)\nr\"git\\s+push\\s+.*--force(?![-a-z])\"  \u002F\u002F Must NOT be followed by \"-with-lease\"\n\n\u002F\u002F Linear engine (character classes)\nr\"rm\\s+-[a-zA-Z]*[rR][a-zA-Z]*f\"     \u002F\u002F Complex but no lookahead\n```\n\n### Performance Budget System\n\ndcg operates under strict latency constraints—every Bash command passes through the hook, so even small delays compound into noticeable sluggishness. The performance budget system enforces these constraints with fail-open semantics.\n\n**Latency Tiers**:\n\n| Tier | Stage | Target | Warning | Panic |\n|------|-------|--------|---------|-------|\n| 0 | Quick Reject | \u003C 1μs | > 10μs | > 50μs |\n| 1 | Normalization | \u003C 5μs | > 25μs | > 100μs |\n| 2 | Safe Pattern Check | \u003C 50μs | > 200μs | > 500μs |\n| 3 | Destructive Pattern Check | \u003C 50μs | > 200μs | > 500μs |\n| 4 | Heredoc Extraction | \u003C 1ms | > 5ms | > 20ms |\n| 5 | Heredoc Evaluation | \u003C 2ms | > 10ms | > 30ms |\n| 6 | Full Pipeline | \u003C 5ms | > 15ms | > 50ms |\n\n**Fail-Open Behavior**:\n\nIf any stage exceeds its panic threshold, dcg logs a warning and **allows the command**:\n\n```\n[WARN] Performance budget exceeded: Tier 2 (safe patterns) took 1.2ms (panic threshold: 500μs)\n[WARN] Failing open to avoid blocking workflow\n```\n\nThis design ensures that:\n1. A pathological input cannot hang the user's terminal\n2. Performance regressions are visible in logs\n3. The tool never becomes a productivity bottleneck\n\n**Budget Enforcement**:\n\n```rust\nfn check_budget(tier: Tier, elapsed: Duration) -> BudgetResult {\n    let budget = TIER_BUDGETS[tier];\n    if elapsed > budget.panic {\n        log::warn!(\"Tier {} exceeded panic threshold\", tier);\n        return BudgetResult::FailOpen;\n    }\n    if elapsed > budget.warning {\n        log::warn!(\"Tier {} exceeded warning threshold\", tier);\n    }\n    BudgetResult::Continue\n}\n```\n\n**Monitoring Performance**:\n\nUse `dcg explain --verbose` to see per-stage timing:\n\n```\nEvaluation Trace:\n  [  0.3μs] Tier 0: Quick reject (PASS - below 1μs target)\n  [  1.2μs] Tier 1: Normalize (PASS - below 5μs target)\n  [  8.7μs] Tier 2: Safe patterns (PASS - below 50μs target)\n  [ 15.2μs] Tier 3: Destructive patterns (PASS - below 50μs target)\n  [ 15.4μs] Total: 15.4μs (PASS - below 5ms target)\n```\n\n### Keyword-Based Pack Pre-filtering\n\nBefore expensive regex matching, dcg uses a multi-level keyword filtering system to quickly skip irrelevant packs. This is critical for performance—with 49+ packs available, checking every pattern against every command would be prohibitively slow.\n\n**How Keyword Filtering Works**:\n\nEach pack declares a set of keywords that must appear in a command for that pack to be relevant:\n\n```rust\nPack {\n    id: \"database.postgresql\".to_string(),\n    keywords: &[\"psql\", \"dropdb\", \"createdb\", \"DROP\", \"TRUNCATE\", \"DELETE\"],\n    \u002F\u002F ...\n}\n```\n\n**Two-Level Filtering**:\n\n1. **Global Quick Reject**: Before any pack evaluation, dcg checks if the command contains *any* keyword from *any* enabled pack. If not, the entire pack evaluation is skipped.\n\n2. **Per-Pack Quick Reject**: For each enabled pack, dcg checks if the command contains any of that pack's keywords before running expensive regex patterns.\n\n**Aho-Corasick Automaton**:\n\nFor packs with multiple keywords, dcg builds an [Aho-Corasick automaton](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAho%E2%80%93Corasick_algorithm) that matches all keywords in a single O(n) pass:\n\n```rust\n\u002F\u002F Built lazily on first pack access\npub keyword_matcher: Option\u003Caho_corasick::AhoCorasick>,\n\npub fn might_match(&self, cmd: &str) -> bool {\n    if self.keywords.is_empty() {\n        return true; \u002F\u002F No keywords = always check patterns\n    }\n\n    \u002F\u002F O(n) matching regardless of keyword count\n    if let Some(ref ac) = self.keyword_matcher {\n        return ac.is_match(cmd);\n    }\n\n    \u002F\u002F Fallback: sequential memchr search\n    self.keywords.iter()\n        .any(|kw| memmem::find(cmd.as_bytes(), kw.as_bytes()).is_some())\n}\n```\n\n**Context-Aware Keyword Matching**:\n\nKeywords are only matched within executable spans (not in comments, quoted strings, or data):\n\n```rust\npub fn pack_aware_quick_reject(cmd: &str, enabled_keywords: &[&str]) -> bool {\n    \u002F\u002F First: fast substring check\n    let any_substring = enabled_keywords.iter()\n        .any(|kw| memmem::find(cmd.as_bytes(), kw.as_bytes()).is_some());\n\n    if !any_substring {\n        return true; \u002F\u002F Safe to skip all pack evaluation\n    }\n\n    \u002F\u002F Second: verify keyword appears in executable context\n    let spans = classify_command(cmd);\n    for span in spans.executable_spans() {\n        if span_matches_any_keyword(span.text(cmd), enabled_keywords) {\n            return false; \u002F\u002F Must evaluate packs\n        }\n    }\n\n    true \u002F\u002F Keywords only in non-executable contexts, safe to skip\n}\n```\n\nThis approach ensures that a command like `echo \"psql\" | grep DROP` doesn't trigger PostgreSQL pack evaluation just because keywords appear in the data being processed.\n\n### 1. Lazy Static Initialization\n\nRegex patterns are compiled once on first use via `LazyLock`:\n\n```rust\nstatic SAFE_PATTERNS: LazyLock\u003CVec\u003CPattern>> = LazyLock::new(|| {\n    vec![\n        pattern!(\"checkout-new-branch\", r\"git\\s+checkout\\s+-b\\s+\"),\n        \u002F\u002F ... 33 more patterns\n    ]\n});\n```\n\nSubsequent invocations reuse the compiled patterns with zero compilation overhead.\n\n### 2. SIMD-Accelerated Quick Rejection\n\nBefore any regex matching, a SIMD-accelerated substring search filters out irrelevant commands. The [memchr](https:\u002F\u002Fgithub.com\u002FBurntSushi\u002Fmemchr) crate uses CPU vector instructions (SSE2, AVX2, NEON) when available:\n\n```rust\nuse memchr::memmem;\n\nstatic GIT_FINDER: LazyLock\u003Cmemmem::Finder\u003C'static>> = LazyLock::new(|| memmem::Finder::new(\"git\"));\nstatic RM_FINDER: LazyLock\u003Cmemmem::Finder\u003C'static>> = LazyLock::new(|| memmem::Finder::new(\"rm\"));\n\nfn quick_reject(cmd: &str) -> bool {\n    let bytes = cmd.as_bytes();\n    GIT_FINDER.find(bytes).is_none() && RM_FINDER.find(bytes).is_none()\n}\n```\n\nFor commands like `ls -la`, `cargo build`, or `npm install`, this check short-circuits the entire matching pipeline. The `memmem::Finder` is pre-compiled once and reused, avoiding repeated setup costs.\n\n### 3. Early Exit on Safe Match\n\nSafe patterns are checked first. On match, the function returns immediately without checking destructive patterns:\n\n```rust\nfor pattern in SAFE_PATTERNS.iter() {\n    if pattern.regex.is_match(&normalized).unwrap_or(false) {\n        return;  \u002F\u002F Allow immediately\n    }\n}\n```\n\n### 4. Compile-Time Pattern Validation\n\nThe `pattern!` and `destructive!` macros include the pattern name in panic messages, making invalid patterns fail at first execution with clear diagnostics:\n\n```rust\nmacro_rules! pattern {\n    ($name:literal, $re:literal) => {\n        Pattern {\n            regex: Regex::new($re).expect(concat!(\"pattern '\", $name, \"' should compile\")),\n            name: $name,\n        }\n    };\n}\n```\n\n### 5. Zero-Copy JSON Parsing\n\nThe `serde_json` parser operates on the input buffer without unnecessary copies. The command string is extracted directly from the parsed JSON value.\n\n### 6. Zero-Allocation Path Normalization\n\nCommand normalization uses `Cow\u003Cstr>` (copy-on-write) to avoid heap allocations in the common case:\n\n```rust\nfn normalize_command(cmd: &str) -> Cow\u003C'_, str> {\n    \u002F\u002F Fast path: if command doesn't start with '\u002F', no normalization needed\n    if !cmd.starts_with('\u002F') {\n        return Cow::Borrowed(cmd);  \u002F\u002F Zero allocation\n    }\n    PATH_NORMALIZER.replace(cmd, \"$1\")  \u002F\u002F Allocation only when path is stripped\n}\n```\n\nMost commands don't use absolute paths to `git` or `rm`, so this fast path avoids allocation entirely for 99%+ of inputs.\n\n### 7. Release Profile Optimization\n\nThe release build uses aggressive optimization settings:\n\n```toml\n[profile.release]\nopt-level = \"z\"     # Optimize for size (lean binary)\nlto = true          # Link-time optimization across crates\ncodegen-units = 1   # Single codegen unit for better optimization\npanic = \"abort\"     # Smaller binary, no unwinding overhead\nstrip = true        # Remove debug symbols\n```\n\n## Example Block Message\n\nWhen a destructive command is intercepted, the hook outputs a colorful warning to stderr (shown below without ANSI codes):\n\n```\n════════════════════════════════════════════════════════════════════════\nBLOCKED  dcg\n────────────────────────────────────────────────────────────────────────\nReason:  git reset --hard destroys uncommitted changes. Use 'git stash' first.\n\nCommand:  git reset --hard HEAD~1\n\nTip: If you need to run this command, execute it manually in a terminal.\n     Consider using 'git stash' first to save your changes.\n════════════════════════════════════════════════════════════════════════\n```\n\n### Suggestion System\n\ndcg doesn't just block commands—it provides actionable guidance to help users make safer choices. The suggestion system generates context-aware recommendations based on the specific command that was blocked.\n\n**Suggestion Categories**:\n\n| Category | Purpose | Example |\n|----------|---------|---------|\n| `PreviewFirst` | Run a dry-run\u002Fpreview command first | \"Run `git clean -n` first to preview deletions\" |\n| `SaferAlternative` | Use a safer command that achieves similar goals | \"Use `--force-with-lease` instead of `--force`\" |\n| `WorkflowFix` | Fix the workflow to avoid the dangerous operation | \"Commit your changes before resetting\" |\n| `Documentation` | Link to relevant documentation | \"See `man git-reset` for reset options\" |\n| `AllowSafely` | How to allowlist if the operation is intentional | \"Add to allowlist: `dcg allowlist add core.git:reset-hard`\" |\n\n**Contextual Suggestions by Command Type**:\n\n| Command Type | Suggestion |\n|-------------|------------|\n| `git reset`, `git checkout --` | \"Consider using 'git stash' first to save your changes.\" |\n| `git clean` | \"Use 'git clean -n' first to preview what would be deleted.\" |\n| `git push --force` | \"Consider using '--force-with-lease' for safer force pushing.\" |\n| `rm -rf` | \"Verify the path carefully before running rm -rf manually.\" |\n| `kubectl delete` | \"Use `kubectl delete --dry-run=client` to preview deletions.\" |\n| `docker system prune` | \"Run with `--dry-run` first to see what would be removed.\" |\n| `DROP TABLE` | \"Consider `TRUNCATE` if you only need to remove data, not the schema.\" |\n\n**Custom Suggestions in Packs**:\n\nEach destructive pattern can specify its own suggestion tailored to the specific operation:\n\n```rust\ndestructive_pattern!(\n    \"restic-forget\",\n    r\"restic(?:\\s+--?\\S+(?:\\s+\\S+)?)*\\s+forget\\b\",\n    \"restic forget removes snapshots and can permanently delete backup data.\",\n    suggestion: \"Run 'restic snapshots' first to review what would be affected.\"\n)\n```\n\nThis approach ensures that suggestions are always relevant to the specific context, not generic warnings.\n\nSimultaneously, the hook outputs JSON to stdout for the Claude Code protocol:\n\n```json\n{\n  \"hookSpecificOutput\": {\n    \"hookEventName\": \"PreToolUse\",\n    \"permissionDecision\": \"deny\",\n    \"permissionDecisionReason\": \"BLOCKED by dcg\\n\\nReason: ...\"\n  }\n}\n```\n\n## Security Considerations\n\n### What This Protects Against\n\n- **Accidental data loss**: AI agents running `git checkout --` or `git reset --hard` on files with uncommitted changes\n- **Remote history destruction**: Force pushes that overwrite shared branch history\n- **Stash loss**: Dropping or clearing stashes containing important work-in-progress\n- **Filesystem accidents**: Recursive deletion outside designated temp directories\n\n### Inherent Limitations\n\nWhile dcg provides comprehensive protection across many tools and platforms, some attack vectors are inherently difficult or impossible to protect against:\n- **Malicious actors**: A determined attacker can bypass this hook\n- **Non-Bash commands**: Direct file writes via Python\u002FJavaScript, API calls, etc. are not intercepted\n- **Committed but unpushed work**: The hook doesn't prevent loss of local-only commits\n- **Bugs in allowed commands**: A `git commit` that accidentally includes wrong files\n- **Commands in scripts**: If an agent runs `.\u002Fdeploy.sh`, we don't inspect what's inside the script\n\n### Threat Model\n\nThis hook assumes the AI agent is **well-intentioned but fallible**. It's designed to catch honest mistakes, not adversarial attacks. The hook runs with the same permissions as the Claude Code process.\n\n## Troubleshooting\n\n### Hook not blocking commands\n\n1. **Check hook registration**: Verify `~\u002F.claude\u002Fsettings.json` contains the hook configuration\n2. **Restart Claude Code**: Configuration changes require a restart\n3. **Check binary location**: Ensure `dcg` is in your PATH\n4. **Test manually**: Run `echo '{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git reset --hard\"}}' | dcg`\n\n### Hook silently removed (recommended: add shell startup check)\n\nClaude Code can silently remove the dcg hook when it rewrites `~\u002F.claude\u002Fsettings.json`. This means you may lose protection without any warning.\n\n**Automatic setup** -- `dcg setup` installs the hook *and* offers to add a shell startup check:\n\n```bash\ndcg setup               # Interactive — prompts before modifying RC files\ndcg setup --shell-check # Non-interactive — adds the check automatically\n```\n\n**Manual setup** -- add this snippet to your `~\u002F.zshrc` and\u002For `~\u002F.bashrc`:\n\n```bash\n# dcg: warn if hook was silently removed from Claude Code settings\nif command -v dcg &>\u002Fdev\u002Fnull && command -v jq &>\u002Fdev\u002Fnull; then\n  if [ -f \"$HOME\u002F.claude\u002Fsettings.json\" ] && \\\n     ! jq -e '.hooks.PreToolUse[]? | select(.hooks[]?.command | test(\"dcg$\"))' \\\n       \"$HOME\u002F.claude\u002Fsettings.json\" &>\u002Fdev\u002Fnull; then\n    printf '\\033[1;33m[dcg] Hook missing from ~\u002F.claude\u002Fsettings.json — run: dcg install\\033[0m\\n'\n  fi\nfi\n```\n\nThis check:\n- Runs in milliseconds (no noticeable shell startup delay)\n- Is completely silent when the hook is present\n- Shows a yellow warning only when the hook is missing\n- Gracefully skips if `dcg`, `jq`, or `settings.json` are absent\n- Works identically in bash and zsh\n\n> **Note:** The `install.sh` installer also offers to add this check during installation.\n\n### Hook blocking safe commands\n\n1. **Check for false positives**: Some edge cases may not be covered by safe patterns\n2. **File an issue**: Report the command that was incorrectly blocked\n3. **Temporary bypass**: Have the user run the command manually in a separate terminal\n4. **Add to allowlist**: Use the allowlist feature below for persistent overrides\n\n### Resolving False Positives with Allowlists\n\nIf dcg blocks a command that is safe in your specific context, you can add it to an allowlist. Allowlists support three layers (checked in order):\n\n1. **Project** (`.dcg\u002Fallowlist.toml`): Applies only to the current project\n2. **User** (`~\u002F.config\u002Fdcg\u002Fallowlist.toml`): Applies to all your projects\n3. **System** (`\u002Fetc\u002Fdcg\u002Fallowlist.toml`): Applies system-wide\n\n**Adding a rule to the allowlist:**\n\n```bash\n# Allow a specific rule by ID (recommended)\ndcg allowlist add core.git:reset-hard -r \"Used for CI cleanup\"\n\n# Allow at project level (default if in a git repo)\ndcg allowlist add core.git:reset-hard -r \"CI cleanup\" --project\n\n# Add to user-level allowlist instead\ndcg allowlist add core.git:reset-hard -r \"Personal workflow\" --user\n\n# Allow with expiration (ISO 8601 format)\ndcg allowlist add core.git:clean-force -r \"Migration\" --expires \"2026-02-01T00:00:00Z\"\n\n# Allow a specific command (exact match) using add-command\ndcg allowlist add-command \"rm -rf .\u002Fbuild\" -r \"Build cleanup\"\n```\n\n**Listing allowlist entries:**\n\n```bash\n# List all entries from all layers\ndcg allowlist list\n\n# List project allowlist only\ndcg allowlist list --project\n\n# List user allowlist only\ndcg allowlist list --user\n\n# Output as JSON\ndcg allowlist list --format json\n```\n\n**Removing entries:**\n\n```bash\n# Remove a rule by ID\ndcg allowlist remove core.git:reset-hard\n\n# Remove from project allowlist specifically\ndcg allowlist remove core.git:reset-hard --project\n```\n\n**Validating allowlist files:**\n\n```bash\n# Check for issues (expired entries, invalid patterns)\ndcg allowlist validate\n\n# Strict mode: treat warnings as errors\ndcg allowlist validate --strict\n```\n\n**Example allowlist.toml:**\n\n```toml\n[[allow]]\nrule = \"core.git:reset-hard\"\nreason = \"Used for CI pipeline cleanup\"\nadded_at = \"2026-01-08T12:00:00Z\"\n\n[[allow]]\nexact_command = \"rm -rf .\u002Fbuild\"\nreason = \"Safe build directory cleanup\"\nadded_at = \"2026-01-08T12:00:00Z\"\nexpires_at = \"2026-02-08T12:00:00Z\"  # Optional expiration\n\n[[allow]]\npattern = \"rm -rf .*\u002Fbuild\"\nreason = \"Build directories across projects\"\nrisk_acknowledged = true  # Required for pattern-based entries\nadded_at = \"2026-01-08T12:00:00Z\"\n```\n\n### Performance issues\n\n1. **Check pattern count**: Excessive custom patterns can slow matching\n2. **Profile with `--release`**: Debug builds are significantly slower\n3. **Check stdin buffering**: Slow JSON input can delay processing\n\n## Running Tests\n\n### Unit Tests\n\n```bash\ncargo test\n```\n\nThe test suite includes 80+ tests covering:\n\n- **normalize_command_tests**: Path stripping for git and rm binaries\n- **quick_reject_tests**: Fast-path filtering for non-git\u002Frm commands\n- **safe_pattern_tests**: Whitelist accuracy for all safe pattern variants\n- **destructive_pattern_tests**: Blacklist coverage for all dangerous commands\n- **input_parsing_tests**: JSON parsing robustness and edge cases\n- **deny_output_tests**: Output format validation\n- **integration_tests**: End-to-end pipeline verification\n\n### Test with Coverage\n\n```bash\ncargo install cargo-tarpaulin\ncargo tarpaulin --out Html\n```\n\n### End-to-End Testing\n\nThe repository includes a comprehensive E2E test script with 120 test cases:\n\n```bash\n# Run full E2E test suite\n.\u002Fscripts\u002Fe2e_test.sh\n\n# With verbose output\n.\u002Fscripts\u002Fe2e_test.sh --verbose\n\n# With specific binary path\n.\u002Fscripts\u002Fe2e_test.sh --binary .\u002Ftarget\u002Frelease\u002Fdcg\n```\n\nThe E2E suite covers:\n- All destructive git commands (reset, checkout, restore, clean, push, branch, stash)\n- All safe git commands (status, log, diff, add, commit, push, branch -d)\n- Filesystem commands (rm -rf with various paths and flag orderings)\n- Absolute path handling (`\u002Fusr\u002Fbin\u002Fgit`, `\u002Fbin\u002Frm`)\n- Non-Bash tools (Read, Write, Edit, Grep, Glob)\n- Malformed JSON input (empty, missing fields, invalid syntax)\n- Edge cases (sudo prefixes, quoted paths, variable expansion)\n\n## Continuous Integration\n\nThe project uses GitHub Actions for CI\u002FCD:\n\n### CI Workflow (`.github\u002Fworkflows\u002Fci.yml`)\n\nRuns on every push and pull request:\n\n- **Formatting check**: `cargo fmt --check`\n- **Clippy lints**: `cargo clippy --all-targets -- -D warnings` (pedantic + nursery enabled)\n- **Compilation check**: `cargo check --all-targets`\n- **Unit tests**: `cargo nextest run` with JUnit XML reports\n- **Coverage**: `cargo llvm-cov` with LCOV output\n\n### Release Workflow (`.github\u002Fworkflows\u002Fdist.yml`)\n\nTriggered on version tags (`v*`):\n\n- Builds optimized binaries for 5 platforms:\n  - Linux x86_64 (`x86_64-unknown-linux-gnu`)\n  - Linux ARM64 (`aarch64-unknown-linux-gnu`)\n  - macOS Intel (`x86_64-apple-darwin`)\n  - macOS Apple Silicon (`aarch64-apple-darwin`)\n  - Windows (`x86_64-pc-windows-msvc`)\n- Creates `.tar.xz` archives (Unix) or `.zip` (Windows)\n- Generates SHA256 checksums for verification\n- Publishes to GitHub Releases with auto-generated release notes\n\nTo create a release:\n\n```bash\ngit tag v0.1.0\ngit push origin v0.1.0\n```\n\n## FAQ\n\n**Q: Why block `git branch -D` but allow `git branch -d`?**\n\nThe lowercase `-d` only deletes branches that have been fully merged. The uppercase `-D` force-deletes regardless of merge status, potentially losing commits that exist only on that branch.\n\n**Q: Why is `git push --force-with-lease` allowed?**\n\nForce-with-lease is a safer alternative that refuses to push if the remote has commits you haven't seen. It prevents accidentally overwriting someone else's work.\n\n**Q: Why block all `rm -rf` outside temp directories?**\n\nRecursive forced deletion is one of the most dangerous filesystem operations. Even with good intentions, a typo or wrong variable expansion can delete critical files. Temp directories are designed to be ephemeral.\n\n**Q: Can I add custom patterns?**\n\nYes. Create YAML pack files and point to them in your config. See the [Custom Packs](#custom-packs) section and [`docs\u002Fcustom-packs.md`](docs\u002Fcustom-packs.md) for the schema and examples.\n\n**Q: What if I really need to run a blocked command?**\n\nSee [Escape Hatch \u002F Bypass](#escape-hatch--bypass). Options include `DCG_BYPASS=1`, allow-once codes, permanent allowlists, or running the command manually in a separate terminal.\n\n**Q: Does this work with other AI coding tools?**\n\nYes. dcg natively supports Claude Code, Gemini CLI, and GitHub Copilot CLI hook payloads. For other tools, support depends on whether they expose a pre-execution shell hook with compatible JSON input\u002Foutput.\n\n**Q: What about database, Docker, Kubernetes, and cloud commands?**\n\ndcg includes 49+ packs covering all of these. See the [Modular Pack System](#modular-pack-system) section for the full list. Enable the packs you need in your config.\n\n## Contributing\n\n*About Contributions:* Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other \"stakeholders,\" which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via `gh` and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.\n\n## License\n\nMIT\n","# dcg（破坏性命令防护）\n\n\u003Cdiv align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FDicklesworthstone_destructive_command_guard_readme_f3551a4f1c3c.webp\" alt=\"破坏性命令防护——保护你的代码免遭意外破坏\">\n\u003C\u002Fdiv>\n\n\u003Cdiv align=\"center\">\n\n[![覆盖率](https:\u002F\u002Fimg.shields.io\u002Fcodecov\u002Fc\u002Fgithub\u002FDicklesworthstone\u002Fdestructive_command_guard?label=coverage)](https:\u002F\u002Fcodecov.io\u002Fgh\u002FDicklesworthstone\u002Fdestructive_command_guard)\n[![许可证：MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\n\u003C\u002Fdiv>\n\n一个高性能的钩子，专为 AI 编码助手设计，在破坏性命令执行前将其拦截，从而保护你的工作成果不被意外删除。\n\n**支持的工具：** [Claude Code](https:\u002F\u002Fclaude.ai\u002Fcode)、[Gemini CLI](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli)、[GitHub Copilot CLI](https:\u002F\u002Fdocs.github.com\u002Fen\u002Fcopilot\u002Fconcepts\u002Fagents\u002Fcoding-agent\u002Fabout-hooks)、[Cursor IDE](https:\u002F\u002Fcursor.com)、[OpenCode](https:\u002F\u002Fopencode.ai)（通过[社区插件](https:\u002F\u002Fgithub.com\u002Faspiers\u002Fai-config\u002Fblob\u002Fmain\u002F.config\u002Fopencode\u002Fplugins\u002Fdcg-guard.js)）、[Aider](https:\u002F\u002Faider.chat\u002F)（有限支持——仅限 Git 钩子）、[Continue](https:\u002F\u002Fcontinue.dev)（仅检测功能）、[Codex CLI](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex)\n\n\u003Cdiv align=\"center\">\n\u003Ch3>快速安装\u003C\u002Fh3>\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --easy-mode\n```\n\n\u003Cp>\u003Cem>适用于 Linux、macOS 和 Windows (WSL)。自动检测你的平台并下载合适的二进制文件。\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\n---\n\n## 简要说明\n\n**问题描述：** AI 编码助手（如 Claude、GPT 等）有时会执行诸如 `git reset --hard`、`rm -rf .\u002Fsrc` 或 `DROP TABLE users` 等灾难性命令，导致数小时未提交的工作在几秒钟内被彻底摧毁。\n\n**解决方案：** dcg 是一个高性能的钩子，能够在破坏性命令执行之前对其进行拦截，并以清晰的解释和更安全的替代方案阻止这些命令的执行。\n\n### 为什么使用 dcg？\n\n| 功能 | 描述 |\n|---------|--------------|\n| **零配置防护** | 开箱即用，直接阻止危险的 Git 和文件系统命令 |\n| **49+ 安全包** | 数据库、Kubernetes、Docker、AWS\u002FGCP\u002FAzure、Terraform 等 |\n| **亚毫秒级延迟** | 基于 SIMD 加速的过滤技术，几乎不会影响性能 |\n| **Heredoc\u002F内联脚本扫描** | 能够捕获 `python -c \"os.remove(...)\"` 和嵌入式 Shell 脚本 |\n| **智能上下文检测** | 不会阻止 `grep \"rm -rf\"`（数据操作），但会阻止 `rm -rf \u002F`（实际执行） |\n| **CI 模式扫描** | 支持预提交钩子和 CI 集成，用于在代码审查阶段捕获危险命令 |\n| **故障开放设计** | 绝不会因超时或解析错误而阻塞你的工作流程 |\n| **解释模式** | `dcg explain \"command\"` 可显示具体为何该命令被拦截 |\n\n### 快速示例\n\n```bash\n# AI 助手尝试运行：\n$ git reset --hard HEAD~5\n\n# dcg 拦截并阻止：\n════════════════════════════════════════════════════════════════\n已阻止  dcg\n────────────────────────────────────────────────────────────────\n原因：  git reset --hard 会丢弃未提交的更改\n\n命令： git reset --hard HEAD~5\n\n提示： 建议先使用 'git stash' 保存你的更改。\n════════════════════════════════════════════════════════════════\n```\n\n### 启用更多防护\n\n```toml\n# ~\u002F.config\u002Fdcg\u002Fconfig.toml\n[packs]\nenabled = [\n    \"database.postgresql\",    # 阻止 DROP TABLE、TRUNCATE\n    \"kubernetes.kubectl\",     # 阻止 kubectl delete namespace\n    \"cloud.aws\",              # 阻止 aws ec2 terminate-instances\n    \"containers.docker\",      # 阻止 docker system prune\n]\n```\n\n### 针对不同 AI 助手的配置文件\n\ndcg 会自动检测调用它的 AI 编码助手，并应用特定于该助手的配置。`trust_level` 字段是一个**建议性标签**，记录在 JSON 输出和日志中——它并不会直接影响规则的评估。行为差异主要由其他配置字段决定：\n\n| 选项 | 效果 |\n|--------|--------|\n| `disabled_packs` | 从评估中移除指定的安全包 |\n| `extra_packs` | 向评估中添加额外的安全包 |\n| `additional_allowlist` | 添加可绕过拒绝规则的命令模式 |\n| `disabled_allowlist` | 当设置为 true 时，忽略所有允许列表条目 |\n\n```toml\n# 对 Claude Code 更加信任——放宽允许列表，减少启用的安全包\n[agents.claude-code]\ntrust_level = \"high\"\nadditional_allowlist = [\"npm run build\", \"cargo test\"]\ndisabled_packs = [\"kubernetes\"]\n\n# 限制未知助手——增加额外规则，禁止绕过允许列表\n[agents.unknown]\ntrust_level = \"low\"\nextra_packs = [\"paranoid\"]\ndisabled_allowlist = true\n```\n\n完整的支持助手列表、信任级别及配置选项，请参阅 [docs\u002Fagents.md](docs\u002Fagents.md)。\n\n---\n\n## 起源与作者\n\n该项目最初是由 Jeffrey Emanuel 使用 Python 编写的脚本，他意识到尽管 AI 编码助手非常有用，但它们有时会执行灾难性的命令，导致数小时未提交的工作瞬间丢失。最初的实现是一个简单却有效的钩子，能够在危险的 Git 和文件系统命令执行前将其拦截。\n\n- **[Jeffrey Emanuel](https:\u002F\u002Fgithub.com\u002FDicklesworthstone)** —— 原始概念提出者及 Python 实现者（[源代码链接](https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fmisc_coding_agent_tips_and_scripts\u002Fblob\u002Fmain\u002FDESTRUCTIVE_GIT_COMMAND_CLAUDE_HOOKS_SETUP.md)）；大幅扩展了 Rust 版本，引入模块化安全包系统（49+ 种安全包）、Heredoc\u002F内联脚本扫描、三层架构、上下文分类、允许列表、扫描模式以及双正则引擎。\n- **[Darin Gordon](https:\u002F\u002Fgithub.com\u002FDowwie)** —— 初始 Rust 移植及性能优化。\n\nDarin 的初始 Rust 移植保持了与原始 Python 实现的模式兼容性，同时通过 SIMD 加速的过滤技术和惰性编译的正则表达式模式实现了亚毫秒级的执行速度。随后，Jeffrey 对 Rust 代码库进行了大规模扩展，增加了上述提到的各项功能。\n\n## 应急通道\u002F绕过机制\n\n如果 dcg 阻止了你确实需要运行的命令：\n\n| 方法 | 适用范围 | 如何操作 |\n|--------|-------|-----|\n| **环境变量绕过** | 单个命令 | `DCG_BYPASS=1 \u003Ccommand>` |\n| **一次性允许** | 单个命令 | 复制拦截信息中的短代码，运行 `dcg allow-once \u003Ccode>` |\n| **永久允许列表** | 规则或命令 | `dcg allowlist add core.git:reset-hard -r \"reason\"` |\n| **移除钩子** | 所有命令 | 删除或注释掉 `~\u002F.claude\u002Fsettings.json` 中的 dcg 条目（或其他对应助手的配置文件） |\n\n`DCG_BYPASS=1` 会禁用此次调用的所有防护措施。请谨慎使用此方法，对于经常需要执行的命令，建议使用允许列表。\n\n## 模块化安全包系统\n\ndcg 使用模块化的“安全包”系统来按类别组织破坏性命令模式。用户可以在配置文件中启用或禁用不同的安全包。\n\n- 完整的安全包 ID 索引：`docs\u002Fpacks\u002FREADME.md`\n- 标准化描述及模式数量：`dcg packs --verbose`\n\n### 核心插件（默认启用）\n- `core.filesystem` - 防御在临时目录之外执行危险的 `rm -rf` 命令\n- `core.git` - 防御可能导致未提交工作丢失、重写历史或破坏暂存区的破坏性 Git 命令\n\n**默认启用的常用插件：**\n- `database.postgresql` - 防御破坏性的 PostgreSQL 操作\n- `containers.docker` - 防御系统清理等破坏性 Docker 操作\n\n### 存储插件\n- `storage.s3` - 防御删除存储桶、递归删除以及 `sync --delete` 等破坏性 S3 操作\n- `storage.gcs` - 防御删除存储桶、对象删除和递归删除等破坏性 GCS 操作\n- `storage.minio` - 防御删除存储桶、对象删除以及管理操作等破坏性 MinIO Client (mc) 操作\n- `storage.azure_blob` - 防御删除容器、Blob 对象以及使用 `azcopy remove` 等破坏性 Azure Blob Storage 操作\n\n### 远程插件\n- `remote.rsync` - 防御带有 `--delete` 或其变体的破坏性 rsync 操作\n- `remote.scp` - 防御覆盖系统路径等破坏性 SCP 操作\n- `remote.ssh` - 防御远程命令执行和密钥管理等破坏性 SSH 操作\n\n### 数据库插件\n- `database.postgresql` - 防御 `DROP DATABASE`、`TRUNCATE` 和 `dropdb` 等破坏性 PostgreSQL 操作\n- `database.mysql` - 保护 MySQL\u002FMariaDB 数据库\n- `database.mongodb` - 防御 `dropDatabase`、`dropCollection` 和无条件删除等破坏性 MongoDB 操作\n- `database.redis` - 防御 `FLUSHALL`、`FLUSHDB` 和批量删除键等破坏性 Redis 操作\n- `database.sqlite` - 防御 `DROP TABLE`、无条件 `DELETE` 以及意外数据丢失等破坏性 SQLite 操作\n- `database.supabase` - 防御 Supabase CLI 中的破坏性操作，包括数据库重置、迁移回滚、函数\u002F密钥\u002F存储删除、项目移除以及基础设施变更\n\n### 容器插件\n- `containers.docker` - 防御系统清理、卷清理和强制移除等破坏性 Docker 操作\n- `containers.compose` - 防御带有 `-v` 的 `docker-compose down` 等破坏性操作，该操作会删除卷\n- `containers.podman` - 防御系统清理、卷清理和强制移除等破坏性 Podman 操作\n\n### Kubernetes 插件\n- `kubernetes.kubectl` - 防御删除命名空间、节点排空以及批量删除等破坏性 kubectl 操作\n- `kubernetes.helm` - 防御未经过试运行就卸载或回滚等破坏性 Helm 操作\n- `kubernetes.kustomize` - 防御与 kubectl 结合使用时未经审查就执行删除操作的破坏性 Kustomize 操作\n\n### 云服务商插件\n- `cloud.aws` - 防御终止实例、删除数据库实例以及递归删除 S3 对象等破坏性 AWS CLI 操作\n- `cloud.azure` - 防御删除虚拟机、存储账户和资源组等破坏性 Azure CLI 操作\n- `cloud.gcp` - 防御删除实例、SQL 实例以及递归删除对象等破坏性 gcloud 操作\n\n### CDN 插件\n- `cdn.cloudflare_workers` - 防御通过 Wrangler CLI 执行的 Cloudflare Workers、KV、R2 和 D1 等破坏性操作\n- `cdn.cloudfront` - 防御删除分发点、缓存策略和函数等破坏性 AWS CloudFront 操作\n- `cdn.fastly` - 防御删除服务、域名、后端和 VCL 等破坏性 Fastly CLI 操作\n\n### API 网关插件\n- `apigateway.apigee` - 防御 Google Apigee CLI 和 apigeecli 中的破坏性操作\n- `apigateway.aws` - 防御 REST API 和 HTTP API 中的破坏性 AWS API Gateway CLI 操作\n- `apigateway.kong` - 防御 Kong Gateway CLI、deck CLI 以及 Admin API 中的破坏性操作\n\n### 基础设施插件\n- `infrastructure.ansible` - 防御 Ansible 中的破坏性操作，如危险的 shell 命令和未经检查的 playbook 执行\n- `infrastructure.pulumi` - 防御 Pulumi 中的破坏性操作，如直接销毁资源或使用 `-y` 自动批准选项进行部署\n- `infrastructure.terraform` - 防御 Terraform 中的破坏性操作，如直接销毁资源、标记污点或自动批准应用更改\n\n### 系统插件\n- `system.disk` - 防御对磁盘的破坏性操作，包括向设备写入数据 (`dd`)、格式化分区 (`mkfs`)、修改分区表（`fdisk`\u002F`parted`）、RAID 管理（`mdadm`）、Btrfs 文件系统操作、设备映射器操作（`dmsetup`）、网络块设备操作（`nbd-client`）以及 LVM 命令（`pvremove`、`vgremove`、`lvremove`、`lvreduce`、`pvmove`）\n- `system.permissions` - 防御危险的权限更改，如将权限设置为 `777`，或对系统目录进行递归式的 `chmod`\u002F`chown`\n- `system.services` - 防御停止关键服务或修改初始化配置等危险的服务操作\n\n### CI\u002FCD 插件\n- `cicd.circleci` - 防御删除上下文、移除密钥、删除 Orb\u002F命名空间或管道等破坏性 CircleCI 操作\n- `cicd.github_actions` - 防御删除密钥\u002F变量，或使用 `gh api DELETE` 请求 GitHub Actions 的 API 端点等破坏性 GitHub Actions 操作\n- `cicd.gitlab_ci` - 防御删除变量、移除构建产物以及注销 Runner 等破坏性 GitLab CI\u002FCD 操作\n- `cicd.jenkins` - 防御删除作业、节点、凭据或构建历史等破坏性 Jenkins CLI\u002FAPI 操作\n\n### 密钥管理插件\n- `secrets.aws_secrets` - 防御删除密钥和参数等破坏性 AWS Secrets Manager 和 SSM Parameter Store 操作\n- `secrets.doppler` - 防御删除密钥、配置、环境或项目等破坏性 Doppler CLI 操作\n- `secrets.onepassword` - 防御删除条目、文档、用户、群组和保险箱等破坏性 1Password CLI 操作\n- `secrets.vault` - 防御删除密钥、禁用认证\u002F秘密引擎、撤销租约\u002F令牌以及删除策略等破坏性 Vault CLI 操作\n\n### 平台插件\n- `platform.github` - 防御删除仓库、Gist、发布版本或 SSH 密钥等破坏性 GitHub CLI 操作\n- `platform.gitlab` - 防御删除项目、发布版本、保护分支和 Webhook 等破坏性 GitLab 平台操作\n\n### DNS 插件\n- `dns.cloudflare` - 防御删除记录、区域以及针对性的 Terraform 销毁等破坏性 Cloudflare DNS 操作\n- `dns.generic` - 防御使用 `nsupdate` 删除记录或进行区域传输等具有风险的 DNS 工具操作\n- `dns.route53` - 防御删除托管区域和修改记录集等破坏性 AWS Route53 DNS 操作\n\n### 邮件防护包\n- `email.mailgun` - 防护破坏性的 Mailgun API 操作，例如删除域名、路由和邮件列表。\n- `email.postmark` - 防护破坏性的 Postmark API 操作，例如删除服务器、模板和发件人签名。\n- `email.sendgrid` - 防护破坏性的 SendGrid API 操作，例如删除模板、API 密钥和域名认证。\n- `email.ses` - 防护破坏性的 AWS Simple Email Service 操作，例如删除身份、模板和配置集。\n\n### 功能标志防护包\n- `featureflags.flipt` - 防护破坏性的 Flipt CLI 和 API 操作。\n- `featureflags.launchdarkly` - 防护破坏性的 LaunchDarkly CLI 和 API 操作。\n- `featureflags.split` - 防护破坏性的 Split.io CLI 和 API 操作。\n- `featureflags.unleash` - 防护破坏性的 Unleash CLI 和 API 操作。\n\n### 负载均衡器防护包\n- `loadbalancer.elb` - 防护破坏性的 AWS Elastic Load Balancing（ELB\u002FALB\u002FNLB）操作，例如删除负载均衡器、目标组或从实时流量中注销目标。\n- `loadbalancer.haproxy` - 防护破坏性的 HAProxy 负载均衡器操作，例如通过运行时 API 停止服务或禁用后端。\n- `loadbalancer.nginx` - 防护破坏性的 nginx 负载均衡器操作，例如停止服务或删除配置文件。\n- `loadbalancer.traefik` - 防护破坏性的 Traefik 负载均衡器操作，例如停止容器、删除配置或执行 API 删除操作。\n\n### 消息队列防护包\n- `messaging.kafka` - 防护破坏性的 Kafka CLI 操作，例如删除主题、消费者组，重置偏移量和删除记录。\n- `messaging.nats` - 防护破坏性的 NATS\u002FJetStream 操作，例如删除流、消费者、键值对、对象和账户。\n- `messaging.rabbitmq` - 防护破坏性的 RabbitMQ 操作，例如删除队列\u002F交换机、清空队列、删除虚拟主机和重置集群状态。\n- `messaging.sqs_sns` - 防护破坏性的 AWS SQS 和 SNS 操作，例如删除队列、清空消息、删除主题和取消订阅。\n\n### 监控防护包\n- `monitoring.datadog` - 防护破坏性的 Datadog CLI\u002FAPI 操作，例如删除监控器和仪表板。\n- `monitoring.newrelic` - 防护破坏性的 New Relic CLI\u002FAPI 操作，例如删除实体或告警资源。\n- `monitoring.pagerduty` - 防护破坏性的 PagerDuty CLI\u002FAPI 操作，例如删除服务和计划（可能导致事件路由中断）。\n- `monitoring.prometheus` - 防护破坏性的 Prometheus\u002FGrafana 操作，例如删除时间序列数据或仪表板\u002F数据源。\n- `monitoring.splunk` - 防护破坏性的 Splunk CLI\u002FAPI 操作，例如删除索引和 REST API 的 DELETE 请求。\n\n### 支付防护包\n- `payment.braintree` - 防护破坏性的 Braintree\u002FPayPal 支付操作，例如通过 API\u002FSDK 调用删除客户或取消订阅。\n- `payment.square` - 防护破坏性的 Square CLI\u002FAPI 操作，例如删除目录对象或客户（可能中断支付流程）。\n- `payment.stripe` - 防护破坏性的 Stripe CLI\u002FAPI 操作，例如删除 Webhook 终结点和客户，或在未协调的情况下轮换 API 密钥。\n\n### 搜索引擎防护包\n- `search.algolia` - 防护破坏性的 Algolia 操作，例如删除索引、清除文档、移除规则\u002F同义词和删除 API 密钥。\n- `search.elasticsearch` - 防护破坏性的 Elasticsearch REST API 操作，例如删除索引、按查询删除、关闭索引和更改集群设置。\n- `search.meilisearch` - 防护破坏性的 Meilisearch REST API 操作，例如删除索引、文档、批量删除和移除 API 密钥。\n- `search.opensearch` - 防护破坏性的 OpenSearch REST API 操作以及 AWS CLI 的域删除操作。\n\n### 备份防护包\n- `backup.borg` - 防护破坏性的 borg 操作，例如删除、修剪、压缩和重建。\n- `backup.rclone` - 防护破坏性的 rclone 操作，例如同步、删除、清理、去重和移动。\n- `backup.restic` - 防护破坏性的 restic 操作，例如忘记快照、修剪数据、移除密钥和清理缓存。\n- `backup.velero` - 防护破坏性的 velero 操作，例如删除备份、计划和位置。\n\n### 其他防护包\n- `package_managers` - 防护危险的包管理操作，例如发布软件包和移除关键系统包。\n- `strict_git` - 更严格的 Git 保护：阻止所有强制推送、变基和重写历史的操作。\n\n在 `~\u002F.config\u002Fdcg\u002Fconfig.toml` 中启用防护包：\n\n```toml\n[packs]\nenabled = [\n    # 数据库\n    \"database.postgresql\",\n    \"database.redis\",\n    \"database.supabase\",\n\n    # 容器与编排\n    \"containers.docker\",\n    \"kubernetes\",  # 启用所有 Kubernetes 子防护包\n\n    # 云服务提供商\n    \"cloud.aws\",\n    \"cloud.gcp\",\n\n    # 秘密管理\n    \"secrets.aws_secrets\",\n    \"secrets.vault\",\n\n    # CI\u002FCD\n    \"cicd.jenkins\",\n    \"cicd.gitlab_ci\",\n\n    # 消息队列\n    \"messaging.kafka\",\n    \"messaging.sqs_sns\",\n\n    # 搜索引擎\n    \"search.elasticsearch\",\n\n    # 备份\n    \"backup.restic\",\n\n    # 平台\n    \"platform.github\",\n\n    # 监控\n    \"monitoring.splunk\",\n]\n```\n\n### 自定义防护包\n\n使用 YAML 文件创建您组织特定的安全防护包。自定义防护包允许您为内部工具、部署脚本和专有系统定义模式，而无需修改 dcg。\n\n```toml\n[packs]\ncustom_paths = [\n    \"~\u002F.config\u002Fdcg\u002Fpacks\u002F*.yaml\",      # 用户防护包\n    \".dcg\u002Fpacks\u002F*.yaml\",               # 项目本地防护包\n]\n```\n\n有关详细的防护包编写指南、模式参考和示例，请参阅 [`docs\u002Fcustom-packs.md`](docs\u002Fcustom-packs.md)。\n\n在部署前验证您的防护包：\n\n```bash\ndcg pack validate mypack.yaml\n```\n\nHeredoc 扫描配置：\n\n```toml\n[heredoc]\n# 启用 Heredoc 和内联脚本（python -c、bash -c 等）的扫描。\nenabled = true\n\n# 提取超时预算（毫秒）。\ntimeout_ms = 50\n\n# 提取内容的资源限制。\nmax_body_bytes = 1048576\nmax_body_lines = 10000\nmax_heredocs = 10\n\n# 可选的语言过滤器（仅扫描这些语言）。留空表示“全部”。\n# languages = [\"python\", \"bash\", \"javascript\", \"typescript\", \"ruby\", \"perl\", \"go\"]\n\n# 优雅降级（挂钩默认为故障开放）。\nfallback_on_parse_error = true\nfallback_on_timeout = true\n```\n\nCLI 对 here-doc 扫描的覆盖选项：\n\n- `--heredoc-scan` \u002F `--no-heredoc-scan`\n- `--heredoc-timeout \u003Cms>`\n- `--heredoc-languages \u003Clang1,lang2,...>`\n\nHeredoc 文档：\n\n- `docs\u002Fadr-001-heredoc-scanning.md`（架构与设计原理）\n- `docs\u002Fpatterns.md`（模式编写 + 模式库）\n- `docs\u002Fsecurity.md`（威胁模型与事件响应）\n\n#### Heredoc 三层架构\n\nHeredoc 和内联脚本扫描采用一种专为性能和准确性设计的三层流水线：\n\n```\n命令输入\n     │\n     ▼\n┌─────────────────┐\n│ 第一层：触发器 │ ─── 不匹配 ──► 允许（快速路径，\u003C100μs）\n│   （RegexSet）    │\n└────────┬────────┘\n         │ 匹配\n         ▼\n┌─────────────────┐\n│ 第二层：提取    │ ─── 错误\u002F超时 ──► 允许 + 回退检查\n│   (\u003C1ms)        │\n└────────┬────────┘\n         │ 成功\n         ▼\n┌─────────────────┐\n│ 第三层：AST     │ ─── 不匹配 ──► 允许\n│   (\u003C5ms)        │ ─── 匹配 ──► 阻止\n└─────────────────┘\n```\n\n**第一层：触发检测** (\u003C100μs)\n\n超快速正则表达式筛选，用于检测 heredoc 标志。使用编译后的 `RegexSet` 对所有触发模式进行 O(n) 同时匹配：\n\n```rust\nstatic HEREDOC_TRIGGERS: LazyLock\u003CRegexSet> = LazyLock::new(|| {\n    RegexSet::new([\n        r\"\u003C\u003C-?\\s*(?:['\\x22][^'\\x22]*['\\x22]|[\\w.-]+)\",  \u002F\u002F Heredocs\n        r\"\u003C\u003C\u003C\",                                          \u002F\u002F Here-strings\n        r\"\\bpython[0-9.]*\\b.*\\s+-[A-Za-z]*[ce]\",        \u002F\u002F python -c\u002F-e\n        r\"\\bruby[0-9.]*\\b.*\\s+-[A-Za-z]*e\",             \u002F\u002F ruby -e\n        r\"\\bnode(js)?[0-9.]*\\b.*\\s+-[A-Za-z]*[ep]\",     \u002F\u002F node -e\u002F-p\n        r\"\\b(sh|bash|zsh)\\b.*\\s+-[A-Za-z]*c\",           \u002F\u002F bash -c\n        \u002F\u002F ... 更多模式\n    ])\n});\n```\n\n不包含任何触发模式的命令会直接进入允许状态——无需进一步处理。\n\n**第二层：内容提取** (\u003C1ms)\n\n对于触发了检测的命令，提取实际需要评估的内容：\n\n- **Heredocs**：`cat \u003C\u003CEOF ... EOF` → 提取分隔符之间的主体内容\n- **Here-strings**：`cat \u003C\u003C\u003C \"content\"` → 提取引号内的内容\n- **内联脚本**：`python -c \"code\"` → 提取代码参数\n\n提取过程受可配置限制约束：\n- 最大主体大小（默认：1MB）\n- 最大行数（默认：10,000）\n- 每个命令的最大 heredoc 数量（默认：10）\n- 超时时间（默认：50ms）\n\n```rust\npub struct ExtractionLimits {\n    pub max_body_bytes: usize,\n    pub max_body_lines: usize,\n    pub max_heredocs: usize,\n    pub timeout_ms: u64,\n}\n```\n\n**第三层：AST 模式匹配** (\u003C5ms)\n\n提取的内容使用语言特定的 AST 语法树解析器（通过 tree-sitter\u002Fast-grep）进行解析，并与结构化模式进行匹配：\n\n```rust\n\u002F\u002F 示例：检测 subprocess.run 且 shell=True 并执行 rm -rf\nlet pattern = r#\"\n    call_expression {\n        function: attribute { object: \"subprocess\" attr: \"run\" }\n        arguments: argument_list {\n            contains string { contains \"rm -rf\" }\n            contains keyword_argument { keyword: \"shell\" value: \"True\" }\n        }\n    }\n\"#;\n```\n\n**递归 Shell 分析**：\n\n当提取的内容本身是 Shell 脚本时（例如 `bash -c \"git reset --hard\"`），第三层会递归提取内部命令，并通过完整流水线重新评估它们：\n\n```rust\nif content.language == ScriptLanguage::Bash {\n    let inner_commands = extract_shell_commands(&content.content);\n    for inner in inner_commands {\n        \u002F\u002F 将内部命令再次与所有规则包进行评估\n        if let Some(result) = evaluate_command(&inner, ...) {\n            if result.decision == Deny {\n                return result; \u002F\u002F 阻止外部命令\n            }\n        }\n    }\n}\n```\n\n如果您遇到应被阻止的命令，请提交问题。\n\n### 环境变量\n\n环境变量优先级高于配置文件（最高优先级）：\n\n- `DCG_PACKS=\"containers.docker,kubernetes\"`：启用规则包（逗号分隔）\n- `DCG_DISABLE=\"kubernetes.helm\"`：禁用规则包\u002F子包（逗号分隔）\n- `DCG_VERBOSE=0-3`：日志详细程度（0 = 静默，3 = 跟踪）\n- `DCG_QUIET=1`：抑制非错误输出\n- `DCG_COLOR=auto|always|never`：颜色模式\n- `DCG_NO_COLOR=1`：禁用彩色输出（等同于 NO_COLOR）\n- `DCG_HIGH_CONTRAST=1`：启用高对比度输出（ASCII 边框 + 单色调色板）\n- `DCG_FORMAT=text|json|sarif`：默认输出格式（命令级别；SARIF 适用于 `dcg scan`）\n- `DCG_BYPASS=1`：完全绕过 dcg（逃生开关；谨慎使用）\n- `DCG_CONFIG=\u002Fpath\u002Fto\u002Fconfig.toml`：使用显式配置文件\n- `DCG_HEREDOC_ENABLED=true|false`：启用\u002F禁用 heredoc 扫描\n- `DCG_HEREDOC_TIMEOUT=50`：heredoc 提取超时时间（毫秒）\n- `DCG_HEREDOC_TIMEOUT_MS=50`：heredoc 提取超时时间（毫秒）\n- `DCG_HEREDOC_LANGUAGES=python,bash`：过滤 heredoc 使用的语言\n- `DCG_POLICY_DEFAULT_MODE=deny|warn|log`：全局默认决策模式\n- `DCG_HOOK_TIMEOUT_MS=200`：挂钩评估超时预算（毫秒）\n\n### 配置层级\n\ndcg 支持来自多个来源的分层配置，高优先级来源会覆盖低优先级来源：\n\n1. 环境变量（DCG_* 前缀）           [最高优先级]\n2. 显式配置文件（DCG_CONFIG 环境变量）\n3. 项目配置（仓库根目录下的 .dcg.toml）\n4. 用户配置（~\u002F.config\u002Fdcg\u002Fconfig.toml）\n5. 系统配置（\u002Fetc\u002Fdcg\u002Fconfig.toml）\n6. 编译默认值                              [最低优先级]\n\n### 无障碍与主题\n\ndcg 支持色盲友好配色方案和高对比度输出。颜色始终与符号\u002F标签搭配使用，以避免仅通过颜色传达含义。\n\n```toml\n[output]\nhigh_contrast = true       # ASCII 边框 + 黑白配色方案\n\n[theme]\npalette = \"colorblind\"     # 默认 | 色盲友好 | 高对比度\nuse_unicode = true         # false 表示仅使用 ASCII 字符\nuse_color = true           # false 表示单色输出\n```\n\n**配置文件位置**：\n\n| 层级 | 路径 | 使用场景 |\n|-------|------|----------|\n| 系统 | `\u002Fetc\u002Fdcg\u002Fconfig.toml` | 组织范围的默认设置 |\n| 用户 | `~\u002F.config\u002Fdcg\u002Fconfig.toml` | 个人偏好 |\n| 项目 | `.dcg.toml`（仓库根目录） | 项目特定设置 |\n| 显式指定 | `DCG_CONFIG=\u002Fpath\u002Fto\u002Ffile` | 测试或覆盖 |\n\n**合并行为**：\n\n配置层按优先级逐层叠加，高优先级来源会覆盖低优先级中的特定字段：\n\n```rust\n\u002F\u002F 只有高优先级配置中显式设置的字段才会覆盖\n\u002F\u002F 缺失的字段将保留来自低优先级源的值\nfn merge_layer(&mut self, other: ConfigLayer) {\n    if let Some(verbose) = other.general.verbose {\n        self.general.verbose = verbose;  \u002F\u002F 如果存在则覆盖\n    }\n    \u002F\u002F 未设置的字段将保留之前的值\n}\n```\n\n这意味着你可以在 `\u002Fetc\u002Fdcg\u002Fconfig.toml` 中设置组织默认值，在 `~\u002F.config\u002Fdcg\u002Fconfig.toml` 中设置个人偏好，并在 `.dcg.toml` 中为项目设置特定覆盖——每一层只需指定与默认不同的设置即可。\n\n**项目特定包配置**：\n\n`[projects]` 部分允许为不同仓库配置不同的包集合：\n\n```toml\n[projects.\"\u002Fhome\u002Fuser\u002Fwork\u002Fproduction-api\"]\npacks = { enabled = [\"database.postgresql\", \"cloud.aws\"], disabled = [] }\n\n[projects.\"\u002Fhome\u002Fuser\u002Fpersonal\u002Fexperiments\"]\npacks = { enabled = [], disabled = [\"core.git\"] }  # 更宽松的实验环境\n```\n\n### 宕机开放理念\n\ndcg 采用 **宕机开放** 的设计理念：当工具因超时、解析错误或资源限制而无法安全分析命令时，它会允许命令继续执行，而不是阻止命令并中断用户的流程。\n\n**为什么是宕机开放？**\n\n1. **流程连续性**：被阻塞的合法命令比漏掉的危险命令更具破坏性。\n2. **性能保障**：钩子绝不能成为瓶颈。\n3. **优雅降级**：部分分析总比完全不分析好。\n\n**宕机开放场景**：\n\n| 场景 | 行为 | 理由 |\n|----------|----------|-----------|\n| Heredoc 解析错误 | 允许执行 + 警告 | 格式错误的输入不应阻断工作 |\n| 提取超时 | 允许执行 + 警告 | 慢速输入不应卡住终端 |\n| 文件大小超出限制 | 允许执行 + 回退检查 | 大文件只进行简化分析 |\n| 正则引擎超时 | 允许执行 + 警告 | 极端模式不应阻塞 |\n| AST 匹配错误 | 跳过该 Heredoc | 继续评估其他内容 |\n| 截止时间超时 | 立即允许执行 | 硬性上限防止处理失控 |\n\n**可配置的严格程度**：\n\n对于高安全性环境，可以禁用宕机开放模式：\n\n```toml\n[heredoc]\nfallback_on_parse_error = false  # 解析错误时阻断\nfallback_on_timeout = false      # 超时时阻断\n```\n\n启用严格模式后，dcg 将在分析失败时阻断命令，并提供详细的错误信息说明原因。\n\n**回退模式检查**：\n\n即使跳过了完整分析，dcg 仍会针对关键的破坏性模式执行轻量级回退检查：\n\n```rust\nstatic FALLBACK_PATTERNS: LazyLock\u003CRegexSet> = LazyLock::new(|| {\n    RegexSet::new([\n        r\"shutil\\.rmtree\",\n        r\"os\\.remove\",\n        r\"fs\\.rmSync\",\n        r\"\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*f\",\n        r\"\\bgit\\s+reset\\s+--hard\\b\",\n        \u002F\u002F ... 其他关键模式\n    ])\n});\n```\n\n这确保了即使是过大或格式错误的输入，在被允许执行之前，也会被检查是否存在最危险的操作。\n\n**绝对超时机制**：\n\n为防止任何单个命令无限期阻塞，dcg 强制执行 **200ms** 的绝对最大处理时间。超过此阈值的命令将立即被允许执行，并记录警告日志。\n\n## 安装\n\n### 快速安装（推荐）\n\n最简单的安装方式是使用安装脚本，它会为您的平台下载预编译的二进制文件：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --easy-mode\n```\n\n简易模式会自动检测您的平台、下载正确的二进制文件、验证 SHA256 校验和、配置所有支持的 AI 代理钩子（Claude Code、Gemini CLI、Copilot CLI、Aider、Codex CLI），并更新您的 PATH。\n\n**其他选项：**\n\n交互式模式（每一步都会提示）：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash\n```\n\n安装特定版本：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --version v0.1.0\n```\n\n安装到 \u002Fusr\u002Flocal\u002Fbin（系统范围，需要 sudo）：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | sudo bash -s -- --system\n```\n\n从源码构建而不是下载二进制文件：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --from-source\n```\n\n仅下载\u002F安装（跳过代理钩子配置）：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --no-configure\n```\n\n> **注意：** 如果您已安装 [gum](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fgum)，安装程序将使用它来进行精美的终端格式化。\n\n安装程序还会在可用时验证 Sigstore cosign 包（如果不可用则回退到仅校验和验证），如果没有预编译的二进制文件，则回退到从源码构建，并在存在时移除旧版 Python 前身（`git_safety_guard.py`）。\n\n\u003Cdetails>\n\u003Csummary>各代理特有说明\u003C\u002Fsummary>\n\n- **Aider：** 不提供 PreToolUse 风格的拦截功能。安装程序会在 `~\u002F.aider.conf.yml` 中启用 `git-commit-verify: true`，以便运行 Git 钩子。要获得全面保护，请将 dcg 安装为 [Git pre-commit 钩子](docs\u002Fscan-precommit-guide.md)。\n- **Continue：** 没有拦截 Shell 命令的钩子。安装程序可以检测到 Continue，但无法自动配置保护。请改用 [Git pre-commit 钩子](docs\u002Fscan-precommit-guide.md)。\n- **Codex CLI：** 实验性 PreToolUse 钩子通过 `~\u002F.codex\u002Fhooks.json` 实现。其数据格式与 Claude Code 兼容。需要注意的是，该模型可以将脚本写入磁盘以绕过基于钩子的阻止机制。\n- **GitHub Copilot CLI：** 钩子是仓库本地的（`.github\u002Fhooks\u002F*.json`）。请在您希望获得保护的每个仓库中运行安装程序。\n- **OpenCode：** 不会自动配置。需要一个基于 Bun 的插件，其中包含 `\"tool.execute.before\"` 钩子键。一个可用的社区插件：[aspiers\u002Fai-config\u002Fdcg-guard.js](https:\u002F\u002Fgithub.com\u002Faspiers\u002Fai-config\u002Fblob\u002Fmain\u002F.config\u002Fopencode\u002Fplugins\u002Fdcg-guard.js)。\n\n\u003C\u002Fdetails>\n\n> **推荐：** 安装后，请运行 `dcg setup` 来添加一个 [Shell 启动检查](#hook-silently-removed-recommended-add-shell-startup-check)，它会在 dcg 钩子被悄无声息地从 `~\u002F.claude\u002Fsettings.json` 中移除时向您发出警告。\n\n### 从源码构建（需要 Rust nightly）\n\n该项目使用了 Rust 2024 版本的特性，因此需要 nightly 工具链。仓库中包含一个 `rust-toolchain.toml` 文件，可自动选择正确的工具链。\n\n```bash\n# 如果您还没有 Rust nightly，请安装\nrustup install nightly\n\n# 直接从 GitHub 安装（由于工作区结构，需要指定包名）\ncargo +nightly install --git https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard destructive_command_guard\n```\n\n### 手动构建\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\ncd destructive_command_guard\n# rust-toolchain.toml 会自动选择 nightly\ncargo build --release\ncp target\u002Frelease\u002Fdcg ~\u002F.local\u002Fbin\u002F\n```\n\n## 更新\n\n运行内置的更新程序以重新为您的平台运行安装程序：\n\n```bash\ndcg update\n```\n\n可选标志与安装脚本相同（示例）：\n\n```bash\ndcg update --version v0.2.7\ndcg update --system\ndcg update --verify\n```\n\n如果您更喜欢，也可以直接重新运行 `install.sh` 或 `install.ps1`。\n\n### 预编译二进制文件\n\n预编译的二进制文件适用于以下平台：\n- Linux x86_64 (`x86_64-unknown-linux-gnu`)\n- Linux ARM64 (`aarch64-unknown-linux-gnu`)\n- macOS Intel (`x86_64-apple-darwin`)\n- macOS Apple Silicon (`aarch64-apple-darwin`)\n- Windows (`x86_64-pc-windows-msvc`)\n\n请从 [GitHub Releases](https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Freleases) 下载，并验证 SHA256 校验和。如果您已安装 cosign，每个发布还包含一个 Sigstore 包（`.sigstore.json`），您可以使用 `cosign verify-blob` 来验证来源。\n\n## 卸载\n\n移除 dcg 及其在各 AI 代理中的所有钩子：\n\n```bash\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Funinstall.sh | bash\n```\n\n卸载程序会：\n- 从 Claude Code、Gemini CLI、GitHub Copilot CLI（仓库本地）和 Aider 中移除 dcg 钩子\n- 移除 dcg 二进制文件\n- 移除配置文件（`~\u002F.config\u002Fdcg\u002F`）和历史记录（`~\u002F.local\u002Fshare\u002Fdcg\u002F`）\n- 在进行更改前提示确认\n\n选项：\n- `--yes` - 跳过确认提示\n- `--keep-config` - 保留配置文件\n- `--keep-history` - 保留历史数据库\n- `--purge` - 删除所有内容（覆盖保留选项）\n\n## Claude Code 配置\n\n在 `~\u002F.claude\u002Fsettings.json` 中添加以下内容：\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"dcg\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n**重要提示：** 添加钩子配置后，请重启 Claude Code。\n\n## Gemini CLI 配置\n\n在 `~\u002F.gemini\u002Fsettings.json` 中添加以下内容：\n\n```json\n{\n  \"hooks\": {\n    \"BeforeTool\": [\n      {\n        \"matcher\": \"run_shell_command\",\n        \"hooks\": [\n          {\n            \"name\": \"dcg\",\n            \"type\": \"command\",\n            \"command\": \"dcg\",\n            \"timeout\": 5000\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n**重要提示：** 添加钩子配置后，请重启 Gemini CLI。\n\n## CLI 使用方法\n\n虽然主要设计为钩子，但该二进制文件也支持直接调用，用于测试、调试以及了解命令为何被阻止或允许。\n\n```bash\n# 显示版本及构建元数据\ndcg --version\n\n# 显示帮助信息及被阻止的命令类别\ndcg --help\n\n# 手动测试命令（将 JSON 通过管道输入到标准输入）\necho '{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git reset --hard\"}}' | dcg\n```\n\n### 测试模式 (`dcg test`)\n\n使用 `dcg test` 可以评估命令 **而不实际执行**。这对于 CI 检查、误报调试以及上线前的配置验证非常有用。\n\n#### 基本用法\n\n```bash\n# 基本评估（人类可读的输出）\ndcg test \"rm -rf .\u002Fbuild\"\n\n# 面向自动化的结构化输出\ndcg test --format json \"kubectl delete namespace prod\" | jq -r .decision\n\n# 使用特定的配置文件\ndcg test --config .dcg.prod.toml \"docker system prune\"\n\n# 仅在此测试运行中临时启用额外的包\ndcg test --with-packs containers.docker,database.postgresql \"docker system prune\"\n\n# 打印完整的评估轨迹（与 `dcg explain` 使用相同的引擎）\ndcg test --explain \"git reset --hard\"\n```\n\n#### 退出码\n\n- `0`: 命令将被允许\n- `1`: 命令将被阻止\n\n#### 标志和选项\n\n- `-c, --config \u003CPATH>`: 使用特定的配置文件\n- `--with-packs \u003CID1,ID2>`: 临时启用额外的包\n- `--explain`: 打印详细的决策轨迹\n- `-f, --format \u003Cpretty|json|toon>`: 输出格式（默认：`pretty`）\n- `--no-color`: 禁用 ANSI 颜色输出\n- `--heredoc-scan`: 强制启用 heredoc\u002F内联脚本扫描\n- `--no-heredoc-scan`: 强制禁用 heredoc\u002F内联脚本扫描\n- `--heredoc-timeout \u003CMS>`: 覆盖 heredoc 提取超时预算\n- `--heredoc-languages \u003CLANG1,LANG2>`: 限制 heredoc AST 扫描的语言\n\n#### 输出格式\n\n- `pretty`: 人类可读的输出，包含命令上下文、匹配规则信息和建议\n- `json`: 用于脚本\u002FCI 的结构化负载；包括元数据，如 `schema_version`、`dcg_version`、`command`、`decision`、规则\u002F包字段，以及在存在时的白名单\u002F代理上下文\n- `toon`: 与 `json` 相同负载的令牌高效结构化编码（适用于代理间\u002F工具流水线）\n\n#### CI\u002FCD 集成示例\n\n在 Shell 流水线中快速失败：\n\n```bash\ndcg test --format json \"rm -rf \u002F\" > \u002Ftmp\u002Fdcg.json\njq -e '.decision == \"allow\"' \u002Ftmp\u002Fdcg.json\n```\n\nGitHub Actions 的最小步骤：\n\n```yaml\n- name: 验证危险命令策略\n  run: |\n    ~\u002F.local\u002Fbin\u002Fdcg test --format json \"git reset --hard HEAD~1\" > \u002Ftmp\u002Fdcg-test.json\n    jq -e '.decision == \"allow\"' \u002Ftmp\u002Fdcg-test.json\n```\n\n#### 故障排除\n\n- 使用 `--format json`（或 `DCG_FORMAT=json`）以便机器解析。\n- 如果日志或解析器因 ANSI 输出而卡住，请添加 `--no-color`。\n- 如果不同环境的结果不一致，请检查配置优先级（`DCG_CONFIG`、项目 `.dcg.toml`、用户\u002F系统配置）。\n- 如果命令意外被允许，请检查当前生效的白名单（`dcg allowlist list`）和已启用的包（`dcg packs --verbose`）。\n- 若要获取完整的决策轨迹，请运行 `dcg test --explain \"\u003Ccommand>\"`（或 `dcg explain \"\u003Ccommand>\"`）。\n\n### 解释模式\n\n当您需要确切了解为何某条命令被阻止（或允许）时，`dcg explain` 命令会提供详细的决策过程跟踪：\n\n```bash\n# 解释为什么一条命令会被阻止\ndcg explain \"git reset --hard HEAD\"\n\n# 解释一条安全的命令\ndcg explain \"git status\"\n\n# 带有详细计时信息的解释\ndcg explain --verbose \"rm -rf \u002Ftmp\u002Fbuild\"\n\n# 以 JSON 格式输出，供程序使用\ndcg explain --format json \"kubectl delete namespace production\"\n```\n\nJSON 输出通过 `schema_version` 进行版本控制（当前为 2）。v2 在检测到模式时，在 `match` 对象中增加了 `matched_span`、`matched_text_preview` 和 `explanation`。\n\n**示例输出**：\n\n```\n命令: git reset --hard HEAD\n规范化: git reset --hard HEAD\n\n决定: 被阻止\n  包: core.git\n  规则: reset-hard\n  原因: git reset --hard 会破坏未提交的更改\n\n评估轨迹：\n  [  0.8μs] 快速拒绝：通过（包含 'git'）\n  [  2.1μs] 规范化：无变化\n  [  5.3μs] 安全模式：未匹配（检查了 34 种模式）\n  [ 12.7μs] 破坏性模式：匹配模式 'reset-hard'\n  [ 12.9μs] 总耗时：12.9μs\n\n建议：请先使用 'git stash' 保存您的更改。\n```\n\n解释模式会显示：\n- **规范化后的命令**：dcg 在路径规范化后如何看待该命令\n- **决定**：该命令是会被阻止还是允许\n- **匹配的规则**：触发该决定的是哪个包和模式\n- **评估轨迹**：每个评估阶段的逐步计时\n- **建议**：关于更安全替代方案的可操作指导\n\n这对于调试误报、理解包的覆盖范围以及验证自定义白名单条目是否按预期工作非常有用。\n\n### 一次性允许（临时例外）\n\n有时您需要临时执行一条被阻止的命令，而无需永久修改白名单。一次性允许系统提供了短代码：\n\n```bash\n# 当一条命令被阻止时，dcg 会输出一个短代码\n# 被阻止：git reset --hard HEAD\n# 一次性允许代码：ab12\n# 要允许此命令：dcg allow-once ab12\n\n# 使用短代码创建临时例外\ndcg allow-once ab12\n\n# 或者使用 --single-use 使例外成为一次性的\ndcg allow-once ab12 --single-use\n```\n\n**一次性允许的工作原理**：\n\n1. 当 dcg 阻止一条命令时，它会生成一个短代码（目前为 4 个十六进制字符；冲突可通过 `--pick` \u002F `--hash` 处理）\n2. 该代码与被阻止的精确命令相关联\n3. 运行 `dcg allow-once \u003Ccode>` 会创建一个临时例外\n4. 例外存储在 `~\u002F.config\u002Fdcg\u002Fpending_exceptions.jsonl` 中\n5. 例外在 24 小时后过期（或如果使用了 `--single-use`，则在首次使用后过期）\n6. 在有效期内，该例外允许在同一目录范围内执行相同的命令。\n\n此工作流程适用于：\n- 一次性且有意破坏性的管理操作\n- 需要重置状态的迁移脚本\n- 不适合进行永久性白名单更改的紧急修复\n\n**安全注意事项**：\n- 短代码由 SHA256（或在设置 `DCG_ALLOW_ONCE_SECRET` 时使用 HMAC-SHA256）生成\n- 代码绝不会被记录或传输\n- 待处理例外文件仅对当前用户可读\n- 过期的代码会自动清理。\n\n`--version` 输出包含用于调试的构建元数据：\n\n```\ndcg 0.1.0\n  构建日期：2026-01-07T22:13:10.413872881Z\n  Rustc 版本：1.94.0-nightly\n  目标平台：x86_64-unknown-linux-gnu\n```\n\n这些元数据在编译时通过 [vergen](https:\u002F\u002Fgithub.com\u002Frustyhorde\u002Fvergen) 嵌入，便于在故障排除时准确识别正在运行的构建版本。\n\n## 仓库扫描\n\n虽然挂钩保护的是**交互式**命令执行，但团队还需要防止那些被**提交到仓库中**的破坏性命令。`dcg scan` 命令可以从文件中提取可执行的命令上下文，并使用相同的模式引擎对其进行评估。\n\n### 扫描是什么（以及不是什么）\n\n**它是：**\n- 基于提取器的扫描器，能够理解可执行上下文\n- 使用与挂钩模式相同的评估器，以确保一致性\n- 支持 CI 集成和预提交钩子\n\n**它不是：**\n- 一种在任何地方简单匹配字符串的 grep 工具\n- 代码审查的替代品\n- 用于任意语言的静态分析工具\n\n与 grep 的关键区别在于：`dcg scan` 知道注释中的 `\"rm -rf \u002F\"` 是数据，而不是代码。它使用能够理解文件结构的提取器（Shell 脚本、Dockerfile、GitHub Actions、Makefile），只查找实际被执行的命令。\n\n### 支持的文件格式\n\ndcg scan 为每种文件格式配备了专门的提取器，能够识别哪些部分包含可执行命令：\n\n| 文件类型 | 检测模式 | 可执行上下文 |\n|-----------|-----------|---------------------|\n| **Shell 脚本** | `*.sh`、`*.bash`、`*.zsh` | 所有非注释、非赋值的行 |\n| **Dockerfile** | `Dockerfile`、`*.dockerfile` | `RUN` 指令（shell 和 exec 形式） |\n| **GitHub Actions** | `.github\u002Fworkflows\u002F*.yml` | 步骤中的 `run:` 字段 |\n| **GitLab CI** | `.gitlab-ci.yml` | `script:`、`before_script:`、`after_script:` |\n| **Makefile** | `Makefile` | 以制表符缩进的配方行 |\n| **Terraform** | `*.tf` | `provisioner` 块（`local-exec`、`remote-exec`） |\n| **Docker Compose** | `docker-compose.yml`、`compose.yml` | `command:` 和 `entrypoint:` 字段 |\n\n**上下文感知提取**：\n\n每个提取器都理解其对应格式的语义：\n\n```yaml\n# GitHub Actions - 仅提取 'run:'\n- name: Build\n  run: |                    # ← 提取\n    npm install\n    npm run build\n  env:\n    NODE_ENV: production    # ← 跳过（非可执行）\n```\n\n```dockerfile\n# Dockerfile - 仅提取 RUN 指令\nFROM node:18\nCOPY . \u002Fapp                 # ← 跳过\nRUN npm install             # ← 提取\nRUN [\"node\", \"server.js\"]   # ← 提取（exec 形式）\nENV PORT=3000               # ← 跳过\n```\n\n```makefile\n# Makefile - 目标下的制表符缩进行\nbuild:\n\tnpm install             # ← 提取（配方行）\n\tnpm run build           # ← 提取\nSOURCES = $(wildcard *.js)  # ← 跳过（变量赋值）\n```\n\n**非可执行上下文过滤**：\n\n提取器会智能地跳过仅用于数据的部分：\n\n- **Shell**：仅赋值的行（`export VAR=value`）\n- **YAML**：`environment:`、`labels:`、`volumes:`、`variables:` 块\n- **Terraform**：所有不在 `provisioner` 块内的内容\n- **所有格式**：注释（根据格式使用 `#`、`\u002F\u002F` 等）\n\n### 快速入门\n\n```bash\n# 安装 pre-commit 钩子\ndcg scan install-pre-commit\n\n# 或手动对暂存文件运行\ndcg scan --staged\n\n# 扫描特定路径\ndcg scan --paths scripts\u002F .github\u002Fworkflows\u002F\n```\n\n### 推荐部署计划\n\n**从保守开始，避免开发者抵触**：\n\n```bash\n# 第 1–2 周：先警告，范围较小\ndcg scan --staged --fail-on error  # 仅在严重规则时失败\n```\n\n创建 `.dcg\u002Fhooks.toml` 文件，设置保守默认值：\n\n```toml\n[scan]\nfail_on = \"error\"          # 仅在高置信度的严重规则时失败\nformat = \"pretty\"          # 人类可读的输出\nredact = \"quoted\"          # 隐藏敏感字符串\ntruncate = 120             # 缩短过长命令\n\n[scan.paths]\ninclude = [\n    \".github\u002Fworkflows\u002F**\",  # 从 CI 配置开始\n    \"Dockerfile\",            # 容器构建\n    \"Makefile\",              # 构建脚本\n]\nexclude = [\n    \"target\u002F**\",\n    \"node_modules\u002F**\",\n    \"vendor\u002F**\",\n]\n```\n\n**逐步扩展**：\n\n1. **第 1–2 周**：仅扫描工作流和 Dockerfile，设置 `--fail-on error`\n2. **第 3–4 周**：添加 Makefile 和 `scripts\u002F` 中的 Shell 脚本\n3. **第 2 个月**：审查结果后启用 `--fail-on warning`\n4. **持续进行**：随着团队信心增强，逐步添加新的提取器\n\n### Pre-commit 集成\n\n#### 一键安装\n\n```bash\ndcg scan install-pre-commit\n```\n\n这将创建一个 `.git\u002Fhooks\u002Fpre-commit` 文件，自动运行 `dcg scan --staged`。\n\n#### 手动设置\n\n如果您更倾向于手动控制或使用钩子管理工具：\n\n```bash\n#!\u002Fbin\u002Fbash\n# .git\u002Fhooks\u002Fpre-commit（或您使用的钩子管理工具的等效位置）\n\nset -e\n\n# 对暂存文件运行 dcg scan\ndcg scan --staged --fail-on error\n\n# 在下方添加其他钩子...\n```\n\n#### 卸载\n\n```bash\ndcg scan uninstall-pre-commit\n```\n\n此命令仅移除由 dcg 安装的钩子（通过哨兵注释检测）。\n\n### 结果解读\n\n输出示例如下：\n\n```\nscripts\u002Fdeploy.sh:42:5: [ERROR] core.git:reset-hard\n  命令：git reset --hard HEAD\n  原因：git reset --hard 会丢弃未提交的更改\n  建议：建议先使用 'git stash' 保存更改。\n```\n\n- **文件:行:列**：源文件中的位置\n- **严重程度**：`ERROR`（严重）或 `WARNING`（需关注）\n- **规则 ID**：稳定的标识符，如 `core.git:reset-hard`\n- **命令**：提取的命令（可能被遮蔽或截断）\n- **原因**：为何该命令被标记\n- **建议**：如何使其更安全\n\n### 修复发现的问题\n\n#### 选项 1：修改代码（推荐）\n\n用更安全的替代方案替换危险命令：\n\n```bash\n# 替换：\ngit reset --hard\n\n# 使用：\ngit stash push -m \"before reset\"\ngit reset --hard\n```\n\n#### 选项 2：获取解释\n\n获取详细分析：\n\n```bash\ndcg explain \"git reset --hard HEAD\"\n```\n\n#### 选项 3：白名单（当确属有意时）\n\n如果确实需要该命令：\n\n```bash\n# 项目级白名单（已提交并经过代码评审）\ndcg allowlist add core.git:reset-hard --reason \"用于 CI 清理\" --project\n\n# 或针对特定命令\ndcg allowlist add-command \"rm -rf .\u002Fbuild\" --reason \"构建清理\" --project\n```\n\n结果输出中会附带方便复制粘贴的白名单命令。Heredoc 规则使用稳定 ID，如 `heredoc.python.shutil_rmtree`。\n\n### 隐私与脱敏处理\n\n扫描支持对输出中潜在敏感内容进行脱敏处理。使用 `--redact quoted` 可隐藏可能包含密钥的引号字符串：\n\n```\n# 原始命令：\ncurl -H \"Authorization: Bearer $TOKEN\" https:\u002F\u002Fapi.example.com\n\n# 使用 --redact quoted 后：\ncurl -H \"...\" https:\u002F\u002Fapi.example.com\n```\n\n选项：\n- `--redact none`：显示完整命令（默认）\n- `--redact quoted`：隐藏引号中的内容（推荐用于 CI 日志）\n- `--redact aggressive`：隐藏更多潜在机密\n\n### 配置参考\n\n`.dcg\u002Fhooks.toml`（项目级，需提交）：\n\n```toml\n[scan]\n# 当发现的问题达到此阈值时退出非零状态\nfail_on = \"error\"      # 选项：none、warning、error\n\n# 输出格式\nformat = \"pretty\"      # 选项：pretty、json、markdown\n\n# 最大扫描文件大小（字节）\nmax_file_size = 1000000\n\n# 发现问题数量达到此上限后停止扫描\nmax_findings = 50\n\n# 敏感内容的脱敏级别\nredact = \"quoted\"      # 选项：none、quoted、aggressive\n\n# 截断过长命令（字符数；0 表示不截断）\ntruncate = 120\n\n[scan.paths]\n# 仅扫描匹配这些模式的文件\ninclude = [\n    \"scripts\u002F**\",\n    \".github\u002Fworkflows\u002F**\",\n    \"Dockerfile*\",\n    \"Makefile\",\n]\n\n# 跳过匹配这些模式的文件\nexclude = [\n    \"target\u002F**\",\n    \"node_modules\u002F**\",\n    \"*.md\",\n]\n```\n\nCLI 标志会覆盖配置文件中的值。\n\n### CI 集成\n\n#### GitHub Actions\n\n```yaml\nname: 安全扫描\non: [pull_request]\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n        with:\n          fetch-depth: 0\n\n      - name: 安装 dcg\n        run: |\n          curl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh\" | bash\n          echo \"$HOME\u002F.local\u002Fbin\" >> $GITHUB_PATH\n\n      - name: 扫描已更改文件\n        run: |\n          dcg scan --git-diff origin\u002F${{ github.base_ref }}..HEAD \\\n            --format markdown \\\n            --fail-on error\n```\n\n#### GitLab CI\n\n```yaml\nscan:\n  stage: test\n  script:\n    - curl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh\" | bash\n    - ~\u002F.local\u002Fbin\u002Fdcg scan --git-diff origin\u002F$CI_MERGE_REQUEST_TARGET_BRANCH_NAME..HEAD --fail-on error\n  rules:\n    - if: $CI_MERGE_REQUEST_ID\n```\n\n### 紧急情况下的绕过\n\n如果您需要临时绕过 pre-commit 钩子：\n\n```bash\ngit commit --no-verify -m \"紧急修复\"\n```\n\n这会在 git 历史中被记录并可见。对于永久性的例外，建议使用白名单。\n\n## 工作原理\n\n您的 AI 代理在执行每个 shell 命令之前，会作为 PreToolUse 钩子调用 dcg。该钩子从标准输入接收命令的 JSON 数据，并通过一个四阶段的流程进行处理：\n\n1. **JSON 解析** -- 验证钩子负载（Claude\u002FGemini\u002FCopilot 变体），提取命令字符串。非 shell 工具会被立即允许。\n2. **规范化** -- 去除绝对路径（`\u002Fusr\u002Fbin\u002Fgit` 变为 `git`），同时保留参数。\n3. **快速拒绝** -- 使用 O(n) 子字符串搜索查找如“git”或“rm”等关键字。不包含这些子字符串的命令将完全跳过正则表达式匹配（可处理 99% 以上的非破坏性命令）。\n4. **模式匹配** -- 首先检查安全模式（匹配即允许）。其次检查破坏性模式（匹配即拒绝，并给出解释）。两者均未匹配则允许。\n\n如果被阻止，dcg 会在标准输出上输出 JSON 拒绝信息，并在标准错误上显示彩色的人类可读警告。如果被允许，dcg 将静默退出（无输出）。当标准错误不是 TTY 时，颜色功能会自动禁用。\n\n## 架构\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│            Claude Code \u002F Gemini CLI \u002F Copilot CLI                │\n│                                                                  │\n│  用户: “删除构建产物”                                           │\n│  代理: 执行 `rm -rf .\u002Fbuild`                                   │\n│                                                                  │\n└─────────────────────┬───────────────────────────────────────────┘\n                      │\n                      ▼ PreToolUse 钩子（标准输入：JSON）\n┌─────────────────────────────────────────────────────────────────┐\n│                     dcg                             │\n│                                                                  │\n│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐       │\n│  │    解析     │───▶│  规范化   │───▶│ 快速拒绝 │       │\n│  │    JSON      │    │   命令    │    │   过滤   │       │\n│  └──────────────┘    └──────────────┘    └──────┬───────┘       │\n│                                                  │               │\n│                      ┌───────────────────────────┘               │\n│                      ▼                                           │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │                   模式匹配                        │   │\n│  │                                                           │   │\n│  │   1. 检查 SAFE_PATTERNS（白名单） ──▶ 匹配则允许  │   │\n│  │   2. 检查 DESTRUCTIVE_PATTERNS ──────▶ 匹配则拒绝    │   │\n│  │   3. 无匹配 ────────────────────────▶ 允许（默认）  │   │\n│  │                                                           │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                                                                  │\n└─────────────────────┬───────────────────────────────────────────┘\n                      │\n                      ▼ 标准输出：JSON（拒绝）或空（允许）\n┌─────────────────────────────────────────────────────────────────┐\n│            Claude Code \u002F Gemini CLI \u002F Copilot CLI                │\n│                                                                  │\n│  如果被拒绝：显示阻止消息，不会执行命令                       │\n│  如果被允许：继续执行命令                                    │\n│                                                                  │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### 上下文分类系统\n\n并非每次出现危险模式都真正具有危险性。字符串 `git reset --hard` 出现在注释、heredoc 文本块或引号内的情况，与它作为实际执行的命令完全不同。dcg 使用一套复杂的上下文分类系统来减少误报，同时不降低安全性。\n\n**SpanKind 分类**\n\n命令中的每个标记都会被归入以下类别之一：\n\n| SpanKind | 描述 | 处理方式 |\n|----------|-------------|-----------|\n| `Executed` | 命令词和未加引号的参数 | **必须检查** - 最高优先级 |\n| `InlineCode` | `-c`\u002F`-e` 标志内的内容（bash -c、python -c） | **必须检查** - 代码将被执行 |\n| `Argument` | 已知安全命令的带引号参数 | 优先级较低，视具体情况而定 |\n| `Data` | 单引号字符串（shell 无法进行变量替换） | **可以跳过** - 被视为字面数据 |\n| `HeredocBody` | heredoc 内部的内容 | 提升到第 2\u002F3 层的 heredoc 扫描 |\n| `Comment` | Shell 注释 (`# ...`) | **跳过** - 永远不会执行 |\n| `Unknown` | 无法确定上下文 | 保守地按 `Executed` 处理 |\n\n**为什么上下文很重要**\n\n考虑以下命令：\n\n```bash\n# 安全：危险模式出现在注释中\necho \"提醒：切勿运行 git reset --hard\"   # git reset --hard 会丢失更改\n\n# 安全：危险模式是用于搜索的数据\ngrep \"git reset --hard\" documentation.md\n\n# 安全：危险模式出现在写入文件的 heredoc 中\ncat \u003C\u003CEOF > safety_guide.md\n警告：git reset --hard 会丢失未提交的更改\nEOF\n\n# 危险：该模式将被执行\ngit reset --hard HEAD\n\n# 危险：该模式被传递给 bash -c 以执行\nbash -c \"git reset --hard\"\n```\n\n如果没有上下文分类，前三个示例都会触发误报。上下文分类器会分析 AST（抽象语法树）结构，以了解模式出现的位置，并仅标记真正危险的情况。\n\n**实现细节**\n\n上下文分类器采用多轮处理方法：\n\n1. **词法分析**：识别带引号的字符串、注释和 here document 标记\n2. **结构分析**：构建命令结构树，识别管道、子 shell 和命令替换\n3. **标志分析**：检测 `-c`、`-e` 等引入内联代码上下文的标志\n4. **范围标注**：为每个字符范围打上其 SpanKind 标签\n\n这种方法在保持对实际命令执行零假阴性原则的同时，显著减少了误报。\n\n## 设计原则\n\n### 1. 白名单优先架构\n\n安全模式会在破坏性模式之前进行检查。这种设计确保了明确安全的命令（如 `git checkout -b`）绝不会被意外阻止，即使它们部分匹配破坏性模式（如 `git checkout`）。\n\n```\ngit checkout -b feature    →  匹配 SAFE “checkout-new-branch”  →  允许\ngit checkout -- file.txt   →  没有安全匹配，匹配 DESTRUCTIVE  →  拒绝\n```\n\n### 2. 安全默认策略\n\n该钩子对未识别的命令采用**默认允许**策略。这确保：\n- 钩子绝不会中断合法的工作流程\n- 只有*已知*的危险模式会被阻止\n- 新的 git 命令在被明确分类之前都会被允许\n\n### 3. 零假阴性原则\n\n模式集合优先考虑**绝不允许危险命令**，而不是避免误报。偶尔多几次手动确认提示是可以接受的；而丢失工作则是不可接受的。\n\n### 4. 多层防御\n\n此钩子只是一层保护措施。它与以下内容相辅而行（而非替代）：\n- 定期提交和推送\n- 在执行风险操作前使用 Git stash\n- 合理的备份策略\n- 代码审查流程\n\n### 5. 最小化延迟\n\n所有 Bash 命令都会经过此钩子。性能至关重要：\n- 惰性初始化的静态正则表达式模式（编译一次，重复使用）\n- 快速拒绝过滤器可在正则表达式之前排除 99% 以上的命令\n- 对于安全命令，在关键路径上不进行堆分配\n- 对于典型命令，执行时间小于一毫秒\n\n## 模式匹配系统\n\n### 安全模式（白名单）\n\n安全模式列表包含 34 种模式，涵盖以下类别：\n\n| 类别         | 模式                     | 目的                           |\n|--------------|--------------------------|--------------------------------|\n| 分支创建     | `checkout -b`, `checkout --orphan` | 创建分支是安全的             |\n| 仅暂存       | `restore --staged`, `restore -S` | 取消暂存不会影响工作区       |\n| 干运行       | `clean -n`, `clean --dry-run` | 预览模式，不会实际删除文件    |\n| 临时清理     | `rm -rf \u002Ftmp\u002F*`, `rm -rf \u002Fvar\u002Ftmp\u002F*` | 临时目录是安全的             |\n| 变量扩展     | `rm -rf $TMPDIR\u002F*`, `rm -rf ${TMPDIR}\u002F*` | Shell 变量形式               |\n| 引用路径     | `rm -rf \"$TMPDIR\u002F*\"`      | 引用变量的形式               |\n| 分开的标志   | `rm -r -f \u002Ftmp\u002F*`, `rm -r -f $TMPDIR\u002F*` | 标志顺序的不同变体           |\n| 长选项       | `rm --recursive --force \u002Ftmp\u002F*`, `$TMPDIR\u002F*` | GNU 风格的长选项             |\n\n### 破坏性模式（黑名单）\n\n破坏性模式列表包含 16 种模式，涵盖以下类别：\n\n| 类别         | 模式                   | 原因                         |\n|--------------|------------------------|------------------------------|\n| 破坏工作区   | `reset --hard`, `reset --merge` | 销毁未提交的更改             |\n| 文件回滚     | `checkout -- \u003Cpath>`    | 丢弃文件修改                 |\n| 恢复工作区   | `restore`（无 --staged） | 丢弃未提交的更改             |\n| 删除未跟踪文件 | `clean -f`            | 永久删除未跟踪文件           |\n| 重写历史记录 | `push --force`, `push -f` | 可能会破坏远程提交           |\n| 不安全删除分支 | `branch -D`          | 强制删除而不检查合并         |\n| 销毁 Stash   | `stash drop`, `stash clear` | 永久删除暂存的工作           |\n| 文件系统清除 | `rm -rf`（非临时路径） | 递归删除临时目录之外的内容   |\n\n### 模式语法\n\n模式使用 [fancy-regex](https:\u002F\u002Fgithub.com\u002Ffancy-regex\u002Ffancy-regex) 来实现高级功能：\n\n```rust\n\u002F\u002F 负向前瞻：阻止 restore，除非存在 --staged\nr\"git\\s+restore\\s+(?!--staged\\b)(?!-S\\b)\"\n\n\u002F\u002F 负向前瞻：不匹配 --force-with-lease\nr\"git\\s+push\\s+.*--force(?![-a-z])\"\n\n\u002F\u002F 字符类：匹配任意标志顺序\nr\"rm\\s+-[a-zA-Z]*[rR][a-zA-Z]*f[a-zA-Z]*\"\n```\n\n## 处理的边缘情况\n\n### 路径规范化\n\n命令可能会使用二进制文件的绝对路径：\n\n```bash\n\u002Fusr\u002Fbin\u002Fgit reset --hard          # 被阻止 ✓\n\u002Fusr\u002Flocal\u002Fbin\u002Fgit checkout -- .   # 被阻止 ✓\n\u002Fbin\u002Frm -rf \u002Fhome\u002Fuser             # 被阻止 ✓\n```\n\n规范化器使用正则表达式来剥离路径，同时保留参数：\n\n```bash\ngit add \u002Fusr\u002Fbin\u002Fsomething         # “\u002Fusr\u002Fbin\u002Fsomething” 是参数，被保留\n```\n\n### 标志顺序变体\n\n`rm` 命令可以以多种方式接受标志：\n\n```bash\nrm -rf \u002Fpath          # 组合标志\nrm -fr \u002Fpath          # 顺序颠倒\nrm -r -f \u002Fpath        # 分开的标志\nrm -f -r \u002Fpath        # 分开且顺序颠倒\nrm --recursive --force \u002Fpath    # 长选项\nrm --force --recursive \u002Fpath    # 长选项，顺序颠倒\nrm -rf --no-preserve-root \u002F     # 额外的标志\n```\n\n所有变体都由灵活的正则表达式模式处理。\n\n### Shell 变量扩展\n\n临时目录变量有多种形式：\n\n```bash\nrm -rf $TMPDIR\u002Fbuild           # 未加引号，简单形式\nrm -rf ${TMPDIR}\u002Fbuild         # 未加引号，带大括号\nrm -rf \"$TMPDIR\u002Fbuild\"         # 加引号，简单形式\nrm -rf \"${TMPDIR}\u002Fbuild\"       # 加引号，带大括号\nrm -rf \"${TMPDIR:-\u002Ftmp}\u002Fbuild\" # 带默认值\n```\n\n### Git 标志组合\n\nGit 命令的标志可以出现在不同的位置：\n\n```bash\ngit push --force                  # 被阻止 ✓\ngit push origin main --force      # 被阻止 ✓\ngit push --force origin main      # 被阻止 ✓\ngit push -f                       # 被阻止 ✓\ngit push --force-with-lease       # 被允许 ✓（安全替代方案）\n```\n\n### 暂存与工作区恢复\n\nrestore 命令的安全性较为微妙：\n\n```bash\ngit restore --staged file.txt           # 被允许 ✓（仅取消暂存）\ngit restore -S file.txt                 # 被允许 ✓（短标志）\ngit restore file.txt                    # 被阻止（丢弃更改）\ngit restore --worktree file.txt         # 被阻止（明确指定工作区）\ngit restore --staged --worktree file    # 被阻止（包括工作区）\ngit restore -S -W file.txt              # 被阻止（包括工作区）\n```\n\n## 性能优化\n\n### 双正则引擎架构\n\ndcg 使用一种复杂的双引擎正则表达式系统，能够自动为每个模式选择最优的引擎。这既保证了性能，又提供了高级的模式匹配功能。\n\n**两种引擎**：\n\n| 引擎         | Crate          | 时间复杂度       | 特性                     | 使用场景               |\n|--------------|----------------|------------------|--------------------------|------------------------|\n| **线性引擎** | `regex`        | 保证 O(n)        | 基础正则、字符类、交替   | 约 85% 的模式           |\n| **回溯引擎** | `fancy_regex`  | 最坏情况 O(2^n)  | 前瞻、后瞻、反向引用     | 约 15% 的模式           |\n\n**自动引擎选择**：\n\n当一个模式被编译时，dcg 会分析它以决定使用哪种引擎：\n\n```rust\npub enum CompiledRegex {\n    Linear(regex::Regex),           \u002F\u002F 保证 O(n)，无前瞻\n    Backtracking(fancy_regex::Regex), \u002F\u002F 支持前瞻\u002F后瞻\n}\n\nimpl CompiledRegex {\n    pub fn new(pattern: &str) -> Result\u003CSelf, Error> {\n        \u002F\u002F 首先尝试线性引擎（更快、可预测）\n        if let Ok(re) = regex::Regex::new(pattern) {\n            return Ok(CompiledRegex::Linear(re));\n        }\n        \u002F\u002F 对于高级特性，则回退到回溯引擎\n        Ok(CompiledRegex::Backtracking(fancy_regex::Regex::new(pattern)?))\n    }\n}\n```\n\n**为什么这很重要**：\n\n1. **性能可预测性**：线性引擎保证 O(n) 的匹配时间，这对于每个命令都要运行的钩子来说至关重要。\n2. **功能完整性**：某些模式需要负向前瞻（例如，“匹配 `--force` 但不匹配 `--force-with-lease`”）。\n3. **自动优化**：模式作者无需考虑引擎选择——dcg 会自动选择最优方案。\n\n**引擎选择示例**：\n\n```rust\n\u002F\u002F 线性引擎（简单模式）\nr\"git\\s+reset\\s+--hard\"              \u002F\u002F 不需要高级特性\n\n\u002F\u002F 回溯引擎（负向前瞻）\nr\"git\\s+push\\s+.*--force(?![-a-z])\"  \u002F\u002F 不能后面跟 \"-with-lease\"\n\n\u002F\u002F 线性引擎（字符类）\nr\"rm\\s+-[a-zA-Z]*[rR][a-zA-Z]*f\"     \u002F\u002F 复杂但没有前瞻\n```\n\n### 性能预算系统\n\ndcg 在严格的延迟约束下运行——每个 Bash 命令都会经过这个钩子，因此即使是微小的延迟也会累积成明显的卡顿。性能预算系统通过“失败开放”的语义来强制执行这些约束。\n\n**延迟等级**：\n\n| 等级 | 阶段                 | 目标      | 警告阈值 | 惊慌阈值 |\n|------|----------------------|-----------|----------|----------|\n| 0    | 快速拒绝             | \u003C 1μs     | > 10μs   | > 50μs   |\n| 1    | 规范化               | \u003C 5μs     | > 25μs   | > 100μs  |\n| 2    | 安全模式检查         | \u003C 50μs    | > 200μs  | > 500μs  |\n| 3    | 破坏性模式检查       | \u003C 50μs    | > 200μs  | > 500μs  |\n| 4    | Heredoc 提取         | \u003C 1ms     | > 5ms    | > 20ms   |\n| 5    | Heredoc 求值         | \u003C 2ms     | > 10ms   | > 30ms   |\n| 6    | 完整管道             | \u003C 5ms     | > 15ms   | > 50ms   |\n\n**失败开放行为**：\n\n如果任何阶段超过其惊慌阈值，dcg 会记录警告并 **允许命令继续执行**：\n\n```\n[WARN] 性能预算超限：第二级（安全模式）耗时 1.2ms（惊慌阈值：500μs）\n[WARN] 失败开放以避免阻塞工作流程\n```\n\n这种设计确保：\n1. 恶意输入不会导致用户终端卡死。\n2. 性能回归会在日志中清晰可见。\n3. 工具永远不会成为生产力瓶颈。\n\n**预算执行**：\n\n```rust\nfn check_budget(tier: Tier, elapsed: Duration) -> BudgetResult {\n    let budget = TIER_BUDGETS[tier];\n    if elapsed > budget.panic {\n        log::warn!(\"Tier {} exceeded panic threshold\", tier);\n        return BudgetResult::FailOpen;\n    }\n    if elapsed > budget.warning {\n        log::warn!(\"Tier {} exceeded warning threshold\", tier);\n    }\n    BudgetResult::Continue\n}\n```\n\n**性能监控**：\n\n使用 `dcg explain --verbose` 可以查看各阶段的耗时：\n\n```\n评估轨迹：\n  [  0.3μs] 第 0 级：快速拒绝（通过——低于 1μs 目标）\n  [  1.2μs] 第 1 级：规范化（通过——低于 5μs 目标）\n  [  8.7μs] 第 2 级：安全模式（通过——低于 50μs 目标）\n  [ 15.2μs] 第 3 级：破坏性模式（通过——低于 50μs 目标）\n  [ 15.4μs] 总计：15.4μs（通过——低于 5ms 目标）\n```\n\n### 基于关键词的包预过滤\n\n在进行昂贵的正则匹配之前，dcg 使用多级关键词过滤系统快速跳过无关的包。这一点对性能至关重要——由于有 49 个以上的包可用，如果对每个命令都逐一检查所有模式，将会极其缓慢。\n\n**关键词过滤的工作原理**：\n\n每个包会声明一组关键词，只有当命令中出现这些关键词时，该包才相关：\n\n```rust\nPack {\n    id: \"database.postgresql\".to_string(),\n    keywords: &[\"psql\", \"dropdb\", \"createdb\", \"DROP\", \"TRUNCATE\", \"DELETE\"],\n    \u002F\u002F ...\n}\n```\n\n**两级过滤**：\n\n1. **全局快速拒绝**：在开始任何包的评估之前，dcg 会检查命令中是否包含任何已启用包的关键词。如果没有，则直接跳过整个包的评估。\n\n2. **逐包快速拒绝**：对于每个已启用的包，dcg 会先检查命令中是否包含该包的任何关键词，然后再运行昂贵的正则模式。\n\n**Aho-Corasick 自动机**：\n\n对于拥有多个关键词的包，dcg 会构建一个 [Aho-Corasick 自动机](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAho%E2%80%93Corasick_algorithm)，能够在一次 O(n) 的遍历中匹配所有关键词：\n\n```rust\n\u002F\u002F 在首次访问包时惰性构建\npub keyword_matcher: Option\u003Caho_corasick::AhoCorasick>,\n\npub fn might_match(&self, cmd: &str) -> bool {\n    if self.keywords.is_empty() {\n        return true; \u002F\u002F 没有关键词则始终检查模式\n    }\n\n    \u002F\u002F 无论关键词数量多少，都是 O(n) 匹配\n    if let Some(ref ac) = self.keyword_matcher {\n        return ac.is_match(cmd);\n    }\n\n    \u002F\u002F 回退：顺序 memchr 搜索\n    self.keywords.iter()\n        .any(|kw| memmem::find(cmd.as_bytes(), kw.as_bytes()).is_some())\n}\n```\n\n**上下文感知的关键词匹配**：\n\n关键词仅在可执行范围内匹配（不在注释、引号字符串或数据中）：\n\n```rust\npub fn pack_aware_quick_reject(cmd: &str, enabled_keywords: &[&str]) -> bool {\n    \u002F\u002F 第一步：快速子串检查\n    let any_substring = enabled_keywords.iter()\n        .any(|kw| memmem::find(cmd.as_bytes(), kw.as_bytes()).is_some());\n\n    if !any_substring {\n        return true; \u002F\u002F 可以跳过所有包的评估\n    }\n\n    \u002F\u002F 第二步：验证关键词是否出现在可执行上下文中\n    let spans = classify_command(cmd);\n    for span in spans.executable_spans() {\n        if span_matches_any_keyword(span.text(cmd), enabled_keywords) {\n            return false; \u002F\u002F 必须评估包\n        }\n    }\n\n    true \u002F\u002F 关键词只出现在非可执行上下文中，可以跳过\n}\n```\n\n这种方法确保像 `echo \"psql\" | grep DROP` 这样的命令不会因为处理的数据中出现了关键词而触发 PostgreSQL 包的评估。\n\n### 1. 延迟静态初始化\n\n正则表达式模式通过 `LazyLock` 在首次使用时编译一次：\n\n```rust\nstatic SAFE_PATTERNS: LazyLock\u003CVec\u003CPattern>> = LazyLock::new(|| {\n    vec![\n        pattern!(\"checkout-new-branch\", r\"git\\s+checkout\\s+-b\\s+\"),\n        \u002F\u002F ... 还有33个模式\n    ]\n});\n```\n\n后续调用会复用已编译好的模式，无需任何编译开销。\n\n### 2. SIMD 加速的快速拒绝\n\n在进行任何正则匹配之前，一个基于 SIMD 的子字符串搜索会过滤掉无关的命令。[memchr](https:\u002F\u002Fgithub.com\u002FBurntSushi\u002Fmemchr) crate 在可用时会利用 CPU 向量指令（SSE2、AVX2、NEON）：\n\n```rust\nuse memchr::memmem;\n\nstatic GIT_FINDER: LazyLock\u003Cmemmem::Finder\u003C'static>> = LazyLock::new(|| memmem::Finder::new(\"git\"));\nstatic RM_FINDER: LazyLock\u003Cmemmem::Finder\u003C'static>> = LazyLock::new(|| memmem::Finder::new(\"rm\"));\n\nfn quick_reject(cmd: &str) -> bool {\n    let bytes = cmd.as_bytes();\n    GIT_FINDER.find(bytes).is_none() && RM_FINDER.find(bytes).is_none()\n}\n```\n\n对于诸如 `ls -la`、`cargo build` 或 `npm install` 等命令，此检查会直接短路整个匹配流程。`memmem::Finder` 只需预编译一次并重复使用，避免了反复的初始化开销。\n\n### 3. 安全匹配时提前退出\n\n首先检查安全模式。一旦匹配成功，函数将立即返回，而无需再检查破坏性模式：\n\n```rust\nfor pattern in SAFE_PATTERNS.iter() {\n    if pattern.regex.is_match(&normalized).unwrap_or(false) {\n        return;  \u002F\u002F 直接允许\n    }\n}\n```\n\n### 4. 编译时模式验证\n\n`pattern!` 和 `destructive!` 宏会在 panic 消息中包含模式名称，使得无效模式在首次执行时便能以清晰的诊断信息失败：\n\n```rust\nmacro_rules! pattern {\n    ($name:literal, $re:literal) => {\n        Pattern {\n            regex: Regex::new($re).expect(concat!(\"pattern '\", $name, \"' should compile\")),\n            name: $name,\n        }\n    };\n}\n```\n\n### 5. 零拷贝 JSON 解析\n\n`serde_json` 解析器直接操作输入缓冲区，无需不必要的复制。命令字符串直接从解析后的 JSON 值中提取。\n\n### 6. 零分配路径规范化\n\n命令规范化使用 `Cow\u003Cstr>`（写时复制）来避免常见情况下的堆分配：\n\n```rust\nfn normalize_command(cmd: &str) -> Cow\u003C'_, str> {\n    \u002F\u002F 快速路径：如果命令不以 '\u002F' 开头，则无需规范化\n    if !cmd.starts_with('\u002F') {\n        return Cow::Borrowed(cmd);  \u002F\u002F 无需分配\n    }\n    PATH_NORMALIZER.replace(cmd, \"$1\")  \u002F\u002F 仅在剥离路径时才分配内存\n}\n```\n\n大多数命令并不会使用 `git` 或 `rm` 的绝对路径，因此这一快速路径能够为超过 99% 的输入完全避免分配。\n\n### 7. Release 配置优化\n\nRelease 构建使用了激进的优化设置：\n\n```toml\n[profile.release]\nopt-level = \"z\"     # 优化大小（精简二进制文件）\nlto = true          # 跨 crate 的链接时优化\ncodegen-units = 1   # 单一代码生成单元以提升优化效果\npanic = \"abort\"     # 更小的二进制文件，无异常处理开销\nstrip = true        # 移除调试符号\n```\n\n## 示例拦截消息\n\n当拦截到破坏性命令时，hook 会向标准错误输出一条彩色警告（以下为去除 ANSI 代码后的示例）：\n\n```\n════════════════════════════════════════════════════════════════════════\nBLOCKED  dcg\n────────────────────────────────────────────────────────────────────────\n原因： git reset --hard 会丢弃未提交的更改。请先使用 'git stash'。\n\n命令： git reset --hard HEAD~1\n\n提示： 如果您确实需要运行此命令，请手动在终端中执行。\n     建议先使用 'git stash' 保存您的更改。\n════════════════════════════════════════════════════════════════════════\n```\n\n### 建议系统\n\ndcg 不仅仅会阻止命令，还会提供可操作的指导，帮助用户做出更安全的选择。建议系统会根据被拦截的具体命令生成上下文相关的建议。\n\n**建议类别**：\n\n| 类别 | 目的 | 示例 |\n|----------|---------|---------|\n| `PreviewFirst` | 先运行试运行\u002F预览命令 | “先运行 `git clean -n` 预览将要删除的内容” |\n| `SaferAlternative` | 使用实现类似目标的安全命令 | “使用 `--force-with-lease` 替代 `--force`” |\n| `WorkflowFix` | 改善工作流程以避免危险操作 | “在重置前先提交更改” |\n| `Documentation` | 链接到相关文档 | “参阅 `man git-reset` 了解重置选项” |\n| `AllowSafely` | 如何将操作加入白名单（若确属有意） | “添加至白名单： `dcg allowlist add core.git:reset-hard`” |\n\n**按命令类型提供的上下文建议**：\n\n| 命令类型 | 建议 |\n|-------------|------------|\n| `git reset`、`git checkout --` | “建议先使用 `git stash` 保存您的更改。” |\n| `git clean` | “请先使用 `git clean -n` 预览将要删除的内容。” |\n| `git push --force` | “建议使用 `--force-with-lease` 进行更安全的强制推送。” |\n| `rm -rf` | “在手动执行 `rm -rf` 之前，请仔细核对路径。” |\n| `kubectl delete` | “使用 `kubectl delete --dry-run=client` 预览将要删除的内容。” |\n| `docker system prune` | “请先使用 `--dry-run` 查看将要移除的内容。” |\n| `DROP TABLE` | “如果您只需删除数据而非模式，可以考虑使用 `TRUNCATE`。” |\n\n**打包自定义建议**：\n\n每个破坏性模式都可以指定针对特定操作的定制化建议：\n\n```rust\ndestructive_pattern!(\n    \"restic-forget\",\n    r\"restic(?:\\s+--?\\S+(?:\\s+\\S+)?)*\\s+forget\\b\",\n    \"restic forget 会移除快照，可能导致备份数据永久丢失。\",\n    suggestion: \"请先运行 'restic snapshots' 查看将受到影响的内容。\"\n)\n```\n\n这种方法确保建议始终与具体情境相关，而不是泛泛而谈的警告。\n\n同时，hook 还会向标准输出输出用于 Claude Code 协议的 JSON 数据：\n\n```json\n{\n  \"hookSpecificOutput\": {\n    \"hookEventName\": \"PreToolUse\",\n    \"permissionDecision\": \"deny\",\n    \"permissionDecisionReason\": \"被 dcg 阻止\\n\\n原因：...\"\n  }\n}\n```\n\n## 安全性考量\n\n### 保护范围\n\n- **意外数据丢失**：AI 代理在未提交更改的情况下运行 `git checkout --` 或 `git reset --hard`\n- **远程历史破坏**：覆盖共享分支历史的强制推送\n- **暂存区丢失**：丢弃或清空包含重要未完成工作的暂存区\n- **文件系统误操作**：在指定临时目录之外进行递归删除\n\n### 固有局限性\n\n尽管 dcg 能够在多种工具和平台上提供全面的保护，但某些攻击向量本质上难以甚至无法防范：\n- **恶意行为者**：意志坚定的攻击者可以绕过此挂钩\n- **非 Bash 命令**：通过 Python\u002FJavaScript、API 调用等直接写入文件的操作不会被拦截\n- **已提交但未推送的工作**：该挂钩无法防止仅存在于本地的提交丢失\n- **允许命令中的漏洞**：例如，`git commit` 命令意外包含了错误的文件\n- **脚本中的命令**：如果代理运行 `.\u002Fdeploy.sh`，我们不会检查脚本内部的内容\n\n### 威胁模型\n\n此挂钩假设 AI 代理是 **善意但可能出错的**。它旨在捕捉诚实的失误，而非对抗性攻击。该挂钩以与 Claude Code 进程相同的权限运行。\n\n## 故障排除\n\n### 挂钩未阻止命令\n\n1. **检查挂钩注册情况**：确认 `~\u002F.claude\u002Fsettings.json` 文件中包含挂钩配置\n2. **重启 Claude Code**：配置更改需要重启\n3. **检查二进制文件位置**：确保 `dcg` 已添加到您的 PATH 中\n4. **手动测试**：运行 `echo '{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git reset --hard\"}}' | dcg`\n\n### 挂钩被静默移除（建议添加 shell 启动检查）\n\nClaude Code 在重写 `~\u002F.claude\u002Fsettings.json` 文件时，可能会静默移除 dcg 挂钩。这意味着您可能会在没有任何警告的情况下失去保护。\n\n**自动设置**——`dcg setup` 不仅会安装挂钩，还会提示您添加 shell 启动检查：\n\n```bash\ndcg setup               # 交互式 —— 修改 RC 文件前会提示\ndcg setup --shell-check # 非交互式 —— 自动添加检查\n```\n\n**手动设置**——将以下代码片段添加到您的 `~\u002F.zshrc` 和\u002F或 `~\u002F.bashrc` 文件中：\n\n```bash\n# dcg：若挂钩从 Claude Code 设置中被静默移除则发出警告\nif command -v dcg &>\u002Fdev\u002Fnull && command -v jq &>\u002Fdev\u002Fnull; then\n  if [ -f \"$HOME\u002F.claude\u002Fsettings.json\" ] && \\\n     ! jq -e '.hooks.PreToolUse[]? | select(.hooks[]?.command | test(\"dcg$\"))' \\\n       \"$HOME\u002F.claude\u002Fsettings.json\" &>\u002Fdev\u002Fnull; then\n    printf '\\033[1;33m[dcg] ~\u002F.claude\u002Fsettings.json 中缺少挂钩 —— 请运行：dcg install\\033[0m\\n'\n  fi\nfi\n```\n\n此检查：\n- 运行时间仅需几毫秒（不会明显延迟 shell 启动）\n- 当挂钩存在时完全静默\n- 仅在挂钩缺失时显示黄色警告\n- 如果缺少 `dcg`、`jq` 或 `settings.json`，会优雅地跳过\n- 在 bash 和 zsh 中表现一致\n\n> **注意**：`install.sh` 安装程序也会在安装过程中提示您添加此检查。\n\n### 挂钩阻止了安全命令\n\n1. **检查误报情况**：某些边缘情况可能未被安全模式覆盖\n2. **提交问题**：报告被错误阻止的命令\n3. **临时绕过**：让用户在另一个终端中手动运行该命令\n4. **加入白名单**：使用下方的白名单功能进行持久性覆盖\n\n### 使用白名单解决误报问题\n\n如果 dcg 在特定情况下阻止了一个实际上安全的命令，您可以将其加入白名单。白名单支持三层（按顺序检查）：\n\n1. **项目级**（`.dcg\u002Fallowlist.toml`）：仅适用于当前项目\n2. **用户级**（`~\u002F.config\u002Fdcg\u002Fallowlist.toml`）：适用于所有项目\n3. **系统级**（`\u002Fetc\u002Fdcg\u002Fallowlist.toml`）：适用于整个系统\n\n**向白名单添加规则：**\n\n```bash\n# 按 ID 允许特定规则（推荐）\ndcg allowlist add core.git:reset-hard -r \"用于 CI 清理\"\n\n# 在项目级别允许（默认，若位于 git 仓库中）\ndcg allowlist add core.git:reset-hard -r \"CI 清理\" --project\n\n# 添加到用户级白名单\ndcg allowlist add core.git:reset-hard -r \"个人工作流\" --user\n\n# 允许并设置过期时间（ISO 8601 格式）\ndcg allowlist add core.git:clean-force -r \"迁移\" --expires \"2026-02-01T00:00:00Z\"\n\n# 使用 add-command 允许特定命令（精确匹配）\ndcg allowlist add-command \"rm -rf .\u002Fbuild\" -r \"构建清理\"\n```\n\n**列出白名单条目：**\n\n```bash\n# 列出所有层级的所有条目\ndcg allowlist list\n\n# 仅列出项目级白名单\ndcg allowlist list --project\n\n# 仅列出用户级白名单\ndcg allowlist list --user\n\n# 以 JSON 格式输出\ndcg allowlist list --format json\n```\n\n**移除条目：**\n\n```bash\n# 按 ID 移除规则\ndcg allowlist remove core.git:reset-hard\n\n# 仅从项目级白名单中移除\ndcg allowlist remove core.git:reset-hard --project\n```\n\n**验证白名单文件：**\n\n```bash\n# 检查问题（过期条目、无效模式）\ndcg allowlist validate\n\n# 严格模式：将警告视为错误\ndcg allowlist validate --strict\n```\n\n**白名单示例：**\n\n```toml\n[[allow]]\nrule = \"core.git:reset-hard\"\nreason = \"用于 CI 管道清理\"\nadded_at = \"2026-01-08T12:00:00Z\"\n\n[[allow]]\nexact_command = \"rm -rf .\u002Fbuild\"\nreason = \"安全的构建目录清理\"\nadded_at = \"2026-01-08T12:00:00Z\"\nexpires_at = \"2026-02-08T12:00:00Z\"  # 可选过期时间\n\n[[allow]]\npattern = \"rm -rf .*\u002Fbuild\"\nreason = \"跨项目的构建目录\"\nrisk_acknowledged = true  # 基于模式的条目必须注明\nadded_at = \"2026-01-08T12:00:00Z\"\n```\n\n### 性能问题\n\n1. **检查模式数量**：过多的自定义模式会降低匹配速度\n2. **使用 `--release` 进行性能分析**：调试版本的执行速度显著较慢\n3. **检查 stdin 缓冲**：JSON 输入缓慢会导致处理延迟\n\n## 运行测试\n\n### 单元测试\n\n```bash\ncargo test\n```\n\n测试套件包含 80 多项测试，涵盖以下内容：\n- **normalize_command_tests**：对 git 和 rm 二进制文件路径的规范化处理\n- **quick_reject_tests**：针对非 git\u002Frm 命令的快速过滤\n- **safe_pattern_tests**：所有安全模式变体的白名单准确性\n- **destructive_pattern_tests**：所有危险命令的黑名单覆盖范围\n- **input_parsing_tests**：JSON 解析的鲁棒性和边缘案例\n- **deny_output_tests**：输出格式验证\n- **integration_tests**：端到端管道验证\n\n### 带覆盖率的测试\n\n```bash\ncargo install cargo-tarpaulin\ncargo tarpaulin --out Html\n```\n\n### 端到端测试\n\n该仓库包含一个全面的 E2E 测试脚本，共 120 个测试用例：\n\n```bash\n# 运行完整的 E2E 测试套件\n.\u002Fscripts\u002Fe2e_test.sh\n\n# 带详细输出\n.\u002Fscripts\u002Fe2e_test.sh --verbose\n\n# 指定二进制文件路径\n.\u002Fscripts\u002Fe2e_test.sh --binary .\u002Ftarget\u002Frelease\u002Fdcg\n```\n\nE2E 测试套件涵盖：\n- 所有破坏性的 git 命令（reset、checkout、restore、clean、push、branch、stash）\n- 所有安全的 git 命令（status、log、diff、add、commit、push、branch -d）\n- 文件系统命令（rm -rf，涉及各种路径和标志顺序）\n- 绝对路径处理（`\u002Fusr\u002Fbin\u002Fgit`、`\u002Fbin\u002Frm`）\n- 非 Bash 工具（Read、Write、Edit、Grep、Glob）\n- 格式不正确的 JSON 输入（空值、缺少字段、语法错误）\n- 边缘情况（sudo 前缀、带引号的路径、变量扩展）\n\n## 持续集成\n\n该项目使用 GitHub Actions 进行 CI\u002FCD：\n\n### CI 工作流（`.github\u002Fworkflows\u002Fci.yml`）\n\n在每次推送和拉取请求时运行：\n\n- **格式检查**：`cargo fmt --check`\n- **Clippy 静态检查**：`cargo clippy --all-targets -- -D warnings`（启用严格模式和实验性规则）\n- **编译检查**：`cargo check --all-targets`\n- **单元测试**：使用 JUnit XML 报告运行 `cargo nextest run`\n- **代码覆盖率**：使用 LCOV 格式输出运行 `cargo llvm-cov`\n\n### 发布工作流（`.github\u002Fworkflows\u002Fdist.yml`）\n\n在版本标签（`v*`）触发时运行：\n\n- 为 5 种平台构建优化的二进制文件：\n  - Linux x86_64（`x86_64-unknown-linux-gnu`）\n  - Linux ARM64（`aarch64-unknown-linux-gnu`）\n  - macOS Intel（`x86_64-apple-darwin`）\n  - macOS Apple Silicon（`aarch64-apple-darwin`）\n  - Windows（`x86_64-pc-windows-msvc`）\n- 创建 `.tar.xz` 归档文件（Unix）或 `.zip` 文件（Windows）\n- 生成 SHA256 校验和以供验证\n- 发布到 GitHub Releases，并自动生成发布说明\n\n创建发布版本的步骤如下：\n\n```bash\ngit tag v0.1.0\ngit push origin v0.1.0\n```\n\n## 常见问题解答\n\n**问：为什么阻止 `git branch -D`，但允许 `git branch -d`？**\n\n小写的 `-d` 只会删除已完全合并的分支。而大写的 `-D` 会强制删除分支，无论是否已合并，可能会导致仅存在于该分支上的提交丢失。\n\n**问：为什么允许 `git push --force-with-lease`？**\n\n`force-with-lease` 是一种更安全的强制推送方式，它会在远程仓库存在你尚未看到的提交时拒绝推送。这样可以防止意外覆盖他人的工作。\n\n**问：为什么禁止在临时目录之外执行所有 `rm -rf` 命令？**\n\n递归强制删除是极其危险的文件系统操作之一。即使出于好意，一个拼写错误或变量扩展错误也可能导致关键文件被删除。临时目录的设计初衷就是短暂使用。\n\n**问：我可以添加自定义规则吗？**\n\n可以。您可以创建 YAML 规则包文件，并在配置中引用它们。请参阅“自定义规则包”部分以及 [`docs\u002Fcustom-packs.md`](docs\u002Fcustom-packs.md)，了解规则包的架构和示例。\n\n**问：如果我确实需要运行被阻止的命令怎么办？**\n\n请参阅“逃生通道\u002F绕过”部分。选项包括设置 `DCG_BYPASS=1`、一次性允许码、永久白名单，或者在单独的终端中手动运行该命令。\n\n**问：这是否适用于其他 AI 编程工具？**\n\n是的。dcg 原生支持 Claude Code、Gemini CLI 和 GitHub Copilot CLI 的钩子负载。对于其他工具，是否支持取决于它们是否提供了兼容 JSON 输入\u002F输出的预执行 Shell 钩子。\n\n**问：数据库、Docker、Kubernetes 和云相关命令呢？**\n\ndcg 包含超过 49 个规则包，涵盖了这些领域。完整的列表请参阅“模块化规则包系统”部分。您只需在配置中启用所需的规则包即可。\n\n## 贡献\n\n*关于贡献：* 请不要误解我的意思，但我目前不接受任何外部贡献。我没有足够的时间和精力来审查这些内容，而且这些项目都以我的名义发布，因此我需要对可能出现的问题负责。从我的角度来看，这种风险与收益极不对称。此外，我还不得不考虑其他“利益相关者”的意见，但这对于我主要为自己免费开发的工具来说并不明智。欢迎提交问题，甚至提出修复建议的 PR，但请理解我不会直接合并它们。相反，我会让 Claude 或 Codex 通过 `gh` 工具审查这些提交，并独立决定是否以及如何处理这些问题。尤其是漏洞报告，我们非常欢迎。抱歉如果这听起来有些冒犯，但我希望避免浪费时间和产生不必要的误会。我明白这与当前倡导社区贡献的开源精神不太一致，但这却是我在保持高效开发的同时维持心理健康唯一可行的方式。\n\n## 许可证\n\nMIT","# destructive_command_guard (dcg) 快速上手指南\n\n**dcg** 是一个高性能的钩子工具，专为 AI 编程助手（如 Claude Code、Cursor、GitHub Copilot CLI 等）设计。它能在破坏性命令执行前进行拦截和阻断，防止因 AI 误操作导致代码丢失、数据库删除或基础设施被毁。\n\n## 环境准备\n\n- **操作系统**：支持 Linux、macOS 以及 Windows (WSL)。\n- **前置依赖**：无需额外依赖。安装脚本会自动检测平台并下载对应的二进制文件。\n- **适用场景**：主要配合 AI 编程代理使用，也可用于 CI\u002FCD 流程中的代码审查。\n\n## 安装步骤\n\n推荐使用官方提供的“简易模式”一键安装脚本。该脚本会自动配置环境变量和钩子。\n\n在终端中运行以下命令：\n\n```bash\ncurl -fsSL \"https:\u002F\u002Fraw.githubusercontent.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fmain\u002Finstall.sh?$(date +%s)\" | bash -s -- --easy-mode\n```\n\n> **注意**：目前官方未提供国内镜像源。如果下载速度较慢，请检查网络环境或尝试使用代理加速。\n\n安装完成后，dcg 将自动集成到支持的 AI 工具中，无需额外配置即可生效。\n\n## 基本使用\n\n安装后，dcg 默认处于守护状态。当 AI 代理尝试执行危险命令时，它会自动拦截并输出详细的阻断信息。\n\n### 1. 默认拦截示例\n\n当 AI 尝试执行 `git reset --hard` 等危险操作时，你会看到如下阻断提示：\n\n```text\n════════════════════════════════════════════════════════════════\nBLOCKED  dcg\n────────────────────────────────────────────────────────────────\nReason:  git reset --hard destroys uncommitted changes\n\nCommand: git reset --hard HEAD~5\n\nTip: Consider using 'git stash' first to save your changes.\n════════════════════════════════════════════════════════════════\n```\n\n### 2. 临时绕过保护（慎用）\n\n如果你确认某条被拦截的命令是安全的，可以通过以下方式临时执行：\n\n**方法 A：使用环境变量 bypass（仅对当前命令生效）**\n```bash\nDCG_BYPASS=1 \u003C你的命令>\n# 例如：\nDCG_BYPASS=1 git reset --hard HEAD~5\n```\n\n**方法 B：一次性授权**\n复制阻断信息中的短代码，运行：\n```bash\ndcg allow-once \u003C代码>\n```\n\n### 3. 自定义保护策略（可选）\n\n你可以通过编辑配置文件 `~\u002F.config\u002Fdcg\u002Fconfig.toml` 来启用更多保护包（如数据库、K8s、云厂商等）或针对特定 AI 代理调整信任级别。\n\n**启用额外保护包示例：**\n```toml\n# ~\u002F.config\u002Fdcg\u002Fconfig.toml\n[packs]\nenabled = [\n    \"database.postgresql\",    # 阻断 DROP TABLE 等操作\n    \"kubernetes.kubectl\",     # 阻断 kubectl delete namespace\n    \"cloud.aws\",              # 阻断 aws ec2 terminate-instances\n    \"containers.docker\",      # 阻断 docker system prune\n]\n```\n\n**针对不同 AI 代理的配置示例：**\n```toml\n# 对 Claude Code 更信任，放宽限制\n[agents.claude-code]\ntrust_level = \"high\"\nadditional_allowlist = [\"npm run build\", \"cargo test\"]\ndisabled_packs = [\"kubernetes\"]\n\n# 对未知代理更严格，启用所有规则且忽略白名单\n[agents.unknown]\ntrust_level = \"low\"\nextra_packs = [\"paranoid\"]\ndisabled_allowlist = true\n```\n\n配置生效后，dcg 会根据调用它的 AI 代理自动应用相应的安全策略。","某后端工程师正利用 Claude Code 自动重构遗留代码库，AI 代理在清理临时文件时误判了目录结构，准备执行高危指令。\n\n### 没有 destructive_command_guard 时\n- **瞬间丢失进度**：AI 直接执行 `rm -rf .\u002Fsrc` 或 `git reset --hard`，导致数小时未提交的代码和本地修改在秒级内彻底消失。\n- **缺乏二次确认**：自动化流程中缺少对“删除”、“重置”等破坏性操作的风险评估，AI 盲目信任生成的命令并立即运行。\n- **误伤正常数据**：无法区分代码中的搜索关键词（如 `grep \"rm -rf\"`）与真实执行指令，要么漏拦危险操作，要么因过度敏感阻断正常开发。\n- **恢复成本高昂**：一旦数据库执行了 `DROP TABLE` 或容器被 `prune` 清理，往往需要花费大量时间从备份中恢复甚至面临数据永久丢失。\n\n### 使用 destructive_command_guard 后\n- **拦截致命指令**：destructive_command_guard 在命令执行前毫秒级拦截，直接阻断 `git reset --hard` 等高风险操作，并提示先用 `git stash` 保存现场。\n- **智能上下文识别**：工具精准识别意图，允许在代码注释或搜索中使用敏感词，仅在实际调用 Shell 执行破坏动作时触发警报。\n- **多环境全面防护**：开启 PostgreSQL 和 Docker 规则包后，自动拦截 `DROP TABLE` 或 `docker system prune` 等针对数据库和容器的毁灭性指令。\n- **提供安全替代方案**：拦截时不仅报错，还给出具体建议（如“考虑先备份”），引导 AI 选择更安全的操作路径，保障开发流不中断。\n\ndestructive_command_guard 如同给 AI 代理人装上了“刹车系统”，在保持自动化效率的同时，彻底杜绝了因误操作导致的灾难性数据损失。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FDicklesworthstone_destructive_command_guard_f3551a4f.webp","Dicklesworthstone","Jeff Emanuel","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002FDicklesworthstone_c96b6d22.jpg","Building in NY",null,"doodlestein","https:\u002F\u002Fwww.jeffreyemanuel.com\u002F","https:\u002F\u002Fgithub.com\u002FDicklesworthstone",[83,87,91,95,99],{"name":84,"color":85,"percentage":86},"Rust","#dea584",92.3,{"name":88,"color":89,"percentage":90},"Shell","#89e051",7.4,{"name":92,"color":93,"percentage":94},"Python","#3572A5",0.2,{"name":96,"color":97,"percentage":98},"PowerShell","#012456",0.1,{"name":100,"color":78,"percentage":101},"RenderScript",0,844,49,"2026-04-17T18:09:55","NOASSERTION","Linux, macOS, Windows (WSL)","未说明",{"notes":109,"python":107,"dependencies":110},"该工具为高性能命令行钩子（基于 Rust 编译的二进制文件），非 Python 库或 AI 模型，因此无 GPU、特定内存或 Python 版本需求。安装脚本会自动检测平台并下载对应的二进制文件。支持通过配置文件启用针对数据库、Kubernetes、云服务商等的 49+ 安全规则包。",[],[45,13],[113,114,115,116,117,118],"ai-agents","cli","developer-tools","rust","safety","git","2026-03-27T02:49:30.150509","2026-04-18T09:19:16.796051",[122,127,132,137,142,146],{"id":123,"question_zh":124,"answer_zh":125,"source_url":126},39517,"在 Ubuntu 22.04 (WSL) 上运行时出现 `GLIBC_2.39' not found` 错误怎么办？","预编译的二进制文件是在较新版本的 Ubuntu 上编译的，依赖 GLIBC 2.39，而 Ubuntu 22.04 默认只提供 GLIBC 2.35。\n\n解决方案有两种：\n1. **从源码构建（推荐）**：这将链接到您系统本地的 GLIBC 版本。\n   ```bash\n   # 安装 Rust（如果尚未安装）\n   curl --proto '=https' --tlsv1.2 -sSf https:\u002F\u002Fsh.rustup.rs | sh\n   \n   # 构建并安装\n   cargo install --git https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\n   ```\n2. **升级系统**：升级到 Ubuntu 24.04 LTS 也可解决此问题。\n\n注意：维护者已发布修复（使用 musl 静态编译），后续版本将提供可移植的二进制文件。","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fissues\u002F34",{"id":128,"question_zh":129,"answer_zh":130,"source_url":131},39518,"如何让 dcg 自动检测项目环境并启用相关的规则包（Packs）？","可以使用 `dcg init --auto` 命令。该功能会扫描项目中的配置文件和依赖项，自动匹配并启用相应的规则包。\n\n支持检测的内容包括：\n- **容器**：Dockerfile, compose.yaml -> 启用 containers.docker\u002Fpodman\n- **基础设施即代码 (IaC)**：Terraform, Pulumi, Ansible, Kubernetes\u002FHelm\n- **CI\u002FCD**：GitHub Actions, GitLab CI, Jenkins\n- **云服务**：AWS, GCP, Azure 配置文件\n- **数据库**：扫描 package.json, Cargo.toml 等依赖文件以识别 PostgreSQL, MySQL, Redis 等驱动\n\n常用命令：\n```bash\ndcg init --auto           # 检测并启用规则包\ndcg init --auto --dry-run # 预览将要启用的内容但不写入配置\n```","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fissues\u002F81",{"id":133,"question_zh":134,"answer_zh":135,"source_url":136},39519,"为什么放在 `~\u002F.config\u002Fdcg\u002Fconfig.toml` 的配置文件没有被自动读取？","这是一个已知问题，已在最新版本中修复。现在工具会优先检查 XDG 风格的路径 `~\u002F.config\u002Fdcg\u002Fconfig.toml`。\n\n如果您遇到此问题，请尝试以下操作：\n1. **更新到最新版本**：确保您使用的是修复后的版本（commit ceffdf5 之后）。\n2. **检查路径优先级**：现在的加载顺序是：\n   - 环境变量 `DCG_CONFIG` 指定的路径（最高优先级）\n   - `~\u002F.config\u002Fdcg\u002Fconfig.toml` (跨平台通用)\n   - 平台原生路径 (例如 macOS 上的 `~\u002FLibrary\u002FApplication Support\u002Fdcg\u002Fconfig.toml`)\n\n如果更新后仍无效，可以暂时通过设置环境变量强制指定：\n```bash\nexport DCG_CONFIG=\"$HOME\u002F.config\u002Fdcg\u002Fconfig.toml\"\n```","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fissues\u002F17",{"id":138,"question_zh":139,"answer_zh":140,"source_url":141},39520,"macOS 用户是否必须将配置文件放在 `~\u002FLibrary\u002FApplication Support` 目录下？","不需要。虽然 macOS 的系统标准配置目录是 `~\u002FLibrary\u002FApplication Support`，但为了保持跨平台一致性，dcg 现已支持并优先读取 `~\u002F.config\u002Fdcg\u002Fconfig.toml`。\n\n修复后的逻辑如下：\n1. 首先检查 `DCG_CONFIG` 环境变量。\n2. 其次检查 `~\u002F.config\u002Fdcg\u002Fconfig.toml`（推荐 macOS 用户也使用此路径，以便与 Linux 保持一致）。\n3. 最后回退到平台原生路径 `~\u002FLibrary\u002FApplication Support\u002Fdcg\u002Fconfig.toml`。\n\n您可以直接将配置文件创建在 `~\u002F.config\u002Fdcg\u002Fconfig.toml`，无需额外设置。","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fissues\u002F16",{"id":143,"question_zh":144,"answer_zh":145,"source_url":136},39521,"如何查看当前配置状态以及为什么某些规则包未生效？","可以使用 `dcg doctor` 命令进行诊断。该命令会检查二进制文件、钩子设置、配置文件加载情况以及规则包状态。\n\n示例输出及含义：\n```text\nChecking configuration... USING DEFAULTS\n  No config file found, using built-in defaults\n  → Run 'dcg init -o ~\u002F.config\u002Fdcg\u002Fconfig.toml' to create one\nChecking pattern packs... OK (1 enabled)\n```\n如果显示 \"USING DEFAULTS\" 或 \"No config file found\"，说明程序未找到您的自定义配置文件。此时应检查文件是否存在于 `~\u002F.config\u002Fdcg\u002Fconfig.toml`，或者使用 `dcg init` 生成一个新配置。",{"id":147,"question_zh":148,"answer_zh":149,"source_url":131},39522,"安装后为什么运行 docker 或 kubectl 的危险命令没有被拦截？","这是因为默认安装仅启用了核心规则包（`core.filesystem` 和 `core.git`），其他特定技术的规则包（如 `containers.docker` 或 `kubernetes.kubectl`）处于禁用状态。\n\n解决方法：\n1. **手动启用**：编辑 `~\u002F.config\u002Fdcg\u002Fconfig.toml`，在 `[packs]` 列表中添加所需的包，例如：\n   ```toml\n   enabled = [\n     \"core.filesystem\",\n     \"core.git\",\n     \"containers.docker\",\n     \"kubernetes.kubectl\"\n   ]\n   ```\n2. **自动启用（推荐）**：在项目根目录运行 `dcg init --auto`，它会自动检测项目中的 Dockerfile 或 K8s 配置文件并启用对应的规则包。",[151,156,161,166,171,176,181,186,191,196,201,206],{"id":152,"version":153,"summary_zh":154,"released_at":155},315463,"v0.4.0","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.3.0...v0.4.0","2026-02-10T08:25:38",{"id":157,"version":158,"summary_zh":159,"released_at":160},315464,"v0.3.0","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.15...v0.3.0","2026-02-02T01:13:36",{"id":162,"version":163,"summary_zh":164,"released_at":165},315465,"v0.2.15","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.14...v0.2.15","2026-01-20T05:42:12",{"id":167,"version":168,"summary_zh":169,"released_at":170},315466,"v0.2.10","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.9...v0.2.10","2026-01-15T17:54:34",{"id":172,"version":173,"summary_zh":174,"released_at":175},315467,"v0.2.9","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.8...v0.2.9","2026-01-14T23:00:22",{"id":177,"version":178,"summary_zh":179,"released_at":180},315468,"v0.2.7","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.6...v0.2.7\n\n**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.6...v0.2.7","2026-01-12T08:06:43",{"id":182,"version":183,"summary_zh":184,"released_at":185},315469,"v0.2.6","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.5...v0.2.6","2026-01-12T08:01:19",{"id":187,"version":188,"summary_zh":189,"released_at":190},315470,"v0.2.5","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.4...v0.2.5","2026-01-12T07:56:07",{"id":192,"version":193,"summary_zh":194,"released_at":195},315471,"v0.2.4","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.3...v0.2.4","2026-01-12T07:50:10",{"id":197,"version":198,"summary_zh":199,"released_at":200},315472,"v0.2.3","**完整更新日志**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.2...v0.2.3","2026-01-12T07:45:32",{"id":202,"version":203,"summary_zh":204,"released_at":205},315473,"v0.2.2","**Full Changelog**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.1...v0.2.2","2026-01-12T07:33:29",{"id":207,"version":208,"summary_zh":209,"released_at":210},315474,"v0.2.1","**Full Changelog**: https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fdestructive_command_guard\u002Fcompare\u002Fv0.2.0...v0.2.1","2026-01-12T07:31:04"]