Entre las más de cien entradas de la versión 2.1.257 de Claude Code hay un grupo que conviene leer junto, porque comparte un patrón incómodo: reglas de permiso que estaban escritas, que aparecían en la configuración y que el usuario daba por aplicadas, pero que en determinadas formas de invocar el mismo comando no llegaban a evaluarse. No son fallos de diseño del sistema de permisos; son huecos en su cobertura. Y un hueco en una regla de denegación es peor que no tener la regla, porque genera una confianza que no está respaldada.
Conviene recordar cómo se evalúa esto. Claude Code aplica las reglas en un orden fijo: primero deny, después ask y por último allow, y la primera coincidencia decide. La especificidad no altera ese orden, así que una denegación amplia gana siempre a un permiso más concreto. Sobre ese esqueleto, los fallos corregidos afectan al momento en el que una regla debía coincidir y no coincidía.
Una regla ask que la subshell se saltaba
El primero es el más directo. En modo automático, una regla permissions.ask —esas que se ponen justamente para conservar un punto de control humano sin salir del modo automático— se omitía cuando el comando coincidente iba dentro de un comando compuesto o de una subshell. Es decir: la regla funcionaba si el comando se ejecutaba solo, y no funcionaba si iba encadenado o entre paréntesis. El comando se ejecutaba sin el aviso de confirmación que la regla existía para provocar.
Quien haya montado un ask sobre despliegues, migraciones o cualquier operación irreversible debería asumir que ese punto de control tenía una fuga. La 2.1.257 lo cierra.
Las formas de leer un fichero que la regla no veía
El segundo hueco es más sutil y explica bien la naturaleza del problema. Las reglas Read() y Edit() no se limitan a las herramientas internas de fichero: Claude Code también las aplica a los comandos de lectura que reconoce dentro de Bash, como cat, head, tail o sed. Esa lista de comandos reconocidos no cubría tac ni egrep, ni contemplaba la redirección de entrada < fichero, que es otra forma perfectamente válida de que el contenido de un archivo acabe en la salida.
Dicho de forma práctica: una regla que denegaba leer tu .env bloqueaba cat .env y no bloqueaba tac .env. A partir de la 2.1.257, una regla de denegación sobre cualquier argumento o sobre el destino de una redirección rechaza el comando entero.
Una regla de denegación con un hueco es peor que no tener la regla: genera una confianza que no está respaldada.
Hay un límite que sigue vigente y que conviene tener presente aunque no sea un fallo: estas reglas se aplican a las herramientas de fichero y a los comandos de Bash que Claude Code reconoce, pero no a un subproceso arbitrario que abra ficheros por su cuenta, como un script de Python o de Node. Para una barrera que valga a nivel de sistema operativo, la vía es activar el sandbox, no ampliar la lista de reglas.
Un symlink bastaba para sacar a un plugin de su directorio
El tercero afecta a quien instala plugins de terceros. Un plugin declara sus componentes —comandos, agentes, skills, hooks— apuntando a rutas dentro de su propio directorio. Resulta que si una de esas rutas declaradas era un enlace simbólico, el plugin podía leer ficheros fuera de su directorio, que es exactamente el confinamiento que la estructura pretendía garantizar. Ahora esas rutas se rechazan con un error.
Es un fallo de bajo ruido y alto significado, porque el modelo mental con el que instalamos plugins es «esto vive en su carpeta». Si acabas de instalar el plugin de agentes de comercio o cualquier otro del ecosistema, no hay nada que hacer más allá de estar en una versión reciente, pero merece la pena que el mecanismo se conozca.
Cuando zsh y bash no leen lo mismo
El cuarto es un clásico de las herramientas que analizan comandos antes de ejecutarlos. Ciertos condicionales [[ ]] que zsh interpreta de forma distinta a bash se estaban auto-aprobando; ahora piden aprobación. La lección de fondo es que cualquier sistema que decida sobre un comando leyéndolo tiene que coincidir con el intérprete que finalmente lo ejecuta, y esa coincidencia no es gratis. Va en la misma línea que otro arreglo del mismo release: los hosts de red del sandbox escritos con un punto final —ejemplo.com.— no quedaban bloqueados por su entrada en deniedDomains, y el «no volver a preguntar» para ese host seguía preguntando.
El modo bypassPermissions deja de valer desde el proyecto
Este no es un arreglo, es un cambio de comportamiento, y es el que con más probabilidad te tocará en caliente. defaultMode: "bypassPermissions" escrito en .claude/settings.json o en .claude/settings.local.json pasa a ignorarse, igual que ya ocurría con "auto". Si quieres ese modo, hay que declararlo en los ajustes de usuario o en los gestionados, o pasar --permission-mode al arrancar.
El razonamiento se entiende en cuanto se recuerda de dónde vienen esos ficheros: los ajustes del proyecto viajan dentro del repositorio. Permitir que un repositorio decida en qué modo de permisos arranca tu sesión es entregar esa decisión a quien escribió el repositorio. Con este cambio, el modo lo decides tú o tu organización, nunca el código que acabas de clonar.
En la misma dirección van dos correcciones para entornos gestionados: --disallowedTools y las reglas de denegación de sesión se caían tras la primera recarga de ajustes cuando allowManagedPermissionRulesOnly estaba activo, y /mcp seguía conectando servidores declarados en un fichero de ajustes que una lista gestionada o strictPluginOnlyCustomization debía bloquear. Ambas son políticas que un administrador creía aplicadas y no lo estaban del todo.
⚠️ Qué revisar hoy en tu configuración
Si tienes defaultMode en los ajustes del proyecto, muévelo a los de usuario o pásalo por línea de comandos: desde la 2.1.257 no hace nada donde está.
Repasa tus reglas deny de lectura sobre credenciales. Si las escribiste asumiendo que cubrían cualquier forma de leer el fichero, ahora es cuando empiezan a hacerlo de verdad.
Y otro del mismo release que conviene conocer: descartar el aviso de consentimiento de Remote Control con Esc contaba como consentimiento, de modo que la siguiente petición conectaba sin preguntar. También está corregido.
La conclusión práctica: escribir la regla no es tenerla
Para un desarrollador que trabaja solo, la lectura útil de esta tanda no es la lista de bugs, es el hábito que sugiere. El sistema de permisos de Claude Code es potente y está bien documentado, pero opera analizando comandos, y analizar comandos es un problema con superficie infinita: siempre existe otra forma de expresar lo mismo. Eso significa que las reglas son una capa de reducción de accidentes, no un perímetro.
Si lo que proteges es un secreto real —la clave de la API, el .env de un cliente, las credenciales de un alojamiento—, la regla de denegación es un buen complemento y un mal único mecanismo. El perímetro de verdad es el sandbox, el contenedor o, más simple todavía, no tener ese fichero al alcance de la sesión. Y una prueba concreta que cuesta un minuto: escribe tu regla, intenta saltártela tú mismo con otra forma del mismo comando, y comprueba si te frena. Si te frena, la regla está donde crees.


















