Master ACOS hooks for automated quality enforcement. SessionStart, PreToolUse, PostToolUse, and Notification hooks that catch issues before they ship.

Implement hooks that automatically enforce quality standards in your ACOS workflows.
Catch mistakes before they ship. Automatically.
ACOS hooks are automated checkpoints that run at key moments: SessionStart (load context), PreToolUse (check before writing), PostToolUse (validate after writing), and Notification (suggest skills). Configure them in .claude/hooks.json. This guide covers the 4 hook types, practical examples, and how to build custom quality gates.
Hooks are automated scripts that run at specific points in the Claude Code lifecycle. Think of them as quality gates that catch issues before they become problems.
Without Hooks:
User: "Write a blog post"
Claude: [Writes post with banned phrases]
User: [Publishes, realizes brand voice is wrong]
User: [Manually fixes, wastes time]
With Hooks:
User: "Write a blog post"
Claude: [Writes post]
Hook: [Detects "synergy", suggests alternative]
Claude: [Rewrites with correct voice]
User: [Publishes confidently]
When: Every time you open Claude Code Purpose: Load context, set up environment
{
"hooks": {
"SessionStart": [
{
"name": "load-acos-context",
"script": "echo 'ACOS v6.0 loaded'",
"timeout": 5000
},
{
"name": "check-skill-rules",
"script": "cat ~/.claude/skill-rules.json > /dev/null && echo 'Skills ready'"
}
]
}
}
Use Cases:
When: Before Claude writes to a file or executes a tool Purpose: Validate content before it's created
{
"hooks": {
"PreToolUse": [
{
"name": "brand-voice-check",
"trigger": "Write|Edit",
"script": "check-brand-voice.sh",
"block_on_failure": true
}
]
}
}
Use Cases:
When: After Claude completes a tool action Purpose: Validate output, trigger follow-up actions
{
"hooks": {
"PostToolUse": [
{
"name": "quality-score",
"trigger": "Write",
"script": "calculate-quality-score.sh"
},
{
"name": "auto-format",
"trigger": "Write|Edit",
"script": "prettier --write"
}
]
}
}
Use Cases:
When: When specific patterns are detected in conversation Purpose: Suggest relevant skills or actions
{
"hooks": {
"Notification": [
{
"name": "suggest-skill",
"pattern": "test|testing|spec",
"message": "Consider loading test-driven-development skill"
}
]
}
}
Use Cases:
The hooks configuration lives in .claude/hooks.json:
{
"version": "1.0",
"hooks": {
"SessionStart": [...],
"PreToolUse": [...],
"PostToolUse": [...],
"Notification": [...]
},
"enforcement": {
"bannedPhrases": ["synergy", "leverage", "circle back"],
"requiredPatterns": ["TL;DR", "FAQ"]
}
}
| Property | Type | Description |
|---|---|---|
name | string | Unique identifier |
script | string | Shell command to run |
trigger | string | Tool name pattern (regex) |
pattern | string | Text pattern to match |
timeout | number | Max execution time (ms) |
block_on_failure | boolean | Stop if hook fails |
message | string | Notification message |
Catch phrases that don't match your brand:
{
"hooks": {
"PreToolUse": [
{
"name": "brand-voice",
"trigger": "Write|Edit",
"script": "~/.claude/scripts/brand-voice-check.sh",
"block_on_failure": true
}
]
},
"enforcement": {
"bannedPhrases": [
"synergy",
"leverage",
"circle back",
"touch base",
"deep dive",
"low-hanging fruit",
"move the needle",
"think outside the box"
],
"suggestedAlternatives": {
"synergy": "collaboration",
"leverage": "use",
"circle back": "follow up",
"touch base": "connect",
"deep dive": "detailed look"
}
}
}
brand-voice-check.sh:
#!/bin/bash
content="$1"
banned=("synergy" "leverage" "circle back")
for phrase in "${banned[@]}"; do
if echo "$content" | grep -qi "$phrase"; then
echo "BLOCKED: Found banned phrase '$phrase'"
echo "Suggestion: Use alternative from brand guide"
exit 1
fi
done
echo "Brand voice check passed"
exit 0
Ensure articles meet SEO requirements:
{
"hooks": {
"PostToolUse": [
{
"name": "seo-check",
"trigger": "Write",
"pattern": "\\.mdx$",
"script": "~/.claude/scripts/seo-check.sh"
}
]
}
}
seo-check.sh:
#!/bin/bash
file="$1"
# Check for TL;DR
if ! grep -q "## TL;DR\|## TL;DR" "$file"; then
echo "WARNING: Missing TL;DR section"
fi
# Check for FAQ
if ! grep -q "## FAQ\|## Frequently Asked" "$file"; then
echo "WARNING: Missing FAQ section"
fi
# Check meta description length
desc=$(grep -A1 "description:" "$file" | tail -1 | tr -d '"')
len=${#desc}
if [ $len -lt 150 ] || [ $len -gt 160 ]; then
echo "WARNING: Meta description is $len chars (target: 150-160)"
fi
echo "SEO check complete"
Format code after every write:
{
"hooks": {
"PostToolUse": [
{
"name": "prettier",
"trigger": "Write|Edit",
"pattern": "\\.(ts|tsx|js|jsx|json)$",
"script": "prettier --write"
},
{
"name": "eslint-fix",
"trigger": "Write|Edit",
"pattern": "\\.(ts|tsx|js|jsx)$",
"script": "eslint --fix"
}
]
}
}
Run tests after code changes:
{
"hooks": {
"PostToolUse": [
{
"name": "run-tests",
"trigger": "Write|Edit",
"pattern": "src/.*\\.(ts|tsx)$",
"script": "npm test -- --related",
"timeout": 30000
}
]
}
}
Suggest skills based on context:
{
"hooks": {
"Notification": [
{
"name": "suggest-tdd",
"pattern": "test|testing|spec|coverage",
"message": "💡 Consider using: /skill test-driven-development"
},
{
"name": "suggest-security",
"pattern": "auth|password|token|secret",
"message": "🔒 Security patterns: /skill security-best-practices"
},
{
"name": "suggest-music",
"pattern": "suno|track|song|music",
"message": "🎵 Music creation: /skill suno-ai-mastery"
}
]
}
}
mkdir -p ~/.claude/scripts
touch ~/.claude/scripts/my-hook.sh
chmod +x ~/.claude/scripts/my-hook.sh
#!/bin/bash
# my-hook.sh
# Input: file path or content passed as argument
input="$1"
# Your validation logic
if [[ condition ]]; then
echo "Check passed"
exit 0
else
echo "Check failed: reason"
exit 1
fi
{
"hooks": {
"PreToolUse": [
{
"name": "my-custom-hook",
"trigger": "Write",
"script": "~/.claude/scripts/my-hook.sh",
"block_on_failure": true
}
]
}
}
# Test the script directly
~/.claude/scripts/my-hook.sh "test content"
# Then use in Claude Code
claude
# Trigger the condition that should run your hook
{
"timeout": 5000 // 5 seconds max
}
Slow hooks frustrate users. If a check takes >5 seconds, consider running it asynchronously.
# Bad
exit 1
# Good
echo "BLOCKED: Found 'synergy' in line 42"
echo "Suggestion: Replace with 'collaboration'"
exit 1
Only block on critical issues:
Don't block on:
#!/bin/bash
# Add to every hook
echo "[$(date)] Hook: $0, Input: $1" >> ~/.claude/hooks.log
# Test before adding to hooks.json
./my-hook.sh "test input"
echo $? # Check exit code
Check hooks.json syntax:
jq . ~/.claude/hooks.json
Verify trigger pattern matches:
echo "Write" | grep -E "Write|Edit"
Check script permissions:
ls -la ~/.claude/scripts/
Run script manually:
~/.claude/scripts/my-hook.sh "test"
Check logs:
tail -f ~/.claude/hooks.log
Add debug output:
set -x # Add to script for verbose output
ACOS v6 ships with these default hooks:
{
"hooks": {
"SessionStart": [
{
"name": "acos-context",
"script": "echo 'ACOS v6.0 | 25 Commands | 80+ Skills | 40+ Agents'"
}
],
"PreToolUse": [
{
"name": "brand-voice",
"trigger": "Write",
"pattern": "\\.mdx$",
"script": "check-brand-voice.sh"
}
],
"PostToolUse": [
{
"name": "quality-score",
"trigger": "Write",
"pattern": "\\.mdx$",
"script": "calculate-quality.sh"
}
],
"Notification": [
{
"name": "skill-suggestions",
"pattern": "blog|article|content",
"message": "Content creation detected. Skills loaded: content-strategy"
}
]
}
}
Hooks are automated scripts that run at specific points in the Claude Code lifecycle. They enable quality gates, brand voice enforcement, and automated workflows without manual intervention.
Yes, if block_on_failure: true is set. Use this for critical quality gates like security checks or brand voice enforcement.
Run the script manually, check the exit code, and review any logs. Add set -x to scripts for verbose output.
Hooks can trigger on any tool. Use the trigger property with regex patterns to match specific tools.
Yes. Hooks run in order defined in the array. If one blocks, subsequent hooks don't run.
.claude/hooks.json in your ACOS installAutomate quality. Ship with confidence.
Read on FrankX.AI — AI Architecture, Music & Creator Intelligence
Join 1,000+ creators and architects receiving weekly field notes on AI systems, production patterns, and builder strategy.
No spam. Unsubscribe anytime.