DCG: When You Get Blocked
Core Insight: Blocks are checkpoints, not errors. A safe alternative almost always exists. Find it before mentioning override.
Constraints
- Never request, generate, or run an allow-once bypass because only the human may authorize and execute the exact blocked command.
- Preserve the user's intended outcome with the narrowest reversible alternative because the guard protects state, not merely command spelling.
- Explain the matched rule and surviving risk before asking for judgment; never retry, obfuscate, or route around a DCG block.
Quick Navigation
| I need to... |
Go to |
| Handle a block right now |
THE EXACT WORKFLOW |
| Find a safe alternative |
Safe Alternatives |
| See all CLI commands |
COMMANDS.md |
| Enable more rule packs |
PACKS.md |
| Configure per-project |
CONFIG.md |
| Debug hook issues |
TROUBLESHOOTING.md |
THE EXACT WORKFLOW
When blocked, follow this sequence every time:
1. Run `dcg explain "cmd"` → Understand why (see trace)
2. Check Safe Alternatives table → Use if exists (DON'T mention override)
3. No alternative? → Explain risk clearly, let human decide
4. Human approves? → THEY run: dcg allow-once CODE
Never: Ask for override first. Never retry silently. Never circumvent.
Risk-tiered approval counts
When no safe alternative exists and the human must decide, the number of
distinct human approvals scales with what the command can destroy:
| Tier |
Blast radius |
Approvals required |
| Recoverable |
undoable via reflog/stash/trash/backup |
1 allow-once for this exact command |
| Destructive-local |
permanently deletes local, uncommitted, or unbacked state |
1 allow-once, granted only after you name the exact state lost and confirm no backup exists |
| Destructive-shared |
shared history, remote branches, databases, namespaces others use |
1 approval per individual command occurrence — never batched, never pattern-widened |
Stop conditions: never present a tier-2 or tier-3 command as tier-1; never
convert several pending blocks into one blanket approval. A single "yes" that
gets spent across multiple destructive commands is the approval laundering
failure mode — each allow-once code is bound to one command in one directory,
and the workflow must keep it that way.
Example block output:
BLOCKED: git reset --hard HEAD
Rule: core.git:reset-hard
Reason: Discards uncommitted changes permanently
Allow-once code: ab12
Safer alternative: git stash
Good response:
"I wanted to discard changes but git reset --hard was blocked. Let me use git stash instead—recoverable if needed." [proceeds with stash]
Safe Alternatives
| Blocked |
Use Instead |
Why |
git reset --hard |
git stash |
Recoverable |
git checkout -- file |
git stash push file |
Preserves changes |
git push --force |
git push --force-with-lease |
Checks remote unchanged |
git clean -fd |
git clean -fdn (preview) |
Shows what would delete |
git stash drop |
git stash list first |
Verify which stash |
rm -rf /path |
rm -ri /path or verify path |
Interactive/confirm |
kubectl delete namespace |
kubectl delete -l app=X |
Selective deletion |
DROP DATABASE |
Backup first |
Human approves |
docker system prune -a |
docker system df first |
See what's used |
Quick Reference
dcg doctor # Health check — hook registered?
dcg explain "cmd" # WHY is it blocked? (with trace)
dcg test "cmd" # Would this be blocked? (dry-run)
dcg allow-once CODE # Human approves (THEY run this)
dcg packs # List available rule packs
dcg scan --staged # Pre-commit: scan for issues
What Gets Blocked
| Category |
Patterns |
Safe Variants |
| Git destructive |
reset --hard, checkout -- |
stash, restore --staged |
| Git history |
push --force, branch -D |
--force-with-lease, -d |
| Git stash |
stash drop, stash clear |
stash list first |
| Filesystem |
rm -rf (dangerous paths) |
/tmp/* allowed |
| Database |
DROP, TRUNCATE, DELETE w/o WHERE |
Add WHERE clause |
| K8s |
delete namespace, delete --all |
-l label selector |
Context-aware (measured on dcg 0.5.6): the temp carve-out allows rm -rf
under /tmp, /private/tmp, /var/tmp, and the literal $TMPDIR form.
Everything else — rm -rf ./build and other relative paths
(core.filesystem:rm-rf-general), absolute paths like /home/... and /
(core.filesystem:rm-rf-root-home), and even /private/var/tmp — is blocked.
Unresolved variables other than $TMPDIR are not treated as temp.
dcg explain example (7-step pipeline):
$ dcg explain "git reset --hard HEAD"
BLOCKED by core.git:reset-hard
Evaluation trace:
1. Config allow overrides: no match
2. Config block overrides: no match
3. Heredoc detection: not applicable
4. Quick reject: triggered (contains "reset")
5. Context sanitization: no changes
6. Normalization: git reset --hard HEAD
7. Pack evaluation:
- Safe patterns: no match
- Destructive: MATCH "reset --hard"
Suggestion: Use `git stash` to preserve changes
Anti-Patterns
❌ "Command blocked. Run dcg allow-once ab12" → Find alternative first!
❌ *Retrying silently or circumventing* → Always acknowledge blocks
❌ Treating blocks as errors → They're checkpoints
❌ Asking user to allow-once without explaining → They need context
Configuration
# .dcg.toml — enable rule packs per-project
[packs]
enabled = ["database.postgresql", "kubernetes.kubectl", "cloud.aws"]
[overrides]
allow_patterns = ["rm -rf ./node_modules"] # Project-specific safe
Environment variables:
DCG_PACKS="containers.docker,kubernetes" — Enable packs
DCG_DISABLE="kubernetes.helm" — Disable specific packs
DCG_BYPASS=1 — Escape hatch (human-only)
Key Facts
- 49+ rule packs available (database, containers, k8s, cloud, etc.)
- Sub-millisecond latency — won't slow your workflow
- Fail-open on timeout — if DCG hangs, command runs (with warning)
- Heredoc scanning — inline scripts (
bash -c, python -c) are analyzed
- Inline-fragment false positives — because scanning matches a destructive token anywhere in the command string, a pattern that appears only as data (a commit message body, a here-doc payload, a probe argument) can trip a block even though nothing destructive would run. Safe pattern: keep the payload off the command line — pass it via a file or stdin (e.g.
git commit -F <file>), or run the intended tool directly instead of inlining the text. Never reconstruct a blocked command by splitting or escaping its tokens to slip past the guard — that defeats the safety layer.
- Allow-once codes — 4 hex chars, 24h expiry, bound to exact command+directory
The Incident That Started It All
On December 17, 2025, an AI agent ran git checkout -- on files containing hours of uncommitted work. The files were recovered via git fsck --lost-found, but it proved: instructions don't prevent execution—mechanical enforcement does.
Validation
# Quick health check
dcg doctor | head -20
# Test if a command would be blocked
dcg test "git reset --hard HEAD"
# Should show: WOULD BE BLOCKED
Output Specification
- Path: the response and command output on stdout/stderr; write
.dcg.toml or .dcg/allowlist.toml only when configuration was explicitly requested.
- Filename: preserve DCG's project filenames exactly; ordinary block handling creates no persistent file.
- Format: state the blocked command, matched rule, risk, reversible alternative, and the alternative's validation result; quote commands exactly.
- Exit code: run
bash skills/dcg/scripts/validate-dcg.sh and require zero for installation/configuration work; a blocked dcg test result is expected evidence, not permission to bypass.
- Downstream handoff: proceed with the validated safe alternative, or hand the exact risk and allow-once choice to the human when no equivalent exists.
Quality Checklist
- The response identifies the exact block and rule without exposing or suggesting an unauthorized bypass path.
- The chosen alternative is narrower, reversible where possible, and demonstrably preserves the user's requested outcome.
- Validation distinguishes an expected destructive-command block from a broken DCG installation or configuration.
Scripts
| Script |
Usage |
./scripts/validate-dcg.sh |
Full installation validation |
References
- COMMANDS.md — Full CLI reference with
dcg explain, dcg scan
- PACKS.md — 49+ rule pack system (database, k8s, cloud, etc.)
- CONFIG.md — Configuration, agent profiles, heredoc settings
- SCENARIOS.md — Detailed examples with good/bad responses
- PHILOSOPHY.md — Why DCG works this way
- TROUBLESHOOTING.md — Common issues and fixes
1---
2name: dcg
3user-invocable: false
4skill_api_version: 1
5hexagonal_role: supporting
6consumes: []
7produces: []
8context_rel: []
9metadata:
10 dependencies: []
11 capabilities: [dcg]
12 effects: [write_dcg_config]
13 canonical_status: canonical
14 disposition: keep_specialist
15 tier: execution
16description: 'Handle blocked destructive commands and configure agent safety guardrails. Triggers: "dcg", "handle a DCG block", "configure agent safety guardrails".'
17practices:
18- pragmatic-programmer
19output_contract: the blocked command, matched rule, surviving risk, and validated safe alternative; config writes only when explicitly requested
20---
21
22<!-- TOC: Core Insight | THE EXACT WORKFLOW | Quick Reference | Safe Alternatives | What Gets Blocked | Anti-Patterns | Configuration | References -->
23
24# DCG: When You Get Blocked
25
26> **Core Insight:** Blocks are checkpoints, not errors. A safe alternative almost always exists. Find it before mentioning override.
27
28## Constraints
29
30- Never request, generate, or run an allow-once bypass because only the human may authorize and execute the exact blocked command.
31- Preserve the user's intended outcome with the narrowest reversible alternative because the guard protects state, not merely command spelling.
32- Explain the matched rule and surviving risk before asking for judgment; never retry, obfuscate, or route around a DCG block.
33
34## Quick Navigation
35
36| I need to... | Go to |
37|--------------|-------|
38| Handle a block right now | [THE EXACT WORKFLOW](#the-exact-workflow) |
39| Find a safe alternative | [Safe Alternatives](#safe-alternatives) |
40| See all CLI commands | [COMMANDS.md](references/COMMANDS.md) |
41| Enable more rule packs | [PACKS.md](references/PACKS.md) |
42| Configure per-project | [CONFIG.md](references/CONFIG.md) |
43| Debug hook issues | [TROUBLESHOOTING.md](references/TROUBLESHOOTING.md) |
44
45---
46
47## THE EXACT WORKFLOW
48
49When blocked, follow this sequence every time:
50
51```
521. Run `dcg explain "cmd"` → Understand why (see trace)
532. Check Safe Alternatives table → Use if exists (DON'T mention override)
543. No alternative? → Explain risk clearly, let human decide
554. Human approves? → THEY run: dcg allow-once CODE
56```
57
58**Never:** Ask for override first. Never retry silently. Never circumvent.
59
60### Risk-tiered approval counts
61
62When no safe alternative exists and the human must decide, the number of
63distinct human approvals scales with what the command can destroy:
64
65| Tier | Blast radius | Approvals required |
66|------|--------------|--------------------|
67| Recoverable | undoable via reflog/stash/trash/backup | 1 allow-once for this exact command |
68| Destructive-local | permanently deletes local, uncommitted, or unbacked state | 1 allow-once, granted only after you name the exact state lost and confirm no backup exists |
69| Destructive-shared | shared history, remote branches, databases, namespaces others use | 1 approval per individual command occurrence — never batched, never pattern-widened |
70
71Stop conditions: never present a tier-2 or tier-3 command as tier-1; never
72convert several pending blocks into one blanket approval. A single "yes" that
73gets spent across multiple destructive commands is the **approval laundering**
74failure mode — each allow-once code is bound to one command in one directory,
75and the workflow must keep it that way.
76
77**Example block output:**
78```
79BLOCKED: git reset --hard HEAD
80Rule: core.git:reset-hard
81Reason: Discards uncommitted changes permanently
82Allow-once code: ab12
83Safer alternative: git stash
84```
85
86**Good response:**
87> "I wanted to discard changes but `git reset --hard` was blocked. Let me use `git stash` instead—recoverable if needed." [proceeds with stash]
88
89## Safe Alternatives
90
91| Blocked | Use Instead | Why |
92|---------|-------------|-----|
93| `git reset --hard` | `git stash` | Recoverable |
94| `git checkout -- file` | `git stash push file` | Preserves changes |
95| `git push --force` | `git push --force-with-lease` | Checks remote unchanged |
96| `git clean -fd` | `git clean -fdn` (preview) | Shows what would delete |
97| `git stash drop` | `git stash list` first | Verify which stash |
98| `rm -rf /path` | `rm -ri /path` or verify path | Interactive/confirm |
99| `kubectl delete namespace` | `kubectl delete -l app=X` | Selective deletion |
100| `DROP DATABASE` | Backup first | Human approves |
101| `docker system prune -a` | `docker system df` first | See what's used |
102
103## Quick Reference
104
105```bash
106dcg doctor # Health check — hook registered?
107dcg explain "cmd" # WHY is it blocked? (with trace)
108dcg test "cmd" # Would this be blocked? (dry-run)
109dcg allow-once CODE # Human approves (THEY run this)
110dcg packs # List available rule packs
111dcg scan --staged # Pre-commit: scan for issues
112```
113
114---
115
116## What Gets Blocked
117
118| Category | Patterns | Safe Variants |
119|----------|----------|---------------|
120| Git destructive | `reset --hard`, `checkout --` | `stash`, `restore --staged` |
121| Git history | `push --force`, `branch -D` | `--force-with-lease`, `-d` |
122| Git stash | `stash drop`, `stash clear` | `stash list` first |
123| Filesystem | `rm -rf` (dangerous paths) | `/tmp/*` allowed |
124| Database | `DROP`, `TRUNCATE`, `DELETE` w/o WHERE | Add WHERE clause |
125| K8s | `delete namespace`, `delete --all` | `-l` label selector |
126
127**Context-aware (measured on dcg 0.5.6):** the temp carve-out allows `rm -rf`
128under `/tmp`, `/private/tmp`, `/var/tmp`, and the literal `$TMPDIR` form.
129Everything else — `rm -rf ./build` and other relative paths
130(`core.filesystem:rm-rf-general`), absolute paths like `/home/...` and `/`
131(`core.filesystem:rm-rf-root-home`), and even `/private/var/tmp` — is blocked.
132Unresolved variables other than `$TMPDIR` are not treated as temp.
133
134**`dcg explain` example (7-step pipeline):**
135```bash
136$ dcg explain "git reset --hard HEAD"
137BLOCKED by core.git:reset-hard
138
139Evaluation trace:
140 1. Config allow overrides: no match
141 2. Config block overrides: no match
142 3. Heredoc detection: not applicable
143 4. Quick reject: triggered (contains "reset")
144 5. Context sanitization: no changes
145 6. Normalization: git reset --hard HEAD
146 7. Pack evaluation:
147 - Safe patterns: no match
148 - Destructive: MATCH "reset --hard"
149
150Suggestion: Use `git stash` to preserve changes
151```
152
153## Anti-Patterns
154
155```
156❌ "Command blocked. Run dcg allow-once ab12" → Find alternative first!
157❌ *Retrying silently or circumventing* → Always acknowledge blocks
158❌ Treating blocks as errors → They're checkpoints
159❌ Asking user to allow-once without explaining → They need context
160```
161
162## Configuration
163
164```toml
165# .dcg.toml — enable rule packs per-project
166[packs]
167enabled = ["database.postgresql", "kubernetes.kubectl", "cloud.aws"]
168
169[overrides]
170allow_patterns = ["rm -rf ./node_modules"] # Project-specific safe
171```
172
173**Environment variables:**
174- `DCG_PACKS="containers.docker,kubernetes"` — Enable packs
175- `DCG_DISABLE="kubernetes.helm"` — Disable specific packs
176- `DCG_BYPASS=1` — Escape hatch (human-only)
177
178## Key Facts
179
180- **49+ rule packs** available (database, containers, k8s, cloud, etc.)
181- **Sub-millisecond latency** — won't slow your workflow
182- **Fail-open on timeout** — if DCG hangs, command runs (with warning)
183- **Heredoc scanning** — inline scripts (`bash -c`, `python -c`) are analyzed
184- **Inline-fragment false positives** — because scanning matches a destructive token anywhere in the command string, a pattern that appears only as *data* (a commit message body, a here-doc payload, a probe argument) can trip a block even though nothing destructive would run. Safe pattern: keep the payload off the command line — pass it via a file or stdin (e.g. `git commit -F <file>`), or run the intended tool directly instead of inlining the text. Never reconstruct a blocked command by splitting or escaping its tokens to slip past the guard — that defeats the safety layer.
185- **Allow-once codes** — 4 hex chars, 24h expiry, bound to exact command+directory
186
187## The Incident That Started It All
188
189> On December 17, 2025, an AI agent ran `git checkout --` on files containing hours of uncommitted work. The files were recovered via `git fsck --lost-found`, but it proved: **instructions don't prevent execution—mechanical enforcement does.**
190
191---
192
193## Validation
194
195```bash
196# Quick health check
197dcg doctor | head -20
198
199# Test if a command would be blocked
200dcg test "git reset --hard HEAD"
201
202# Should show: WOULD BE BLOCKED
203```
204
205## Output Specification
206
207- **Path:** the response and command output on stdout/stderr; write `.dcg.toml` or `.dcg/allowlist.toml` only when configuration was explicitly requested.
208- **Filename:** preserve DCG's project filenames exactly; ordinary block handling creates no persistent file.
209- **Format:** state the blocked command, matched rule, risk, reversible alternative, and the alternative's validation result; quote commands exactly.
210- **Exit code:** run `bash skills/dcg/scripts/validate-dcg.sh` and require zero for installation/configuration work; a blocked `dcg test` result is expected evidence, not permission to bypass.
211- **Downstream handoff:** proceed with the validated safe alternative, or hand the exact risk and allow-once choice to the human when no equivalent exists.
212
213## Quality Checklist
214
215- The response identifies the exact block and rule without exposing or suggesting an unauthorized bypass path.
216- The chosen alternative is narrower, reversible where possible, and demonstrably preserves the user's requested outcome.
217- Validation distinguishes an expected destructive-command block from a broken DCG installation or configuration.
218
219---
220
221## Scripts
222
223| Script | Usage |
224|--------|-------|
225| `./scripts/validate-dcg.sh` | Full installation validation |
226
227---
228
229## References
230
231- [COMMANDS.md](references/COMMANDS.md) — Full CLI reference with `dcg explain`, `dcg scan`
232- [PACKS.md](references/PACKS.md) — 49+ rule pack system (database, k8s, cloud, etc.)
233- [CONFIG.md](references/CONFIG.md) — Configuration, agent profiles, heredoc settings
234- [SCENARIOS.md](references/SCENARIOS.md) — Detailed examples with good/bad responses
235- [PHILOSOPHY.md](references/PHILOSOPHY.md) — Why DCG works this way
236- [TROUBLESHOOTING.md](references/TROUBLESHOOTING.md) — Common issues and fixes