# Maximum Processing Timeout and 200ms Deadline in dcg: How Destructive Command Guard Enforces Hard Limits

> Understand the Destructive Command Guard's 200ms deadline and maximum processing timeout. Learn how dcg prevents workflow blocking by enforcing hard limits on command evaluation.

- Repository: [Jeff Emanuel/destructive_command_guard](https://github.com/Dicklesworthstone/destructive_command_guard)
- Tags: internals
- Published: 2026-07-13

---

**The Destructive Command Guard (dcg) enforces a hard 200ms processing deadline for every command evaluation, automatically failing open (allowing the command) when the limit is exceeded to prevent workflow blocking.**

The **Destructive Command Guard** (`dcg`) is a Rust-based safety hook that intercepts shell commands before execution in AI-coding environments. To guarantee it never blocks a user's workflow, the project implements a strict **maximum processing timeout** of 200ms that triggers a fail-open mechanism when exceeded, as defined in the core performance module and enforced throughout the evaluation pipeline.

## Where the 200ms Deadline is Defined in dcg

The absolute maximum processing time is hardcoded as a constant in the performance module.

In **[`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs)**, the primary constant is defined at line 277:

```rust
pub const ABSOLUTE_MAX: Duration = Duration::from_millis(200);

```

This value is also exposed as a configuration constant at lines 79-84:

```rust
pub const HOOK_EVALUATION_BUDGET_MS: u64 = 200;

```

The **`should_fail_open`** helper function (lines 90-93) provides a convenient check:

```rust
pub fn should_fail_open(duration: Duration) -> bool {
    duration > ABSOLUTE_MAX
}

```

Documentation across the repository reinforces this limit. The **README.md** (lines 58-61) explicitly states the "Absolute Timeout" of 200ms, while **AGENTS.md** (line 701) lists the "Hook fail-open deadline: 200 ms" for agent integration.

## How the 200ms Deadline Works at Runtime

When `dcg` processes a command, it creates a `Deadline` instance in **[`src/main.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/main.rs)** (lines 1001-1008) using the configured timeout:

```rust
let deadline = Deadline::new(
    config
        .general
        .hook_timeout_ms
        .map_or(HOOK_EVALUATION_BUDGET, |ms| {
            Duration::from_millis(ms.max(destructive_command_guard::perf::MIN_HOOK_TIMEOUT_MS))
        }),
);

```

The evaluation process follows this pattern:

1. **Initialization** – After reading and size-checking the command, `dcg` builds a `Deadline` with the 200ms budget (or user-configured value clamped to minimums).
2. **Periodic checks** – Every expensive stage—including heredoc extraction, AST matching, and pattern-matching tiers—calls **`deadline.is_exceeded()`** in **[`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs)**.
3. **Fail-open behavior** – When the deadline passes, `dcg` skips remaining heavy analysis tiers, emits a warning to `stderr`, and returns no JSON denial. This safety-first design treats blocking a legitimate command for >200ms as worse than allowing it unchecked.

If the deadline is exceeded, only a lightweight **critical-pattern** check (`FALLBACK_PATTERNS`) runs before allowing the command.

## Configuring the Maximum Processing Timeout

While 200ms is the default, you can adjust the timeout via the TOML configuration file. The **`hook_timeout_ms`** parameter in the `[general]` section allows customization:

```toml

# dcg.toml

[general]
hook_timeout_ms = 300   # Increase budget for complex scripts

```

The code enforces a **minimum timeout** of `MIN_HOOK_TIMEOUT_MS` (10ms) to prevent an instant "allow-all" bypass. If you specify a value below 10ms, the code clamps it to the minimum in [`src/main.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/main.rs):

```rust
Duration::from_millis(ms.max(destructive_command_guard::perf::MIN_HOOK_TIMEOUT_MS))

```

## Practical Code Examples

### Checking the Deadline Programmatically

You can use the `Deadline` helper directly in Rust code:

```rust
use destructive_command_guard::perf::{Deadline, ABSOLUTE_MAX};
use std::time::Duration;

// Initialize with the 200ms hard limit
let deadline = Deadline::new(Duration::from_millis(200));

// During analysis...
if deadline.is_exceeded() {
    eprintln!("[dcg] Warning: evaluation exceeded 200ms, allowing command");
    return;
}

```

### Using the Fail-Open Convenience Function

For manual duration checks, use the **`should_fail_open`** function:

```rust
use destructive_command_guard::perf::should_fail_open;
use std::time::Instant;

let start = Instant::now();
// ... perform expensive operation ...
let elapsed = start.elapsed();

if should_fail_open(elapsed) {
    eprintln!("[dcg] Warning: operation took >200ms, fail-open");
    // Allow command to proceed
}

```

### Handling Timeout in Custom Evaluators

When implementing custom evaluation logic, respect the fallback pattern behavior:

```rust
if deadline.is_exceeded() {
    // Only check critical patterns
    if fallback_patterns.matches(&command) {
        // Deny if critical pattern matches
    } else {
        // Allow command - deadline exceeded but no critical match
    }
}

```

## Summary

- **`ABSOLUTE_MAX`** in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs) defines the hard 200ms limit as a `Duration` constant.
- The **`should_fail_open`** function determines if elapsed time exceeds the 200ms threshold.
- **`Deadline::new`** constructs the timeout tracker in [`src/main.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/main.rs) using either the default 200ms or a user-configured `hook_timeout_ms`.
- **Fail-open behavior** ensures commands are allowed rather than blocked when analysis exceeds the deadline.
- **Minimum timeout** of 10ms (`MIN_HOOK_TIMEOUT_MS`) prevents configuration bypasses.
- The 200ms limit is documented in [`README.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/README.md) and [`AGENTS.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/AGENTS.md) for both users and agent developers.

## Frequently Asked Questions

### What happens when dcg exceeds the 200ms deadline during evaluation?

When the deadline is exceeded, `dcg` immediately stops expensive analysis tiers (like AST matching and pattern evaluation) and enters a lightweight fallback mode. It checks only critical patterns (`FALLBACK_PATTERNS`), and if none match, the command is allowed to execute. A warning is emitted to `stderr` indicating the timeout occurred.

### Can I increase the 200ms timeout in dcg?

Yes, you can configure a longer timeout by setting `hook_timeout_ms` in your [`dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/dcg.toml) configuration file under the `[general]` section. However, the code clamps this value to a minimum of 10ms (`MIN_HOOK_TIMEOUT_MS`) to prevent accidentally disabling the guard with a near-zero timeout.

### Where is the deadline checked during command evaluation?

The deadline is checked periodically in **[`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs)** before entering expensive stages like heredoc extraction, AST parsing, and pattern-matching tiers. The `deadline.is_exceeded()` method is called to determine whether to skip remaining analysis and proceed to the fail-open fallback.

### What is the minimum timeout value allowed in dcg?

The minimum allowed timeout is **10ms**, defined as `MIN_HOOK_TIMEOUT_MS` in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs). If you configure `hook_timeout_ms` to a value lower than 10ms, the code automatically clamps it to 10ms using `ms.max(MIN_HOOK_TIMEOUT_MS)` in the deadline construction logic in [`src/main.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/main.rs).