Claude Code hooks: el límite programable alrededor del modelo
La respuesta breve
CLAUDE.md puede indicarle a Claude cómo debería comportarse, pero si Claude lo sigue depende del criterio del modelo. Los hooks son otra respuesta: un mecanismo de control programable que se ejecuta dentro del flujo de ejecución de Claude Code.
Cuando Claude está a punto de llamar a una herramienta, escribir un archivo o ejecutar un comando, los hooks intervienen antes de la acción y deciden si permitirla, bloquearla o pedir confirmación humana. El juicio no depende de que el modelo recuerde una regla: depende del código que hayas escrito de antemano. Esa es la garantía central.
Estructura de un hook
Los hooks viven en settings.json, organizados en tres capas anidadas:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{ "type": "command", "command": "echo 'a write happened'" }
]
}
]
}
}
- Event —
PreToolUse,PostToolUse,Notification, etc. El registro de dónde quieres intervenir. - Matcher — cuándo se activa este grupo.
Writesolo coincide con escrituras de archivo; omítelo para coincidir con todo. - Hook — la lógica real, p. ej. un comando o una llamada HTTP.
El sistema oficial actualmente lista 28 eventos y 5 tipos de hook (command, http, mcp_tool, prompt, agent). Los hooks pueden definirse en seis ubicaciones: ajustes de usuario, proyecto, proyecto local, política gestionada, plugin hooks y frontmatter de skill/agent.
Bloqueante vs no bloqueante y la trampa del código de salida
Los eventos siguen dos caminos:
- Eventos del flujo principal (SessionStart, PreToolUse, PermissionRequest, PostToolUse, Stop) pueden ser bloqueantes: pausan el flujo y su resultado decide qué sucede a continuación.
- Eventos de vía lateral (Notification, ConfigChange) son no bloqueantes: observan y notifican sin interceptar.
Para eventos bloqueantes hay dos formas de bloquear, y significan cosas distintas:
exit 2— un error a nivel de sistema (herramienta faltante, entorno roto). El modelo percibe que la operación falló y puede intentar otra forma de resolverlo.exit 0+ JSON con una decisión de política como{"decision": "deny"}— un rechazo por regla de negocio. El modelo acepta la decisión y se ajusta. El JSON también puede adjuntar unareasony modificar la entrada de la herramienta medianteupdatedInput.
> La trampa oculta: exit 1 no es bloqueante en el sistema de hooks de Claude Code. Solo exit 2 bloquea realmente el flujo.
Mecanismos de fusión y decisión
Cuando hooks de múltiples capas (usuario, proyecto, plugin, skill) coinciden en el mismo evento, Claude Code:
- Los ejecuta en paralelo.
- Elimina duplicados de hooks idénticos — misma cadena de comando o misma URL para HTTP.
- Resuelve las decisiones por el resultado más estricto: deny > ask > allow.
Un deny de cualquier capa es suficiente para bloquear. Permitir requiere que todos estén de acuerdo; rechazar necesita solo un veto. Así que no tienes que repetir cada restricción en cada capa: gana el resultado más estricto independientemente de dónde provenga.
Alcance y ciclo de vida
Los hooks tienen distintas duraciones según dónde se definan:
- Los hooks de la configuración principal son residentes — activos durante toda la sesión.
- Los hooks de plugins se activan cuando el plugin se carga.
- Los hooks de skills y subagents son temporales — se registran al invocarlos y se eliminan cuando terminan. Esto evita que los hooks de una skill contaminen otros trabajos.
Un subagent puede registrar hooks en su frontmatter: por ejemplo, un code-reviewer oficial valida cada comando Bash antes de que se ejecute y realiza linting después de cada edición. Si registras un hook Stop en un subagent, en tiempo de ejecución se convierte automáticamente en SubagentStop.
Una nota de seguridad: los plugin subagents no admiten hooks — los campos hooks, mcpServers y permissionMode en el frontmatter de un plugin-subagent son ignorados, por lo que un rol con menos privilegios no puede reescribir las reglas de control de flujo.
Uso real
Los hooks no solo bloquean. Los casos más instructivos los usan para contexto y puente:
- superpowers registra un único hook
SessionStartque inyecta sus instrucciones metodológicas en la sesión como contexto, de modo que cada sesión comienza correctamente — un uso ligero de "llevar la información correcta en el momento correcto". - claude-code-warp registra varios hooks (SessionStart, Stop, Notification, PermissionRequest, UserPromptSubmit, PostToolUse) para traducir los eventos del ciclo de vida de Claude Code en eventos de estado del terminal — convirtiendo el protocolo en una experiencia de notificación de finalización/permiso.
Ese segundo patrón es común: hooks como puente de eventos, sincronizando la ejecución de Claude Code con un sistema externo.
Conclusión
Los hooks ocupan una posición insustituible en el sistema de Claude Code: CLAUDE.md ayuda al modelo a entender el proyecto, las skills organizan tareas complejas y los hooks protegen el límite en puntos clave. Cambian el "esperar que el modelo lo recuerde" por "código determinista que se ejecuta en el momento correcto".
Trátalos como código de producción, porque eso es lo que son: un script con un código de salida incorrecto puede interrumpir el flujo, y un Stop mal manejado puede atrapar la sesión en un bucle. Diseña para las rutas de error con la misma seriedad que para cualquier código que vayas a desplegar.
Fuente primaria: A Complete Guide to Claude Code: Hooks (zhaozhiming), que sintetiza la documentación oficial de hooks. El recuento de eventos (28), tipos de hook (5) y las semánticas de exit-code/fusión se verificaron contra la guía y se cruzaron con la documentación oficial el 2026-08-08.