Si tienes suficientes proyectos secundarios en producción, seguro que alguna parte de tu automatización está silenciosamente en llamas — y te enteras días después, cuando ya es tarde.

Este artículo es la entrega más reciente de una serie sobre cómo construir una base sólida de automatización para producir side projects en masa. Hoy vamos a diseñar un watchdog no supervisado que permite a una IA detectar, reparar y verificar scripts rotos, y que empuja cambios a producción solo cuando la verificación pasa exitosamente.

“No confíes en el auto-reporte de Claude” — esa es la regla de oro.

¿Por qué es necesario que se repare solo?

Cuando produces side projects de forma masiva, la cantidad de scripts de automatización siempre activos crece sin control: publicar artículos de afiliados, scrapers, enviar informes a Discord, verificar el estado de revisión de apps iOS. Cada uno corre bajo launchd o cron. Cuando uno falla, pasan días sin que nadie lo note.

Monitorear y arreglar todo manualmente tiene un límite. Pero simplemente “dejar que la IA lo arregle” conlleva riesgos: reescrituras no deseadas, commits con secretos expuestos, o que reporte una reparación como exitosa cuando en realidad sigue rota.

La solución es self-repair.sh, un watchdog con este flujo:

Detectar → Claude identifica la causa y la repara → el watchdog ejecuta la verificación
     → commit/push/deploy solo cuando pasa
     → revierte los cambios y notifica a un humano si falla

Estructura general del watchdog

Los archivos se organizan así:

~/.claude/self-repair/
├── registry.tsv              # lista de proyectos monitoreados
├── checks/
│   ├── <slug>-health.sh      # health check (exit 0=sano, !=0=roto)
│   └── <slug>-verify.sh      # verificación post-reparación
├── state/
│   └── <slug>-YYYYMMDD.count # contador de intentos del día
└── ~/.claude/scripts/self-repair.sh

~/.claude/logs/
└── self-repair.log

El bucle principal lee registry.tsv y llama a process() para cada proyecto.

Las 7 capas de seguridad del watchdog

Guard 1: Verificación independiente

El watchdog ejecuta verify.sh por su cuenta después de que Claude reporta haber terminado. Si el script de verificación no existe, el watchdog no repara — solo notifica.

[ -x "$verify" ] || {
  log "$slug: verify ausente → reparación no supervisada peligrosa, se salta"
  notify alerts "⚠️ $slug está anómalo pero sin verify → requiere revisión humana"
  return
}

Guard 2: Reversión inmediata en caso de fallo

Si la verificación falla, restore() revierte todo con git reset --hard y git clean -fdq. Los cambios de Claude desaparecen por completo.

Guard 3: Escaneo de secretos

Antes de hacer push, el watchdog escanea el diff staged con expresiones regulares para detectar .env, claves API de Stripe, tokens de AWS, GitHub, Slack, llaves privadas y claves de Google.

“Este escaneo está integrado en el script porque los hooks de Claude no se ejecutan cuando corre bajo launchd.”

Guard 4: Límite de intentos

Máximo 2 intentos por proyecto al día. Al alcanzar el límite, notifica por Discord que “un humano necesita revisar esto”. Así se evita un bucle infinito de reparación.

Guard 5: Límite de costo

Si los tokens de salida del bloque de 5 horas superan un umbral configurable, el watchdog omite todo el ciclo. Es la última línea de defensa contra una fuga de facturación.

Guard 6: Restricción de alcance

Claude corre con --allowedTools "Read,Write,Edit,Bash,Grep,Glob" y máximo 40 turnos, limitado estrictamente al directorio del proyecto.

Guard 7: Verificación del propietario del push

No hace push a menos que el remote de GitHub sea de tu propia cuenta. Esto evita escribir accidentalmente en forks de terceros.

Cómo construir el prompt de reparación

El prompt se ensambla dinámicamente dentro de process(). La clave es pasar la salida de health.sh y los logs recientes como contexto, y declarar explícitamente las restricciones.

La parte más importante es la palabra clave UNFIXABLE:. Cuando la causa está fuera del directorio del proyecto (una API caída, un error de configuración de cron, etc.), el diseño evita que Claude toque lo que no debe.

# Cuando no puedas repararlo, di solo 'UNFIXABLE: <razón>' y termina

Modo “solo detectar”

Configurando mode=detect, el watchdog solo verifica que algo está roto y notifica, sin llamar a Claude. Crea un archivo flag en state/ para notificar solo una vez al día.

Los proyectos que no están bajo git, aquellos donde la reparación tiene efectos secundarios (escritura en APIs externas), o los que no tienen verify.sh, deben dejarse en modo detect.

Ejecución desde launchd

En producción, el watchdog corre periódicamente vía un plist de launchd cada 30 minutos. Como nvm no se carga al ejecutarse desde launchd, hay que pasar la ruta completa al comando claude o exportar PATH explícitamente.

Errores comunes que encontré

  • Olvidar git stash -u: hace que la restauración quede sucia. Siempre hacer stash → reparar → descartar en caso de fallo.
  • Usar el mismo script para health.sh y verify.sh: no tiene sentido. verify.sh debe incluir una prueba que realmente ejecute el procesamiento completo.
  • Construir el escaneo de secretos: no confíes en la protección de push de GitHub. Escanea tú mismo antes de hacer push.
  • Sin gtimeout en macOS: el timeout no funciona. Verificar su existencia con command -v gtimeout.

Resumen

  • Solo registra slug, dir y mode en registry.tsv y el watchdog monitorea todo automáticamente
  • No confíes en el auto-reporte de Claude; el watchdog ejecuta verify.sh independientemente
  • Commit → escaneo de secretos → push solo cuando la verificación pasa. En caso de fallo, reversión inmediata
  • Las 7 capas de seguridad son lo que hace segura la reparación no supervisada
  • Para proyectos fuera de git, sin verify o con efectos secundarios, usa modo detect
  • La escape hatch “UNFIXABLE:” en el prompt evita reescrituras innecesarias

Cuanto más automatización tengas, más crece proporcionalmente el “costo de detectar y reparar fallos”. Una vez que configuras un watchdog, las fallas silenciosas se reducen drásticamente, y aunque algo se rompa a las 3 de la mañana, despiertas con un mensaje de “reparado automáticamente” en Discord.

“El costo de escribir health.sh y verify.sh para cada proyecto es de una sola vez, y el costo operativo es casi cero.”


Sigue explorando estos temas en el blog de DojoFullStack.