Performance Impact of Enabling Heredoc Scanning for Inline Scripts in dcg
Enabling heredoc scanning in dcg adds negligible latency for most commands, with zero overhead for commands without heredocs and sub-5ms processing for complex inline scripts, while remaining fail-open to prevent workflow stalls.
The destructive_command_guard (dcg) repository provides a security layer that inspects Bash commands before execution. When heredoc scanning for inline scripts is enabled, the evaluator extends its analysis pipeline to detect, extract, and analyze embedded scripts within heredoc blocks. This article examines the specific performance budgets, benchmark results, and architectural safeguards defined in the source code.
Performance Tiers and Budgets
When heredoc scanning is active, dcg adds four specialized tiers to its evaluation hot-path. Each tier carries strict microsecond and millisecond budgets defined in src/perf.rs to ensure real-time command processing.
Tier 3: Heredoc Trigger Detection
The first check uses a lightweight regex in check_triggers to determine if a command contains heredoc markers (<<). According to src/perf.rs lines 26-33, the budget for HEREDOC_TRIGGER is:
- Target: < 5 µs
- Warning: > 10 µs
- Panic: > 100 µs
For commands without heredocs, this quick-reject test costs approximately 1 µs and exits the pipeline immediately.
Tier 4: Heredoc Extraction
If the trigger fires, extract_content (defined in src/heredoc.rs) parses the <<-EOF blocks and enforces ExtractionLimits. The HEREDOC_EXTRACT budget in src/perf.rs lines 34-41 specifies:
- Target: < 200 µs
- Warning: > 500 µs
- Panic: > 2 ms
Benchmark measurements show a medium heredoc of approximately 50 lines consumes roughly 150 µs, while a large 500-line heredoc processes in approximately 1.2 ms—well within the panic threshold.
Tier 5: Language Detection
The ScriptLanguage::detect function examines shebang lines and language-specific patterns to classify the extracted script. As defined in src/perf.rs lines 46-53, LANGUAGE_DETECT budgets are:
- Target: < 20 µs
- Warning: > 50 µs
- Panic: > 200 µs
Typical detection completes in under 10 µs for scripts with clear identifiers.
Tier 6: Full Pipeline Execution
When a heredoc is present, evaluate_command_with_pack_order executes the complete pipeline. The FULL_HEREDOC_PIPELINE budget in src/perf.rs lines 60-67 sets aggressive limits:
- Target: < 5 ms
- Warning: > 15 ms
- Panic: > 20 ms
Even with large embedded scripts, the benchmark bench_full_pipeline demonstrates total processing times of 3-4 ms on modern hardware.
Real-World Benchmark Results
The benchmark suite in benches/heredoc_perf.rs validates these budgets against representative workloads:
| Fixture | Size | Measured Time | Budget Status |
|---|---|---|---|
simple_heredoc (~3 lines) |
Tiny | ~30 µs | ✅ Within target |
medium_heredoc (~50 lines) |
Moderate | ~150 µs | ✅ Below 200 µs warning |
large_heredoc (~500 lines) |
Heavy | ~1.2 ms | ✅ Below 2 ms panic |
full_pipeline (complete evaluation) |
Varied | 3-4 ms total | ✅ Below 5 ms target |
These measurements confirm that enabling heredoc scanning for inline scripts introduces microsecond-scale overhead for small snippets and remains under 5 ms for complex, multi-hundred-line embedded scripts.
Configuration and Control
Heredoc scanning is controlled via HeredocConfig in src/config.rs. By default, HeredocSettings::default enables scanning, but you can disable it entirely to eliminate tiers 3-6 overhead.
Enabling or Disabling Heredoc Scanning
Create or edit ~/.config/dcg/config.toml:
[heredoc]
enabled = true # default: scan for heredocs
timeout_ms = 200 # max extraction time
max_body_bytes = 64_000
max_body_lines = 500
max_heredocs = 3
languages = ["bash", "python"] # limit detection scope
When enabled = false, dcg skips all heredoc-specific processing and follows the standard quick-reject path.
Fail-Open Safety Mechanism
The implementation in src/evaluator.rs uses a fail-open strategy to prevent user workflow stalls. If any tier exceeds its panic threshold—such as encountering a pathological 10 KB heredoc—dcg immediately allows the command to execute and logs a warning. This ensures that performance edge cases never block legitimate operations.
Summary
- Zero overhead applies to commands without heredocs due to the sub-5 µs quick-reject test in
check_triggers. - Microsecond to millisecond overhead occurs only when heredocs are present, with extraction typically consuming 30 µs to 1.2 ms depending on script size.
- Sub-5 ms total processing is maintained for the complete heredoc pipeline, including language detection and security analysis.
- Fail-open behavior guarantees that budget violations never stall the user, allowing commands to proceed while logging performance warnings.
- Configuration via
src/config.rsallows complete disabling of the feature or tuning of limits viaExtractionLimits.
Frequently Asked Questions
What happens if heredoc extraction exceeds the time budget?
If extract_content in src/heredoc.rs exceeds the 2 ms panic threshold defined in src/perf.rs, dcg triggers its fail-open mechanism. The command is immediately approved without full heredoc analysis, and a warning is logged to indicate the budget violation.
How do I completely disable heredoc scanning to minimize overhead?
Set enabled = false in the [heredoc] section of your config.toml. According to src/config.rs, this prevents the evaluator from invoking check_triggers and subsequent tiers, reducing the hot-path to the standard command evaluation only.
Does heredoc scanning slow down simple commands without embedded scripts?
No. For commands lacking heredoc markers, the HEREDOC_TRIGGER regex test in src/heredoc.rs executes in approximately 1 µs and returns immediately. This falls well within the existing fast-path budget and produces no measurable impact on execution flow.
What are the default limits for heredoc extraction?
The ExtractionLimits struct in src/heredoc.rs enforces boundaries on parsed content. By default, the system limits extraction to 500 lines, 64 KB of body text, and 3 heredocs per command. These constraints prevent memory exhaustion and ensure the 5 ms total pipeline target remains achievable even with complex inline scripts.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →