# Performance Budget for Hook Evaluation and Deadline Exhaustion in Destructive Command Guard

> Discover the 200ms performance budget for hook evaluation in Destructive Command Guard. Learn how deadline exhaustion prevents unsafe commands from executing silently.

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

---

**Destructive Command Guard enforces a strict 200 ms absolute performance budget for hook evaluation, returning an explicit indeterminate result when deadlines are exceeded to prevent unsafe commands from executing silently.**

Destructive Command Guard (dcg) evaluates every Bash command in real-time to intercept potentially destructive operations. To maintain interactive shell performance without compromising safety, the Rust codebase implements strict tiered latency budgets and a deadline exhaustion mechanism. This article examines the specific performance budgets defined in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs) and how the system handles timeout conditions across the evaluation pipeline.

## Tiered Performance Budgets for Hook Evaluation

The dcg evaluation pipeline is divided into seven distinct tiers, each with specific target latencies, warning thresholds, and panic thresholds. These budgets ensure that fast-path operations remain microsecond-scale while allowing heavier analysis (like heredoc extraction) more time without blocking the shell.

| Tier | Operation | Target latency | Warning threshold | Panic threshold |
|------|-----------|----------------|-------------------|-----------------|
| 0 | Quick-reject (keyword gating) | < 1 µs | > 5 µs | > 50 µs |
| 1 | Fast-path (safe-pattern match) | < 75 µs | > 150 µs | > 500 µs |
| 2 | Full pattern matching (pack evaluation) | < 100 µs | > 250 µs | > 1 ms |
| 3 | Heredoc trigger check | < 5 µs | > 10 µs | > 100 µs |
| 4 | Heredoc extraction | < 200 µs | > 500 µs | > 2 ms |
| 5 | Language detection (shebang/heuristics) | < 20 µs | > 50 µs | > 200 µs |
| 6 | Full heredoc pipeline (trigger + extract + analyse) | < 5 ms | > 15 ms | > 20 ms |

Each tier represents a stage in the evaluation pipeline found in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs). The **panic thresholds** are used by CI to fail builds if budgets are breached, while runtime warnings log performance degradation without blocking execution—unless the absolute budget is exceeded.

## Absolute Budget and Deadline Creation

Beyond the tiered targets, dcg defines an **absolute hook-evaluation budget** of 200 ms. This hard limit is encoded as `ABSOLUTE_MAX = Duration::from_millis(200)` in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs).

When a request enters the hook, dcg creates a `Deadline` structure that records the start time and maximum allowed duration. The `Deadline::hook_default()` constructor automatically applies the 200 ms limit:

```rust
// src/main.rs
use destructive_command_guard::perf::Deadline;

let deadline = Deadline::hook_default(); // max = 200 ms

```

This deadline object is passed through the entire evaluation pipeline, allowing each tier to check remaining time before executing expensive operations.

## How Deadline Exhaustion Works

When the evaluation pipeline exceeds its performance budget, dcg implements a **fail-closed** strategy that explicitly refuses to classify commands as safe. The mechanism operates through four specific behaviors:

**Deadline Checking** – Throughout the pipeline in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs), the code repeatedly calls `deadline.is_exceeded()` to test if elapsed time has surpassed `max_duration`. If true, evaluation stops immediately.

**Bounded Outcome** – When a deadline is exceeded, dcg does not fall back to silently allowing the command. Instead, [`src/hook.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/hook.rs) returns a `hookSpecificOutput` with `permissionDecision: "indeterminate"`. This guarantees that potentially unsafe commands are never treated as safe simply because analysis timed out.

**Budget-Aware Shortcuts** – The `Deadline::has_budget_for(&budget)` helper method allows the pipeline to skip work that cannot possibly finish before a tier's panic threshold. This prevents wasted CPU cycles when only nanoseconds remain.

**CI vs Runtime Behavior** – While panic thresholds trigger CI failures during development, runtime enforcement only activates warnings for tier breaches. Only the absolute 200 ms deadline forces an indeterminate decision, ensuring interactive shells remain usable even under load.

## Code Implementation Examples

Creating a deadline with the default hook budget:

```rust
use destructive_command_guard::perf::Deadline;
use std::time::Duration;

// In the hook entry point
let deadline = Deadline::hook_default(); // 200 ms max

```

Checking whether heredoc extraction can proceed within remaining budget:

```rust
use destructive_command_guard::perf::{HEREDOC_EXTRACT, Deadline};

if deadline.has_budget_for(&HEREDOC_EXTRACT) {
    // Safe to run the extraction (panics < 2 ms)
    extract_heredoc(...);
} else {
    // Abort and return indeterminate result
}

```

Early abort pattern used in the evaluator:

```rust
// src/evaluator.rs
if deadline.is_some_and(Deadline::is_exceeded) {
    return HookResult::indeterminate("deadline exceeded");
}

```

## Summary

- **Destructive Command Guard** evaluates Bash commands under a strict **200 ms absolute budget** defined in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs) as `ABSOLUTE_MAX`.
- The **tiered budget system** assigns specific latency targets to operations ranging from quick-reject (< 1 µs) to full heredoc pipeline (< 5 ms).
- **Deadline exhaustion** triggers an explicit **indeterminate result** rather than allowing potentially unsafe commands to execute.
- The `Deadline` struct provides `hook_default()`, `is_exceeded()`, and `has_budget_for()` methods to enforce budgets throughout [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs) and [`src/hook.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/hook.rs).
- Panic thresholds enable CI-driven performance regression detection while runtime behavior prioritizes safety over speed only when the absolute 200 ms limit is breached.

## Frequently Asked Questions

### What happens when the 200 ms absolute budget is exceeded?

When the absolute deadline is exceeded, dcg returns a `hookSpecificOutput` with `permissionDecision: "indeterminate"` as implemented in [`src/hook.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/hook.rs). This explicit indeterminate state prevents the command from being classified as safe, ensuring that timeout conditions never result in destructive operations being silently approved.

### How does dcg prevent unsafe commands when deadlines are exhausted?

Instead of failing open (allowing the command), dcg fails closed by returning an indeterminate result. The evaluation pipeline in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs) checks `deadline.is_exceeded()` at critical junctures, and if time has run out, it aborts further analysis and marks the decision as indeterminate, forcing the calling system to handle the uncertainty explicitly.

### What is the difference between warning and panic thresholds in the tiered budget system?

**Warning thresholds** (e.g., > 150 µs for fast-path matching) log performance degradation during runtime but allow execution to continue. **Panic thresholds** (e.g., > 500 µs) trigger CI build failures to catch regressions during development. Only the absolute 200 ms deadline affects runtime behavior by forcing an indeterminate result; tier panic thresholds are strictly for development-time enforcement.

### How can I check if there is enough budget remaining for a specific operation?

Use the `Deadline::has_budget_for(&budget)` method, which compares the remaining time against a specific `Budget` constant (such as `HEREDOC_EXTRACT` defined in [`src/perf.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/perf.rs)). This method returns true only if the remaining time exceeds the operation's panic threshold, allowing the pipeline to skip expensive work when time is short.