← 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
148 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
Dynamic workflows en Claude Code: orquesta cientos de subagentes
El 28 de mayo de 2026 Claude Code estrenó dynamic workflows: Claude escribe un script JS que coordina decenas o cientos de subagentes en paralelo. Un dev portó Bun de Zig a Rust —750K líneas— en 11 días. Aquí cómo funciona.
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.