How to Configure Project-Specific Pack Configurations in dcg

Create a .dcg.toml file in your repository root with a [packs] table containing enabled, disabled, and custom_paths arrays to define which destructive command guards are active for that specific project.

The dcg (Destructive Command Guard) tool uses a layered configuration system that allows repositories to define project-specific pack configurations. By placing a .dcg.toml file at your project root, you can override user and system defaults, enable specific protection packs like database.postgresql or kubernetes, and even load custom YAML rule files local to the repository. This approach ensures that dangerous command patterns are tailored to your project's specific technology stack and deployment workflows.

Understanding the Configuration Hierarchy

dcg merges configuration from multiple sources, with later sources overriding earlier ones. According to src/config.rs (lines 6-14), the priority from highest to lowest is:

  1. CLI flags (e.g., dcg --packs …)
  2. Environment variables (DCG_PACKS, DCG_DISABLE)
  3. Explicit file path (DCG_CONFIG=/path/to/config.toml)
  4. Project config (.dcg.toml in the repository root)
  5. User config (~/.config/dcg/config.toml)
  6. System config (/etc/dcg/config.toml)
  7. Compiled defaults (built-in hardcoded values)

This hierarchy means that a .dcg.toml file in your project root will override the user and system configuration files, but can itself be overridden by environment variables or command-line flags.

Creating a Project-Level Configuration File

To configure project-specific pack configurations, create a file named .dcg.toml at the root of your repository. The [packs] table in this file controls which protection packs are active.

The PacksConfig struct defined in src/config.rs (lines 1343-1365) supports three fields:

pub struct PacksConfig {
    pub enabled: Vec<String>,
    pub disabled: Vec<String>,
    #[serde(default)]
    pub custom_paths: Vec<String>,
}

A minimal project configuration looks like this:

[packs]
enabled = ["core", "database.postgresql", "kubernetes"]
disabled = ["kubernetes.helm"]

Enabling and Disabling Packs for Your Project

The enabled array accepts pack IDs or category prefixes. When you enable a category like kubernetes, all sub-packs (e.g., kubernetes.kubectl, kubernetes.helm) are included. The disabled array removes specific packs even if their parent category is enabled.

Example configuration:

[packs]
enabled = [
    "database.postgresql",
    "kubernetes",
    "windows.filesystem",
]
disabled = [
    "kubernetes.helm",
]

This enables all PostgreSQL database guards and Kubernetes protections, but explicitly disables Helm commands while keeping other Kubernetes checks active.

Loading External Project-Local Packs

For rules specific to your project that aren't covered by built-in packs, use the custom_paths field to load external YAML pack files. According to src/packs/external.rs, these paths support glob patterns and the ${repo_root} variable, which resolves to the nearest directory containing a .git folder.

Configuration example:

[packs]
enabled = ["mycompany.custom"]
custom_paths = ["${repo_root}/.dcg/packs/*.yaml"]

Place your custom pack definition at .dcg/packs/mycompany.yaml:

schema_version: 1
id: mycompany.custom
name: MyCompany Custom Pack
version: 1.0.0
description: Project-specific dangerous commands
destructive_patterns:
  - name: prod-deploy
    pattern: deploy\s+--env\s*=?\s*prod
    severity: critical
    description: Direct production deployment
    explanation: |
      Production deployments must go through CI/CD. Use the pipeline instead.
safe_patterns:
  - name: staging-deploy
    pattern: deploy\s+--env\s*=?\s*(staging|dev)
    description: Non-production deployments are allowed

The loader is fail-open: malformed YAML files are logged but do not abort the entire configuration.

How Pack Resolution Works

When dcg determines which packs to activate, it calls enabled_pack_ids() in src/config.rs (lines 65-89). This method:

  1. Starts with the IDs listed in enabled
  2. Removes any IDs listed in disabled and any sub-packs whose prefix matches a disabled category
  3. Automatically inserts the core pack
  4. Adds the system.disk pack unless explicitly disabled
  5. On Windows, adds windows.filesystem and windows.system unless disabled

You can verify the final active packs by running:

dcg packs enabled

Validating Custom Packs

Before distributing a custom pack to your team, validate it using the built-in validator:

dcg pack validate path/to/mycompany.yaml

This command checks YAML syntax, required fields (id, schema_version, destructive_patterns or safe_patterns), regex compilation, and duplicate pattern names. Errors abort loading, while warnings are printed but allow the pack to load.

Summary

  • Project-specific pack configurations in dcg are defined in a .dcg.toml file at your repository root
  • The configuration hierarchy prioritizes CLI flags and environment variables over project, user, and system configs
  • Use the [packs] table with enabled and disabled arrays to control which protection categories are active
  • Load custom YAML rule files via custom_paths using glob patterns and the ${repo_root} variable
  • The enabled_pack_ids() function in src/config.rs resolves the final set of active packs by merging defaults, explicit enables, and disabled entries
  • External packs are loaded fail-open: malformed files are logged but don't crash the application

Frequently Asked Questions

Can I disable the core pack in my project configuration?

Yes, though not recommended. You can add "core" to the disabled array in your .dcg.toml, but the enabled_pack_ids() method in src/config.rs automatically re-inserts it unless explicitly removed via the disabled list. Note that disabling core removes fundamental protections against common destructive patterns like rm -rf /.

What happens if my custom YAML pack file has syntax errors?

dcg uses a fail-open approach implemented in src/packs/external.rs. Malformed YAML files are logged as warnings but do not abort the entire configuration loading process. Other valid packs will still load and protect against destructive commands.

How do environment variables interact with project-specific configurations?

Environment variables override project configuration. According to the hierarchy in src/config.rs, DCG_PACKS and DCG_DISABLE take precedence over .dcg.toml settings. This is useful for CI pipelines where you might need to temporarily adjust pack behavior without modifying committed files.

Can I use relative paths without the ${repo_root} variable in custom_paths?

While you can specify relative paths, using ${repo_root} ensures the configuration works correctly regardless of the directory from which dcg is invoked. The variable resolves to the nearest parent directory containing a .git folder, making it the safest choice for project-specific pack configurations that need to reference files within the repository.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →