← SCRAM AI Lab
PreToolUse y PostToolUse son el lugar correcto para bloquear commits a main, formatear código, ejecutar tests y validar comandos peligrosos. Sin pedirle permiso al modelo.
May 21, 2026
10 lecturas
Llevas tres semanas escribiendo "no hagas commits directos a main" en CLAUDE.md y el modelo lo respeta el 95% del tiempo. El otro 5% es el que rompe producción. La solución no es escribirlo más fuerte; es mover la validación fuera del modelo. Los hooks de Claude Code se ejecutan en el harness, no en el LLM: no se "olvidan", no se distraen, no negocian. Si el matcher dispara, el hook corre. Punto.
Esto vive en .claude/settings.json (proyecto) o ~/.claude/settings.json (global). El matcher filtra por nombre de herramienta:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "node ~/.claude/hooks/block-dangerous-bash.js"
}]
},
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "node ~/.claude/hooks/block-protected-files.js"
}]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "node ~/.claude/hooks/prettier-format.js"
}]
}
]
}
}
// ~/.claude/hooks/block-dangerous-bash.js
const input = JSON.parse(require("fs").readFileSync(0, "utf-8"));
const cmd = input.tool_input?.command ?? "";
const dangerous = [
/git\s+push\s+.*\s(main|master)\b/,
/git\s+reset\s+--hard/,
/rm\s+-rf\s+\//,
/DROP\s+TABLE/i,
];
for (const re of dangerous) {
if (re.test(cmd)) {
console.error(`Blocked: command matches ${re}. If intentional, run in shell directly.`);
process.exit(2); // exit code 2 = block + show stderr to model
}
}
process.exit(0);
El exit code 2 es la convención: bloquea la herramienta y pasa el stderr al modelo para que entienda por qué falló. El modelo entonces busca otra forma de cumplir la tarea, no se queda peleando con el harness.
Si te encuentras escribiendo "siempre debes hacer X antes de Y" en un skill, eso es un hook disfrazado. Muévelo.
sk-, AKIA, ghp_.vitest related solo sobre archivos tocados.Si tu hook tarda 4 segundos, lo pagas en cada Edit. Multiplica por 80 edits en una sesión y son 5 minutos perdidos. Los hooks deben ser sub-segundo: validación pura, sin red, sin builds. Si necesitas algo pesado, dispáralo en background y deja que falle async (Slack, métricas), no bloquees la conversación.
Cuenta tus hooks. Si tienes menos de tres, probablemente le estás pidiendo al modelo cosas que el harness debería hacer solo. ¿Cuál validación repites en cada CLAUDE.md y nunca codificaste?
Artículos relacionados
Multiagent en CC v2.1.130: lead delega a specialists
El patrón donde un lead agent delega a specialists usando el filesystem como bus de comunicación. Funciona cuando coordinar tres specialists cuesta menos que hacerlo serial.
Construye tu primer MCP server: el patrón real
Stdio sigue siendo la mejor opción para MCPs propios. HTTP solo si necesitas multi-cliente o auth. Una herramienta, un caso de uso atómico, schema Zod estricto.
MCPs propios: cuándo construir vs adoptar
Adopta cuando hay un MCP mantenido por gente seria. Construye cuando tu lógica de negocio, credenciales o latencia no toleran un intermediario genérico.