🌱 Empieza aquí · Candado de Umbral de Calidad
¿Alguna vez tu asistente te entregó algo diciendo "quedó listo" cuando en realidad quedó a medio filo? Esta semilla le pone un candado de calidad: tú fijas un umbral mínimo para la sesión (por ejemplo, "esta entrega no baja de 9.5") y, si su propia auto-evaluación queda por debajo de ese número, el candado no lo deja cerrar. Lo obliga a seguirle hasta alcanzar la vara que pediste, o a pararte y pedirte permiso si de verdad se atoró. Se acabó el "casi" disfrazado de "listo".
Para instalarla
Abre esta carpeta con Claude Code o Cowork y dile a tu asistente:
"Siembra esta semilla 🌱"
Con eso basta de tu parte. Tu asistente hace todo lo técnico y al final te dice cómo comprobar que quedó funcionando. Vas a ver algunas palabras en inglés en la pantalla; ni caso, él te guía.
¿Otras formas de pedírselo? "instala esta semilla", "pon a funcionar el candado de calidad", "haz el setup de esto". Te entiende igual.
Para el asistente que siembra 🤖
Instala este hook (gancho de automatización) del evento Stop (cuando terminas de
responder). Sigue estos pasos y no inventes rutas: usa $HOME y $CLAUDE_PROJECT_DIR.
Cómo funciona el candado (léelo antes de instalar)
El candado se apoya en dos archivos JSON que viven en el directorio de estado
($CLAUDE_PROJECT_DIR si Claude Code lo expone, si no $HOME/.claude):
eval-gate-active.json— arma el candado de la sesión. Lo escribe la persona (o tú a su pedido) cuando quiere fijar una vara de calidad. Campos:threshold(número): el umbral mínimo, ej.9.5.active_until(texto):"session_end"mientras el candado esté vivo. Cualquier otro valor lo apaga.reason(texto, opcional): por qué se fijó esa vara.
eval-current-score.json— la auto-evaluación del trabajo. La escribes TÚ, el asistente, ANTES de presentar el cierre como "listo para firma". Campos:score(número): qué te calificaste.approved(booleano):falsepor defecto; solotruesi la persona aceptó explícitamente cerrar por debajo del umbral.evidence(texto, opcional): en qué basaste la calificación.
Con el candado armado, si tu score queda por debajo del threshold y approved no
es true, el hook devuelve exit 2 y no te deja cerrar: itera hasta pasar la vara, o
pídele permiso a la persona.
1. Copia el script del kernel (el corazón de la semilla)
Copia kernel/eval-gate-blocker.sh a la carpeta de hooks del usuario y dale permiso
de ejecución.
Claude Code / Cowork (macOS o Linux):
mkdir -p "$HOME/.claude/hooks"
cp kernel/eval-gate-blocker.sh "$HOME/.claude/hooks/eval-gate-blocker.sh"
chmod +x "$HOME/.claude/hooks/eval-gate-blocker.sh"
Windows (Git Bash / WSL): misma ruta ~/.claude/hooks/. El script usa bash,
sed y python3 (o python), disponibles en Git Bash / WSL. Si el usuario corre
Claude Code nativo en Windows sin bash o sin python, avísale que este hook necesita
un entorno con ambos.
2. Registra el hook en settings.json
Abre $HOME/.claude/settings.json (créalo si no existe) y agrega esta entrada dentro
de hooks.Stop. Si ya hay hooks de Stop, suma este objeto al arreglo hooks
existente en lugar de reemplazarlo:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash $HOME/.claude/hooks/eval-gate-blocker.sh",
"timeout": 10
}
]
}
]
}
}
¿Prefieres que muerda también tras cada herramienta de escritura? Puedes registrarlo además en
PostToolUsecon"matcher": "Write|Edit". ConStopbasta para el caso principal (bloquear el cierre).
3. Deja una instrucción permanente para que el asistente se auto-evalúe (recomendado)
El candado solo muerde si el asistente escribe su auto-evaluación en
eval-current-score.json antes de cerrar. Si el asistente del usuario ya tiene el
hábito de auto-calificarse al cerrar, este paso sobra. Si no lo tienes garantizado, deja
esta instrucción donde se cargue siempre, para que el reflejo persista más allá de esta
siembra (si no la dejas, el candado se queda sin score que comparar y deja pasar en
silencio).
Claude Code / Cowork: crea $HOME/.claude/rules/eval-gate-self-score.md (los
archivos de esa carpeta se cargan solos al inicio de cada sesión). Codex: pega el
mismo texto dentro de AGENTS.md. Contenido:
Cuando exista un candado de calidad activo para la sesión (un archivo
`eval-gate-active.json` con `active_until: "session_end"` en el directorio de estado del
candado), antes de presentar cualquier trabajo como "listo para firma" escribe tu
auto-evaluación honesta en `eval-current-score.json`, en ese mismo directorio, con los
campos `score` (número) y `approved` (booleano, `false` salvo que la persona haya
aceptado el hueco). Si tu score queda por debajo del umbral, itera hasta alcanzarlo o
pide permiso explícito; no cierres sin haber escrito tu auto-evaluación.
4. (Opcional) Cambia dónde viven los archivos de estado
Por defecto el candado busca eval-gate-active.json y eval-current-score.json en
$CLAUDE_PROJECT_DIR (o $HOME/.claude si no está definido). Para cambiar la
ubicación, exporta antes de que corra el hook:
EVAL_GATE_DIR— carpeta donde viven ambos archivos.EVAL_GATE_FILE— ruta directa al archivo que arma el candado.EVAL_SCORE_FILE— ruta directa al archivo de auto-evaluación.
5. Verificación post-siembra (obligatoria)
Vamos a probar los tres caminos: bloquea, deja pasar por aprobación y deja pasar sin candado. Usamos una carpeta temporal para no tocar los archivos reales.
a) Caso que BLOQUEA (score por debajo del umbral, sin aprobar):
D=$(mktemp -d)
printf '{"threshold": 9.5, "active_until": "session_end", "reason": "prueba"}' > "$D/eval-gate-active.json"
printf '{"score": 9.3, "approved": false}' > "$D/eval-current-score.json"
EVAL_GATE_DIR="$D" bash "$HOME/.claude/hooks/eval-gate-blocker.sh"; echo "EXIT=$?"
Salida esperada: una línea que empieza con [CANDADO DE CALIDAD · BLOQUEANTE] y
EXIT=2. El candado mordió.
b) Caso que DEJA PASAR por aprobación (mismo score bajo, pero la persona aceptó):
printf '{"score": 9.3, "approved": true}' > "$D/eval-current-score.json"
EVAL_GATE_DIR="$D" bash "$HOME/.claude/hooks/eval-gate-blocker.sh"; echo "EXIT=$?"
Salida esperada: sin bloqueo y EXIT=0.
c) Caso sin candado (no hay gate file → cero fricción):
rm -f "$D/eval-gate-active.json"
EVAL_GATE_DIR="$D" bash "$HOME/.claude/hooks/eval-gate-blocker.sh"; echo "EXIT=$?"
rm -rf "$D"
Salida esperada: sin salida y EXIT=0.
Por último, confirma que el hook quedó registrado en settings.json:
grep -q 'eval-gate-blocker' "$HOME/.claude/settings.json" && echo 'REGISTRADO'
Salida esperada: REGISTRADO.
Cuando las cuatro pruebas den lo esperado, avísale al usuario que ya quedó y explícale en una línea qué gana con esto.
✅ ¿Cómo sé que funcionó?
A partir de ahora puedes decirle a tu asistente algo como "para esta entrega, la vara es 9.5" y él arma el candado. Cuando esté por cerrarte el trabajo, se califica a sí mismo; si no llegó a la vara, el candado lo frena y lo obliga a seguirle hasta pasarla —o a pararte y decirte "me quedé en 9.3 por esto, ¿lo aceptas o le sigo?"—. Nunca más un "listo" que en realidad era un "casi".
Y cuando NO fijas ninguna vara, el candado ni aparece: cero fricción en el día a día. Eso es todo. 🌱
