Checklist · Intermedio · 10 min
Antes de fusionar código de Claude Code: checklist de revisión
Ocho comprobaciones antes de fusionar código escrito por Claude Code: tests reales, secretos, dependencias, licencias, alcance, revisión y un script.
Probado con Claude Code 2.1.316 · revisado
Ver los archivos en GitHub Gratis · licencia MIT
Para qué sirve
Ocho comprobaciones para hacer antes de fusionar una rama escrita (en todo o en parte) por Claude Code: que los tests se ejecuten de verdad y no se hayan debilitado, que no haya secretos, que las dependencias nuevas existan y estén justificadas, que las licencias encajen, que no haya cambios fuera del alcance de la tarea, que se haya tocado o no la configuración de la IA y del CI, una revisión independiente (/code-review, /security-review o un subagente revisor) y, siempre, una persona que entiende el cambio y lo aprueba. Incluye un script de bash, revisar-rama.sh, que señala dónde mirar.
La lista
- Por qué: la guía oficial lo dice así: Claude para cuando el trabajo parece terminado, y «todos los tests pasan» sin más no dice casi nada. Pide siempre la evidencia: el comando que ejecutó y su salida. Y un fallo típico del código de IA es «arreglar» un test rojo cambiando el test: borrándolo, saltándolo o aflojando la aserción.
- Cómo comprobarlo: ejecuta tú los tests en la rama, o mira el check del CI del PR; no te fíes solo del resumen.
- Tests borrados:
git diff --diff-filter=D --name-only main...HEAD | grep -i test. - Tests saltados o enfocados en las líneas añadidas:
@unittest.skip,pytest.mark.skipoxfail,it.skip,describe.only,xit. El script del final lo hace por ti. - Valores esperados cambiados: lee el diff de la carpeta de tests. Si un valor esperado cambió para coincidir con el resultado nuevo, eso solo es correcto si el comportamiento debía cambiar.
- Tests nuevos para lo nuevo: un arreglo de bug sin un test que lo reproduzca vuelve a romperse.
- Prevenir: para que Claude no pueda terminar con los tests rotos, la plantilla de proyecto trae un hook Stop que los ejecuta cada vez que Claude intenta acabar su turno.
- Por qué: el código generado a veces deja una clave de ejemplo «temporal», copia un token del entorno en un archivo de configuración o escribe credenciales en un test. Una vez fusionado y subido, el secreto está en el historial aunque lo borres después: hay que rotarlo.
- Cómo comprobarlo: busca en las líneas añadidas palabras como
api_key,secret_key,token,passwordoBEGIN … PRIVATE KEY:git diff main...HEAD | grep -vE '^\+\+\+' | grep -niE '^\+.*(api[_-]?key|token|passw(or)?d|PRIVATE KEY)'. - Ningún .env en git:
git diff --name-only main...HEAD | grep -E '(^|/)\.env'. - Para un análisis serio: usa una herramienta dedicada de detección de secretos en el CI (por ejemplo gitleaks) o el escaneo de secretos de tu plataforma.
- Prevenir es mejor: con reglas deny
Read(./.env)y un hook que bloquea leer secretos (receta hooks de seguridad), Claude no llega a ver el valor y no puede copiarlo. El paso de CI de la plantilla de proyecto falla si se versiona un.env.
- Por qué: un asistente puede resolver algo con un paquete poco conocido, con uno que no existe (y que alguien podría registrar después con ese nombre) o subir una versión sin que lo pidas. Cada dependencia es mantenimiento y superficie de ataque.
- Cómo comprobarlo: lista los manifiestos tocados (
package.json, archivos de bloqueo,requirements*.txt,pyproject.toml,go.mod,Cargo.toml…); el script lo hace. - Para cada paquete nuevo: ¿era necesario? ¿Lo hace ya la biblioteca estándar o algo que ya usas? Comprueba que existe y que es el que crees (
npm view <paquete>opip index versions <paquete>) y mira su repositorio, autor, descargas y fecha de la última versión. - Avisos conocidos:
npm auditopip-audit. - Archivo de bloqueo: un cambio enorme por una línea en el manifiesto merece una pregunta.
- Prevenir: en CLAUDE.md, «no añadas dependencias sin preguntar»; en settings.json,
askparanpm install *opip install *: un ask pregunta incluso en modo auto.
- Por qué: una dependencia nueva trae su licencia, y algunas (por ejemplo, las copyleft fuertes) pueden no encajar con tu proyecto o con lo que tu empresa permite. También puede aparecer un bloque grande de código que parece copiado de otro proyecto.
- Cómo comprobarlo: para cada dependencia nueva, mira el campo de licencia en su registro (
npm view <paquete> license) o en su repositorio. - Muchas dependencias: usa un listador de licencias en el CI (por ejemplo, license-checker en Node o pip-licenses en Python) y compara con la lista que tu equipo acepta.
- Código que no encaja: si ves un archivo o una función larga que no se parece al estilo del resto, con comentarios ajenos o un aviso de copyright, pregunta de dónde sale antes de fusionarlo.
- Ojo: esta checklist no es asesoría legal; si trabajas para una empresa, sigue su política de licencias.
- Por qué: pediste arreglar un bug y la rama trae, además, un refactor de tres archivos, un formateo masivo o un cambio de configuración. Esos extras esconden errores en el ruido y hacen el PR imposible de revisar.
- Cómo comprobarlo:
git diff --stat main...HEAD: ¿cada archivo tiene que ver con la tarea? Si no, pide separarlo en otra rama o revertirlo. - Configuración de la IA y del CI: mira con lupa los cambios en
.claude/,.mcp.json,CLAUDE.md,AGENTS.mdy.github/. Un cambio ahí altera lo que Claude podrá hacer la próxima vez (una regla allow nueva, un hook, un servidor MCP) o lo que se comprueba en cada PR. El script los lista aparte. - Worktrees: si trabajaste con
claude --worktree, revisa la ramaworktree-<nombre>contra la base correcta: por defecto el worktree parte de la rama por defecto remota, no de tu HEAD. - Prevenir: una tarea por rama, prompts con límites claros («no toques X», «sin refactors») y el
askparaEdit(/.github/**)de la plantilla de proyecto.
- Por qué: la guía oficial explica que pasarle la misma tarea a otro agente no da mejor respuesta, pero un revisor nuevo sí ayuda, porque no ha visto el razonamiento que produjo el código y no se deja llevar por él.
/code-review(o su alias/review): revisa los cambios de tu rama y los que no has confirmado buscando errores de corrección. Corre como subagente en segundo plano con su propio contexto y te trae los hallazgos. Puedes apuntarlo a un PR (/code-review 1234), a una rama (/code-review main...mi-rama) o a una ruta, y pasarle un nivel de esfuerzo:lowda menos hallazgos y más seguros; demediumamaxamplía la cobertura. Con--fixaplica los arreglos, pero ojo: esas ediciones quedan fuera de los puntos de control y/rewindno las deshace; usa git./security-review: analiza el diff de tu rama contra la rama por defecto de origin buscando inyecciones, problemas de autenticación o exposición de datos. Necesita un remotoorigin.- Un subagente revisor de solo lectura (como
revisor.mdde la plantilla de proyecto) contra una especificación: «usa un subagente para revisar el diff contra SPEC.md, comprueba que cada requisito está implementado y que los casos límite tienen test, informa solo de fallos de corrección y omite el estilo». No quites lo de omitir el estilo: un revisor al que se le pide encontrar problemas siempre encuentra algo. Más sobre esto en subagentes.
- Por qué: la revisión con IA filtra, pero no decide. La documentación de seguridad de Claude Code lo dice sin rodeos: eres responsable de revisar el código y los comandos propuestos antes de aprobarlos. Y si quien pidió el cambio no sabe explicar qué hace, no está listo para fusionarse.
- Cómo comprobarlo: quien abre el PR puede explicar en dos frases qué cambia y por qué, y cómo lo probó (con la salida). La skill
/preparar-prde la plantilla de proyecto redacta esa descripción. - Zonas de riesgo: lee el diff entero en autenticación, permisos, dinero, datos de clientes, migraciones de base de datos y despliegue. Ahí la aprobación es siempre humana.
- Casos límite que la IA suele saltarse: valores nulos o vacíos, cero, listas vacías, errores de red, entradas sin validar.
- Protección de la rama principal: actívala en tu plataforma, exigiendo que pase el CI y al menos una revisión aprobada antes de fusionar.
- Atribución: si quieres saber qué commits hizo Claude, por defecto añade una línea de atribución a sus commits y PR; el ajuste
attributionla cambia o la oculta.
- Por qué: aunque todo lo anterior salga bien, algo se escapará alguna vez. Lo que importa es poder deshacerlo rápido.
- Ramas pequeñas: fusiona una tarea cada una. Un PR de 2.000 líneas generado en una tarde no se revisa: se aprueba a ciegas.
- Historial reversible: prefiere uno que puedas revertir de un golpe (
git revert <commit>o un squash merge por PR). - No confíes en
/rewindcomo plan de vuelta atrás para lo fusionado: deshace las ediciones de las herramientas de archivos de esa conversación, pero no los cambios hechos solo con Bash, ni los de subagentes, ni los de/code-review --fixen segundo plano. Git sí. - Después de fusionar: mira el CI de la rama principal y, si despliegas, los registros del primer despliegue.
El script: dónde mirar antes de fusionar
revisar-rama.sh no sustituye nada de lo anterior: en unos segundos te dice dónde mirar primero (archivos, posibles secretos, dependencias, tests saltados y configuración de la IA). Guárdalo en tu repo o en tu PATH, dale permisos con chmod +x revisar-rama.sh y ejecútalo desde la rama que quieres fusionar:
#!/usr/bin/env bash
# Revisión rápida de una rama antes de fusionar: ./revisar-rama.sh [rama-base]
# No sustituye la revisión humana: te dice dónde mirar primero.
set -euo pipefail
base="${1:-main}"
rango="$base...HEAD"
git rev-parse --verify -q "$base" >/dev/null || { echo "No existe la rama base '$base'" >&2; exit 1; }
echo "== Archivos cambiados (¿todos tienen que ver con la tarea?)"
git diff --stat "$rango"
echo; echo "== Posibles secretos en líneas añadidas"
git diff "$rango" | grep -vE '^\+\+\+' | grep -niE '^\+.*((api|secret|private)[_-]?key|token|passw(or)?d|BEGIN [A-Z ]*PRIVATE KEY)' || echo "(nada a la vista)"
echo; echo "== Dependencias tocadas"
git diff --name-only "$rango" | grep -E '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|requirements[^/]*\.txt|pyproject\.toml|uv\.lock|poetry\.lock|go\.(mod|sum)|Cargo\.(toml|lock)|Gemfile(\.lock)?|composer\.(json|lock))$' || echo "(ninguna)"
echo; echo "== Tests borrados, saltados o enfocados"
git diff --diff-filter=D --name-only "$rango" | grep -iE 'test' || true
git diff "$rango" | grep -nE '^\+.*(@unittest\.skip|pytest\.mark\.(skip|xfail)|\b(it|describe|test)\.(skip|only)\(|\bx(it|describe)\()' || echo "(ninguno añadido)"
echo; echo "== Configuración de la IA y del CI tocada"
git diff --name-only "$rango" | grep -E '^(\.claude/|\.mcp\.json|CLAUDE\.md|AGENTS\.md|\.github/)' || echo "(nada)"
Salida real sobre una rama con cuatro fallos sembrados (1-nov-2026). Los números de los hallazgos son líneas de la salida de git diff, no del archivo:
$ ./revisar-rama.sh main
== Archivos cambiados (¿todos tienen que ver con la tarea?)
CLAUDE.md | 1 +
requirements.txt | 1 +
src/app/__init__.py | 1 +
tests/test_app.py | 1 +
4 files changed, 4 insertions(+)
== Posibles secretos en líneas añadidas
21:+API_KEY = "sk-falsa-123"
== Dependencias tocadas
requirements.txt
== Tests borrados, saltados o enfocados
33:+ @unittest.skip("luego")
== Configuración de la IA y del CI tocada
CLAUDE.md
La revisión independiente dentro de Claude Code:
/code-review # tu rama + cambios sin confirmar, en un subagente aparte
/code-review low main...mi-rama # pocos hallazgos, los más seguros
/code-review high 1234 # un pull request, más cobertura
/security-review # diff contra la rama por defecto de origin
# Contra la especificación, con el subagente revisor de la plantilla de proyecto:
usa el subagente revisor para revisar git diff main...HEAD contra SPEC.md: comprueba que cada requisito
está implementado y que los casos límite tienen test; informa solo de fallos de corrección y omite el estilo
Si quieres que además cada PR se revise solo en GitHub, añade la receta de revisión de PRs con GitHub Actions.
Errores típicos
- Fusionar porque Claude dijo «todos los tests pasan» → sin el comando y su salida no sabes qué se ejecutó → ejecuta tú los tests o mira el check del CI.
- El test rojo «se arregló» y nadie miró cómo → se borró, se saltó o se aflojó la aserción → revisa el diff de la carpeta de tests y pasa
revisar-rama.sh. - Borrar un secreto en un commit posterior → sigue en el historial → rota el secreto.
- Aprobar un paquete que «suena bien» → puede no existir o no ser el que crees →
npm viewopip index versions, y su repositorio. - Ignorar un cambio en
.claude/o.github/dentro de un PR de otra cosa → cambia lo que Claude podrá hacer o lo que se comprueba en cada PR → sepáralo y revísalo aparte. - Usar
/code-review --fixy luego/rewind→ esas ediciones quedan fuera de los puntos de control → haz commit antes y deshaz con git. - Revisar la rama de un worktree contra tu HEAD → el worktree parte de la rama por defecto remota → compara contra la base correcta.
Qué probamos y qué falta
En este PC (Linux, Claude Code 2.1.316): revisar-rama.sh se ejecutó sobre una rama de un repo de prueba con cuatro fallos sembrados (una API_KEY escrita en el código, un requirements.txt nuevo, un @unittest.skip y un cambio en CLAUDE.md) y señaló los cuatro; en una rama sin cambios no señala nada; detecta un test borrado; con una rama base inexistente sale con código 1; bash -n confirma la sintaxis. No probamos /code-review, /security-review ni el subagente revisor, porque necesitan una sesión con cuenta: su comportamiento sale de la documentación oficial (code-review-local, commands, best-practices). npm view, pip index versions, npm audit, pip-audit, gitleaks, license-checker y pip-licenses se citan como herramientas habituales, sin probarlas aquí.
Preguntas frecuentes
¿/code-review sustituye la revisión humana?
No. Encuentra errores de corrección con un subagente que no vio la conversación, lo que lo hace útil, pero la documentación deja la responsabilidad de revisar en ti. Úsalo como primer filtro y deja la aprobación final a una persona, sobre todo en autenticación, dinero, datos y despliegue.
¿Qué diferencia hay entre /code-review y la revisión de PR en GitHub Actions?
/code-review corre en tu sesión, en local, y cuenta en tu plan como el resto de la sesión. La receta de GitHub Actions (claude-code-action) revisa cada PR en GitHub de forma automática. También existe el servicio gestionado Code Review para planes Team y Enterprise. Puedes combinarlos: local antes de abrir el PR, automático en el PR.
¿/code-review lee mi CLAUDE.md?
Sí, sigue tu CLAUDE.md, también en una ejecución con -p. No lee REVIEW.md, que solo configura el servicio gestionado de Code Review en GitHub.
¿Por qué el script no encontró un secreto que sí hay?
Porque solo busca palabras típicas en las líneas añadidas: una clave guardada en una variable con otro nombre o codificada se le escapa. Es un aviso rápido, no un escáner. Para eso, añade una herramienta de detección de secretos al CI.
¿Cómo evito que Claude debilite los tests para que pasen?
Díselo en CLAUDE.md («no cambies ni saltes tests existentes sin preguntar»), revisa el diff de tests/ en cada PR y pide al revisor que señale tests borrados, saltados o con aserciones aflojadas, como hace la skill /preparar-pr de la plantilla de proyecto.