Hooks System

How Skilltrace integrates with Claude Code without touching your conversation.

Overview

Skilltrace uses four Claude Code hook events to observe and react at key moments during your session. All hooks are defined in hooks/hooks.json and dispatched via hooks/wrapper.sh. The most critical hook, PreToolUse, delegates to a dedicated gate script (hooks/gate.sh) that controls project initialization and task-boundary enforcement.

Hook Events

EventWhenWhat Skilltrace Does
PreToolUseBefore every tool callThree-stage gate: subagent bypass, project initialization, task boundary enforcement
SessionStartSession opensCreates required directories, prints welcome message
UserPromptSubmitAfter each user promptArms a pending file for the task boundary gate
SessionEndSession closesTriggers final skilltracer evaluation

The Gate

The PreToolUse hook delegates to hooks/gate.sh, the core enforcement mechanism. Every tool call passes through three stages in order:

Stage 0 — Subagent Bypass

If the incoming request contains an agent_id, the tool call came from a subagent spawned by Claude main (such as the skilltracer itself). These calls exit immediately with code 0 — spawned agents skip the gate entirely.

Stage 1 — Init Gate

If the project's .skilltrace marker file is missing, the gate blocks all tool calls and forces an AskUserQuestion prompt, asking the user whether to enable tracking or skip. A whitelist allows non-blocking tools through even when the project is uninitialized: AskUserQuestion, TaskCreate, TaskUpdate, TaskList, TaskGet, and Cron* tools.

The gate is worktree-aware: when running inside a Claude Code worktree, it resolves the .skilltrace marker from the original project root rather than the worktree directory.

Stage 2 — Task Boundary

When the UserPromptSubmit hook arms a pending file, the gate denies the very first tool call to force Claude main to spawn the skilltracer agent in background before continuing work. The pending file is consumed atomically via mv to prevent race conditions in concurrent sessions. After the denial, a whitelist of tools is allowed through: AskUserQuestion, Task*, Cron*, wrapper.sh, skilltrace: commands, Workflow, Agent, and EnterPlanMode.

Zero Context Pollution

Hooks run outside your main conversation. Skilltrace never injects text into your chat, never adds system prompts, and never consumes your context window.

Cross-Platform Dispatch

The hooks/wrapper.sh script handles platform detection and routes hook events to the appropriate Python handlers. Works on macOS, Linux, and Windows.

Worktree Support

When Claude Code is running inside a worktree (under .claude/worktrees/), the gate resolves the .skilltrace marker from the original project root. This ensures tracking state is shared across the main checkout and all worktrees, so you never get duplicate initialization prompts.