Hooks

Audience: Customer — this page explains what data Rulecatch captures from your Claude Code sessions.

Rulecatch uses Claude Code hooks to capture AI development events. Hooks run as shell commands outside the AI's context window, adding zero token overhead.


All 14 Hook Events

Rulecatch registers all 14 Claude Code hook types during setup. Each hook fires at a specific point in the AI workflow:

Session Lifecycle

Hook Event Type When It Fires What It Captures
SessionStart session_start Claude Code session begins Model, git context, account info, working directory
SessionEnd session_end Session concludes Token deltas, cost estimate, model breakdown, git diff stats

Tool Lifecycle

Hook Event Type When It Fires What It Captures
PreToolUse pre_tool_use Before a tool runs Tool name (used internally for pre-processing)
PostToolUse tool_call After a successful tool call Tool name, file path, I/O size, language, lines changed, git context
PostToolUseFailure tool_call After a failed tool call Tool name, error message, file path (toolSuccess=false)
PermissionRequest permission_request Tool requests elevated permissions Tool name requesting permission

User Interaction

Hook Event Type When It Fires What It Captures
UserPromptSubmit user_prompt User sends a message Prompt length (never prompt content)
Stop session_end User exits Claude Code Final token counts, cost, git diff stats

Turn & Conversation

Hook Event Type When It Fires What It Captures
Notification notification System notification occurs Notification type and message
PreCompact compaction_start Conversation context is compressed Trigger type (auto or manual)

Subagents & Teams

Hook Event Type When It Fires What It Captures
SubagentStart subagent_start A subagent is spawned Agent type
SubagentStop subagent_stop A subagent finishes Agent type
TeammateIdle teammate_idle A teammate goes idle Teammate name
TaskCompleted task_completed A task finishes Task subject

Data Captured Per Event

session_start

Field Source Description
type Set to session_start Event type
sessionId Claude Code Unique session identifier
model Claude Code AI model being used
cwd System Working directory (encrypted if privacy enabled)
gitRepo Git Repository name
gitBranch Git Current branch
gitCommit Git Current commit hash
gitUsername Git Configured git username (encrypted)
gitEmail Git Configured git email (encrypted)
timestamp System ISO timestamp

tool_call (PostToolUse / PostToolUseFailure)

Field Source Description
type Set to tool_call Event type
sessionId Claude Code Session identifier
toolName Claude Code (stdin) Tool name (Read, Write, Edit, Bash, etc.)
toolSuccess Hook logic true for PostToolUse, false for PostToolUseFailure
filePath Parsed from tool input File being operated on (encrypted)
language Derived from file extension Programming language
toolInputSize Calculated Input data size in bytes
toolOutputSize Calculated Output data size in bytes
linesAdded Git diff Lines added (incremental)
linesRemoved Git diff Lines removed (incremental)
fileOperation Parsed Type of operation (read/write/edit/etc.)
model Cached from session start Model name for cost estimation
activeTimeMs Calculated Time since last event
timestamp System ISO timestamp

session_end (Stop / SessionEnd)

Field Source Description
type Set to session_end Event type
sessionId Claude Code Session identifier
inputTokens Stats cache delta Total input tokens for session
outputTokens Stats cache delta Total output tokens for session
thinkingTokens Stats cache delta Total thinking tokens
cacheReadTokens Stats cache delta Cache read tokens
cacheWriteTokens Stats cache delta Cache write tokens
estimatedCost Calculated Estimated session cost
model Cached from session start Primary model used
modelsBreakdown Stats cache Per-model token/cost breakdown
linesAdded Git diff Final lines added count
linesRemoved Git diff Final lines removed count
timestamp System ISO timestamp

user_prompt (UserPromptSubmit)

Field Source Description
type Set to user_prompt Event type
sessionId Claude Code Session identifier
promptLength Calculated Character count of user's prompt
timestamp System ISO timestamp

Note: Prompt content is never captured — only the length.

turn_complete

Field Source Description
type Set to turn_complete Event type
sessionId Claude Code Session identifier
timestamp System ISO timestamp

subagent_start / subagent_stop

Field Source Description
type subagent_start or subagent_stop Event type
sessionId Claude Code Session identifier
agentType Claude Code Type of subagent (e.g., "Explore", "Plan")
timestamp System ISO timestamp

permission_request

Field Source Description
type Set to permission_request Event type
sessionId Claude Code Session identifier
toolName Claude Code Tool requesting permission
timestamp System ISO timestamp

Other event types

notification, teammate_idle, task_completed, and compaction_start follow a similar minimal structure with type, sessionId, timestamp, and type-specific metadata fields.


How Hooks Work

1. Hook Registration

During init, all 14 hooks are registered in ~/.claude/settings.json:

{
  "hooks": {
    "SessionStart": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 30 }] }],
    "SessionEnd": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 30 }] }],
    "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "PreToolUse": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "PostToolUse": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "PostToolUseFailure": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "PermissionRequest": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "Notification": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "SubagentStart": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "SubagentStop": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "Stop": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "TeammateIdle": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "TaskCompleted": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }],
    "PreCompact": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/rulecatch-track.sh", "timeout": 10, "async": true }] }]
  }
}

2. Hook Execution

When Claude Code fires a hook:

  1. The hook script receives event data via stdin (JSON) and environment variables
  2. The script extracts relevant fields
  3. PII fields are encrypted locally (if encryption is configured)
  4. Creates a JSON buffer file
  5. Appends to events.log for the live monitor
  6. Exits immediately (< 1ms)

3. Buffer File

Each event is written as a separate JSON file:

~/.claude/rulecatch/buffer/<timestamp>-<type>-<random>.json

Example: 1707234567890-tool_call-a3f2b1.json

4. Flush Trigger

After writing the buffer file, the hook checks if the buffer has reached the batch size threshold. If so, it triggers the flush script asynchronously (in the background, without blocking Claude Code).


Model Detection

The model is captured at session_start and cached to a temporary file:

/tmp/rulecatch-model-<SESSION_ID>

This cached model is used in subsequent events when the model isn't directly available from hook context.


Git Diff Stats

Lines added/removed are captured from git diff:

git diff --stat HEAD

This is run incrementally on each tool call, providing real-time code change metrics without waiting for session end.


File Locations

File Purpose
~/.claude/hooks/rulecatch-track.sh Main hook script
~/.claude/hooks/rulecatch-flush.js Flush/send script
~/.claude/rulecatch/buffer/*.json Buffered events
~/.claude/rulecatch/events.log Event log (for live monitor)
~/.claude/rulecatch/flush.log Flush activity log
/tmp/rulecatch-hook.log Hook debug log
/tmp/rulecatch-model-* Cached model per session

Zero Token Guarantee

Hooks add zero tokens because:

  1. Shell execution — Hooks run as shell commands, completely outside the AI model's context
  2. No prompt modification — Nothing is added to AI prompts
  3. No response modification — AI responses pass through unmodified
  4. Async buffer writes — File I/O doesn't block the AI
  5. Background flushes — Network calls happen in background processes

Debugging

Check Hook Log

npx @rulecatch/ai-pooler logs --source=hook

Check if Hooks Are Registered

npx @rulecatch/ai-pooler status
# Look for "Hooks config: + All 14/14 registered"

Manual Hook Test

echo '{"tool_name":"Read","tool_input":"/test.ts"}' | bash ~/.claude/hooks/rulecatch-track.sh tool_call

See Also