How to Add Organization-Specific Command Patterns to dcg's Quick Rejection Filter

You can extend dcg's quick-rejection filter by creating a custom internal pack in src/packs/ or by loading an external YAML pack via configuration, both of which merge their keywords into the SIMD-accelerated lookup used before regex evaluation.

The Destructive Command Guard (dcg) repository by Dicklesworthstone uses a high-performance pre-filter to scan commands for dangerous keywords before invoking expensive regex engines. To add organization-specific command patterns, you must inject custom keywords into this fast-path filter, which aggregates enabled pack definitions and performs SIMD-accelerated substring searches to minimize latency.

Understanding the Quick-Rejection Architecture

The quick-rejection filter serves as the first line of defense in src/evaluator.rs, checking commands against a compiled set of keywords before any pattern matching occurs. This system relies on two core components:

  • collect_enabled_keywords in src/packs/mod.rs gathers keywords from all enabled packs (both core and external) into a unified lookup table.
  • keyword_matches_span (lines 78-86) performs the actual SIMD-accelerated scan using memmem::Finder to detect substrings without regex overhead.

When you add organization-specific patterns, you are essentially expanding the keyword list that feeds into this pre-compiled filter.

Method 1: Create a Custom Internal Pack

Internal packs ship with the binary and require recompilation, but offer the best performance and version control for organization-specific logic.

Step 1: Create the Pack Module

Create a new file under src/packs/myorg/mod.rs and define your pack metadata:

use crate::packs::Pack;

pub const PACK: Pack = Pack {
    id: "myorg",
    description: "Organization-specific destructive commands",
    // Keywords trigger the quick-reject filter
    keywords: &["myorg-delete", "myorg-reset"],
    patterns: &[
        pattern!("myorg-delete-resource", r"myorg-delete\s+--resource\s+\S+"),
        destructive!(r"myorg-reset\s+--force", "Critical reset of org resources"),
    ],
};

The keywords array feeds directly into the quick-reject pre-filter, ensuring any command containing these strings receives full evaluation.

Step 2: Register the Pack

Expose your module in src/packs/mod.rs by adding:

pub mod myorg;

Step 3: Enable in Configuration

Add your pack to the enabled list in ~/.config/dcg/config.toml or a project-local dcg.toml:

[packs]
enabled = ["myorg", "core.git", "core.filesystem"]

Step 4: Recompile

Build the binary to compile your keywords into the static filter:

cargo build --release

Your organization-specific keywords are now embedded in the SIMD-based quick-reject filter and will intercept matching commands before the regex engine runs.

Method 2: Add an External YAML Pack

External packs allow runtime customization without recompiling the binary, ideal for rapidly evolving organization policies.

Step 1: Define the YAML Pack

Create a file following the schema defined in src/packs/external.rs:

id: myorg
description: Organization-specific destructive commands
keywords:
  - myorg-delete
  - myorg-reset
patterns:
  - name: myorg-delete-resource
    regex: "myorg-delete\\s+--resource\\s+\\S+"
    type: destructive
    severity: high

Step 2: Configure the Load Path

Point dcg to your external file in ~/.config/dcg/config.toml:

[external_packs]
paths = ["/path/to/myorg_pack.yml"]

Step 3: Runtime Loading

When dcg starts, load_external_packs in src/packs/mod.rs reads the YAML, extracts the keywords, and merges them into the global quick-reject store using the same memmem::Finder fast-path as internal packs. No recompilation is required.

Verifying Your Configuration

Confirm your patterns are active by testing a command:

dcg explain "myorg-delete --resource production-db"

If configured correctly, the output will show the command matched the quick-reject filter, proceeded to full pattern evaluation, and returned a denial JSON containing your ruleId (e.g., myorg:myorg-delete-resource) and defined severity.

Summary

  • The quick-rejection filter aggregates keywords from all enabled packs via collect_enabled_keywords in src/packs/mod.rs and scans commands using SIMD-accelerated substring search before regex evaluation.
  • Internal packs require creating a Rust module under src/packs/, registering it in src/packs/mod.rs, enabling it in config.toml, and recompiling with cargo build --release.
  • External packs use YAML files loaded at runtime via the external_packs configuration path, parsed by src/packs/external.rs, requiring no recompilation.
  • Keywords defined in either method feed into the same fast-path filter (keyword_matches_span), ensuring organization-specific commands are caught early with minimal performance overhead.

Frequently Asked Questions

Where does dcg store the compiled keywords for quick rejection?

The keywords are aggregated at runtime (or compile-time for internal packs) by the collect_enabled_keywords function in src/packs/mod.rs. This function merges keywords from all enabled packs into a lookup structure that src/evaluator.rs uses to perform SIMD-accelerated checks via memmem::Finder before invoking the regex engine.

Do external YAML packs require recompiling dcg?

No. External packs are loaded at runtime by the load_external_packs function in src/packs/mod.rs, which parses the YAML definitions and extracts keywords dynamically. You only need to restart the dcg process after updating the external_packs paths in your configuration file.

What is the performance impact of adding many organization-specific keywords?

The impact is minimal. The quick-rejection filter uses SIMD-accelerated substring search (via memmem::Finder) to check all keywords in parallel, ensuring that even extensive custom keyword lists add negligible latency compared to the regex evaluation phase.

How can I test if my organization-specific patterns are active?

Use the dcg explain command followed by your test command string. If the quick-rejection filter contains your keywords, the output will indicate that the command matched the pre-filter and proceeded to pattern evaluation, displaying the specific ruleId and severity level defined in your custom pack.

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 →