<mission_control> <objective>Create event-driven hooks that intercept operations and enforce security patterns</objective> <success_criteria>Generated hook has valid matcher, action type, and timeout configuration</success_criteria> </mission_control>
<interaction_schema> event_analysis → matcher_design → action_definition → security_review → output</interaction_schema>
Hook Development
Skill Location: This file
Quick Start
Create hook: Follow matcher + action structure with timeout configuration
Review hook: Use quality-standards skill → Apply security patterns
Test matcher: Verify with Bash command before deployment
Why: Hooks intercept operations at runtime—prevention is more valuable than post-hoc correction.
Critical Reference Loading
Key Reference: references/pattern_advanced.md contains critical event handling patterns. Read in full when implementing complex hooks—partial understanding leads to runtime errors.
Navigation
| If you need... | Read... |
|---|---|
| Create hook | ## Implementation Patterns |
| Review hook quality | Use quality-standards skill |
| Test matcher | See Bash examples in this file |
| Event matcher patterns | references/pattern_advanced.md |
| Security anti-patterns | references/lookup_quality.md |
| Migration guidance | references/workflow_migration.md |
External References
- •Hooks Reference - Complete API documentation
- •Hooks Guide - Getting started tutorial
System Requirements
- •Hook config: JSON format with
matcher+hooksarray - •Action types:
prompt(requires user confirmation) orcommand(silent blocking) - •Timeout: Required for
prompthooks (prevents blocking operations) - •Matcher syntax:
"Bash","Write|Edit","*", or regex patterns (tool names only) - •Portability: Use project-relative paths, no hardcoded environment paths
Operational Patterns
This skill follows these behavioral patterns:
- •Planning: Switch to planning mode for architectural decisions
- •Discovery: Locate files matching patterns and search file contents for hook integration points
- •Delegation: Delegate planning and exploration to specialized workers
- •Tracking: Maintain a visible task list for hook development
<critical_constraint> Use native tools to fulfill these patterns. The System Prompt selects the correct implementation for semantic directives. </critical_constraint>
Implementation Patterns
Pattern: Destructive Operation Block
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/scripts/rm-safety.sh"
}
]
}
See scripts/rm-safety.sh for portable rm -rf and path traversal blocking.
Pattern: Project-Specific Dangerous Commands
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/scripts/dangerous-commands.sh"
}
]
}
See scripts/dangerous-commands.sh for project-specific patterns. Edit this file to add/remove patterns without modifying hook logic.
Pattern: Sudo Confirmation
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'Sudo requires explicit confirmation.'"
}
]
}
Pattern: Protected File Guard
if [[ "$file_path" == *".env"* ]]; then
echo '{"decision": "deny", "reason": "Protected file"}' >&2
exit 2
fi
Troubleshooting
| Issue | Symptom | Solution |
|---|---|---|
| Broad match blocking all operations | Matcher "*" or overly generic | Target specific tool + dangerous args |
| User confused why operation failed | Silent block with no explanation | Use prompt type with clear message |
| Hook blocking forever | Missing timeout on prompt hook | Add timeout: 30 or similar |
| Hook failing on different machines | Hardcoded paths like /home/user/ | Use project-relative paths with ${CLAUDE_PROJECT_DIR} |
| Variable injection vulnerability | Unquoted variables with spaces | Always quote variables: "$file_path" |
| Security bypass | No confirmation for destructive ops | Add prompt hook with confirmation requirement |
Hooks are event-driven automation that intercept operations before execution. They provide safety mechanisms, enforce patterns, and enable automated intervention based on event matching.
Core principle: Hooks must be event-specific, security-conscious, and provide clear intervention logic.
What Hooks Are
Hooks provide:
- •Event interception: Pre-execution validation and control
- •Safety mechanisms: Prevent destructive operations
- •Pattern enforcement: Ensure compliance with standards
- •Automated intervention: Proactive issue prevention
- •Security controls: Authentication and authorization checks
Hook Architecture
Event-Driven: Hooks respond to specific events (Bash commands, tool usage, file operations)
Two-Phase Operation:
- •Matcher: Identifies target events
- •Action: Executes intervention logic
Core Structure
Hook Configuration
{
"hooks": {
"[EventName]": [
{
"matcher": "Event matching criteria",
"hooks": [
{
"type": "prompt" | "command",
"prompt": "Intervention message or validation",
"timeout": 30
}
]
}
]
}
}
Hook Body
- •Event identification: What events to intercept
- •Matching logic: How to identify target operations
- •Intervention strategy: What action to take
- •Security implications: Safety and risk considerations
- •Timeout handling: Prevention of blocking operations
Common Mistakes to Avoid
Mistake 1: The Broad Match
❌ Wrong:
"matcher": "*"
Generates noise and blocks legitimate operations.
✅ Correct:
"matcher": "Bash"
Then filter inside the script using the JSON input from stdin.
Mistake 2: The Silent Block
❌ Wrong:
"type": "command", "command": "exit 1"
User sees generic failure with no guidance.
✅ Correct:
"type": "prompt", "prompt": "Destructive rm -rf detected. This cannot be undone. Type 'DELETE' to confirm.", "timeout": 30
Mistake 3: The Missing Timeout
❌ Wrong:
"type": "prompt"
Operations without timeouts can deadlock the system.
✅ Correct:
"type": "prompt", "prompt": "Confirm destructive operation", "timeout": 30
Mistake 4: The Hardcoded Path
❌ Wrong:
"command": "/home/user/scripts/validate.sh"
Fails when team members have different home directories.
✅ Correct:
"command": "bash ${CLAUDE_PROJECT_DIR}/.claude/scripts/validate.sh"
Mistake 5: The Unquoted Variable
❌ Wrong:
rm -rf $file_path
Injection risk with spaces or special chars.
✅ Correct:
rm -rf "$file_path"
Correct Patterns
Prompt for destructive operations:
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "rm -rf detected. This cannot be undone. Type 'DELETE' to confirm.",
"timeout": 30
}
]
}
Block sudo with clear message:
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'Sudo requires explicit confirmation. Remove this block if needed.'"
}
]
}
Protect sensitive files:
# Check for .env before allowing operations
if [[ "$file_path" == *".env"* ]]; then
echo '{"decision": "deny", "reason": "Protected file"}' >&2
exit 2
fi
Validation Checklist
Before claiming hook development complete:
Matcher Design:
- • Matcher targets specific tool + dangerous operation
- • Avoided broad matches like
"*" - • Tested to catch intended operations without false positives
Action Configuration:
- • Used
prompttype for destructive operations requiring confirmation - • Used
commandtype for clear blocking with explanation - • Timeout set on prompt hooks (prevents blocking)
Security:
- • Destructive operations require explicit confirmation
- • Protected files (
.env, credentials) have special handling - • Variables properly quoted to prevent injection
Portability:
- • Used project-relative paths with
${CLAUDE_PROJECT_DIR} - • No hardcoded environment paths
- • Works across different team member environments
Team Collaboration Best Practices
Shared vs Personal Hooks
Team-wide hooks (.claude/settings.json):
- •Committed to version control
- •Enforce project standards across team
- •Security policies, quality gates
- •Build/test requirements
Personal hooks (.claude/settings.local.json):
- •Gitignored (add to
.gitignore) - •Personal development preferences
- •Local debugging tools
- •Custom workflow automation
Hook Independence
Design hooks assuming parallel execution:
- •Hooks don't see each other's output
- •No ordering guarantees
- •Each hook should be independently useful
- •Avoid duplicate functionality across team and personal hooks
Best Practices Summary
✅ DO:
- •Target specific tool + dangerous args in matchers
- •Use
prompttype for destructive operations - •Set
timeout: 30on all prompt hooks - •Use project-relative paths with
${CLAUDE_PROJECT_DIR} - •Quote all variables in bash commands
- •Explain clearly what was detected and why
❌ DON'T:
- •Use broad matches like
"*"that block everything - •Use silent
commandblocks without explanation - •Omit timeout values on prompt hooks
- •Hardcode paths like
/home/user/ - •Leave variables unquoted
- •Skip confirmation for destructive operations
Advanced Hooks Best Practices
- •Keep hooks independent: Don't rely on execution order
- •Use timeouts: Set appropriate limits for each hook type
- •Handle errors gracefully: Provide clear error messages
- •Document complexity: Explain advanced patterns in project README
- •Test thoroughly: Cover edge cases and failure modes
- •Monitor performance: Track hook execution time
- •Version configuration: Commit hook configs to git
- •Provide escape hatches: Allow bypass via flag files when needed
Common Pitfalls to Avoid
❌ Assuming Hook Order
# BAD: Assumes hooks run in specific order # Hook 1 saves state, Hook 2 reads it # This can fail because hooks run in parallel!
❌ Long-Running Hooks
# BAD: Hook takes 2 minutes to run sleep 120 # This will timeout and block the workflow
❌ Uncaught Exceptions
# BAD: Script crashes on unexpected input file_path=$(echo "$input" | jq -r '.tool_input.file_path') cat "$file_path" # Fails if file doesn't exist
✅ Proper Error Handling
# GOOD: Handles errors gracefully
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
if [ ! -f "$file_path" ]; then
echo '{"continue": true, "systemMessage": "File not found, skipping check"}' >&2
exit 0
fi
Genetic Code
This component carries essential Seed System principles for context: fork isolation:
<critical_constraint>
Portability invariant: The skill must function without CLAUDE.md, CLAUDE.local.md, or .claude/rules/ dependencies. Core patterns are self-contained in SKILL.md and references/. Optional external tooling (jq, bash) is assumed available in standard environments. Never use relative paths pointing outside the skill itself. When referencing other components, use: "invoke skill-name" or "invoke skill-name and read its file".
Achieve 80-95% autonomy (0-5 AskUserQuestion rounds per session).
Use What-When-Not-Includes format in descriptions (third person).
Progressive disclosure: SKILL.md contains core philosophy; references/ contains detailed content.
Use XML for control (mission_control, critical_constraint), Markdown for data.
</critical_constraint>
Delta Standard: Good Component = Expert Knowledge − What Claude Already Knows
Recognition Questions
| Question | Recognition |
|---|---|
| Would Claude know this without being told? | Delete (zero delta) |
| Can this work standalone? | Fix if no (non-self-sufficient) |
| Did I read the actual file, or just see it in grep? | Verify before claiming |
Validation Checklist
Before claiming hook development complete:
- • Matcher targets specific tools
- • User communication is clear
- • Timeout protection configured
- • Paths are project-relative
The Path to High-Quality Hooks
1. Precise Matcher Design
Hooks work reliably when matchers target specific tools rather than broad patterns.
- •Target specifically: Match tool name (e.g.,
"Bash"), then filter inside script - •Avoid broad matches: Generic
"*"matchers block legitimate operations - •Test thoroughly: Verify matchers catch intended operations without false positives
2. Clear User Communication
Hooks succeed when users understand why operations are blocked.
- •Prompt type for confirmation: Use
type: "prompt"for destructive operations requiring user consent - •Command type for clear blocks: Use
type: "command"with explanation messages - •Explain clearly: Describe what was detected and why it matters
3. Timeout Protection
Hooks prevent system blocking when timeout values are properly configured.
- •Always set timeouts:
timeout: 30or similar prevents indefinite waiting - •Prevent deadlocks: Operations without timeouts can hang the entire system
- •Reasonable defaults: 30 seconds works for most confirmation prompts
4. Portability Through Relative Paths
Hooks work across environments when paths are project-relative.
- •Use
${CLAUDE_PROJECT_DIR}: Instead of hardcoded paths like/home/user/ - •Environment variables: Externalize configuration for different machines
- •Team compatibility: Project-relative paths work across different home directories
5. Variable Safety
Hooks prevent injection vulnerabilities when variables are properly quoted.
- •Always quote variables:
"$file_path"instead of$file_path - •Prevent injection: Unquoted variables with spaces cause security issues
- •Bash best practices: Use
[[ ]]for tests and quote all expansions
6. Security-First Design
Hooks protect systems when safety mechanisms are properly implemented.
- •Destructive operation confirmation:
rm -rf,sudo, and similar commands require explicit approval - •Protected file guards:
.env, credentials, and config files need special handling - •Escape hatches: Provide emergency override mechanisms for legitimate operations
<critical_constraint> System Physics:
- •Zero external dependencies (portability invariant)
- •Hooks require timeout values to prevent blocking operations
- •Prompt hooks for user confirmation, command hooks for clear blocking
- •Completion claims require verification evidence </critical_constraint>