Tag: Programación

  • Impacto del compilador Go en TypeScript 7.0 y su migración

    Impacto del compilador Go en TypeScript 7.0 y su migración

    TypeScript con compilador en Go: qué cambia en tu día a día

    Tiempo estimado de lectura: 4 min

    • Rendimiento: TypeScript 7.0 mueve el motor de tipos fuera de Node.js a un binario en Go, prometiendo hasta 10x en chequeo de tipos en repos grandes.
    • Compatibilidad: Dejar de ser paquete Node.js rompe integraciones que importan la API JS del compilador (p. ej. transformers, ts-morph).
    • Migración práctica: Requiere auditoría de dependencias, estrategias de CI para binarios y puentes (IPC/FFI) para plugins críticos.
    • Balance: Beneficios reales en CI y editor, pero coste organizativo técnico en tooling y librerías.

    TypeScript con compilador en Go: qué cambia en tu día a día es la pregunta que tu equipo debería haberse hecho ayer. TypeScript 7.0 reescribe el motor de validación de tipos fuera de Node.js y lo ejecuta como binario en Go. La promesa es velocidad (hasta 10x en chequeo de tipos en repos grandes). La consecuencia práctica: breaking changes reales en tooling, plugins y pipelines. Este artículo ordena el impacto, da criterio y propone un plan de migración accionable.

    Resumen rápido (lectores con prisa)

    Qué es: TypeScript 7.0 reescribe el motor de tipos como binario en Go, fuera de Node.js.

    Cuándo usarlo: Cuando busques chequeos de tipos significativamente más rápidos y puedas auditar dependencias que tocan el AST.

    Por qué importa: Reduce tiempo en CI y mejora la latencia del IDE, pero rompe integraciones que dependen de la API JS del compilador.

    Cómo funciona (resumen): El compilador pasa de paquete Node.js a binario/WASM; consumidores que importan typescript pierden acceso directo a la API JS y se requieren puentes (IPC/FFI) para mantener compatibilidad.

    TypeScript con compilador en Go: impacto técnico y operativo

    Rendimiento

    Mover el compilador de JavaScript a Go no es un simple cambio de implementación; cambia el modelo de extensión y la superficie de integración.

    • Rendimiento: el chequeo de tipos (tsc) se beneficia de concurrencia nativa (goroutines) y memoria más eficiente. Pipelines que tardaban minutos pasan a segundos.

    Forma de consumo

    • Forma de consumo: deja de ser un paquete Node.js importable; pasa a ser un binario (o potencialmente WASM). Los consumidores que usaban import ts from 'typescript' pierden acceso directo a la API JS del compilador.

    Plugins y transformers

    • Plugins y transformers: APIs como ts.Program, ts.Transformer y librerías como ts-morph quedan en una zona de incompatibilidad. Reconstruir puentes implica IPC/FFI y coste de latencia.

    Estrictez y errores emergentes

    • Estrictez y errores emergentes: el nuevo compilador puede ser más estricto en resolución de módulos y rutas, sacando a la luz configuraciones frágiles en tsconfig.json.

    Fuentes útiles: TypeScript, esbuild, swc, Vite.

    Qué mejora en tu día a día (y sin fricción)

    • CI/CD: tsc --noEmit deja de ser el cuello de botella. Menos tiempo en runners reduce facturación en GitHub Actions, CircleCI, etc.
    • IDE: TSServer consume menos RAM y responde mejor en proyectos con tipos complejos (Zod, Prisma, tRPC — Zod, Prisma, tRPC).
    • Monorepos: escalabilidad de chequeos por paquete, menor bloqueo en cambios amplios.

    Estos beneficios son reales y medibles. Pero no son automáticos para todos los proyectos.

    Qué se rompe en la práctica

    • Frameworks que dependen del AST en tiempo de compilación: Angular, NestJS y ORMs que usan transformers y decoradores verán fallos si no migran sus pipelines.
    • Herramientas de generación de código y scripts que importan typescript quedarán sin la API JS directa.
    • Plugins de bundlers y herramientas de análisis estático (p. ej. ts-morph) requieren reescritura o compatibilidad por puente.

    La migración implica trabajo no trivial por parte de mantenedores de librerías. No es sólo actualizar package.json.

    Plan de acción para equipos (prioritario y práctico)

    1. Auditoría de superficie de riesgo

    • Busca en tu árbol de dependencias cualquier uso de import 'typescript' o require('typescript').
    • Lista paquetes que usan transformers o ts.Program. Estas son las integraciones en riesgo inmediato.

    2. Aísla la transpilación del type-checking

    • Usa Vite/esbuild para bundling y transpile rápido.
    • Corre tsc --noEmit como job paralelo en CI. Esto desacopla cambios de runtime del chequeo estricto.

    3. Congela versiones y crea una ventana de transición

    • Si dependes de plugins no migrados (decoradores de NestJS, Angular compilers), fija TypeScript a ~5.x hasta validar compatibilidad.
    • Comunica fechas internas de evaluación y migración para dependencias clave.

    4. Prepara CI y runners

    • Asegúrate de que los runners pueden descargar y ejecutar binarios (amd64/arm64).
    • Considera imágenes Docker con el binario del compilador preinstalado para reproducibilidad.

    5. Estrategia de puentes para plugins

    • Para librerías críticas, evalúa dos alternativas: 1) reescribir transformadores en Go o 2) implementar un proceso IPC que exponga el AST a JS (aceptable temporalmente, pero con latencia).
    • Prioriza reescrituras sólo si la librería es central; para consumo general, pide a mantenedores roadmap y plazos.

    6. Testing y despliegue gradual

    • Canary builds: ejecuta el compilador en Go en un subset de repos o paquetes.
    • Monitorea regresiones en CI (errores nuevos de tipo o resolución) y en IDEs de desarrolladores.

    Criterio técnico final

    Adoptar TypeScript 7.0 por rendimiento sin auditoría es una apuesta peligrosa. El enfoque correcto es pragmático: separar responsabilidades, auditar dependencias que manipulan AST, preparar CI para binarios y coordinar migraciones con mantenedores de librerías críticas.

    La ventaja económica y productiva es real: feedback loops más rápidos, menos microinterrupciones del IDE y menos coste de CI. El precio es técnico y organizativo: trabajo de migración en tooling. Quien lo planifique hoy evita picos de trabajo y bloqueos de entrega mañana.

    FAQ

    ¿Qué cambia con TypeScript 7.0?

    TypeScript 7.0 reescribe el motor de validación de tipos fuera de Node.js y lo ejecuta como binario en Go. Como consecuencia, deja de ser un paquete Node.js importable y puede ofrecer mejoras de velocidad (hasta 10x en chequeo de tipos en repos grandes) gracias a concurrencia nativa y manejo de memoria en Go.

    ¿Afecta esto a mi CI?

    Sí. tsc --noEmit puede dejar de ser el cuello de botella y reducir el tiempo de ejecución en runners, lo que baja costes en servicios como GitHub Actions o CircleCI. Sin embargo, es necesario garantizar que los runners puedan descargar y ejecutar binarios en las arquitecturas requeridas.

    ¿Qué pasa con plugins que usan transformers?

    APIs que manipulan el AST o dependen de la API JS del compilador (por ejemplo, ts-morph) quedan en riesgo de incompatibilidad. Las alternativas son reescribir transformadores en Go o implementar puentes IPC/FFI para exponer el AST a procesos JS, con coste de latencia.

    ¿Debo migrar inmediatamente?

    No necesariamente. Es recomendable auditar dependencias que usen typescript, congelar versiones críticas (p. ej. ~5.x) y crear una ventana de transición hasta validar compatibilidad de librerías y plugins antes de adoptar en producción.

    ¿Cómo mitigo riesgos en monorepos?

    Aísla la transpilación del type-checking usando herramientas como Vite o esbuild, ejecuta chequeos de tipos como jobs paralelos en CI y aplica canary builds para ejecutar el compilador en Go en subsets de paquetes antes del despliegue general.

  • Identificando problemas de vibe coding en equipos empresariales

    Identificando problemas de vibe coding en equipos empresariales

    Problemas de vibe coding para equipos empresariales (2026)

    Tiempo estimado de lectura: 4 min

    • Vibe coding —iterar con un LLM hasta que el código “parece funcionar”— acelera entrega pero genera deuda técnica opaca.
    • Cinco problemas concretos: código huérfano, erosión arquitectónica, riesgos de seguridad en la cadena de suministro, degradación del criterio técnico y sobrecarga en code review.
    • La solución no es prohibir la IA: es imponer controles técnicos y procesos (Design-First, ADRs, testing liderado por humanos, CI/CD restrictivo, verificación de dependencias y rotación de ownership).
    • Permitir vibe coding solo en prototipos desechables, scripts aislados o mocks; evitarlo en autenticación, transacciones y caminos con implicaciones regulatorias.
    ¿Tu repositorio funciona hoy y nadie lo entiende mañana? Los problemas de vibe coding para equipos empresariales (2026) son eso: soluciones rápidas que se convierten en deuda técnica silenciosa. Para Tech Leads, Arquitectos y CTOs, esto ya no es una discusión teórica. Es mantenimiento que se vuelve imposible, incidentes que aparecen a horas raras y una superficie de ataque que crece sin control.

    Resumen rápido (lectores con prisa)

    Vibe coding: iterar con LLMs hasta que el bloque “parece funcionar”. Útil para prototipos; peligroso en código de producción. Obliga a controles: diseño previo, ADRs, testing liderado por humanos, CI/CD restrictivo y validación de dependencias. Evitar en caminos críticos.

    Problemas de vibe coding para equipos empresariales (2026): diagnóstico rápido

    1) Código huérfano: funciona, pero nadie lo mantiene

    La IA entrega un módulo que pasa tests básicos. Nadie lo escribió línea por línea. Nadie puede explicar el flujo en un incidente P1. Eso aumenta el tiempo de resolución dramáticamente: lo que se ahorró en desarrollo se pierde multiplicado en debugging.

    Ejemplo realista: un endpoint de autenticación generado que falla ante tokens caducados en escenarios de reintentos — el path feliz funciona, el resto no. Resultado: latencia, errores y horas de on-call.

    2) Erosión arquitectónica: soluciones locales que rompen el todo

    Los modelos no tienen una visión sistémica del repo. Producen utilidades reinventadas, acoplan capas y rompen contratos explícitos. Cuando varios devs usan prompts distintos, el cóctel es un monolito fragmentado con estilos y anti-patterns mezclados.

    3) Seguridad y cadena de suministro: vulnerabilidades sutiles

    No es solo SQL injection. Son flujos de autorización incompletos, validaciones omitidas en edge cases y dependencias “sugeridas” que están obsoletas o son inexistentes. La comunidad de seguridad ya documentó riesgos de typosquatting y abuso de paquetes; automatizar la adopción de dependencias sin verificación amplifica ese vector (ver OWASP).

    4) Degradación del criterio técnico

    Delegar la implementación en prompts empobrece el aprendizaje. Juniors que se vuelven “prompteadores” no construyen modelos mentales sobre complejidad, rendimiento o diseño de sistemas. A la larga, el activo más valioso —criterio técnico— se erosiona.

    5) Code review convertido en cuello de botella

    Revisar código generado exige más contexto y tiempo. Los patrones de error humano son predecibles; las soluciones de LLM son impecables sintácticamente pero opacas conceptualmente. Los leads pasan de decidir arquitectura a auditar toneladas de PRs.

    Cómo mitigar sin renunciar a la IA

    Prohibir la IA no es opción. Las empresas competitivas aplican control, no veto. Aquí un set de medidas prácticas y verificables.

    • Design-First: define contratos, diagramas y contratos de datos antes de cualquier generación. La IA implementa; no diseña.
    • ADRs obligatorios: cualquier módulo generado con complejidad no trivial debe acompañarse de un Architecture Decision Record. Plantilla y ejemplo: Plantilla y ejemplo
    • Testing humano-led (BDD): el desarrollador define casos, edge cases y aserciones. La IA genera el boilerplate de tests, no la lógica de cobertura.
    • CI/CD restrictivo: integra análisis estático y políticas que bloqueen PRs con saltos bruscos de complejidad ciclomática o inclusión de paquetes no verificados. Herramientas como Semgrep ayudan a automatizar reglas.
    • Verificación de dependencias fuera del flujo PR: antes de aceptar librerías sugeridas por un LLM, pásalas por un proceso de validación de licencias y reputación. Sigue guías de NIST sobre desarrollo seguro.
    • Pares y rotación de ownership: obliga a que otro ingeniero entienda y firme el ADR antes del merge. Pair-programming para integración crítica.
    • Entrenamiento deliberado: formación interna en diseño, debugging profundo y análisis de performance. No atajos educativos.

    Límites claros: cuándo permitir vibe coding y cuándo no

    Permite vibe coding en prototipos desechables, scripts aislados o generación de mocks. Evítalo en autenticación, transacciones, migraciones de estado y cualquier camino con implicaciones regulatorias o legales.

    Conclusión: la IA potencia, pero el criterio no se automatiza

    Los problemas de vibe coding para equipos empresariales (2026) no son culpa de las herramientas. Son consecuencia de adoptarlas sin procesos. La diferencia entre un equipo que escala con IA y uno que se ahoga en deuda técnica está en una palabra: criterio. No lo externalices. Defínelo, mídelo y exige documentación. La IA hará el trabajo pesado; los humanos deben seguir decidiendo qué trabajo merece hacerse.

    Apúntate al newsletter de Dominicode para la siguiente entrega: hablaremos de políticas concretas de CI/CD y reglas Semgrep para detectar “sospecha de generación automática” en PRs.

    Encuentra una continuación práctica y recursos experimentales en Dominicode Labs. Allí publicamos plantillas de ADR, reglas Semgrep y ejemplos de pipelines seguros que complementan este artículo.

    FAQ

    ¿Qué es exactamente “vibe coding”?

    Es el patrón de trabajo donde un desarrollador itera con un modelo de lenguaje (Copilot, Claude, Cursor u otros) hasta que el código “parece funcionar”, sin aplicar diseño previo ni verificación humana exhaustiva.

     

    ¿En qué escenarios es aceptable usar IA para generar código?

    Aceptable en prototipos desechables, scripts aislados y generación de mocks. No es recomendable en autenticación, transacciones, migraciones de estado o caminos con implicaciones regulatorias.

     

    ¿Cómo se evita que las dependencias sugeridas por LLM introduzcan riesgo?

    Implementando un proceso de validación de dependencias fuera del flujo PR que verifique licencias, reputación y coincidencia con políticas internas antes de su aceptación.

     

    ¿Qué debe incluir un ADR cuando el código fue generado por IA?

    Descripción de la decisión, alternativas consideradas, riesgos identificados, responsables y link al módulo generado. La plantilla recomendada se puede consultar en Plantilla y ejemplo.

     

    ¿Cómo cambia el proceso de code review con uso intensivo de LLMs?

    Requiere más contexto en las revisiones, énfasis en arquitectura y pruebas, y posibles políticas de pares y rotación de ownership para asegurar que otro ingeniero pueda explicar y mantener el código.

     

    ¿Qué herramientas ayudan a automatizar políticas que mitiguen vibe coding?

    Herramientas de análisis estático y reglas en CI/CD (por ejemplo, Semgrep), y procesos de verificación de dependencias siguiendo guías como las de NIST.

  • Asegura el tipo de datos en function calling usando TypeScript

    Asegura el tipo de datos en function calling usando TypeScript

    Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo

    Tiempo estimado de lectura: 4 min

    • Ideas clave:
    • Los LLMs fallan en formato y semántica: validar la salida evita errores en producción.
    • Define esquemas con Zod, deriva tipos con z.infer<>, y valida antes de ejecutar herramientas.
    • Usa .parse() para fallar rápido en endpoints y .safeParse() para autocorrección en agentes.
    • Mide y registra: trazabilidad completa (prompt, response, error de Zod, tool invocada).

    Introducción

    Cuando un agente llama a una herramienta, el modelo genera un JSON con argumentos. Asumir que ese JSON tendrá la forma correcta es la fuente de la mayoría de fallos en producción. Implementar Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo no es opcional: es ingeniería defensiva. Con Zod validas en runtime, con z.infer<> obtienes tipos sincronizados y con un framework que integre ambos cierras el círculo.

    Fuentes útiles: Vercel AI SDK, Zod, OpenAI Structured Outputs.

    Resumen rápido (lectores con prisa)

    Qué es: Validación tipada de la salida de modelos mediante Zod y TypeScript.

    Cuándo usarlo: Siempre que un LLM invoque herramientas, modifique estado o llame APIs críticas.

    Por qué importa: Previene errores por campos faltantes, tipos incorrectos o JSON mal formado en producción.

    Cómo funciona: Define esquemas Zod, deriva tipos con z.infer<>, valida con .parse() o .safeParse() antes de ejecutar.

    Por qué tipar el function calling importa ahora

    Los LLMs fallan de formas predecibles: omiten campos, envían strings en vez de números, rodean JSON con Markdown o inventan claves. Si procesas ese output con JSON.parse() y as Tipo, renuncias a la seguridad de TypeScript en runtime. El resultado: escrituras corruptas en bases de datos, llamadas a APIs con parámetros inválidos y bugs que sólo aparecen semanas después.

    La alternativa técnica es clara:

    • declarar el esquema con Zod,
    • derivar el tipo TypeScript con z.infer<>,
    • validar antes de ejecutar la herramienta.

    Eso convierte la entrada del agente en un contrato matemático que protege tu lógica de negocio.

    Arquitectura práctica: esquema → validación → ejecución

    Patrón recomendado:

    1. Define el esquema Zod y añádele descripciones que el LLM pueda leer.
    2. Expón ese esquema en el prompt (o úsalo con Structured Outputs).
    3. Valida la respuesta del LLM con .safeParse() o .parse() antes de llamar a la función.
    4. Si falla, captura el ZodError, loguéalo y opcionalmente reintenta con autocorrección.

    Código mínimo (ejemplo de consulta de divisas)

    import { tool } from 'ai'; // p. ej. Vercel AI SDK
    import { z } from 'zod';
    
    const ExchangeSchema = z.object({
      base: z.string().length(3).toUpperCase().describe('Moneda base ISO 4217, ej. USD'),
      target: z.string().length(3).toUpperCase().describe('Moneda destino ISO 4217, ej. EUR'),
    });
    
    type ExchangeParams = z.infer;
    
    export const getExchangeRate = tool({
      description: 'Devuelve el tipo de cambio entre dos monedas',
      parameters: ExchangeSchema,
      execute: async ({ base, target }: ExchangeParams) => {
        const res = await fetch(`https://api.exchangerate-api.com/v4/latest/${base}`);
        if (!res.ok) throw new Error('API externa falló');
        const data = await res.json();
        return { rate: data.rates[target] };
      }
    });
    

    Si la validación falla, execute nunca se ejecuta: el SDK/Zod detiene la cadena y devuelve un error estructurado.

    .parse() vs .safeParse() y autocorrección

    Usa .parse() cuando quieras fallar rápido (endpoints HTTP que deben devolver 4xx/5xx). Usa .safeParse() en agentes y workflows que puedan auto‑corregirse sin intervención humana.

    Patrón de autocorrección:

    1. LLM genera JSON.
    2. .safeParse() devuelve success: false y error.
    3. Serializas error.flatten() y lo inyectas en un nuevo prompt: “Tu respuesta falló por X. Corrige el JSON.”
    4. Reintentás N veces con backoff; si sigue fallando, encolas para revisión humana.

    Ese ciclo convierte errores estructurales en una conversación de corrección con el modelo, robusta y trazable.

    Operaciones y observabilidad

    No basta con validar: mide y actúa.

    Métricas recomendadas:

    • tasa de validación fallida por prompt/modelo,
    • latencia media de autocorrección,
    • número de reintentos hasta éxito,
    • porcentaje de degradaciones a intervención humana.

    Registra siempre: prompt, raw response, resultado de Zod (.error.flatten()), y el tool invocado. Eso te da trazabilidad: prompt → response → validación → acción. Sin esos registros no hay postmortem útil.

    Decisiones arquitectónicas y trade‑offs

    – Structured Outputs (OpenAI) y generateObject reducen errores de formato pero no sustituyen la validación semántica: un amount: -5 puede pasar el schema si no validas signo y rango. Siempre valida con Zod (https://zod.dev/).

    – Tipar desde el día 0 exige disciplina: los esquemas son contratos que obligan a diseñar prompts claros y a mantener tests de integración. La deuda que previene compensa la inversión inicial.

    – En entornos orquestados (n8n, XState) preferir que el LLM decida la herramienta y que la ejecución quede en una máquina de estado puede ser más seguro para acciones críticas. Igual aplica: la entrada debe validarse antes de actuar.

    Conclusión: deja de adivinar, empieza a garantizar

    Function calling tipado con TypeScript: deja de adivinar lo que devuelve el modelo — es una fórmula sencilla y comprobada: define el esquema (Zod), extrae el tipo (z.infer<>), valida antes de ejecutar y automatiza la corrección cuando tenga sentido. Esa disciplina transforma un LLM impredecible en un componente confiable de tu arquitectura. Si tu agente escribe en bases de datos, llama APIs facturadas o toma decisiones que afectan a clientes, no hay excusas: valida antes de ejecutar y loguea todo. Así se construyen agentes que pueden correr solos, y no problemas que sólo aparecen en producción.

    Para continuar explorando prácticas operativas y experimentos en automatización e IA aplicada, consulta Dominicode Labs. Esta referencia complementa las técnicas descritas y ofrece recursos prácticos para implementar pipelines seguros y trazables en producción.

    FAQ

    ¿Por qué no basta con hacer JSON.parse() y castear a un tipo?

    Porque JSON.parse() solo asegura formato JSON válido, no la semántica ni la presencia y tipo de campos esperados. Castear con as Tipo ignora la verificación en runtime, lo que permite entradas inválidas que pueden provocar errores en bases de datos o llamadas a APIs en producción.

    ¿Cuándo debo usar .parse() en lugar de .safeParse()?

    Usa .parse() en contextos donde quieras fallar rápido y retornar un error (por ejemplo endpoints HTTP que deben devolver 4xx/5xx). Usa .safeParse() cuando el flujo puede intentar autocorrección o reintentos antes de degradar a intervención humana.

    ¿Qué hago si .safeParse() falla continuamente?

    Serializa el error con error.flatten(), inyecta esa información en un nuevo prompt pidiendo corrección, y reintenta N veces con backoff. Si sigue fallando, encola la unidad para revisión humana y registra el incidente para análisis posterior.

    ¿Debo exponer el esquema Zod en el prompt?

    Sí: exponer el esquema ayuda al modelo a generar la estructura correcta (especialmente con Structured Outputs). Aun así, la validación con Zod debe ejecutarse en runtime; el esquema en el prompt no sustituye la verificación.

    ¿Qué debo registrar para tener trazabilidad adecuada?

    Registra el prompt, la respuesta cruda del modelo, el resultado de Zod (error.flatten()), y la herramienta (tool) invocada. Esos datos permiten reconstruir el flujo prompt → response → validación → acción para postmortems.

    ¿Los Structured Outputs sustituyen la validación con Zod?

    No. Structured Outputs y utilidades como generateObject reducen errores de formato, pero no validan semántica ni rangos (por ejemplo, amount: -5 podría pasar). Sigue validando con Zod en runtime.

  • Cómo gestionar la memoria en agentes entre sesiones de forma eficiente

    Cómo gestionar la memoria en agentes entre sesiones de forma eficiente

    Context Engineering — el arte de gestionar el contexto del agente entre sesiones

    Tiempo estimado de lectura: 5 min

    • Context Engineering es disciplina operativa para mantener la memoria de agentes entre sesiones y evitar que “arranquen desde cero”.
    • Tres archivos clave (CLAUDE.md, AGENTS.md, memory files) convierten reglas, roles y memoria en infraestructura reutilizable.
    • Arquitectura de sub-agentes (orquestador, especialistas, QA) minimiza ruido y mejora precisión, latencia y coste.
    • Prácticas concretas: cierre de sesión obligatorio, outputs estructurados (JSON/Zod), RAG con caché semántico y auditoría por ejecución.

    Context Engineering es la práctica de diseñar y mantener la memoria operativa de agentes entre sesiones. Si aplicas GSD a equipos humanos, Context Engineering aplica GSD a agentes: dividir tareas, documentar decisiones y asegurar que la próxima sesión no sea una pizarra en blanco. Sin esta disciplina, los agentes alucinan, revierten decisiones y se vuelven caras e ineficaces.

    Resumen rápido (lectores con prisa)

    Context Engineering diseña la memoria y reglas permanentes de agentes para mantener continuidad entre sesiones. Úsalo cuando un sistema de agentes necesita precisión, trazabilidad y bajo coste operativo. Importa porque evita alucinaciones, pérdida de progreso y decisiones reversibles. Funciona con tres capas: reglas estáticas, memoria dinámica y sub-agentes especializados.

    El problema

    El problema es elegante y directo: los LLMs razonan bien, pero olvidan. El historial de chat como única memoria funciona en demos; colapsa en repositorios reales. Más tokens en el prompt solo añaden ruido. La solución práctica es convertir el repositorio en la memoria del agente mediante tres capas: reglas estáticas, memoria dinámica y sub-agentes especializados.

    Tres archivos que cambian el juego: CLAUDE.md, AGENTS.md y memory files

    CLAUDE.md (o .cursorrules) — la “constitución” del proyecto

    Propósito: reglas inmutables que el agente debe respetar.

    Contenido práctico: stack exacto (Node 20, React 18), políticas de seguridad, restricciones arquitectónicas y decisiones no negociables.

    Ejemplo (resumen):

    • Stack: Node 20, TypeScript 5.x, Next.js 14.
    • Convenciones: ESLint + Prettier; tests en Vitest.
    • Restricciones: “Nunca acceder a Supabase desde cliente; usar Server Actions”.

    CLAUDE.md es lo primero que un agente debe leer al comenzar.

    AGENTS.md — el organigrama legible por máquinas

    Propósito: definir quién hace qué en un sistema multi-agente.

    Contenido práctico: routing de tareas, roles (FrontendWorker, DBOptimizer, QAReviewer), permisos para commits.

    Resultado: orquestador capaz de delegar la tarea correcta al sub-agente correcto sin mandar TODO el repo como contexto.

    Memory files — la memoria viva (.context/ o .ai/)

    active_task.md: la tarea actual, objetivo y criterios de éxito.

    changelog_ai.md: decisiones y porqués (no sólo el qué).

    lessons_learned.md: problemas recurrentes y soluciones definitivas.

    Rutina obligatoria: al cerrar sesión el agente actualiza estos archivos. Al abrir sesión, los lee y retoma.

    Sub-agentes: aislar contexto, reducir ruido, mejorar precisión

    Arquitectura propuesta:

    Arquitectura propuesta

    • Agente Orquestador (Router): lee AGENTS.md, empaqueta contexto mínimo y llama al especialista.
    • Agente Especialista (Worker): recibe solo lo necesario (e.g., esquema DB + active_task.md) para reducir ruido.
    • Agente Revisor (QA): valida output contra CLAUDE.md y tests antes de aplicar cambios.

    Ventaja: un sub-agente con 10k tokens relevantes produce mejores resultados que un mega-agente con 100k tokens llenos de ruido. También reduce costos y latencia.

    Prácticas operativas (lo que realmente marca la diferencia)

    • Obliga a un “cierre de sesión”: el prompt final del día debe ser “Actualiza active_task.md, changelog_ai.md y sugiere el siguiente paso”.
    • Usa esquemas para outputs: fuerza JSON/Zod para evitar outputs malformados.
    • RAG + caché semántico: externaliza historial pesado en una vector DB y recupera solo lo necesario por tarea. (Ver LangChain)
    • Streaming y UX: implementa streaming token a token para evitar bloqueos de UI. (Vercel AI SDK: Vercel AI SDK)
    • Auditoría y permisos: registra cada ejecución de sub-agente y limita quién puede hacer merges automáticos.

    Estructura mínima recomendada del repo

    /project-root
      /src
      /.ai
        CLAUDE.md
        AGENTS.md
        active_task.md
        changelog_ai.md
        lessons_learned.md
      /.ai/logs
      /docs

    Herramientas y lecturas útiles

    Criterio final para equipos técnicos

    Context Engineering no es documentación bonita. Es infraestructura operativa que convierte agentes en miembros persistentes del equipo. Si inviertes en reglas estáticas (CLAUDE.md), memoria dinámica (memory files) y una red de sub-agentes bien definida (AGENTS.md + orquestador), ganarás precisión, velocidad y trazabilidad. Sin esto, los agentes seguirán siendo costosos “showrooms” en lugar de fuerza productiva real.

    Aplica GSD a tus agentes: trocea, documenta, cierra sesiones. Si lo haces bien, el agente no volverá a arrancar desde cero.

    Dominicode Labs

    Si te interesa profundizar en automatización, agentes y workflows aplicados a equipos técnicos, puedes continuar explorando recursos y experimentos en Dominicode Labs. Es una continuación lógica para poner en práctica patrones de Context Engineering mencionados aquí.

    FAQ

    ¿Qué es Context Engineering?

    Context Engineering es la práctica de diseñar y mantener la memoria operativa y reglas de agentes entre sesiones para mantener continuidad, reducir alucinaciones y preservar decisiones previas.

    ¿Cuándo debo usar CLAUDE.md?

    Usa CLAUDE.md al empezar cualquier sesión de agente: contiene reglas inmutables, stack, convenciones y restricciones que el agente debe respetar. Es el primer archivo que el agente debe leer.

    ¿Para qué sirve AGENTS.md?

    AGENTS.md define roles, routing de tareas y permisos en sistemas multi-agente, permitiendo al orquestador delegar correctamente sin enviar el repo entero como contexto.

    ¿Qué contienen los memory files y quién los actualiza?

    Contain archivos como active_task.md, changelog_ai.md y lessons_learned.md. El agente en sesión debe actualizarlos al cerrar sesión; el próximo agente los lee al abrir sesión.

    ¿Por qué usar sub-agentes en lugar de un mega-agente?

    Porque un sub-agente centrado con contexto relevante (p. ej. 10k tokens) produce resultados más precisos y eficientes que un mega-agente con 100k tokens de ruido. Reduce costos, latencia y errores.

    ¿Qué es RAG y por qué es relevante aquí?

    RAG (Retrieval-Augmented Generation) externaliza historial pesado en una vector DB y recupera solo lo necesario por tarea. Es relevante para evitar enviar todo el historial en cada prompt y mantener precisión.

    ¿Cómo auditar ejecuciones de sub-agentes?

    Registra cada ejecución en logs estructurados (.ai/logs), incluye metadatos (input mínimo, decision hashes) y limita permisos para merges automáticos. La auditoría debe permitir reproducir la decisión y revisar cumplimiento con CLAUDE.md.

  • Cómo especificar un agente SDD antes de su implementación

    Cómo especificar un agente SDD antes de su implementación

    SDD + Agentes: cómo especificar un agente antes de construirlo

    Tiempo estimado de lectura: 5 min

    Ideas clave

    • Especificar antes de construir: define flujos de decisión, límites de herramientas y condiciones de parada antes de programar.
    • SDD para agentes ≠ SDD tradicional: los agentes requieren specs que formalicen libertad, herramientas y puntos de escalado humano.
    • Tres bloques críticos: topología de decisión, contratos de herramienta con schemas y guardrails cuantificables.
    • La spec debe ser ejecutable: tests automatizados, simuladores de fallo y verificación en CI/CD.

     

    Introducción

    SDD + Agentes: cómo especificar un agente antes de construirlo — dilo antes de teclear. Si no documentas la caja de arena cognitiva del LLM, lo que construyas será frágil, caro y peligroso. La especificación no es burocracia: es la diferencia entre un experimento que explota y un servicio que vive en producción.

    En las primeras líneas: especificar un agente significa definir flujos de decisión, límites de herramientas y condiciones de parada antes de escribir una sola línea de código. Hazlo así y reduces bucles infinitos, facturas de API descontroladas y escrituras destructivas en tus bases.

    Resumen rápido (lectores con prisa)

    Qué es: Una spec agéntica formaliza topología de decisión, contratos de herramientas y condiciones de parada.

    Cuándo usarla: Antes de implementar agentes que razonan o que pueden tocar recursos críticos.

    Por qué importa: Evita comportamientos estocásticos dañinos, costes inesperados y fallos de integridad de datos.

    Cómo se aplica: Define un patrón operativo único, schemas de entrada/salida para cada tool, y guardrails cuantificables con telemetría y pruebas.

    Por qué SDD para agentes no es lo mismo que SDD tradicional

    En apps CRUD, spec = modelos de datos + endpoints + contratos. Un 404 es un fallo leve. Un agente sin spec puede intentar cien variaciones de la misma consulta SQL, escribir datos corruptos o invocar herramientas fuera de scope. Aquí falla la arquitectura, no el prompt.

    Los agentes razonan de forma estocástica. Por eso la spec debe formalizar:

    • Qué libertad tiene el agente en cada punto.
    • Qué herramientas puede tocar y cómo.
    • Cuándo debe pararse y llamar a un humano.

    Anthropic recomienda priorizar flujos orquestados sobre autonomía total para casos críticos (ver: Anthropic — Building effective agents). Toma nota: la industria no apuesta por “agentes libres” en producción sin guardrails.

    Tres bloques que debe cubrir tu spec agéntica

    1) Flujos de decisión: topología y patrón operativo

    Decide uno (y solo uno) de estos patrones por caso de uso:

    • Enrutamiento semántico: el LLM clasifica intenciones y delega a código determinista.
    • Máquina de estados orquestada: el LLM elige transiciones entre nodos predefinidos (n8n, LangGraph, XState).
    • Bucle ReAct autónomo: pensamiento-observación-acción libre (solo para experimentos controlados).

    No mezcles sin regla. Define explícitamente qué patrón rige cada intent/endpoint y por qué.

    2) Límites de herramientas (Tool Boundaries)

    Una herramienta para un agente no es un endpoint cualquiera. Tu spec de herramienta debe incluir, al menos:

    • Contrato de datos (Zod o JSON Schema). No aceptes “any”.
    • Descripciones semánticas por campo: guía al LLM sobre qué producir exactamente.
    • Precondiciones de uso: cuándo está permitido invocar la tool.
    • Protocolo de fallo: ¿autocorrección (con el error serializado), retry con backoff, usar valor por defecto o abortar y escalar?

    Ejemplo mínimo (JSON Schema + fallback):

    {
      "name": "createUser",
      "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email" } }, "required": ["email"] },
      "description": "Crea un usuario. email debe ser un correo válido. No inferir dominios.",
      "precondition": "email provisto por usuario",
      "onError": { "strategy": "abort_and_escalate", "max_retries": 0 }
    }

    Si dejas el onError en blanco, el agente decidirá por su cuenta —y lo hará mal.

    3) Guardrails y condiciones de parada

    Los guardrails no son sugerencias; son límites numéricos y verificables:

    • Max Steps: 5–10 iteraciones razonables por sesión antes de forzar cierre.
    • Retries por herramienta: típicamente 1–3, con backoff y registro.
    • Presupuesto operativo: tokens máximos por ejecución y tiempo máximo (p. ej. 30s wall clock).
    • Reglas de escalado humano: por ejemplo, tres fallos consecutivos de la misma tool o confianza del modelo < 0.6 → escalar.

    Documenta esos números en la spec. Implanta telemetría que lo verifique en tiempo real.

    Ingeniería práctica: plantilla rápida para tu spec agéntica

    Un documento mínimo y accionable debe contener:

    1. Directiva principal (system prompt base, objetivo inmutable).
    2. Fronteras negativas (anti-prompts: qué nunca debe hacer el agente).
    3. Contrato de memoria (qué guarda la memoria episódica y qué va a la semántica, p. ej. pgvector).
    4. Matriz de herramientas (schema, descripciones, precondiciones, fallback).
    5. Criterios de interrupción y política de escalado humano.
    6. Tests de comportamiento (simulaciones de fallo: error DB, timeout API, input malicioso).

    Incluye URLs en la spec para APIs críticas, contratos de datos y documentación de seguridad. Un equipo debe poder reproducir el flujo completo sin leer código.

    Trade‑offs y decisiones reales

    – Ventana de contexto gigante vs memoria estructurada: ventajas teóricas hay, pero en producción la memoria estructurada gana por latencia, coste y precisión (ver problema “lost in the middle”: arXiv:2307.03172).

    – Autonomía vs auditabilidad: cuanto más autónomo, menos auditable. Para negocios, prioriza auditabilidad.

    – Retry agresivo vs abort + humano: lo primero puede romper tu DB; lo segundo ralentiza workflows pero salva integridad.

    Cierre operativo: de la spec al CI/CD

    La spec no es un PDF muerto. Debe formar parte del pipeline:

    • Tests automatizados que validen precondiciones y fallbacks.
    • Simuladores que reproduzcan errores de herramientas.
    • Guardrails chequeados en staging y alertas de telemetría en producción.

    Si tu spec no se puede testear automáticamente, no es spec: es promesa. Y las promesas no pagan facturas.

    Define la caja de arena antes de soltar los músculos del agente. Es la única manera de que tus agentes actúen con intención, no con catástrofe.

    Dominicode Labs

    Para equipos que implementan pipelines y simuladores de fallo como parte de la spec, una referencia práctica y recursos complementarios están disponibles en Dominicode Labs. Considéralo como un recurso adicional para integrar tests y telemetría en tu CI/CD.

     

    FAQ

    ¿Por qué no vale con un buen prompt para controlar un agente?

    Un prompt no formaliza contratos ni límites verificables. Los agentes razonan de forma estocástica; sin schemas, precondiciones y guardrails numéricos, el prompt será frágil frente a inputs inesperados.

    ¿Qué es un contrato de herramienta y por qué usar JSON Schema?

    Un contrato de herramienta define tipos, formatos y campos requeridos. JSON Schema o Zod son formalismos que permiten validar entradas/salidas de forma determinista y evitar “any” que produzca comportamiento impredecible.

    ¿Cuántas iteraciones (Max Steps) son razonables?

    La guía práctica sugiere entre 5 y 10 iteraciones por sesión antes de forzar cierre. Ese rango reduce bucles infinitos y consumo excesivo de recursos.

    ¿Cómo debo manejar fallos recurrentes de una herramienta?

    Define un protocolo de fallo en la spec: retries limitados con backoff, registro y una estrategia de escalado (por ejemplo, abort_and_escalate tras N retries). No dejes el comportamiento en blanco.

    ¿Qué pruebas automatizadas son mínimas para una spec agéntica?

    Al menos: validación de precondiciones, simuladores de fallo de tools (DB error, timeout), y tests que verifiquen que los guardrails se activan (Max Steps, budget, retries).

    ¿Dónde documentar la política de escalado humano?

    La política de escalado debe estar en la spec principal, con reglas verificables (ej. tres fallos consecutivos de la misma tool o confianza < 0.6 → escalado) y enlaces a contactos/runbooks en tu repositorio de operaciones.

  • Cómo manejar errores en agentes de IA usando TypeScript

    Cómo manejar errores en agentes de IA usando TypeScript

    Error handling en agentes de IA: TypeScript te obliga a hacerlo bien

    Tiempo estimado de lectura: 3 min

    Ideas clave

    • Evita try/catch genéricos: ocultan la causa raíz y llevan a reintentos inútiles o a falsos positivos.
    • Usa Result<T, E>: convierte errores en valores tipados que el orquestador y el LLM pueden razonar.
    • Forzar exhaustividad con never: el compilador impide desplegar manejadores incompletos.
    • Persistir errores en memoria: guarda fallos estructurados en la memoria episódica para decisiones posteriores.
    • Instrumenta y prueba: telemetría, tests y SLAs para garantizar conducta operativa.

    Tabla de contenidos

    Introducción

    Error handling en agentes de IA: TypeScript te obliga a hacerlo bien. Dilo alto. Si tu agente llama herramientas, escribe datos o encadena flujos, el modo en que tratas los fallos decide si tendrás un sistema autocorrectivo o un monstruo que consume tokens y rompe tablas.

    Los try/catch genéricos son la forma más rápida de cegar a un agente. TypeScript, usado con disciplina, no te da magia: te da garantías. Garantías que convierten excepciones impredecibles en valores tipados que el agente puede razonar, registrar y recuperar.

    Resumen rápido (lectores con prisa)

    Qué: Trata errores como valores con Result<T,E> en lugar de throw.

    Cuándo: Siempre que tu agente llame herramientas, escriba en DB o coordine flujos.

    Por qué importa: Evita reintentos ciegos, reduce tokens gastados y hace al agente reparable.

    Cómo funciona: Devuelve {ok: true|false} con error tipado y usa checks exhaustivos con never para obligar a manejar nuevos casos.

    Por qué los try/catch genéricos matan tus agentes

    Un humano reintenta después de un HTTP 500. Un agente no. Cuando un LLM recibe solo “Error executing tool”, pierde la causa raíz. ¿Duplicado en la DB? ¿Timeout? ¿Bad payload? Sin esa información, el agente hará una de dos cosas útiles para nadie: reintentar la misma acción hasta agotar tu presupuesto o “alucinar” que la acción fue exitosa para seguir el flujo.

    En sistemas agénticos cada fallo es una señal. Ocultarla con un mensaje opaco equivale a apagar los sensores del coche mientras conduces rápido.

    Result<T, E>: convertir errores en datos con contrato

    La respuesta práctica es sencilla: deja de tirar (throw) y empieza a devolver. El patrón Result<T, E> transforma errores en valores discriminados que obligan al consumidor a lidiar con ellos.

    type Result<T, E> =
      | { ok: true; value: T }
      | { ok: false; error: E };

    Ejemplo de herramienta:

    async function createUser(email: string): Promise<Result<User, 'DUPLICATE_EMAIL' | 'DB_TIMEOUT' | 'INVALID_SCHEMA'>> {
      // nunca throw; siempre retorna ok: true | ok: false
    }

    ¿Qué cambia? Ahora el orquestador recibe información accionable. Si ok: false y error === ‘DUPLICATE_EMAIL’, inyectas esa razón en la memoria episódica y el LLM pregunta por otro email en vez de repetir la misma INSERT. Transformas ruido en contexto.

    Documentación útil sobre Result (concepto inspirado en Rust): Documentación útil sobre Result (concepto inspirado en Rust)

    never y exhaustive checks: el compilador como guardarraíl

    Pasa esto en equipos: alguien añade un nuevo error y olvida manejarlo. Resultado: el agente se comporta de forma impredecible en producción. Aquí entra el patrón de comprobación exhaustiva con never.

    Define tus errores como unión discriminada:

    type AgentError =
      | { type: 'DatabaseError'; code: number }
      | { type: 'AuthError'; reason: string }
      | { type: 'ValidationError'; issues: string[] };

    Y formatea para el LLM con un switch que fuerza exhaustividad:

    function formatErrorForLLM(error: AgentError): string {
      switch (error.type) {
        case 'DatabaseError': return `DB failure (${error.code}). No retry.`;
        case 'AuthError': return `Auth failed: ${error.reason}. Re-auth required.`;
        case 'ValidationError': return `Invalid: ${error.issues.join(', ')}. Fix and retry.`;
        default:
          const _exhaustive: never = error;
          return _exhaustive;
      }
    }

    Si alguien añade { type: 'RateLimit' } a AgentError y no actualiza este switch, TypeScript fallará en compilación. Lee sobre exhaustiveness checks: Lee sobre exhaustiveness checks

    Eso no es paranoia: es disciplina. Tu CI/CD no permitirá desplegar un agente que no explica cada fallo.

    Integración práctica con memoria y orquestación

    Errores tipados deben viajar junto con resultados hacia la memoria episódica. Diseño minimalista:

    • La tool retorna Result.
    • El orquestador persiste tanto éxitos como fallos en la memoria episódica (Redis) y semántica (vector DB si aplica).
    • El prompt incluye el fallo estructurado antes de la siguiente llamada al LLM.
    • El LLM decide la acción (retry con modificación, pedir datos al usuario, escalar).

    Además: valida entradas con Zod/JSON Schema antes de llamar a la tool. Un buen schema reduce la superficie de errores y hace que los fallos restantes sean reales y manejables.

    Operacional: telemetría, tests y SLAs

    No sirve con tipos si no lo verificas. Tienes que medir:

    • Retries por tipo de error (P50/P95).
    • Frecuencia de errores no mapeados (build-breakers).
    • Tokens gastados en reintentos.
    • Casos escalados a humano.

    Incluye tests que simulen fallos de DB, timeouts y errores de validación. Tu pipeline debe romper si un nuevo error llega a producción sin un handler en el switch exhaustivo.

    Cierre operativo

    El try/catch genérico es cómodo. También es la razón por la que tu agente se convierte en una caja negra con facturas altas y datos rotos. Convertir errores en valores tipados (Result<T,E>) y forzar comprobaciones exhaustivas con never no es estilo: es seguridad operativa.

    Aplica esto ya, instrumenta telemetría y haz que tu build falle si alguien olvida un caso de error. En el próximo artículo mostraremos cómo serializar esos errores en memoria episódica y usar feedback estructurado para que el agente aprenda a autocorregirse sin intervención humana.

    Dominicode Labs

    Para equipos que diseñan agentes y pipelines de orquestación, es útil contar con recursos y experimentos que muestren patrones de integración entre memoria episódica y errores tipados. Continúa explorando técnicas y prototipos en Dominicode Labs para ver implementaciones prácticas y ejemplos aplicados a agentes y workflows.

    FAQ

    ¿Por qué no debo usar try/catch genéricos en agentes?

    Porque ocultan la causa raíz y priven al agente de información accionable. Un mensaje opaco lleva a reintentos inútiles o a continuar el flujo como si la acción hubiera tenido éxito.

    ¿Qué es Result<T,E> y cómo cambia la arquitectura?

    Es un patrón que devuelve un valor tipado indicando éxito o fallo ({ok: true; value} | {ok: false; error}). Obliga al consumidor a tratar explícitamente los errores y permite que orquestadores y LLMs actúen sobre causas concretas.

    ¿Cómo obliga TypeScript a manejar nuevos errores?

    Mediante comprobaciones exhaustivas usando never en un switch sobre una unión discriminada. Si se añade un nuevo caso y no se maneja, el compilador falla.

    ¿Dónde guardo los errores para que el agente los use?

    Persiste fallos en la memoria episódica (ej. Redis) y en la memoria semántica si aplica (vector DB). El orquestador debe guardar tanto éxitos como fallos para proporcionar contexto al LLM.

    ¿Qué métricas debo instrumentar primero?

    Retries por tipo de error (P50/P95), frecuencia de errores no mapeados, tokens gastados en reintentos y casos escalados a humano.

    ¿Cómo debo testear los manejadores de error?

    Incluye tests que simulen fallos de DB, timeouts y errores de validación; el pipeline debe fallar si un nuevo error llega a producción sin handler.

    ¿Qué herramientas de validación recomiendan antes de llamar a una tool?

    Valida entradas con Zod o JSON Schema para reducir la superficie de errores y asegurar que los fallos restantes sean reales y manejables.

  • Guía para migrar funciones Edge y simplificar autenticación en Supabase

    Guía para migrar funciones Edge y simplificar autenticación en Supabase

    npm install @supabase/server@latest y npx skills add supabase/server: guía práctica para migrar Edge Functions, Hono y agentes IA

    Tiempo estimado de lectura: 4 min

    • Reduce boilerplate de autenticación gracias a un modelo declarativo y SupabaseContext por petición.
    • Automatiza migraciones con agentes usando npx skills add supabase/server para dar contexto y patrones a agentes de código.
    • Flujo incremental y seguro: withSupabase para la mayoría de endpoints; primitives o createSupabaseContext para casos complejos.
    • Soporta rotación de claves y despliegues controlados con variables plurales y canary deploys.

    Introducción

    npm install @supabase/server@latest y npx skills add supabase/server son las dos acciones que debes ejecutar si quieres adoptar el nuevo flujo de trabajo de Supabase: un paquete que elimina el boilerplate de autenticación y un “skill” que da contexto a agentes de código. En las primeras líneas: estos comandos son el punto de partida para migrar funciones Edge, automatizar refactors con agentes y levantar APIs Hono seguras en minutos.

    Resumen rápido (lectores con prisa)

    Instala @supabase/server para obtener contexto de autenticación y clientes por petición. Añade el skill supabase/server para que agentes de código puedan identificar y actualizar inicializaciones antiguas. Usa withSupabase para la mayoría de endpoints; recurre a primitives o createSupabaseContext para casos compuestos.

    npm install @supabase/server@latest — qué instala y qué te da

    Instalar @supabase/server provoca algo más que añadir una dependencia: introduce un modelo declarativo para control de acceso y un SupabaseContext listo para usar. Tras la instalación obtienes primitives y wrappers que:

    • Verifican JWT asimétricos sin jose/JWKS manual.
    • Inicializan dos clientes por petición: ctx.supabase (usuario, respeta RLS) y ctx.supabaseAdmin (service role).
    • Inyectan userClaims, jwtClaims y authMode en el contexto.
    • Ofrecen withSupabase (wrapper), createSupabaseContext (imperativo) y primitives en @supabase/server/core.

    Documentación oficial: Documentación oficial y repo: Repositorio en GitHub

    npx skills add supabase/server — por qué lo necesitas si usas agentes

    npx skills add supabase/server alimenta a herramientas como Claude Code, Codex o Cursor con la superficie de la API, patrones de adaptadores y rutas de migración. Resultado práctico: un agente puede escanear tu repo, identificar inicializaciones antiguas, reemplazarlas por withSupabase y migrar claves a las nuevas variables sin equivocarse.

    Prompts útiles (ejemplos que puedes dar al agente):

    • “Analyze all Edge Functions and plan a full migration to use the new API keys with @supabase/server”
    • “Scaffold a Hono REST API with CRUD for todos using per-route auth”
    • “Create an Edge Function that accepts user or secret auth, reads profile with RLS and writes audit logs with admin client”

    Plan de migración: pasos prácticos y ordenados

    1. Auditoría rápida

    Busca patrones repetidos (creación de clientes, verificación JWT, _shared/*.ts).

    2. Añade la dependencia e instala el skill

    Ejecuta los comandos:

    npm install @supabase/server@latest
    npx skills add supabase/server

    3. Sustitución incremental

    • Reemplaza inicializaciones manuales por withSupabase({ auth }) en funciones individuales.
    • Para funciones multifunción, usa createSupabaseContext o primitives (verifyAuth, createContextClient).

    4. Variables de entorno

    Cambia a formas plurales si es necesario: SUPABASE_PUBLISHABLE_KEYS y SUPABASE_SECRET_KEYS (soporta rotación). Valida inyección en plataformas (Supabase CLI, Vercel, Cloudflare).

    5. Test y rollout

    • Tests unitarios sobre handlers con contexto mockeado.
    • Canary deploy para funciones críticas.

    6. Limpieza

    • Elimina utilidades compartidas de verificación JWT (ya no necesarias).
    • Actualiza docs internas y runbooks.

    Ejemplo rápido: Hono + withSupabase (CRUD /todos)

    El adaptador Hono inyecta el contexto en c.var.supabaseContext:

    import { withSupabase } from '@supabase/server/adapters/hono'
    import { Hono } from 'hono'
    
    const app = new Hono()
    
    app.get('/todos', withSupabase({ auth: 'user' }), async (c) => {
      const { supabase } = c.var.supabaseContext
      const { data } = await supabase.from('todos').select()
      return c.json(data)
    })
    
    export default { fetch: app.fetch }

    Per-route auth es explícito y visible en la firma: mantenimiento y auditoría mucho más sencillos.

    Edge Function protegida con operaciones admin (patrón recomendado)

    Cuando necesitas dual-mode auth (usuario o secret) y escribir logs de auditoría:

    • Declara auth: ['user','secret'].
    • Usa ctx.supabase para lecturas que respetan RLS.
    • Usa ctx.supabaseAdmin para escribir auditoría o tareas privilegiadas.

    Si necesitas control imperativo sobre errores, usa createSupabaseContext:

    import { createSupabaseContext } from 'npm:@supabase/server'
    
    const { data: ctx, error } = await createSupabaseContext(req, { auth: ['user','secret'] })
    if (error) return Response.json({ error: error.message }, { status: error.status })

    Recomendaciones prácticas y criterios técnicos

    • Prioriza withSupabase para la mayoría de endpoints: claridad y seguridad por defecto.
    • Usa primitives solo cuando debas combinar múltiples auth en una función o manipular headers de forma estricta.
    • Aprovecha npx skills para automatizar auditoría y migración; reduce errores humanos en refactors masivos.
    • Mantén tests que mockeen SupabaseContext para evitar dependencia de la red en unit tests.
    • Revisa el repo y docs oficiales para edge-cases y actualizaciones: Repositorio en GitHub y Documentación oficial

    Conclusión

    Instalar @supabase/server y añadir el skill cambia la ergonomía del backend: elimina la repetición, reduce superficie de ataque y hace tus funciones Edge predecibles para humanos y agentes por igual. Empieza migrando funciones críticas con canary deploys, automatiza el resto con el skill y conserva primitives para los casos realmente especiales. El resultado: menos fontanería, más foco en la lógica que aporta valor.

    Mención: Dominicode Labs

    Si estás planificando automatizaciones o migraciones con agentes, puede resultar útil ver recursos y experimentos aplicados a workflows y agentes. Más información y proyectos relacionados en Dominicode Labs.

    FAQ

    Respuesta: Instalar @supabase/server introduce un modelo declarativo de control de acceso y un SupabaseContext por petición, con clientes ctx.supabase y ctx.supabaseAdmin, verificación de JWT asimétrica y utilidades como withSupabase y createSupabaseContext.

    Respuesta: npx skills add supabase/server aporta la superficie de la API y patrones a agentes de código, permitiendo que escaneen repos, identifiquen inicializaciones antiguas y automaticen refactors de forma segura.

    Respuesta: Cambia a variables plurales como SUPABASE_PUBLISHABLE_KEYS y SUPABASE_SECRET_KEYS para soportar rotación. Valida la inyección en plataformas como Supabase CLI, Vercel o Cloudflare antes del despliegue.

    Respuesta: Usa withSupabase por defecto para claridad y seguridad. Emplea createSupabaseContext o primitives cuando necesites combinar múltiples modos de auth en una sola función o manipular headers de forma estricta.

    Respuesta: Escribe tests unitarios que mockeen el SupabaseContext para evitar llamadas de red. Realiza canary deploys para funciones críticas antes del rollout completo.

    Respuesta: Sí: una vez migradas las funciones a @supabase/server, las utilidades compartidas de verificación JWT que replican lógica ya gestionada por el paquete dejan de ser necesarias y pueden eliminarse tras validar el comportamiento.

  • Comparativa técnica de Agentic Harness: Claude Code, Cursor y más

    Comparativa técnica de Agentic Harness: Claude Code, Cursor y más

    Agentic Harness comparado — Claude Code vs Cursor vs Codex CLI vs Aider vs Cline

    Tiempo estimado de lectura: 6 min

    • Un agentic harness convierte un LLM en un actor sobre tu repo: necesita contexto eficiente, aplicación segura de cambios y bucles de verificación.
    • Elige la herramienta según dominio: Cursor para UI y revisión visual, Aider para refactors y auditabilidad, Claude Code para pipelines, Cline para acceso a infra, Codex/Copilot CLI para utilidades tácticas.
    • Prioriza: context slicing (RAG/AST), rollback y trazabilidad, integración CI/CD, permisos/extensibilidad y observabilidad.
    • Gobernanza: define qué puede hacer el agente sin revisión, qué debe proponer como PR y cómo auditar acciones.

    El desarrollo asistido por IA dejó de ser un experimento cuando los equipos empezaron a pedir algo concreto: no sólo sugerencias, sino ejecución fiable. Aquí tienes un análisis técnico y accionable de Agentic Harness comparado — Claude Code vs Cursor vs Codex CLI vs Aider vs Cline, pensado para Tech Leads y equipos reales que deben decidir estrategia, integraciones y límites de autonomía.

    Resumen rápido (lectores con prisa)

    Un agentic harness es la capa que permite a un LLM operar sobre un repositorio con seguridad y trazabilidad.

    Úsalo cuando necesites ejecutar cambios repetibles, verificables y revertibles — no sólo sugerencias.

    Elige según dominio: UI (Cursor), refactor/legacy (Aider), pipelines/infra (Claude Code), acceso a infra interna (Cline).

    Prioriza RAG/AST para contexto, commits/diffs para trazabilidad y bucles de tests para verificación.

    Agentic Harness comparado — por qué importa y qué debes exigirle

    Un agentic harness no es un plugin bonito: es la capa que convierte un LLM en un actor capaz de operar sobre tu repo. A nivel técnico debe resolver tres problemas simultáneos:

    • Resolución de contexto: indexación del repo + selección de snippets relevantes (RAG, AST-aware slicing).
    • Aplicación segura de cambios: diffs atómicos, commits, PRs y rollback.
    • Bucle de verificación: pruebas, linters y reintentos automáticos leyendo stderr/exit codes.

    Si la herramienta que evalúas no cubre esas tres piezas de forma explícita, la estás usando como un asistente, no como un agente.

    Resumen rápido de cada harness

    Cursor — editor visual AI-first

    Cursor es un fork de VS Code que trae IA integrada a la experiencia del editor. Su valor es UX: Composer permite editar múltiples archivos en contexto y previsualizar diffs antes de aplicar. Técnica clave: contexto calculado desde archivos abiertos y navegación del cursor, útil para producción de features frontend donde la verificación visual es crítica. URL: Cursor

    Cuándo elegirlo: equipos Full Stack que quieren control visual y revisión humana inmediata. Fricción: migración de editor.

    Claude Code — CLI para razonamiento extendido

    Claude Code (Anthropic) es un CLI pensado para ejecución en terminal. Diseñado para Claude 3.7 con extended thinking, ejecuta bucles autónomos: corre tests, inspecciona logs y corrige iterativamente. Técnica clave: integración terminal-native y capacidad de manejar workflows en CI/CD. URL: Claude Code docs

    Cuándo elegirlo: backend, infra y pipelines automatizados donde no necesitas UI pero sí razonamiento arquitectónico.

    Aider — control Git como seguridad

    Aider es Open Source y opera en CLI con filosofía “Git-first”: cada cambio satisfactorio produce un commit automático. Técnica clave: mapeo del repo vía AST para minimizar el contexto enviado al modelo y trazabilidad total mediante commits. URL: Aider

    Cuándo elegirlo: repos grandes, legacy codebases y equipos que exigen revertibilidad y auditoría precisa.

    Cline — extensión VS Code con MCP

    Cline implementa MCP (Model Context Protocol) y permite que el agente consulte servicios externos (DBs, docs internas) antes de escribir código. Técnica clave: permisos explícitos por acción y extensibilidad mediante MCP. URL: Cline

    Cuándo elegirlo: organizaciones con infra y APIs internas que quieren que el agente actúe con contexto real y seguro.

    Codex CLI / Copilot CLI — utilidades tácticas

    Herramientas como Codex CLI o Copilot CLI están enfocadas en traducir NL a comandos de terminal. Útiles para scripting y tareas puntuales, no para refactorizaciones autónomas: carecen del bucle iterativo sobre el repo. Recurso: Codex (OpenAI)

    Cuándo elegirlo: tareas de DevOps ad-hoc, scripting, comandos complejos — no para “delega la refactorización”.

    Criterios técnicos para elegir

    1. Context slicing: ¿la herramienta usa RAG o análisis AST para minimizar tokens? Si no, pagarás tokens y recibirás ruido.
    2. Rollback y trazabilidad: commits automáticos + mensajes generados por IA (Aider) vs diffs aprobados por UI (Cursor). Decide si prefieres control humano o commits automáticos.
    3. Integración CI/CD: ¿el harness puede operar en pipelines sin UI y corregir builds? Claude Code brilla aquí.
    4. Extensibilidad y permisos: MCP (Cline) permite consultas reales a infra interna; obligatorio si necesitas que el agente lea DBs o docs privadas.
    5. Observabilidad y métricas: tokens, fallos de parseo, reintentos y coste por sesión. Sin métricas no puedes gobernar autonomía.

    Ejemplos prácticos

    • Refactorización de API en un monorepo grande: usa Aider por AST-mapping + commits automáticos. Revertir es simple y el contexto es eficiente.
    • Corregir fallo en CI que rompe build: lanza Claude Code en la pipeline; ejecutará tests, leerá logs y propondrá patches iterativos.
    • Añadir componente UI y actualizar rutas: Cursor acelera al mostrar previews y permitir aceptar diffs por pantalla.
    • Integración con servicio interno (consulta de esquema DB antes de generar ORM): Cline + MCP para consultas reales antes de generar código.

    Recomendación práctica para equipos

    No hay una sola herramienta “mejor”. La arquitectura razonable es híbrida:

    • Cursor para trabajo de producto diario y revisión rápida.
    • Aider para refactors críticos y control de cambios.
    • Claude Code en pipelines automatizados y tareas de infra.
    • Cline cuando necesites que el agente hable con infra interna.
    • Codex/Copilot CLI para utilidades puntuales de scripting.

    Antes de adoptar, define: qué puede hacer el agente sin revisión humana, qué debe proponer como PR, y cómo auditarás cada acción (logs, commits, approvals). Sin estas reglas, la herramienta genera ruido o riesgos.

    Recursos y lecturas

    Si vas a integrar agentes en producción, no lo hagas por moda. Prepara contexto (CLAUDE.md / AGENTS.md / memory files), define límites y selecciona el harness según el dominio: UI, infra, refactor o integración con sistemas internos. Así, la IA deja de ser un “showroom” y pasa a ser una herramienta medible y auditable.

    Como continuación lógica para equipos que diseñan flujos de agentes y gobernanza técnica, consulta los experimentos y recursos de Dominicode Labs. Allí encontrarás guías prácticas para implementar context slicing, auditoría de commits y métricas de observabilidad en flujos con agentes.

    FAQ

    ¿Qué es exactamente un agentic harness?

    Es la capa que permite a un modelo de lenguaje operar sobre un repositorio con procesos definidos: resolución de contexto, aplicación segura de cambios y bucle de verificación mediante tests/linters.

    ¿Cuándo debo usar Aider en lugar de Cursor?

    Usa Aider para refactors en repos grandes o legacy donde necesitas commits automáticos y trazabilidad. Usa Cursor cuando la experiencia visual y la revisión humana inmediata son prioritarias (UI, previews, aceptación de diffs).

    ¿Claude Code reemplaza un CI tradicional?

    No necesariamente. Claude Code facilita la automatización y el razonamiento en pipelines (ejecutar tests, leer logs, proponer parches), pero suele integrarse con CI/CD existente como una herramienta para corregir y iterar en builds.

    ¿Qué es MCP y por qué importa con Cline?

    MCP es el Model Context Protocol: permite que el agente consulte servicios externos (DBs, docs internas) antes de escribir código. Es crítico si el agente necesita contexto real y permisos explícitos para interactuar con infra interna.

    ¿Puedo usar Codex/Copilot CLI para refactorizaciones?

    No son la mejor opción para refactorizaciones autónomas. Están pensados para traducir lenguaje natural a comandos de terminal y scripting; carecen del bucle iterativo y la gestión de diffs sobre el repo que requieren refactors complejos.

    ¿Cómo audito las acciones de un agente?

    Define trazabilidad mediante commits/diffs, logs de sesión, métricas de tokens y reintentos. Decide qué acciones requieren aprobación humana vs commit automático y conserva archivos de contexto (CLAUDE.md / AGENTS.md / memory files) para replicabilidad.

  • Cómo utilizar OpenSpec para gestionar especificaciones en Brownfield

    Cómo utilizar OpenSpec para gestionar especificaciones en Brownfield

    ¿Es OpenSpec la herramienta para las specs en Brownfield?

    Tiempo estimado de lectura: Calculando con ~220 palabras por minuto.

    Tiempo estimado de lectura: 3 min

    • OpenSpec acelera la obtención de una spec base desde comportamiento observable.
    • Su valor real aparece al combinar generación automática con revisión humana y guardrails en CI/CD.
    • No es una solución mágica: puede cristalizar deuda si se usa sin enriquecimiento semántico.
    • Proceso recomendado: discovery → human-in-the-loop → guardrails → evolución controlada.

    Introducción

    ¿Es OpenSpec la herramienta para las specs en Brownfield? Sí —pero no como solución mágica. OpenSpec (entendido como el ecosistema de herramientas que generan y mantienen OpenAPI/AsyncAPI automáticamente) es el punto de partida más práctico para recuperar contratos en sistemas heredados. Su valor real aparece cuando lo combinas con juicio humano, revisión semántica y guardrails en CI/CD.

    Resumen rápido (lectores con prisa)

    OpenSpec: conjunto de herramientas que generan especificaciones (OpenAPI/AsyncAPI) automáticamente desde tráfico o análisis estático. Útil para Brownfield cuando se usa como extractor inicial, no como fuente final sin revisión. Importante integrarlo con revisión humana y validaciones en pipelines.

    ¿Es OpenSpec la herramienta para las specs en Brownfield? — contexto y por qué importa

    Problema en Brownfield

    En Brownfield tienes código en producción, dependencias cruzadas y documentación que normalmente no refleja la realidad. El problema no es generar YAML: es detener el sangrado de cambios no esperados en producción. Aquí OpenSpec aporta dos cosas fundamentales:

    Qué aporta OpenSpec

    • Rapidez para obtener una línea base estructural a partir del comportamiento real del sistema.
    • Mecanismos para convertir una spec en infraestructura (drift detection, validación en pipelines).

    Herramientas de referencia: Optic, Akita, Specmatic. Para extracción desde código: Springdoc, tsoa. Consulta la especificación OpenAPI.

    Qué puede y qué no puede hacer OpenSpec en un Brownfield

    Lo que sí hace bien

    • Extrae la estructura observable de endpoints, métodos y esquemas de payloads.
    • Produce specs rápidamente desde tráfico en staging o desde análisis estático.
    • Habilita detección de deriva en CI: bloquea merges que cambian respuestas esperadas.

    Lo que no hace

    • No captura semántica de negocio: no sabe que status: 2 significa “Cuenta suspendida”.
    • No documenta edge cases que no aparecieron en el tráfico observado.
    • No corrige malos diseños: puede cristalizar inconsistencias si aceptas la spec sin filtrar.

    Si tratas la generación automática como la verdad absoluta, produces un contrato falso-seguro. Si la usas como un extractor inicial, reduces semanas de trabajo manual a horas.

    Estrategia práctica para implantar OpenSpec en Brownfield

    Implementarlo sin generar más deuda exige disciplina. Siguientes pasos probados en equipos técnicos:

    1. Generación de baseline (Discovery)

    • Captura tráfico en staging o usa análisis estático según el stack.
    • Herramientas: Optic para captura/visualización, Akita para inferencia basada en tráfico, Springdoc/tsoa para extracción desde código.
    • Objetivo: obtener un OpenAPI.yaml que represente el comportamiento observado, no la versión final.

    2. Enriquecimiento semántico (Human-in-the-loop)

    • Asigna a domain owners para revisar y documentar campos críticos, códigos de estado y reglas de negocio.
    • Corrige nombres ambiguos y elimina endpoints internos expuestos por accidente.
    • Añade ejemplos y descripciones para cada campo sensible.

    3. Control automático (Guardrails)

    • Integra la spec en CI: Specmatic u Optic pueden ejecutar contract tests o comparar contratos en PR.
    • Fallo en la spec = bloqueo del merge hasta revisión explícita.
    • Mantén logs de cambios automáticos y un proceso claro para aprobar modificaciones del contrato.

    4. Evolución controlada

    • No distribuyas la spec al consumidor externo hasta que se haya ratificado por el equipo.
    • Versiona la spec y comunica breaking changes con políticas (semver, fechas, deprecations).

    Ejemplo real y conciso

    Situación: monolito en Node que sirve APIs REST sin spec.

    • Paso 1: Instrumenta un proxy de captura en staging con Optic. Ejecuta suites de integración para generar tráfico representativo.
    • Paso 2: Optic genera un OpenAPI básico. Equipo revisa y detecta 3 endpoints con campos inconsistentes.
    • Paso 3: Ajustes manuales, se añaden descripciones de status y se documentan errores 422 y 503 que no aparecieron en tráfico.
    • Paso 4: Integra Specmatic en CI para validar que cambios en PR no alteren respuestas esperadas sin aprobación.

    Resultado: en semanas tienes una spec utilizable y protección automática contra cambios no controlados.

    Riesgos y mitigaciones operativas

    • Riesgo: cristalizar deuda técnica. Mitigación: obligar enriquecimiento semántico antes de promover spec a “source of truth”.
    • Riesgo: cobertura incompleta por tráfico insuficiente. Mitigación: complementar capture con tests orientados a edge cases y análisis estático.
    • Riesgo: falsa confianza en herramientas. Mitigación: auditorías periódicas de la spec por arquitectos y product owners.

    Conclusión — criterio técnico

    OpenSpec es la herramienta indicada para arrancar specs en Brownfield. No reemplaza la discusión humana sobre contratos ni el trabajo de diseño del dominio. Su fuerza está en reducir trabajo mecánico y convertir documentación en infraestructura verificable. Si tu equipo integra generación automática con revisión semántica y guardrails en CI, OpenSpec deja de ser una “herramienta” y pasa a ser una palanca que reduce riesgo y acelera refactors con seguridad.

    Para equipos que trabajan con automatización de workflows, captura de tráfico e integración CI, puede interesar explorar más recursos y experimentos en Dominicode Labs. Es una referencia complementaria para prototipos y pruebas de integración de herramientas OpenSpec en pipelines.

    FAQ

  • Implementación efectiva de Angular Aria para accesibilidad en UI

    Implementación efectiva de Angular Aria para accesibilidad en UI

    Angular Aria — nueva librería de accesibilidad

    Tiempo estimado de lectura: 4 min

    • Ideas clave:
    • Angular Aria ofrece primitivas “headless” que implementan patrones APG para teclado, foco y lectores de pantalla.
    • Diferencia con Material y CDK: Material provee UI completa, CDK utilidades low‑level, Aria patrones sin estilo.
    • Beneficios: reduce deuda técnica, mejora consistencia y facilita cumplimiento de auditorías WCAG.
    • Riesgos: API inicial puede cambiar; requiere disciplina de integración con el Design System.

    Introducción

    Angular Aria — nueva librería de accesibilidad llega para resolver lo que suele hacerse mal una y otra vez: la lógica de interacción accesible. En las primeras líneas: no es un tema de añadir atributos; es una capa de comportamiento (gestión de foco, navegación por teclado, anuncios a lectores de pantalla) que ahora Angular ofrece como primitivas headless, complementando Angular Material y el CDK.

    Resumen rápido (lectores con prisa)

    Qué es: Colección de patrones UI headless que implementan prácticas APG para accesibilidad.

    Cuándo usarlo: Cuando necesitas control visual propio y comportamiento accesible consistente.

    Por qué importa: Reduce errores de interacción al estandarizar foco, teclado y anuncios a lectores de pantalla.

    Cómo encaja: Primitivas headless que exponen estado y handlers; tú aplicas estilos desde tu Design System.

    Qué es Angular Aria — nueva librería de accesibilidad y por qué importa

    Angular Aria es una colección de patrones de UI “headless” diseñada para implementar las prácticas recomendadas de WAI-ARIA (APG) sin imponer estilos. La idea es separar semántica y comportamiento de la capa visual: tú pones los estilos, Angular Aria se encarga de que el componente responda correctamente a teclado, foco y tecnologías asistivas.

    Documentación relevante:

    ¿Por qué importa? Porque los errores de accesibilidad no son solo reputacionales ni legales: son errores de interacción. Un Combobox mal implementado deja fuera a usuarios con teclado o lectores de pantalla. La complejidad real no está en el atributo aria-label; está en coordinar foco, roles, aria-live, y atajos de teclado en todas las plataformas.

    Diferencias claras: Angular Material vs CDK vs Angular Aria

    Angular Material

    Componentes completos con estilo y accesibilidad integrada. Ideal si aceptas Material Design y quieres velocidad.

    Docs: Docs

    Angular CDK

    Utilidades de bajo nivel (Overlays, FocusMonitor, LiveAnnouncer). Es la caja de herramientas para construir componentes.

    CDK a11y: CDK a11y

    Angular Aria

    Patrones de componentes sin estilo (Accordion, Dialog, Combobox, Menu, etc.) con semántica ARIA y gestión de interacción resuelta. Tú aplicas CSS.

    Piensa en Aria como la “implementación canónica” de las APG para Angular: reduce la deuda técnica y la variabilidad entre implementaciones de distintos equipos.

    Ejemplo conceptual (cómo encaja en un Design System)

    No entraré a nombrar APIs finales —las convenciones pueden evolucionar—, pero un flujo habitual sería:

    1. Importas la primitiva headless (p. ej. DialogBehavior).
    2. Montas el markup semántico y enlazas directivas/servicios que exponen estado y handlers.
    3. Aplicas estilos desde tu sistema (Tailwind, Sass, CSS Modules).

    Pseudocódigo conceptual:

    <app-dialog *ariaDialog>
      <div ariaDialogTrigger>Abrir diálogo</div>
      <div ariaDialogContent>
        <!-- foco gestionado, escape cierra, roles y aria-hidden se aplican automáticamente -->
      </div>
    </app-dialog>

    Resultado: el comportamiento accesible ya está cubierto; el equipo sólo diseña la apariencia.

    Impacto en equipos y auditorías de accesibilidad

    • Time to Market: menor, porque no rehaces la lógica de interacción en cada componente.
    • Consistencia: menos variaciones entre módulos y menos fallos en auditorías WCAG 2.1 AA.
    • Mantenibilidad: actualizaciones de patrones centralizadas en la librería oficial reducen riesgo técnico.

    Si tu organización debe pasar auditorías (WCAG, EN 301 549), Angular Aria reduce la superficie de riesgo técnico al ofrecer implementaciones alineadas con APG.

    Riesgos, limitaciones y puntos de decisión

    • Estabilidad de API: siendo lanzamiento reciente, algunas APIs pueden cambiar. Revisa changelogs antes de adopciones masivas.
    • Superposición con CDK a11y: es probable que parte del CDK siga existiendo como utilidades de bajo nivel; Aria levantará patrones completos.
    • Integración visual: necesitas disciplina en el Design System para unir las primitivas headless con tokens y utilidades de estilos.

    Criterio técnico para la adopción (resumen accionable)

    Adopta Angular Aria si:

    • Estás construyendo un Design System white‑label o con identidad visual propia.
    • Tu equipo usa CSS utilitario (Tailwind) o quiere control total sobre la apariencia.
    • Tienes requisitos normativos o usuarios con necesidades de accesibilidad.

    No es prioritaria si:

    • Estás plenamente integrado con Angular Material y aceptas su estética.
    • Tu proyecto es un prototipo o MVP donde la prioridad es velocidad visual sin personalización.

    Checklist de integración mínima:

    • Añade pruebas de accesibilidad automatizadas (axe, Pa11y) en CI.
    • Mantén lockfiles y revisa cambios en dependencias a nivel de PR.
    • Planifica migración por componentes: empezar por Dialogs/Comboboxes reduce riesgo.

    Conclusión

    Angular Aria no es “otro paquete” más; es la pieza que permite a Angular competir en el terreno del Headless UI con garantías de accesibilidad. Para equipos que construyen componentes a medida, representa una inversión de tiempo recuperable en forma de consistencia, cumplimiento y reducción de deuda técnica. Implementa pruebas y políticas de adopción por fases, y usa Aria para que la accesibilidad deje de ser un añadido y pase a ser la base del comportamiento de tus interfaces.

    FAQ

    ¿Qué es Angular Aria?

    Una colección de patrones UI headless para implementar prácticas WAI-ARIA (APG) en Angular, separando comportamiento accesible de la capa visual.

    ¿En qué se diferencia de Angular Material?

    Material ofrece componentes completos con estilo; Angular Aria ofrece patrones sin estilo que gestionan interacción y semántica accesible.

    ¿Tengo que dejar de usar CDK a11y?

    No necesariamente. CDK seguirá siendo útil como utilidades de bajo nivel; Angular Aria ofrece patrones completos construidos sobre prácticas APG.

    ¿Qué beneficios trae para auditorías WCAG?

    Reduce la superficie de riesgo técnico al proporcionar implementaciones alineadas con APG, lo que ayuda a pasar auditorías WCAG 2.1 AA y otras normativas.

    ¿Cuáles son los riesgos al adoptar Angular Aria ahora?

    La API puede cambiar en etapas tempranas; es recomendable revisar changelogs y planificar migraciones por componentes para mitigar riesgo.

    ¿Dónde puedo leer las prácticas y ejemplos relacionados?

    Revisa la WAI-ARIA Authoring Practices Guide y la documentación oficial de Angular. También hay ejemplos en React Aria y Radix UI.