Summary
Add a PreToolUse hook enforcement system that physically prevents agent misbehavior, replacing the current advisory-only allowed-tools declarations in skill frontmatter with runtime enforcement via shell script hooks.
Motivation (from Kiln Analysis)
Kiln uses 13 PreToolUse hooks in a single enforce-pipeline.sh shell script to physically block agent tool calls before they execute. Their core insight: "Verbal compliance from a language model is not compliance. It's an echo."
The hook receives JSON on stdin with tool_name, agent_type, and tool_input, then validates and exits 0 (allow) or 2 (block with stderr message). This is Claude Code's native PreToolUse hook mechanism.
The 4 Enforcement Categories
1. Delegation (Hooks 1-3) — Prevent delegation agents from writing files directly:
- Codex agent blocked from Write/Edit (must delegate to GPT-5.4 via CLI)
- Plato agent blocked from Write/Edit (synthesis is delegated work)
- Sun-Tzu agent blocked from Write/Edit (provides context, delegates planning)
- Each block includes "teachable enforcement" — tells the agent exactly what to do instead
2. Sequencing (Hooks 4-6) — Gate downstream dispatches until prerequisites complete:
- krs-one blocked from dispatching to codex/sphinx until
architecture.md AND patterns.md have <!-- status: complete --> markers
- aristotle blocked from dispatching to planners until
architecture.md is complete
- Backup gate on
codex exec duplicates the architecture/patterns check as safety net
- Uses
_status_ok() helper: [[ -f "$1" ]] && head -1 "$1" | grep -q '<!-- status: complete -->'
3. Flags (Hooks 7-10) — Enforce correct CLI invocation:
- No
-m model flag (model set in config, not overridable by agents)
- No
--config override
- No
--full-auto (Landlock support not guaranteed)
- No
--skip-git-repo-check
4. Safety (Hooks 11-13) — Protect system resources:
- System config protection: blocks Write/Edit to
~/.codex/, ~/.claude/settings*, ~/.claude/projects/
- Destructive recovery protection: regex catches
rm -rf /DEV/, rm -rf ., etc., provides git recovery instructions
- Memory isolation: blocks Read of
~/.claude/*/memory/ — agents should only use their spawn prompt
Enforcement Philosophy
- Teachable enforcement: Every block includes the correct pattern, not just "denied"
- Fail-safe design: If pipeline directory doesn't exist, gates fail open
- Clear escalation: System config issues escalate to operator; destructive commands show git recovery
- Stateless validation: Pure regex + file markers, no persistent state
Current State in DevFlow
DevFlow's allowed-tools in skill frontmatter (e.g., allowed-tools: Read, Grep, Glob) is advisory only — it tells Claude what tools a skill should use, but nothing prevents an agent from calling Write or Edit anyway. There is no runtime enforcement.
Technical Approach
1. Create scripts/hooks/enforce-tools.sh
A single shell script that handles all enforcement rules. Receives PreToolUse JSON on stdin:
#!/bin/bash
# Read tool call metadata from stdin
read -r JSON
TOOL=$(echo "$JSON" | jq -r '.tool_name')
AGENT=$(echo "$JSON" | jq -r '.agent_type // empty')
FILE_PATH=$(echo "$JSON" | jq -r '.tool_input.file_path // empty')
COMMAND=$(echo "$JSON" | jq -r '.tool_input.command // empty')
# CATEGORY 1: DELEGATION - Reviewer agents are read-only
if [[ "$AGENT" =~ ^reviewer ]]; then
if [[ "$TOOL" =~ ^(Write|Edit)$ ]]; then
echo "BLOCKED: Reviewer agents report findings — they never modify source code." >&2
echo "Write your findings to a review report file instead." >&2
exit 2
fi
fi
# ... additional rules
2. DevFlow-Specific Enforcement Rules
| Rule |
Agent |
Blocked Tools |
Rationale |
| Reviewer read-only |
reviewer-* |
Write, Edit |
Reviewers report, never modify source |
| Coder no-push-main |
coder |
Bash (git push.*main) |
Coder works on branches only |
| Simplifier no-create |
simplifier |
Write (new files) |
Simplification = modify existing only |
| Skimmer read-only |
skimmer |
Write, Edit |
Pure exploration agent |
| System config protection |
all |
Write/Edit to ~/.claude/ |
No agent modifies system config |
| Destructive command interception |
all |
Bash (rm -rf) |
Catch dangerous deletions |
3. Register in Plugin Manifests
Add PreToolUse hook declarations to relevant plugin.json files:
{
"hooks": {
"PreToolUse": [{
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/enforce-tools.sh"
}]
}
}
4. Integration with Dispatch Gating (see #issue for File Markers)
The enforcement script can also check file markers for sequencing, combining Categories 1-4 in a single hook.
Acceptance Criteria
References
- Kiln repo:
skills/kiln-pipeline/scripts/enforce-pipeline.sh (13 hooks, 4 categories)
- Claude Code PreToolUse hook docs: hooks receive JSON on stdin, exit 0 (allow) or 2 (block with stderr)
- DevFlow agent roster:
shared/agents/ (10 shared agents)
- Priority: High impact, Medium effort — "Do first"
Summary
Add a PreToolUse hook enforcement system that physically prevents agent misbehavior, replacing the current advisory-only
allowed-toolsdeclarations in skill frontmatter with runtime enforcement via shell script hooks.Motivation (from Kiln Analysis)
Kiln uses 13 PreToolUse hooks in a single
enforce-pipeline.shshell script to physically block agent tool calls before they execute. Their core insight: "Verbal compliance from a language model is not compliance. It's an echo."The hook receives JSON on stdin with
tool_name,agent_type, andtool_input, then validates and exits0(allow) or2(block with stderr message). This is Claude Code's native PreToolUse hook mechanism.The 4 Enforcement Categories
1. Delegation (Hooks 1-3) — Prevent delegation agents from writing files directly:
2. Sequencing (Hooks 4-6) — Gate downstream dispatches until prerequisites complete:
architecture.mdANDpatterns.mdhave<!-- status: complete -->markersarchitecture.mdis completecodex execduplicates the architecture/patterns check as safety net_status_ok()helper:[[ -f "$1" ]] && head -1 "$1" | grep -q '<!-- status: complete -->'3. Flags (Hooks 7-10) — Enforce correct CLI invocation:
-mmodel flag (model set in config, not overridable by agents)--configoverride--full-auto(Landlock support not guaranteed)--skip-git-repo-check4. Safety (Hooks 11-13) — Protect system resources:
~/.codex/,~/.claude/settings*,~/.claude/projects/rm -rf /DEV/,rm -rf ., etc., provides git recovery instructions~/.claude/*/memory/— agents should only use their spawn promptEnforcement Philosophy
Current State in DevFlow
DevFlow's
allowed-toolsin skill frontmatter (e.g.,allowed-tools: Read, Grep, Glob) is advisory only — it tells Claude what tools a skill should use, but nothing prevents an agent from calling Write or Edit anyway. There is no runtime enforcement.Technical Approach
1. Create
scripts/hooks/enforce-tools.shA single shell script that handles all enforcement rules. Receives PreToolUse JSON on stdin:
2. DevFlow-Specific Enforcement Rules
reviewer-*codergit push.*main)simplifierskimmer~/.claude/rm -rf)3. Register in Plugin Manifests
Add PreToolUse hook declarations to relevant
plugin.jsonfiles:{ "hooks": { "PreToolUse": [{ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/enforce-tools.sh" }] } }4. Integration with Dispatch Gating (see #issue for File Markers)
The enforcement script can also check file markers for sequencing, combining Categories 1-4 in a single hook.
Acceptance Criteria
scripts/hooks/enforce-tools.shcreated with enforcement rules/code-reviewReferences
skills/kiln-pipeline/scripts/enforce-pipeline.sh(13 hooks, 4 categories)shared/agents/(10 shared agents)