Skip to content

Hooks Overview

The Mistaber encoding plugin uses seven specialized hooks to enforce workflow discipline, validate encoding quality, log source fetches, and ensure human approval at critical checkpoints.

Hook Architecture

graph TB
    subgraph "Session Lifecycle"
        SS[SessionStart] --> H1[session-init]
    end

    subgraph "PreToolUse Hooks"
        PT[PreToolUse] --> H2[phase-gate]
        PT --> H3[encoding-guard]
        PT --> H4[sefaria-logger]
        PT --> H5[git-commit-guard]
    end

    subgraph "PostToolUse Hooks"
        PO[PostToolUse] --> H6[validation-handler]
    end

    subgraph "Session End"
        ST[Stop] --> H7[checkpoint-enforcement]
    end

The Seven Hooks

1. Session Initialization (session-init)

Event: SessionStart Purpose: Load workflow state, inject context about current phase and pending checkpoints.

Attribute Value
Event SessionStart
Matcher None (all sessions)
Blocking Never
Timeout 10000ms

Full Documentation


2. Phase Gate (phase-gate)

Event: PreToolUse (Write, Edit) Purpose: Prevent out-of-order writes to ontology files.

Attribute Value
Event PreToolUse
Matcher Write|Edit
Blocking Yes (when checkpoint not approved)
Timeout 5000ms

Full Documentation


3. Encoding Guard (encoding-guard)

Event: PreToolUse (Write .lp) Purpose:* Validate HLL content before writing to ontology files.

Attribute Value
Event PreToolUse
Matcher Write
Blocking Yes (when validation fails)
Timeout 5000ms

Full Documentation


4. Sefaria Logger (sefaria-logger)

Event: PreToolUse (Sefaria MCP) Purpose: Log all Sefaria source fetches for traceability.

Attribute Value
Event PreToolUse
Matcher mcp__sefaria
Blocking Never
Timeout 3000ms

Full Documentation


5. Validation Handler (validation-handler)

Event: PostToolUse (Bash) Purpose: Parse test results, update session state.

Attribute Value
Event PostToolUse
Matcher Bash
Blocking Never
Timeout 5000ms

Full Documentation


6. Checkpoint Enforcement (checkpoint-enforcement)

Event: Stop Purpose: Warn about pending checkpoints on session end.

Attribute Value
Event Stop
Matcher None (all stops)
Blocking Never (warning only)
Timeout 5000ms

Full Documentation


7. Git Commit Guard (git-commit-guard)

Event: PreToolUse (Bash git commit) Purpose: Require review approval before committing ontology changes.

Attribute Value
Event PreToolUse
Matcher Bash
Blocking Yes (when review not approved)
Timeout 5000ms

Full Documentation


Hook Event Types

SessionStart

Triggered once at the beginning of each Claude Code session.

Available Variables: None

Use Cases: - Initialize session state - Display welcome messages - Load configuration

PreToolUse

Triggered before any tool execution.

Available Variables:

Variable Description
$TOOL_NAME Name of the tool being called
$TOOL_INPUT JSON input to the tool

Use Cases: - Validate tool inputs - Enforce workflow order - Log operations - Block prohibited actions

PostToolUse

Triggered after tool execution completes.

Available Variables:

Variable Description
$TOOL_NAME Name of the tool called
$TOOL_INPUT JSON input to the tool
$TOOL_OUTPUT Output from the tool

Use Cases: - Parse command output - Update state based on results - Capture metrics

Stop

Triggered when the session ends.

Available Variables: None

Use Cases: - Save session state - Generate summaries - Warn about pending work

Hook Configuration

Hooks are defined in hooks/hooks.json:

{
  "SessionStart": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-init.py",
          "timeout": 10000
        }
      ]
    }
  ],
  "PreToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/phase-gate.py \"$TOOL_INPUT\"",
          "timeout": 5000
        }
      ]
    },
    {
      "matcher": "Write",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/encoding-guard.py \"$TOOL_INPUT\"",
          "timeout": 5000
        }
      ]
    },
    {
      "matcher": "mcp__sefaria",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/sefaria-logger.py \"$TOOL_NAME\" \"$TOOL_INPUT\"",
          "timeout": 3000
        }
      ]
    },
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/git-commit-guard.py \"$TOOL_INPUT\"",
          "timeout": 5000
        }
      ]
    }
  ],
  "PostToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validation-handler.py \"$TOOL_OUTPUT\"",
          "timeout": 5000
        }
      ]
    }
  ],
  "Stop": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/checkpoint-enforcement.py",
          "timeout": 5000
        }
      ]
    }
  ]
}

Hook Execution Order

When multiple hooks match the same event, they execute in the order defined in hooks.json:

sequenceDiagram
    participant Tool as Tool Call
    participant HE as Hook Engine
    participant H1 as Hook 1
    participant H2 as Hook 2
    participant Exec as Tool Execution

    Tool->>HE: Write tool called
    HE->>H1: phase-gate
    H1-->>HE: continue: true
    HE->>H2: encoding-guard
    H2-->>HE: continue: true
    HE->>Exec: Execute tool
    Exec-->>HE: Result
    HE-->>Tool: Complete

Chaining Rules:

  1. Hooks execute in order
  2. If any hook returns continue: false, subsequent hooks are skipped
  3. Tool execution only proceeds if all hooks return continue: true

Hook Response Format

All hook scripts must output JSON to stdout:

{
  "continue": true,
  "message": "Optional message to display"
}

Response Fields:

Field Type Required Description
continue boolean Yes true to allow, false to block
message string No Message displayed to user

Blocking Response:

{
  "continue": false,
  "message": "BLOCKED: Checkpoint not approved\n\nDetails..."
}

Non-Blocking Response:

{
  "continue": true,
  "message": "Logged source fetch: Genesis 1:1"
}

Blocking vs Non-Blocking Hooks

Blocking Hooks

These hooks can prevent tool execution:

Hook Blocks When
phase-gate Writing to ontology without checkpoint approval
encoding-guard HLL validation fails
git-commit-guard Committing without review approval

Non-Blocking Hooks

These hooks never prevent tool execution:

Hook Purpose
session-init Informational only
sefaria-logger Logging only
validation-handler State update only
checkpoint-enforcement Warning only

Session State Integration

Several hooks read and write session state in .mistaber-session.yaml:

current_phase: hll-encode
target_seif: "YD:87:3"
checkpoints:
  corpus-prep:
    status: approved
    timestamp: "2026-01-25T10:30:00Z"
  hll-encode:
    status: pending_review
  validate:
    status: not_started
    # validation-handler writes here:
    last_test_run: "2026-01-25T14:00:00Z"
    test_results:
      passed: 25
      failed: 0
  review:
    status: not_started

State Access:

Hook Reads Writes
session-init Yes No
phase-gate Yes No
encoding-guard No No
sefaria-logger No Yes (log file)
validation-handler Yes Yes
checkpoint-enforcement Yes Yes
git-commit-guard Yes No

Debugging Hooks

Enable Debug Output

export MISTABER_DEBUG=1

Test Hooks Manually

# Test session-init
python mistaber-skills/hooks/scripts/session-init.py

# Test phase-gate
python mistaber-skills/hooks/scripts/phase-gate.py '{"file_path": "test.lp"}'

# Test encoding-guard
python mistaber-skills/hooks/scripts/encoding-guard.py '{"file_path": "test.lp", "content": "rule(r_test)."}'

Check Hook Output

# Run hook and see JSON output
python mistaber-skills/hooks/scripts/session-init.py | jq .

Common Issues

Hook Timeout

Symptom: Hook doesn't respond in time.

Solutions: 1. Increase timeout in hooks.json 2. Optimize hook script 3. Check for network issues (sefaria-logger)

Hook Script Not Found

Symptom: "Script not found" error.

Solutions: 1. Verify ${CLAUDE_PLUGIN_ROOT} is set 2. Check script path in hooks.json 3. Ensure Python is available

Hook Blocks Incorrectly

Symptom: Legitimate operations blocked.

Solutions: 1. Check session state file 2. Verify checkpoint status 3. Review hook matching pattern

Quick Reference

Hook Summary Table

Hook Event Matcher Blocks Purpose
session-init SessionStart - No Initialize session
phase-gate PreToolUse Write|Edit Yes Enforce phase order
encoding-guard PreToolUse Write Yes Validate HLL
sefaria-logger PreToolUse mcp__sefaria No Log sources
validation-handler PostToolUse Bash No Parse test results
checkpoint-enforcement Stop - No Warn on pending
git-commit-guard PreToolUse Bash Yes Require approval