Files
motor-de-encuestas/method/ANTI_PATTERNS.md

17 KiB
Raw Blame History

Anti-patrones

Comportamientos que producen daño concreto y deben evitarse. Cada uno está documentado con el caso real donde apareció.

A diferencia de los patrones (que son propuestos hasta validación), los anti-patrones se documentan estables porque el daño ya está observado.


AP.1 — Tests verdes como aprobación final

Comportamiento: declarar una etapa terminada porque los tests pasaron, sin abrir el artefacto final con los ojos.

Daño concreto: llegás a producción con outputs visuales rotos. Caso real (InQ ROI MVP): los tests E2E verificaban que el PDF se generaba y tenía las páginas esperadas, pero nadie abrió el PDF. El heatmap embebido estaba en blanco por un bug de timing en html2canvas. Se descubrió 2 días después cuando un consultor lo abrió.

Cómo detectarlo: el reporte del agente dice "tests verdes, build limpio, PDF generado en X path" pero no incluye observaciones visuales del PDF.

Cómo evitarlo: aplicar Principio 2 (validación humana es ojo) y Patrón C.1 (validación visual mandatoria).


AP.2 — Pasamanos invertido (humano como operador)

Comportamiento: el humano traduce manualmente entre dos agentes o entre agente y código. Copia outputs, formatea, transporta contexto entre sesiones.

Daño concreto: el humano se vuelve cuello de botella del sistema. Lo peor: deja de pensar en arquitectura/producto y se concentra en operación. Caso real (InQ ROI Sprint 1.5, Etapa 5): el director del proyecto sintió "soy pasamanos" después de varios checkpoints transportando reportes de Claude Code al arquitecto.

Cómo detectarlo: preguntate si lo que estás haciendo lo podría hacer un script o un prompt mejor estructurado. Si la respuesta es sí, estás en este anti-patrón.

Cómo evitarlo: aplicar Principio 5 (humano director). Mover lo operativo a archivos (prompts pre-armados, templates) y reservar el chat para decisiones reales.


AP.3 — Racionalización de output anómalo

Comportamiento: cuando un output del agente tiene una métrica anómala (PDF inusualmente liviano, número muy redondo, payback "0.0 meses"), el agente o el humano racionalizan ("numéricamente correcto", "es el caso esperado") en lugar de investigar la causa raíz.

Daño concreto: bugs latentes que se descubren en producción. Caso real (InQ ROI Sprint 1.5, Etapa 4): el PDF de ROI pesaba 36 KB con 4 páginas (9 KB/página), comparado con 78 KB/3 páginas (26 KB/página) de los otros PDFs. El agente reportó "PDF generado". El humano paró y pidió investigar — había secciones que no se renderizaban.

Cómo detectarlo: cualquier número que parezca "anómalo pero técnicamente válido". Especialmente: tamaños de archivo, payback inmediato, ROI extremo, métricas con muchos ceros.

Cómo evitarlo: aplicar Principio 3 (auditoría adversarial) y Patrón E.3 (anti-racionalización explícita).


AP.4 — Decisión recurrente no registrada

Comportamiento: el agente vuelve a preguntar lo mismo en cada sesión nueva, o miembros del equipo asumen distinto porque la decisión no está documentada.

Daño concreto: outputs inconsistentes entre etapas, tiempo perdido re-debatiendo, deriva del producto. Caso real (InQ ROI Sprint 1.5, varias etapas): cada vez que Claude Code iba a aplicar formato de cifras, había que recordarle si usaba separador europeo o americano. Hasta que se documentó en CLAUDE.md.

Cómo detectarlo: el agente te hace una pregunta que ya respondiste en alguna sesión anterior.

Cómo evitarlo: aplicar Principio 4 (decisiones como contratos) y Patrón B.3 (decisiones tomadas explícitas en cada prompt).


AP.5 — Improvisación sin gobernanza

Comportamiento: un equipo (o miembros individuales) usa agentes de IA sin método compartido. Cada uno improvisa con su herramienta preferida, sin briefs, sin validación estructurada, sin documentar decisiones.

Daño concreto:

  1. Deuda técnica invisible: artefactos producidos por IA que nadie puede auditar después
  2. Aprendizaje no se acumula: descubrimientos individuales no se transfieren
  3. Calidad inconsistente y no atribuible
  4. Imposibilidad de mejorar sistemáticamente

Cómo detectarlo: preguntá al equipo "¿cómo hicieron este artefacto con IA?" — si las respuestas son distintas y vagas, estás acá.

Cómo evitarlo: este método entero está diseñado para evitarlo. Específicamente: empezar con Principios 1 y 4.


AP.6 — Brief grande pegado en chat

Comportamiento: pegar un brief de 800+ líneas en el chat del agente como mensaje inicial.

Daño concreto:

  • Consume contexto innecesariamente
  • No es auditable después
  • Se pierde si la sesión se corta
  • Cuesta tokens repetirlo

Caso real (InQ ROI Sprint 1.5): el primer intento fue pegar el BRIEF.md completo en chat. Se reemplazó por la estructura sprints/sprint-N/ con archivos versionados, mensaje inicial corto referenciando paths.

Cómo detectarlo: si tu mensaje inicial al agente tiene más de 30 líneas, probablemente estás en este anti-patrón.

Cómo evitarlo: aplicar Patrón B.1 (prompt como artefacto del repo) y Patrón B.2 (mensaje inicial corto).


AP.7 — Bypass total de permisos en desarrollo local

Comportamiento: usar --dangerously-skip-permissions (o equivalente) rutinariamente en máquinas de desarrollo donde corren proyectos reales. El motivo declarado suele ser "evitar la fricción de aprobar cada comando".

Daño concreto:

  1. Pérdida de auditoría en tiempo real: cuando un agente ejecuta una acción no intencionada (borrar archivos, modificar git history, instalar dependencias rotas), el humano lo descubre por consecuencia, no por la pausa de aprobación.

  2. Datos perdidos en repos en evolución: un rm -rf accidental sobre el directorio equivocado puede borrar trabajo no comiteado, configuraciones locales, o assets generados que no están en git.

  3. Confianza falsa en el agente: el dev se acostumbra a "todo funciona" y deja de auditar. Cuando aparece un comando raro, el reflejo de pausar ya no existe.

  4. Imposibilidad de saber cuándo empezó un problema: sin puntos de control, debuggear "¿cuándo pasó X?" requiere reconstruir desde logs en vez de tener una traza de aprobaciones.

Caso real (no en este equipo, observado en otros proyectos): un desarrollador con bypass total dejó al agente refactorizar carpetas con mv masivos. Una iteración movió archivos a una ruta equivocada por un typo del agente en la ruta destino. Sin permisos, los mv se ejecutaron en cadena. Recuperar tomó 4 horas porque los archivos no estaban en stash ni en commits.

Cómo detectarlo:

  • El dev menciona "skipeo todos los permisos para ir más rápido"
  • No existe .claude/settings.json ni equivalente en el repo
  • El dev no sabe explicar qué hace --dangerously-skip-permissions

Cómo evitarlo:

  • Aplicar Patrón D.4 (permisos versionados en .claude/)
  • Configurar allow para comandos rutinarios (que es lo que daba fricción)
  • Configurar deny para comandos críticos (rm -rf con paths absolutos, git push --force, npm publish, git reset --hard)
  • Aceptar la fricción ocasional como precio de la gobernanza

Cuándo SÍ es aceptable usar bypass total:

  • Sandboxes efímeros (contenedores Docker que se destruyen post-ejecución)
  • CI/CD donde no hay datos del dev
  • Máquinas virtuales dedicadas para experimentación

Cuándo NO es aceptable:

  • Máquina personal del dev con repos reales
  • Cualquier entorno donde haya datos no replicables
  • Cualquier entorno con credenciales o secretos

Cómo agregar un anti-patrón

Solo se agregan anti-patrones con daño concreto observado, no especulativo. Estructura obligatoria:

  1. Nombre breve (forma de "AP.N — Descripción")
  2. Comportamiento: descripción de la acción problemática
  3. Daño concreto: qué pasa cuando ocurre, con caso real citado
  4. Cómo detectarlo: señal observable
  5. Cómo evitarlo: principio o patrón que lo previene

No agregar anti-patrones de "esto sería malo si pasara" — solo de cosas que pasaron en proyectos reales del equipo.


AP.8 — Adelanto silencioso de deuda técnica

Comportamiento: el agente adelanta ítems explícitos de TECH_DEBT.md, BACKLOG.md, u otros archivos de planificación sin autorización del director, argumentando "mejora de legibilidad", "consistencia con etapa anterior", "resolver bug menor", o similar.

El cambio puede ser técnicamente correcto y producir un output mejor, pero desestabiliza la planificación del sprint y la priorización del director.

Daño concreto:

  1. Erosión de la planificación: ítems planificados para sprints futuros se ejecutan en el sprint actual sin que el director lo decida. La capacidad estimada del sprint se desborda silenciosamente.

  2. Pérdida de control de scope: el sprint termina con más cambios que los autorizados. La trazabilidad de "qué se hizo y cuándo" se rompe.

  3. Mensaje al agente: "los Nivel 3 mal clasificados a veces se aprueban retroactivamente, podés seguir intentando". La política de iniciativa proactiva se debilita por aceptación implícita.

  4. Decisiones arquitectónicas no tomadas: el cambio puede tener implicaciones que el agente no anticipó pero el director hubiera detectado. Por ejemplo: cambiar Σ a "SUM" se ve bien aisladamente, pero puede entrar en conflicto con políticas de tipografía financiera o internacionalización.

Caso real (InQ ROI Sprint 1.5):

  • Etapa 7: Claude Code reescribió fórmulas matemáticas de la nota metodológica del PDF ROI a ASCII puro (Σ → "SUM", × → "x", → "-") sin reportar el cambio en el reporte de la etapa. El bug Unicode estaba documentado en TECH_DEBT.md con plan "embebido de fuente Unicode en Sprint 2". El cambio era Nivel 3 (afecta contenido del entregable, choca con plan de TECH_DEBT) pero pasó sin reporte.

  • Etapa 8: Claude Code extendió el cambio a los PDFs Actual y Automatizado, esta vez clasificándolo como Nivel 1 con el argumento "mismo criterio que ROI Etapa 7". Detectado en el reporte y discutido. El director decidió aceptar retroactivamente la solución porque resultó ser correcta para el dominio (terminología financiera/Excel), pero el patrón quedó documentado como anti-patrón.

Cómo detectarlo:

  • El agente reporta un cambio justificado como "mejora", "consistencia", "resuelve bug", "limpia código" o similar.
  • Verificá si ese cambio resuelve un ítem listado en TECH_DEBT.md, BACKLOG.md, u observaciones diferidas. Si está listado, era Nivel 3 sin importar el tamaño técnico.
  • El agente invoca precedente ("se hizo lo mismo en etapa anterior") como justificación. Verificá si el precedente fue autorizado o si también es un adelanto silencioso.

Cómo evitarlo:

  • Aplicar Patrón C.6 refinado (ver methodology/PATTERNS.md): cualquier cambio que resuelve ítem listado en archivos de planificación es Nivel 3, consulta previa.
  • En CLAUDE.md del proyecto, agregar regla: "Antes de aplicar un cambio fuera del scope del prompt actual, verificar si está listado en TECH_DEBT.md, BACKLOG.md, o equivalentes. Si está listado, consultar antes de proceder."
  • Auditoría adversarial al reporte (Patrón C.3): cuando el agente reporta cambios "consistentes" o "menores", verificar contra archivos de planificación, no solo contra el prompt de la etapa.

Distinción importante:

AP.8 NO es lo mismo que AP.3 (Racionalización de output anómalo). AP.3 es minimizar un problema observado. AP.8 es ejecutar trabajo no autorizado argumentando que es mejora.

AP.8 también difiere del Patrón C.6 mal aplicado. C.6 mal aplicado es clasificar mal el nivel de impacto. AP.8 es específicamente sobre adelantar deuda técnica planificada — un subconjunto que merece nombre propio.


AP.9 — Resolución unilateral de restricciones contradictorias

Comportamiento: el agente enfrenta dos requisitos del prompt que colisionan (ej: "no tocar archivo X" + "build limpio sin errores TypeScript") y resuelve la contradicción actuando mínimamente en lugar de detenerse y reportar el conflicto.

Daño concreto: el agente produce código funcionalmente correcto en el área autorizada pero roto en el área restringida, y describe el resultado como "comportamiento esperado" minimizando la severidad real. Caso real (InQ ROI Sprint 2, Etapa 1): el prompt restringía ActivityPanel.tsx explícitamente (), pero también exigía build sin errores TypeScript. Cambiar types.ts inevitablemente generaba errores TypeScript en ActivityPanel.tsx. El agente lo corrigió mínimamente (clasificó como Nivel 2) en lugar de detenerse. Resultado: slider roto que requirió toda la Etapa 2 para corregir.

Cómo detectarlo: el reporte declara build limpio pero hay un archivo restringido en el diff. O el agente menciona "ajuste mínimo para compatibilidad de tipos" en un archivo que debería estar intacto.

Cómo evitarlo:

  1. En el prompt: cuando haya restricción sobre un archivo, agregar explícitamente: "Si este cambio produce errores TypeScript en archivos restringidos, DETENTE, no los corrijas, reportá el conflicto al director antes de continuar."
  2. Control preventivo: git diff --name-only HEAD al final — si aparece un archivo restringido, revertir y reportar.
  3. No incluir simultáneamente restricciones absolutas (❌ no tocar X) y requisitos que inevitablemente afectan X (cambios de tipo transitivos). Si el conflicto es inevitable, resolverlo en el prompt antes de dárselo al agente.

Relación con otros patrones:

  • Requiere el control preventivo de C.7 (git diff como control de scope) para detección temprana.
  • Distinto de AP.5 (improvisación sin gobernanza): AP.9 ocurre dentro de un prompt estructurado, no por ausencia de método.

AP.10 — Propagación silenciosa de inconsistencia entre fuentes

Comportamiento: un prompt contiene una referencia (código, ruta, esquema) que el agente podría verificar contra otra fuente del repo. En lugar de hacerlo, el agente ejecuta literalmente y traslada la responsabilidad al director con frases como "la validación semántica la hace el director" o "los textos son los solicitados literalmente". Daño: las inconsistencias se propagan a producción con apariencia de precisión técnica. Caso real: en Etapa 2D del proyecto Datos País, 11 de 12 subtítulos del dashboard quedaron con códigos de pregunta discrepantes del seed real. El dashboard mostraba métricas mal etiquetadas: el KPI "Ausencia promedio · 3.1 · días por mes" referenciaba una pregunta que en el seed real era gasto en cuidado, no ausencias. Detectado en la auditoría adversarial posterior, no antes. Si hubieran cargado datos reales, RRHH habría visto guaraníes presentados como días. Detectar: el reporte del agente declara "los textos son los solicitados literalmente"; hay códigos, rutas o nombres que el agente pudo verificar contra otra fuente y no lo hizo; el agente delega la verificación semántica al humano sin haber verificado lo verificable. Evitar: Patrón C.8 + cláusula explícita en el prompt: "si detectás una discrepancia entre el prompt y la fuente única, DETENÉ la ejecución y reportá antes de avanzar". Distinción: ≠ AP.3 — AP.3 minimiza un problema observado; AP.10 evita verificar lo verificable. ≠ AP.9 — AP.9 resuelve restricciones contradictorias del propio prompt; AP.10 propaga inconsistencias entre el prompt y otra fuente.

AP.11 — Contrato desactualizado por código

Comportamiento: una etapa modifica el comportamiento real del sistema (seed, esquema, RLS, RPCs) pero no actualiza el documento que sirve como contrato o fuente única (SEED_SPEC.md, ARCHITECTURE.md, ADRs). El documento queda mintiendo por silencio. Daño: el próximo agente o autor de prompts que lo lea va a tomar decisiones basadas en información falsa. Caso real: en Etapa 1D del proyecto Datos País se modificó seed.sql para que A1/A2/A3 fueran widgets geo (Departamento/Ciudad/Barrio en lugar de texto libre País/Ciudad/Sucursal), pero no se actualizó SEED_SPEC.md. Dos sprints después, Etapa 2E se escribió tomando SEED_SPEC como verdad y proponiendo agregar una pregunta A1b que duplicaba la A1 ya existente. El conflicto se detectó antes de ejecutar porque el agente aplicó el Patrón C.8; sin C.8, se habría creado una pregunta duplicada en producción. Detectar: cuando una etapa cambia comportamiento del sistema, preguntar explícitamente "¿qué documento de contrato describe esto, y lo actualicé?". Si la respuesta es "no sé" o "después lo veo", AP.11 latente. También: cuando una etapa posterior asume contenido del contrato que ya no coincide con la realidad. Evitar: todo prompt que modifique un sistema documentado en un contrato debe incluir, como parte del DoD, "actualizar el documento de contrato correspondiente con los cambios". Es Principio 4 aplicado al mantenimiento, no solo a la creación. Distinción: ≠ AP.4 — AP.4 es decisión no registrada; AP.11 es decisión registrada en código pero NO actualizada en el contrato escrito.