Claude Code — auto mode y el classifier de permisos

Auto mode es el permission mode de Claude Code que elimina los prompts de confirmación rutinarios: en vez de preguntar a Esteban antes de cada acción, un classifier (un segundo modelo, aparte del que conduce la sesión) evalúa cada llamada a herramienta contra el contexto de la conversación y bloquea lo irreversible, lo destructivo, o lo que apunte fuera del entorno de confianza declarado. permissions.deny y las reglas ask explícitas se evalúan antes del classifier y siguen bloqueando o preguntando igual — el classifier es una segunda capa, no un reemplazo de esas reglas.

Los permission modes

ModoComportamiento
default (alias manual)Pregunta la primera vez que se usa cada herramienta.
acceptEditsAuto-acepta ediciones de archivo y comandos de filesystem comunes (mkdir, touch, mv, cp) dentro del directorio de trabajo.
planSolo lee/explora, no edita; con auto mode disponible también corren los comandos que el classifier ya aprobó.
autoAuto-aprueba llamadas a herramientas pasándolas por el classifier.
dontAskRestrictivo, no permisivo: deniega automáticamente todo lo que no esté pre-aprobado vía permissions.allow. Pensado para corridas scriptadas donde una llamada inesperada debe fallar de forma ruidosa, no ejecutarse.
bypassPermissionsSe salta todos los prompts, incluida escritura a rutas protegidas (.git, .claude). Advertencia oficial: usarlo solo en contenedores/VMs aislados, nunca en una máquina de uso normal.

permissions.disableBypassPermissionsMode / permissions.disableAutoMode (valor "disable") son flags para impedir que esos modos se usen — pensados para managed settings de una organización, no algo que se active para ganar autonomía.

Dónde vive la configuración del classifier

El bloque autoMode en settings.json es lo que el classifier lee para saber qué confiar. Importante: el classifier solo lee autoMode de ~/.claude/settings.json (user settings), de managed settings, o de un --settings inline — nunca de .claude/settings.json ni .claude/settings.local.json a nivel de proyecto. Esto es deliberado: evita que un repo clonado o un build step inyecte sus propias reglas de auto-aprobación.

Cuatro listas, todas en prosa (lenguaje natural, no regex ni patrones de herramienta):

  • environment — qué repos, buckets, dominios y servicios son de confianza. Todo lo no listado se trata como posible destino de exfiltración.
  • allow — excepciones a bloqueos “soft”. Es la palanca correcta para pedir más autonomía en una categoría concreta: el classifier sigue razonando con contexto, solo que ahora con permiso explícito para esa categoría.
  • soft_deny — bloqueos que la intención explícita del usuario en el chat puede anular (un pedido genérico como “limpia el repo” no cuenta; “haz force-push a esta rama” sí).
  • hard_deny — bloqueo incondicional, ni allow ni la intención del usuario lo anulan (ej. exfiltración de datos).

Cada lista puede incluir el string literal "$defaults" para conservar las reglas incorporadas y solo agregar las propias; omitirlo reemplaza por completo esa sección, perdiendo protecciones como el bloqueo de force-push o curl | bash.

permissions.deny es una capa aparte, anterior al classifier, y nada la anula — ni el classifier ni la intención del usuario. Es el mecanismo correcto para un bloqueo que debe cumplirse siempre, sin excepción de contexto.

Configuración aplicada en esta cuenta (ctunlinux, 2026-09-07)

~/.claude/settings.json en este host (usuario ealcocer) ya traía permissions.defaultMode: "auto" y un bloque autoMode.environment generado por /auto-mode-setup en una sesión anterior. A pedido explícito de Esteban de maximizar autonomía, se agregó autoMode.allow (con "$defaults" preservado) permitiendo sin confirmación:

  • Force-push, borrado de ramas/tags remotos, y reescritura de historia remota.
  • git reset --hard, git clean -fd/-fx y otras operaciones destructivas locales de git.
  • Descarga y ejecución de scripts de terceros (curl | bash, wget | sh).
  • Operaciones destructivas de filesystem dentro del directorio de trabajo del proyecto.

Alcance deliberadamente global: como el bloque vive en ~/.claude/settings.json (user settings), aplica a cualquier proyecto que Esteban trabaje desde este host con Claude Code — incluidos los repos de trabajo de Trivasa, no solo proyectos scratch. Esto se le señaló explícitamente antes de aplicar el cambio (la alternativa era acotar las entradas a un repo nombrado) y Esteban confirmó que sí quería el alcance amplio. hard_deny (protección contra exfiltración de datos) se dejó intacto — no se pidió tocarlo y los defaults oficiales lo describen como un piso que no debe cruzarse nunca.

Esta configuración es local a este host. A diferencia de ~/.claude/skills (ver claude-skills-repo), ~/.claude/settings.json no se distribuye por ningún mecanismo (ni Syncthing ni git) — repetir esta misma autonomía en otro host de la flota (pop-os, vm-playground, vm-personal, etc.) requiere aplicar el mismo cambio ahí por separado, o centralizarlo en managed settings si algún día se quiere fleet-wide.

Qué hacer cuando se requiere que Claude Code sea más autónomo

Procedimiento para la próxima vez que Esteban pida esto, en cualquier host:

  1. Confirmar que auto ya es el defaultMode en ~/.claude/settings.json de ese host (permissions.defaultMode: "auto"). Sin esto, el classifier ni siquiera entra en juego.
  2. Identificar la categoría concreta que se quiere aflojar, no aplicar autonomía genérica a ciegas. Las categorías típicas ya cubiertas en este host son force-push, reset --hard/clean, y curl | bash — para algo distinto, agregar una entrada de prosa nueva a autoMode.allow describiendo el caso, siguiendo el mismo formato que las ya existentes (qué se permite + por qué es seguro en este contexto).
  3. Preguntar el alcance antes de escribir el cambio: ¿solo un repo/proyecto nombrado explícitamente, o global vía ~/.claude/settings.json? Un alcance global en un host donde también se trabajan repos de negocio (como este, con Trivasa) tiene implicaciones reales que Esteban debe decidir con esa información, no asumirse.
  4. Usar autoMode.allow, no reglas estáticas de permissions.allow, para lo destructivo. Una regla permissions.allow para un comando como Bash(rm *) se resuelve antes del classifier y bypassa su razonamiento por completo para cualquier invocación de ese comando — incluida una catastrófica. autoMode.allow mantiene al classifier evaluando cada llamada con contexto, solo que ahora con permiso para esa categoría.
  5. Nunca tocar hard_deny (protección contra exfiltración de datos) a menos que Esteban lo pida de forma explícita y consciente del motivo — no es parte de “más autonomía” genérica.
  6. Verificar el resultado con claude auto-mode config (imprime las reglas efectivas, con $defaults expandido) y, si se escribieron reglas propias en soft_deny/allow, claude auto-mode critique para una revisión de ambigüedades. Revertir con claude auto-mode reset si hace falta.

Véase también