# How to Interpret `dcg explain` Output and Understand Rule Matching

> Learn to interpret dcg explain output & understand rule matching. Traces command evaluation from filters to pattern matching, showing why commands are allowed or denied.

- Repository: [Jeff Emanuel/destructive_command_guard](https://github.com/Dicklesworthstone/destructive_command_guard)
- Tags: how-to-guide
- Published: 2026-07-14

---

**The `dcg explain` command traces every step of the evaluation pipeline—from quick‑reject filters to pattern matching—to show exactly why a command was allowed or denied, including the specific Rule ID, severity level, and remediation options.**

Destructive Command Guard (`dcg`) is a safety tool that intercepts potentially dangerous shell commands before they execute. When you need to understand why a command triggered a denial—or why it was permitted despite looking risky—the `dcg explain` subcommand provides transparent visibility into the rule matching logic, as implemented in the `Dicklesworthstone/destructive_command_guard` repository.

## Understanding the `dcg explain` Report Structure

When you invoke `dcg explain "git reset --hard"` or any other command string, the tool evaluates the input through several internal stages and prints a structured report. According to the source code in [`src/trace.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/trace.rs) and [`src/output/denial.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/output/denial.rs), the output contains the following key fields:

- **Command**: The original command string you passed to the evaluator.
- **Decision**: The final verdict—**`allow`** or **`deny`**—determined by the matching logic in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs).
- **Rule ID**: A stable identifier for the matched rule (e.g., `core.git:reset-hard`). This identifier is the authoritative key you use in allowlists, defined in the pack files like [`src/packs/core/git.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/core/git.rs) and documented in [`docs/patterns.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/patterns.md).
- **Pack ID**: The origin pack that supplied the rule (e.g., `core.git`). Packs group related destructive and safe patterns together.
- **Severity**: A risk classification (`critical`, `high`, `medium`, `low`) indicating how dangerous the matched operation is, as formatted in [`src/output/denial.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/output/denial.rs).
- **Confidence**: A numeric score between 0 and 1 generated by [`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs) indicating the certainty of the match.
- **Explanation**: Human‑readable rationale describing why the rule triggered, produced by the tracing logic in [`src/trace.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/trace.rs).
- **Remediation**: Suggested safe alternatives and a temporary **allow‑once** code, generated by [`src/suggestions.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/suggestions.rs), which you can use to bypass the block for 24 hours.

## How Rule Matching Works Internally

The `explain` output reflects a specific evaluation pipeline implemented in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs). Understanding this flow helps you interpret why a specific Rule ID appeared in your output.

### Quick‑Reject and Normalization

First, a **quick‑reject filter** (using `memchr`‑based scanning) discards clearly non‑dangerous commands early to minimize overhead. If the command survives this filter, [`src/normalize.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/normalize.rs) strips absolute binary paths (e.g., `/usr/bin/git`) and expands aliases, ensuring the command can be matched consistently against predefined patterns.

### Safe‑Pattern Whitelist

The evaluator checks **safe‑pattern whitelists** defined in pack files such as [`src/packs/core/git.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/core/git.rs). If the normalized command matches a safe pattern, `dcg` immediately returns an **allow** decision, and the `explain` output reflects this early exit with no rule ID.

### Destructive‑Pattern Blacklist

If no safe pattern matches, the engine proceeds to **destructive‑pattern blacklists** (also defined in pack files like [`src/packs/core/git.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/core/git.rs)). The first matching destructive pattern produces a **deny** decision, populating the `explain` output with that rule’s metadata, including severity and confidence scores calculated in [`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs).

### Default‑Allow Fallback

If neither safe nor destructive patterns match, the command follows the **default‑allow** policy. In this case, `dcg explain` reports an `allow` decision but provides no rule information, indicating the command passed through the gauntlet without triggering specific protections.

## Output Formats and Practical Usage

The tool supports two output modes, parsed in [`src/main.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/main.rs) and rendered via [`src/output/console.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/output/console.rs) for TTY environments.

### Human‑Readable Format

By default, `dcg explain` produces a colorful, formatted report suitable for terminal reading:

```bash
dcg explain "git reset --hard"

```

This prints a structured breakdown including the Rule ID (`core.git:reset-hard`), severity (`critical`), confidence (`0.95`), and remediation suggestions such as using `git stash` as a safe alternative.

### JSON Trace Mode

For programmatic processing or CI/CD integration, use the `--format json` flag:

```bash
dcg explain --format json "git reset --hard"

```

This outputs a machine‑readable object containing the `trace` field—a complete internal trace from [`src/trace.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/trace.rs) that includes the quick‑reject result, normalized command string, safe‑pattern check results, destructive‑pattern check results, and any AST‑based matches.

### Permanently Allowing a Rule

Because Rule IDs are stable strings, you can add them to an allowlist file. Create or edit [`.dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml) in your project root (or use `~/.config/dcg/allowlist.toml` for user‑level configuration, or [`/etc/dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main//etc/dcg/allowlist.toml) for system‑wide settings):

```bash
echo 'core.git:reset-hard = { allow = true }' >> .dcg/allowlist.toml
git add .dcg/allowlist.toml && git commit -m "Allow git reset --hard in project"

```

### Temporarily Bypassing with Allow‑Once

When `dcg explain` generates a denial, it includes an **allow‑once code** in the remediation section. Extract this code and use it to bypass the guard for a single execution within a 24‑hour window:

```bash

# Extract the code from JSON output

dcg explain --format json "git reset --hard" | jq -r .remediation.allowOnceCode

# Use the code to allow the command once

dcg allow-once a1b2c3

```

## Summary

- **`dcg explain`** reveals the exact Rule ID (e.g., `core.git:reset-hard`) that triggered a denial, which you should reference—not the raw regex—when configuring allowlists.
- The evaluation pipeline runs through **quick‑reject**, **normalization** ([`src/normalize.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/normalize.rs)), **safe‑pattern** checks, and **destructive‑pattern** checks ([`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs)) before reaching a decision.
- **Severity** and **confidence** scores help you triage whether a blocked command requires immediate review or can be safely allowed.
- You can permanently permit commands by adding Rule IDs to **[`.dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml)**, or temporarily bypass them using **`dcg allow-once <code>`** valid for 24 hours.

## Frequently Asked Questions

### What is the Rule ID format and why is it important?

The **Rule ID** follows the format `<pack_id>:<rule_slug>`, such as `core.git:reset-hard`. This stable identifier is defined in the pack source files (e.g., [`src/packs/core/git.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/core/git.rs)) and documented in [`docs/patterns.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/patterns.md). You must use this ID—not the underlying regular expression—when adding entries to your allowlist files ([`.dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml)), ensuring your configuration remains valid even if the pattern implementation changes.

### How is the confidence score calculated?

The **confidence** field is a floating‑point value between 0 and 1 generated by the scoring logic in [`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs). It reflects how closely the normalized command matches the rule’s pattern, considering factors like exact token matches versus wildcard matches. A score of `0.95` indicates high certainty that the identified destructive behavior is present.

### What is the difference between safe‑pattern and destructive‑pattern checks?

**Safe‑pattern whitelists** are evaluated first and immediately grant **allow** status if matched, preventing false positives on benign variations of dangerous commands. **Destructive‑pattern blacklists** are evaluated only if no safe pattern matches; the first match produces a **deny** decision and populates the `dcg explain` output with the corresponding Rule ID and severity. This two‑stage filtering reduces unnecessary blocks while maintaining security.

### Where should I store my allowlist configuration?

You can store allowlists at three levels, checked in order: project‑specific **[`.dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml)** in your repository root (recommended for team consistency), user‑level **`~/.config/dcg/allowlist.toml`** for personal exceptions, or system‑wide **[`/etc/dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main//etc/dcg/allowlist.toml)** for global policies. The tool merges these configurations, with more specific scopes taking precedence, as outlined in the repository documentation.