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
| Event | When | What Skilltrace Does |
|---|---|---|
PreToolUse | Before every tool call | Three-stage gate: subagent bypass, project initialization, task boundary enforcement |
SessionStart | Session opens | Creates required directories, prints welcome message |
UserPromptSubmit | After each user prompt | Arms a pending file for the task boundary gate |
SessionEnd | Session closes | Triggers 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.