Tips & Tricks (Actualizado: 3/6/2026)

Incidentes de producción con Claude Code: detección, rollback, RCA y prevención

Guía práctica para incidentes con Claude Code: secretos, borrados, BD, costes, rollback, RCA y prevención.

Incidentes de producción con Claude Code: detección, rollback, RCA y prevención

Claude Code acelera el trabajo porque puede leer archivos, editar código y ejecutar comandos. En producción, esa velocidad también aumenta el daño posible: una aprobación vaga puede filtrar un secreto, borrar archivos locales, sobrescribir main, ejecutar una migración peligrosa o disparar llamadas a una API.

Este artículo no afirma que estos casos pertenezcan a una empresa concreta. Son escenarios compuestos a partir de simulacros de ClaudeCodeLab, revisión de repositorios y tareas de contenido. Las horas y cantidades son ejemplos, pero los patrones son útiles para practicar antes de una crisis real.

Un incidente es cualquier evento que afecta usuarios, datos, seguridad, coste o disponibilidad. Contener significa impedir que el daño siga creciendo. RCA es análisis de causa raíz. Rollback es volver a la última versión segura.

Consulta la documentación oficial de Claude Code settings y hooks para la sintaxis actual. Aquí convertimos esas piezas en un flujo: detectar, contener, diagnosticar, revertir, comunicar, hacer postmortem y prevenir recurrencias.

Flujo de respuesta

FaseObjetivoQué pedir a Claude Code
DetectarSaber qué cambió y a quién afectaResumir alertas, logs, diff, despliegues y comandos recientes
ContenerFrenar el dañoProponer revocar claves, pausar jobs, apagar flags o desactivar endpoints
DiagnosticarAcotar la causa directaComparar el último despliegue sano con el cambio fallido
RollbackVolver a un estado seguroListar versión objetivo, riesgo de datos y comandos de verificación
ComunicarAlinear a las personasRedactar estado, impacto, próxima actualización y responsable
PostmortemConvertir el fallo en aprendizajeCompletar RCA, línea temporal, detección fallida y acciones
PrevenirHacer más difícil repetirloAñadir permisos, hooks, CI, alertas y revisión

La regla es contener antes de investigar cuando hay secretos, facturación, datos personales o escrituras en BD.

Siete patrones concretos

PatrónQué ocurrePrimer pasoError frecuente
Fuga de secreto.env, logs o capturas exponen una claveRevocar, rotar, revisar logsLimpiar git pero olvidar logs de CI
Borrado peligrosorm -rf elimina archivos necesariosParar, revisar copias, listar no versionadosgit checkout . no recupera archivos sin seguimiento
Force pushmain sobrescribe commits del equipoParar push, mirar reflog, crear rama de recuperaciónConfundir --force-with-lease con --force
Migración de BDDrop, update masivo o lock rompe producciónPausar escrituras, tomar snapshot, restaurarEjecutar SQL no probado en producción
Reintentos infinitosLa lógica de retry sube costesMatar proceso, pausar cola, revisar límites”Reintentar” se vuelve bucle infinito
Dependencias rotasEl despliegue arranca con 503Reactivar despliegue anterior, mirar lockfilenpm update sube versiones mayores
Falta de authEndpoint admin queda públicoDesactivar endpoint, revisar accesos”Es admin” no equivale a requisito de autenticación

Casos de uso de incidente

Primero, fuga de API key. La detección puede venir de secret scanning de GitHub, una alerta de nube o la pantalla de facturación. La primera acción es revocar la clave, no investigar. Después se revisan repositorios públicos, PR, logs de CI, chat y monitorización.

git status --short
git diff --cached --name-only
git log --all -- .env .env.local
git grep -n "sk-" -- ':!node_modules' ':!dist'

Segundo, migración fallida de base de datos. Antes de explicar la causa, se paran escrituras con mantenimiento, flag desactivado o workers pausados.

psql "$DATABASE_URL" -c "select now();"
psql "$DATABASE_URL" -c "\d users"
pg_dump "$DATABASE_URL" --schema-only > schema_before_repair.sql

Tercero, reintentos infinitos. Guarda este archivo como incident-budget-runner.mjs y úsalo para envolver tareas batch.

#!/usr/bin/env node
import { spawn } from "node:child_process";

const command = process.argv.slice(2);
const maxAttempts = Number(process.env.MAX_ATTEMPTS || 3);
const maxCostCents = Number(process.env.MAX_COST_CENTS || 200);
const costPerAttempt = Number(process.env.COST_PER_ATTEMPT_CENTS || 0);

if (command.length === 0) {
  console.error("uso: node incident-budget-runner.mjs <comando> [...args]");
  process.exit(2);
}

let estimatedCost = 0;

for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
  const child = spawn(command[0], command.slice(1), {
    stdio: "inherit",
    shell: process.platform === "win32"
  });
  const exitCode = await new Promise((resolve) => {
    child.on("exit", (code) => resolve(code ?? 1));
  });
  estimatedCost += costPerAttempt;
  if (exitCode === 0) process.exit(0);
  if (estimatedCost >= maxCostCents) {
    console.error(`detenido: coste estimado ${estimatedCost} céntimos`);
    process.exit(1);
  }
  const delayMs = Math.min(1000 * 2 ** (attempt - 1), 10_000);
  await new Promise((resolve) => setTimeout(resolve, delayMs));
}

console.error(`falló tras ${maxAttempts} intentos`);
process.exit(1);

Guardrails para Claude Code

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(git push --force *main*)",
      "Bash(git push -f *main*)",
      "Bash(rm -rf /*)",
      "Bash(rm -rf ~*)"
    ],
    "ask": [
      "Bash(git push*)",
      "Bash(rm*)",
      "Bash(npm install*)",
      "Bash(*migrate*)",
      "Bash(*deploy*)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-danger.sh"
          }
        ]
      }
    ]
  }
}
#!/usr/bin/env bash
set -euo pipefail

payload="$(cat)"
command="$(node -e 'const fs = require("fs"); const raw = fs.readFileSync(0, "utf8") || "{}"; const json = JSON.parse(raw); console.log(json.tool_input?.command || "");' <<< "$payload")"
blocked='(rm[[:space:]]+-rf[[:space:]]+(/|~)|git[[:space:]]+push[[:space:]].*(-f|--force)([[:space:]]|$)|DROP[[:space:]]+TABLE|TRUNCATE[[:space:]])'

if [[ "$command" =~ $blocked ]]; then
  echo "Comando peligroso bloqueado: $command" >&2
  exit 2
fi

exit 0

Plantillas de comunicación y postmortem

## Actualización de incidente
- Estado: investigando / contenido / validando recuperación
- Impacto: función, usuarios, hora de inicio
- Acción actual: job detenido, despliegue revertido, logs en revisión
- Próxima actualización: YYYY-MM-DD HH:mm
- Responsable:
# Postmortem: [título]

## Resumen
- Inicio:
- Detección:
- Resolución:
- Impacto:
- Severidad: P0/P1/P2/P3

## Línea temporal
| Hora | Evento |
| --- | --- |
| HH:mm | |

## Causa
- Causa directa:
- Causa raíz:
- Por qué se detectó tarde:

## Prevención
| Acción | Responsable | Fecha límite |
| --- | --- | --- |
| | | |

La referencia externa más útil es Postmortem Culture de Google SRE.

Lecturas y CTA

Lee también buenas prácticas de seguridad, guía de permisos, costes de API y flujo de verificación.

Para empezar solo, usa la cheatsheet gratuita. Para plantillas reutilizables revisa productos de ClaudeCodeLab. Si tu equipo necesita CLAUDE.md, permisos, hooks, revisión y simulacros, entra en formación y consultoría.

Al probar estas plantillas en simulacros de ClaudeCodeLab, el mayor cambio fue escribir la contención antes del diagnóstico. Validar JSON, Bash y Node antes de publicar también redujo errores. Un ensayo de 20 minutos revela alertas ausentes, copias no probadas y permisos demasiado amplios.

#claude-code #incident #production #sre #security #postmortem
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.