How to Integrate DCG with Codex CLI Using the Hook Protocol
You integrate DCG with Codex CLI by registering it as a PreToolUse hook in ~/.codex/hooks.json; DCG then reads JSON from stdin, detects the Codex protocol via the turn_id field in src/hook.rs, and returns a minimal permissionDecision: "deny" payload to block destructive Bash commands while silently exiting on safe commands.
Destructive Command Guard (DCG) from the Dicklesworthstone/destructive_command_guard repository adds a safety layer to AI-driven terminal workflows by intercepting shell commands before execution. When you integrate DCG with Codex CLI using the hook protocol, it evaluates every Bash tool invocation in real time without requiring changes to existing Codex commands.
Integrating DCG with Codex CLI via the PreToolUse Hook Protocol
The Codex CLI exposes a hook system that runs external binaries before tool execution. DCG implements the PreToolUse event handler, which receives a JSON document on stdin describing the pending command. This allows DCG to inspect and either block or allow the command before it reaches the shell.
Hook Detection and Protocol Selection in src/hook.rs
In src/hook.rs, the detect_protocol function inspects the incoming JSON to determine whether the caller is Codex or Claude. According to the DCG source code, Codex payloads contain a non-empty turn_id field. When this field is present, DCG selects HookProtocol::Codex and branches to Codex-specific formatting logic around line 1200.
// Protocol selection in src/hook.rs
match detect_protocol(&input) {
HookProtocol::Codex => HookProtocol::Codex,
_ => HookProtocol::Claude,
}
Minimal Denial Payload Requirements for Codex
Codex is strict about extra fields in hook responses. As implemented in src/hook.rs around line 1500, DCG strips all DCG-only metadata from the denial output and emits only the fields the Codex parser expects. Any unexpected keys cause Codex to fail open with a parsing error.
// Denial payload for Codex (src/hook.rs, around line 1500)
if matches_destructive {
eprintln!("⚠️ {rule_id}: {reason}");
// Minimal JSON required by Codex
println!(r#"{{"hookSpecificOutput":{{"hookEventName":"PreToolUse","permissionDecision":"deny","ruleId":"{rule_id}"}}}}"#);
std::process::exit(0);
}
Installing the DCG Hook for Codex CLI
You do not need to rebuild Codex or modify its source to add DCG. The project provides an installation script that registers the DCG binary as a hook in the Codex configuration directory.
Automated Setup with install.sh
Run the following command to download and execute the installer:
curl -sSfL https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh | bash
The install.sh script creates a PreToolUse entry inside ~/.codex/hooks.json that points to the DCG binary. The src/agent.rs file defines the Agent::CodexCli variant, which DCG activates when the CODEX_CLI=1 environment variable is present or when the Codex protocol is detected.
Manual Hook Configuration Structure
If you prefer to edit the file yourself, add an entry with the event set to PreToolUse and the tool filtered to Bash:
{
"command": "dcg",
"args": [],
"event": "PreToolUse",
"tool": "Bash"
}
Runtime Behavior: Deny vs. Allow
Once installed, DCG evaluates every Bash command that Codex attempts to run. The outcome depends on whether the command matches a destructive pattern in src/evaluator.rs.
Blocking Destructive Commands
When src/evaluator.rs flags a command as dangerous, DCG writes a human-readable warning to stderr and prints the minimal JSON denial object to stdout. Codex receives the permissionDecision: "deny" value and halts the tool call. The following command demonstrates a blocked invocation:
codex run -- bash -c "git reset --hard HEAD~3"
If the command is blocked, Codex receives the minimal JSON denial and prints the warning generated by DCG.
Allowing Safe Commands Silently
If the command passes all safety checks, DCG produces no stdout output and exits with status code 0. This silent success path is essential because any unexpected stdout from the hook interferes with Codex's internal parsing. The src/config.rs module loads per-agent profiles to ensure Codex-specific handling stays lightweight.
Core Source Files Powering the Integration
Understanding the architecture helps when debugging or extending the integration.
src/main.rs— The CLI entry point that dispatches to the correct agent protocol based on the environment and active agent.src/hook.rs— Implements thePreToolUsehook, hostsdetect_protocol, and formats the Codex-specific denial payload.src/agent.rs— DefinesAgent::CodexCliand the detection logic tied toCODEX_CLI=1.src/evaluator.rs— The core pattern-matching engine that decides which commands are destructive.src/config.rs— Loads per-agent profiles, including Codex-specific settings.install.shanduninstall.sh— Manage the~/.codex/hooks.jsonregistration automatically.
Summary
- Register DCG as a
PreToolUsehook in~/.codex/hooks.jsonto integrate it with Codex CLI. - The
detect_protocolfunction insrc/hook.rsidentifies Codex by the presence of aturn_idfield in the stdin JSON. - Blocked commands return a minimal JSON payload containing
permissionDecision: "deny"and no extra metadata. - Safe commands exit silently with code 0, allowing Codex to proceed without modification.
- Run
install.shto automate hook registration, or manually edit~/.codex/hooks.jsonto point to thedcgbinary.
Frequently Asked Questions
What happens if the DCG denial payload contains extra fields?
Codex treats extra fields in the hook response as a parsing error and fails open, which means the command might run unsafely. DCG avoids this by emitting only the required hookEventName, permissionDecision, and ruleId fields when handling HookProtocol::Codex in src/hook.rs.
How does DCG know it is running inside a Codex CLI session?
DCG detects the active agent through two mechanisms. First, it checks the CODEX_CLI=1 environment variable defined in src/agent.rs. Second, src/hook.rs inspects the incoming JSON for the turn_id field, which is unique to Codex payloads and triggers the HookProtocol::Codex branch.
Can I use DCG with other agents besides Codex?
Yes. The detect_protocol function in src/hook.rs defaults to HookProtocol::Claude when the Codex turn_id field is absent. The src/main.rs dispatcher supports multiple agent variants, so the same binary protects Claude and other AI CLI tools.
Where does DCG output the warning when it blocks a command?
DCG writes the human-readable warning to stderr via eprintln!, while the structured JSON denial is written to stdout. This separation ensures Codex receives valid JSON on stdout without mixing in display text. The user sees the explanatory rule identifier and reason directly in the terminal.
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 →