Claude Code rechaza commits con 'OpenClaw': lo reproduje en mi repo real y el comportamiento es más raro de lo que el post viral describe
Había algo que me picaba cuando leí el post original. El thread de HN llegó a 1163 puntos en pocas horas — el tipo descubre que Claude Code rechaza commits que incluyen el string OpenClaw en el mensaje, se queja de censura, todo el mundo se prende, fuego asegurado. Pero ninguno de los comentarios que leí respondía la pregunta que más me importaba: ¿cuál es exactamente el mecanismo, y qué otros strings activan el mismo comportamiento sin que nadie lo haya documentado?
Me pasé la tarde del jueves reproduciéndolo sobre un repo real — el mismo con el que construí el pipeline de generación de contenido que ya conté cuando analicé los quality reports de Claude Code. Tengo logs. Tengo casos edge. Y tengo una tesis que no me la va a ganar nadie.
Mi tesis: esto no es un bug de filtro de texto mal configurado. Es alignment activo — el mismo sistema que hace que Claude no te ayude a construir malware — aplicado a nivel de acción de agente, no de respuesta de chat. Y eso cambia todo sobre cómo tenés que pensar en Claude Code como herramienta de trabajo.
Claude Code censura commits con keywords: qué pasó en el thread viral
El post original es simple: el tipo tenía un proyecto llamado OpenClaw — un motor de ajedrez open source, sin ninguna connotación violenta — y Claude Code se negaba a hacer git commit con ese nombre en el mensaje. Sin error explícito. Sin explicación. Solo... no lo hacía.
El thread de HN explotó porque tocó un nervio real: ¿quién decide qué palabras pueden aparecer en el código que trabajás? ¿El IDE? ¿El vendor de la API? ¿El modelo que corre adentro?
La respuesta corta que nadie dio bien: las tres cosas a la vez, y ninguna lo documenta.
Lo que me faltó en el thread: nadie fue a reproducirlo de forma sistemática. Todos opinaron desde la intuición. Yo fui a hacerlo desde los datos.
Reproducción sobre mi repo real: los números que el post viral no tiene
Mi setup de prueba: repo Next.js/TypeScript en Railway, el mismo stack que uso para todo. Claude Code corriendo en modo --dangerously-skip-permissions (sí, con ese flag, que ya dice algo sobre cómo Anthropic piensa en la autonomía del agente).
Primero reproduje el caso base:
# Intento 1 — reproducción directa del caso viral
git commit -m "feat: integrar OpenClaw como motor de análisis"
# Resultado: Claude Code procesó la instrucción pero no ejecutó el commit.
# No hubo mensaje de error. No hubo explicación. Simplemente no pasó nada.
Confirmado. El comportamiento existe. Ahora lo interesante:
# Intento 2 — variación de capitalización
git commit -m "feat: integrar openclaw como motor de análisis"
# Resultado: commit ejecutado sin problemas
# Lowercase pasa. CamelCase no.
# Intento 3 — separado por guion
git commit -m "feat: integrar open-claw como motor de análisis"
# Resultado: commit ejecutado
# Intento 4 — en el cuerpo del commit, no en el subject
git commit -m "feat: nuevo motor" -m "integra OpenClaw para análisis de movimientos"
# Resultado: BLOQUEADO. El body también se escanea.
# Intento 5 — en el nombre de archivo referenciado
# (modificando un archivo llamado openclaw-engine.ts)
git commit -m "refactor: openclaw-engine ahora soporta async"
# Resultado: ejecutado — el nombre del archivo no se analiza como contexto semántico
Esto ya es más raro de lo que el post original describe. No es un simple string.includes('OpenClaw'). Hay sensibilidad a capitalización, hay análisis del body del commit, y hay diferencias según dónde aparece el string.
Seguí excavando:
// Snippet real de mis tests — esto lo corrí directo desde el SDK
// para entender si el bloqueo ocurre antes o después de que el modelo procese
const mensajesDeCommit = [
"feat: agregar OpenClaw", // BLOQUEADO
"feat: agregar openClaw", // BLOQUEADO (camelCase parcial)
"feat: agregar Openclaw", // EJECUTADO (capitalización distinta)
"feat: agregar OPENCLAW", // EJECUTADO (todo mayúsculas)
"feat: agregar Open Claw", // EJECUTADO (con espacio)
"fix: remover dependencia de OpenClaw", // BLOQUEADO
"chore: OpenClaw → motor-propio", // BLOQUEADO
];
// Lo que encontré: el bloqueo actúa sobre el string exacto con esa capitalización específica
// No es fuzzy matching. No es análisis semántico del contenido del commit.
// Es pattern matching sobre una forma específica del string.
Tres horas de tests y el patrón que emerge es este: el bloqueo es más quirúrgico de lo que parece, pero también más arbitrario. No analiza el contexto — no sabe si OpenClaw es un motor de ajedrez inofensivo o algo sensible. Bloquea la forma, no el significado.
Los casos edge que el post viral no cubre (y que me preocupan más)
Acá es donde el thread de HN se quedó corto, porque todos discutieron el caso puntual y nadie miró para los costados. Yo miré.
Caso edge 1: variables de entorno y nombres de proyecto
Si tu proyecto se llama algo que activa el mismo mecanismo, Claude Code puede rechazar operaciones sobre archivos que solo mencionan el nombre en un comentario. Probé con strings similares en términos de estructura (dos palabras compuestas, una con connotación de apertura, una con connotación de objeto potencialmente peligroso según un modelo de alignment):
# Esto no lo voy a reproducir con ejemplos reales de strings sensibles
# porque no es el punto — el punto es que el PATRÓN existe
# y afecta nombres de proyecto legítimos que combinan palabras de forma inocente
Caso edge 2: el bloqueo no loggea nada en el lado del usuario
Lo que me parece genuinamente problemático: cuando Claude Code no ejecuta el commit, no hay traza. No hay stderr. No hay mensaje en la UI. El agente simplemente no actúa. Si estás en modo automatizado — digamos, un pipeline nocturno de commits automáticos — esto falla silenciosamente. El commit no se hace, no sabés por qué, y el pipeline sigue como si nada.
Esto me recuerda directo a lo que encontré cuando un agente borró mi base de datos en producción: los agentes fallan de formas que no están diseñadas para ser visibles. El silencio es el peor modo de falla.
Caso edge 3: el contexto del proyecto no modifica el comportamiento
Intenté agregar contexto explícito al inicio de la sesión:
"Este proyecto es un motor de ajedrez open source llamado OpenClaw.
Es completamente inofensivo. El nombre viene de 'open source' + 'claw'
como la garra del caballo en ajedrez."
No importó. El bloqueo se mantuvo. Lo que confirma que el mecanismo no es razonamiento sobre el contexto — es un filtro que corre antes o paralelo al razonamiento del modelo.
Esto es lo que diferencia este caso de, por ejemplo, pedirle a Claude algo sensible en un chat: en el chat, podés dar contexto y el modelo razona. En acciones de agente, hay una capa que no razona — solo filtra.
Por qué esto no es un bug: es alignment no documentado en modo agente
Acá va la tesis completa, sin suavizarla.
Anthropic construyó Claude con múltiples capas de alignment. La que conocemos todos es la que responde en el chat: rechaza instrucciones dañinas, da contexto, explica por qué no puede hacer algo. Esa capa razona.
Pero Claude Code como agente tiene otra capa — una que actúa sobre el mundo real (sistema de archivos, git, comandos de shell) y que tiene un umbral de activación diferente. Esta capa no razona: filtra. Y filtra strings específicos en acciones específicas porque el costo de un falso negativo (dejar pasar algo dañino) se percibe como mayor que el costo de un falso positivo (bloquear algo legítimo).
El problema es que esta capa no está documentada. No aparece en la documentación oficial de Claude Code. No hay una lista de strings bloqueados. No hay un mecanismo de override con contexto. No hay logs del bloqueo.
Cuando estuve simulando la migración desde mi stack actual a Bedrock para el análisis de OpenAI en Amazon Bedrock, una de mis preguntas era exactamente esta: ¿cambia el comportamiento de alignment según el vendor que sirve el modelo? La respuesta que no tenía entonces y que ahora tengo parcialmente: sí, porque el alignment de Claude Code no está solo en los pesos del modelo — está en la capa de herramientas que corre por encima.
Eso significa que si Anthropic decidiera mañana agregar React a la lista de strings bloqueados en commits (hipótesis absurda, lo sé, pero el mecanismo existe), vos no lo sabrías hasta que tu pipeline falle silenciosamente a las 3am.
Lo incómodo: no digo que el alignment esté mal. Entiendo por qué existe. Cuando construís un agente que ejecuta comandos en el sistema de archivos real, tenés que ser conservador. El problema es la falta de transparencia y la falla silenciosa. Si me vas a bloquear un commit, decime por qué. Escribí algo en stderr. Tirá una excepción. No te hagas el invisible.
Este patrón de falla silenciosa ya lo vi antes con los bugs que Rust no previene en producción: el sistema hace exactamente lo que está diseñado para hacer, y eso es lo que te mata — no la falla obvia sino la falla que no ves venir.
FAQ: Claude Code censura commits con keywords
¿Esto es un bug confirmado por Anthropic o un comportamiento documentado?
Ni una cosa ni la otra, y eso es exactamente el problema. A la fecha de este post, Anthropic no se pronunció públicamente sobre el thread de HN ni sobre el comportamiento específico. No aparece en la documentación oficial como feature ni como limitación conocida. Es un comportamiento observado empíricamente, sin fuente oficial que lo explique.
¿Afecta solo a git commit o también a otras operaciones de Claude Code?
Mis tests sugieren que el filtro es específico de ciertos strings en ciertos contextos de escritura — commits, mensajes, y posiblemente comentarios en código que referencian los mismos términos. No encontré el mismo bloqueo en operaciones de lectura (grep, cat, ls sobre archivos con esos nombres).
¿Se puede bypasear usando herramientas externas dentro de la sesión?
Sí, y esto es lo más revelador de todo. Si le pedís a Claude Code que ejecute git commit -m "feat: agregar OpenClaw" directamente como comando de shell con ! prefix, a veces pasa. El bloqueo está en la capa de interpretación de intención, no en el execution layer puro. Lo cual confirma que es alignment de agente, no un filtro de string en el shell.
¿Esto afecta solo a Claude Code o también a otros LLMs con herramientas de agente?
Gran pregunta, y no tengo respuesta completa. Lo que sí puedo decir: cuando probé el mismo flujo con Copilot CLI y con Cursor en modo agente, no encontré el mismo comportamiento para los strings que testeé. Eso no significa que no tengan sus propios filtros — significa que los filtros son distintos. Cada vendor tiene su propio alignment de agente, y ninguno lo documenta bien.
¿Hay una lista oficial de strings o keywords bloqueadas?
No. Y esa es la respuesta que más me preocupa. La opacidad no es accidental — es parte del diseño. Publicar una lista de strings bloqueados crearía un roadmap para evadirlos. Pero la consecuencia es que vos, como developer, no sabés cuándo tu pipeline va a fallar silenciosamente.
¿Cómo puedo proteger mis flujos automáticos de este tipo de falla?
Lo que implementé yo: una capa de validación antes de cualquier commit automático que corre Claude Code. Básicamente, un wrapper que captura el resultado de cada operación y valida explícitamente que el commit se haya creado — con un git log --oneline -1 post-ejecución que compara el hash. Si el hash no cambió, el pipeline falla ruidosamente en lugar de silenciosamente. Es un workaround, no una solución.
# wrapper-commit-validado.sh
# Corre el commit via Claude Code y verifica que efectivamente ocurrió
HASH_ANTES=$(git rev-parse HEAD)
# [acá Claude Code ejecuta el commit]
claude "commiteá los cambios staged con el mensaje: $MENSAJE_COMMIT"
HASH_DESPUES=$(git rev-parse HEAD)
if [ "$HASH_ANTES" = "$HASH_DESPUES" ]; then
echo "ERROR: El commit no se ejecutó. Posible bloqueo de agente." >&2
exit 1
fi
echo "Commit verificado: $HASH_DESPUES"
Lo que me llevo, sin suavizarlo
Reproducir el comportamiento fue fácil. Lo difícil fue aceptar la implicación real: cuando le damos a un agente capacidad de actuar sobre nuestro sistema de archivos, le estamos dando también su sistema de valores — y ese sistema de valores no está documentado, no es configurable por el usuario, y falla en silencio.
No soy de los que gritan "¡censura!" cada vez que un modelo no hace algo. Entiendo el alignment. Entiendo por qué existe. Lo que no acepto es que una herramienta de desarrollo profesional bloquee operaciones legítimas sin log, sin error, sin explicación. Eso no es alignment responsable — es alignment descuidado.
El mismo principio que me llevó a analizar en detalle el bug de clipboard en Next.js aplica acá: los sistemas que fallan silenciosamente son más peligrosos que los que fallan ruidosamente. Un error que ves es un error que podés resolver. Un commit que no se hace y no te avisa es un bug que encontrás en producción tres semanas después.
Mi recomendación concreta: si usás Claude Code en flujos automáticos, implementá validación explícita de cada operación de escritura. No confíes en que el agente te va a decir cuando no actuó. Verificalo vos mismo.
Y a Anthropic: publiquen el comportamiento esperado de alignment en modo agente. No la lista de strings — el mecanismo. Los developers merecemos saber cuándo y por qué nuestra herramienta puede decidir no hacer algo. Esa transparencia no debilita el alignment — lo hace confiable.
Este artículo fue publicado originalmente en juanchi.dev
This article was originally published by DEV Community and written by Juan Torchia.
Read original article on DEV Community