Skill hooks
Fire inline only, not in a fork; full JSON over stdin: middleware.
One node in a single signed graph. Here is how this primitive connects across the other layers.
Skill hooks are frontmatter-configured middleware that fire on tool use events during inline (non-forked) skill execution.
How They Work
Hooks attach to a skill via YAML frontmatter under hooks, scoped to PreToolUse or PostToolUse events. Each entry specifies a tool matcher (e.g. Read, Bash) and a list of hook actions; supported action types include command (shell execution). Hooks fire synchronously during the matched tool invocation within the main thread of the skill that defined them.
hooks:
PreToolUse:
- matcher: "Read"
hooks:
- type: command
command: "echo 'before read' >> /tmp/audit.log"
PostToolUse:
- matcher: "Read"
hooks:
- type: command
command: "echo 'after read' >> /tmp/audit.log"
What the Test Found
A test skill with PreToolUse and PostToolUse hooks on the Read tool ran successfully in inline context; both hooks fired in order. However, when the same skill ran with context: fork, the hooks did not fire. The forked agent received the skill instructions but not the frontmatter hooks. The once: true option was confirmed to work as a per-invocation gate: a hook marked once: true fires exactly once per skill invocation, resetting on the next invocation.
Scope and Constraints
Hooks are main-thread only. Forked execution isolates a skill into a separate agent context where frontmatter hooks are not available. This is by design: hooks can have side effects (file I/O, external calls), and isolation prevents unexpected propagation to child processes. Hooks are scoped to the skill that defines them; they fire only during that skill's execution, not globally.
Use Cases
Skill hooks enable inline validation (check preconditions before a tool runs), audit logging (track tool usage), external system triggers, and guardrails (block or modify sensitive operations). Fork-free skills can leverage hooks for deterministic middleware; forked skills must rely on logic within the skill instructions themselves.
- commitc3b72df ↗
primitive_3216f3cc238fe42f806c32dbed255199b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd009575e9e1b2a2f3c6a11980f53e9763b2071327fcfa174ecdfd0583c3b3f79e0013a66214d13236e8b2f6b400b36635dabe5ab989471b7225db2d3864b2e50bSigned with an ed25519 key held off the repo. Anyone can verify against the published public key; nobody without the secret key can forge it. Click verify: it recomputes the signature in your browser. The signature proves integrity and authorship of this exact content — not a third-party timestamp or that the underlying claim is objectively true. signedAt is when the @f3/attest pipeline ran, not when the work happened; the evidence refs carry the source dates.
- instance-of Event Interposition Class
- introduces (in) Claude Code 2.1.0 (Night Zero) Release
- verifies (in) Skill hooks — runtime test Test