Category: Blog

Your blog category

  • Implementando Plum para Gobernanza de Decisiones en Código

    Implementando Plum para Gobernanza de Decisiones en Código

    ¿Y si te dijera que tu “spec” es una tarjeta de bienvenida para el caos si no la conviertes en evidencia viva?

    Tiempo estimado de lectura: 6 min

    • Plum convierte decisiones de diseño y agentes en evidencia rastreable ligada a commits.
    • Fallar commits a propósito es el checkpoint que fuerza la aprobación humana y evita decisiones no registradas.
    • El flujo incluye init, extracción de decisiones, bloqueo de commits si hay decisiones pendientes y sincronización spec↔tests↔código.
    • Limitaciones reales: Pytest-only ahora, backfill difícil, deduping fuzzy y riesgo de ruido de interrupción.

    Introducción

    Poca gente habla claro de esto: cuando un Product Manager cambia una regla, la pregunta real no es “¿habrá que tocar el código?” sino “¿cómo sabré mañana quién decidió qué, por qué y con qué pruebas?”. Spoiler: la mayoría no lo sabe. Y con agentes de IA metidos en la cocina, ese “no saber” se vuelve que arda todo en silencio.

    Esto no es teoría bonita. Es práctica sucia. Y la herramienta que te salva la vida se llama Plum. Sí, Plum. La plomada. La que te dice si lo que has levantado está vertical o te lo estás inventando sobre la marcha.

    Resumen rápido (lectores con prisa)

    Qué es: Plum es un guardián operativo que convierte decisiones (humanas o de LLM) en artefactos rastreables ligados a commits.

    Cuándo usarlo: Cuando usas agentes o LLMs para tomar decisiones que afectan código, specs o tests.

    Por qué importa: Evita que las decisiones queden atrapadas en chats y que el repositorio pierda la memoria de intención.

    Cómo funciona (resumen): Hooks de Git + extracción de traces + bloqueo de commits hasta aprobación + sincronización spec↔tests↔código.

    Por qué hay que preocuparse ahora

    – Porque los LLMs generan código a ritmo industrial.

    – Porque cambios urgentes o hotfixes se meten directo al trunk.

    – Porque las decisiones que importan quedan atrapadas en chats —los famosos traces— y se evaporan al cerrar la sesión.

    – Porque las especificaciones se quedan en Markdown como si fueran altares estáticos, sin reflejar lo que el código realmente hace.

    La consecuencia: código que pasa tests pero no cumple intención. Tests que validan outputs, no contratos. Specs que no son contrato sino historia. Y equipos que no pueden responder cuando algo explota en producción.

    Cómo funciona Plum —sin poesía— pero con sentido

    1) plum init

    – Crea .plum y .plumignore.

    – Te pide dónde están tus specs (Markdown) y tus tests (por ahora Pytest).

    – Añade hooks a Git: el commit se convierte en punto de control, no en trámite.

    2) Haces código con un agente

    – El agente toma decisiones en el chat. Tú las apruebas o las ajustas.

    – Al intentar git commit, Plum hace su trabajo: compara diffs desde el último commit y escanea los traces del agente.

    3) Plum extrae decisiones

    – Deduplica (sí, imperfecto; más abajo explico por qué).

    – Te presenta: “estas son las decisiones que tomaste desde el último commit. ¿Las apruebas?”.

    – Si hay decisiones pendientes, el commit falla. Sí, falla a propósito. Tú apruebas o corriges.

    4) Aprobadas → actualizaciones y registro

    – Aprobadas => Plum actualiza la spec (Markdown) y genera un registro .jsonl con la decisión, la autoría (humano o LLM), rama, timestamps y vínculo al diff.

    5) Ejecutas plum sync

    – Plum te muestra las brechas entre spec, tests y código: requisitos sin tests, tests sin caso claro, etc.

    Por qué no puede ser “una skill” del agente

    Porque una skill es una sugerencia dentro del agente. Y las sugerencias se ignoran cuando hay prisa. Si quieres gobernanza necesitas un checkpoint externo e innegociable. Si el commit no falla, la herramienta es una opción más que nadie usa. Plum falla commits a propósito para forzar el acto reflexivo: “aprobación humana o nada”.

    La plomada no pinta paredes. Te evita derrumbes.

    Qué hay dentro del archivo JSONL y por qué importa

    El .jsonl no es un “log más”. Es un registro de intención con metadatos para auditoría.

    Ejemplo de entrada:

    – question: “¿Batchear updates de spec o aplicar por decisión?”

    – decision: “Batch spec updates across all decisions”

    – approved_by: user@example.com

    – proposed_by: LLM (o human)

    – branch: feature/x

    – diff_link: git://…

    – timestamps: created, approved, synced

    Ese registro responde a: quién decidió, qué decidió, por qué y cuándo. Lo que todo equipo serio debería exigir.

    Limitaciones reales (no las bonitas)

    • Pytest-only por ahora. Si usas otro runner, el análisis de cobertura falla. Esto es temporal, pero real.
    • Backfill: Plum funciona mejor si la spec va adelante del código. Analizar un monolito legacy y generar spec desde cero es una tarea distinta.
    • Decision deduping es fuzzy. Identificar “la misma decisión” entre conversaciones humanas y LLMs no es trivial. Depende del repo, del dominio y de tu tolerancia.
    • Ruido de interrupción. Si generas cinco decisiones por un hotfix, te puede cortar el flow. Por eso Plum necesita umbrales de interrupción configurables.
    • Rollbacks automáticos: si rechazas una decisión en la CLI, que se revierta el cambio en el código todavía requiere flujo claro entre agente y control de versiones. No siempre está resuelto. Lo ideal: rechazo en el CLI que abre un “rework” en el agente con rollback automático; hoy es work-in-progress.

    Diseño de umbrales —el arte de no volver loco al dev

    Velocidad es vida. Interrupciones matan. Así que Plum permite (y debe permitir) configurar tolerancias:

    • Modo “dangerously approve all” para prototipos.
    • Modo “auditable strict” para banking, salud, compliance.
    • Filtros por carpeta o tipo de archivo (ej.: cambios en README no generan decisiones).
    • Severidad: solo interrumpir cuando la decisión sea contradictoria con reglas previas o afecte invariantes del sistema.
    • Timebox: decisiones ligeras se acumulan y se presentan en lote, las críticas se presentan inmediatamente.

    Esto es clave: la herramienta debe ser lo suficientemente simple para que cada dev la mantenga en su cabeza. Si no, la ignorarán.

    DSPy y la búsqueda del determinismo

    No me gustan las soluciones que dependen sólo de LLMs para validar la validez de una regla. Cuando puedes usar código —tests, parsers, análisis sintáctico— úsalo. Donde no puedas, estructura las llamadas a LLMs. DSPy ayuda: define inputs/outputs tipados para las llamadas a modelos, reduce alucinaciones y permite testear las respuestas.

    Ejemplo práctico:

    • Deducción de decisión = tarea rápida → GPT-OSS (rápido).
    • Parse semántico de spec = tarea precisa → modelo con DSPy que devuelva JSON estricto.
    • Cuando falla la determinación, vuelve al humano.

    Por qué esto cambia la revisión de código

    Hoy revisas sintaxis y estilo. Mañana, sin estas herramientas, revisarás humo. Con Plum revisas intención. Ves “por qué existe esta función” y no sólo “si el PR es legible”. Es code review con memoria. Y esa memoria evita que los agentes te reproduzcan antiguas prohibiciones por olvido de contexto.

    Checklist mínimo para empezar (15 minutos)

    1. Pip install plum-dev
    2. plumb init (apunta al folder de specs y a tu carpeta de tests)
    3. Añade .plumignore para evitar ruido (README, docs, etc.)
    4. Ajusta umbrales: prototipo vs production.
    5. Corre un hotfix con agente y haz commit — observa el commit-fail, aprueba decisiones.
    6. Ejecuta plum sync y revisa cobertura spec↔tests↔código.
    7. Guarda el .jsonl en la rama y pásalo por review.

    Casos de uso concretos

    • Startups: modo “dangerously approve” para protos, switch a strict cuando tienes usuarios reales.
    • Fintech / Salud: strict desde el primer día, cada micro-decision auditada.
    • Open Source: Plum ayuda a traducir PRs dispersos en decisiones rastreables y aprobadas.

    Metáfora breve

    Tu repo es un edificio. Los agentes son una cuadrilla hiperactiva que puede añadir habitaciones a velocidad absurda. La spec es el plano. Si no actualizas planos y firmas cambios, un día entras y la escalera está en el baño. Plum es la plomada: no te dice cómo pintar, te dice si la pared está derecha.

    La urgencia práctica

    Si ya usas agentes y no capturas decisiones, estás construyendo un legado que nadie asumirá. La deuda técnica no es solo trabajo: es riesgo legal, fiscal y reputacional. La gobernanza no es un lujo, es supervivencia.

    ¿Quieres empezar ahora?

    Pruébalo: pip install plum-dev y corre plum init en una rama de feature.

    Si quieres que te lo haga más fácil, te doy 3 cosas ahora mismo:

    • Un template de .jsonl para registrar decisiones.
    • Un flujo de PR (CI) que bloquea merges hasta sync exitoso.
    • Un checklist para integrar Plum en 15 minutos.

    Respóndeme este mensaje y te lo envío. O instala plum-dev y me cuentas qué encuentras en tu primer commit con agente. Te prometo que descubrirás decisiones que no sabías que habías tomado.

    Si el artículo y su enfoque encajan con tus flujos de automatización, considera explorar más en Dominicode Labs como continuación lógica a la integración de herramientas y procesos en equipos técnicos.

    FAQ

    ¿Qué hace exactamente Plum cuando instalo y lo configuro?

    Instala hooks de Git, identifica dónde están tus specs (Markdown) y tests (Pytest por ahora), y añade puntos de control en commits para extraer y registrar decisiones tomadas por humanos o agentes.

    ¿Plum genera código o modifica mi base de código automático?

    No. Plum no genera código. Actualiza specs y registra decisiones; el código lo sigue haciendo la persona o el agente. Plum actúa como checkpoint y registro.

    ¿Qué pasa si no quiero que ciertos cambios sean bloqueados?

    Puedes configurar umbrales, filtros por carpeta/tipo de archivo y modos (ej.: “dangerously approve all”) para reducir interrupciones en prototipos o áreas no críticas.

    ¿Plum soporta todos los frameworks de tests?

    No: actualmente es Pytest-only. El análisis de cobertura falla con otros runners hasta que se añada soporte explícito.

    ¿Cómo se ve un registro de decisión y qué metadatos incluye?

    Un .jsonl incluye: question, decision, approved_by, proposed_by (LLM o human), branch, diff_link y timestamps (created, approved, synced).

    ¿Qué ocurre si Plum detecta decisiones conflictivas?

    Plum puede bloquear el commit y presentar las decisiones para aprobación. La resolución puede requerir rework en el agente o intervención humana; el flujo de rollback automático es work-in-progress.

    ¿Plum puede integrarse en CI para bloquear merges?

    Sí. Un flujo de PR (CI) puede bloquear merges hasta que plum sync sea exitoso y las brechas entre spec, tests y código hayan sido resueltas.

  • Implementación del Model Context Protocol en Angular 21

    Implementación del Model Context Protocol en Angular 21

    Hacer post sobre los MCPs de angular 21

    Tiempo estimado de lectura: 6 min

    • MCP estandariza cómo los agentes de IA leen, razonan y proponen cambios en repositorios Angular 21.
    • Orden de inspectores (list_projects → get_best_practices → search_documentation → find_examples → onpush_zoneless_migration) minimiza cambios destructivos.
    • MCP exige trazabilidad: cada recomendación debe incluir referencia a la documentación oficial y reglas del proyecto.
    • Integración práctica: CI/pipelines y IDEs deben ejecutar inspectores antes de ofrecer o aplicar cambios.
    • Riesgos reales: reduce alucinaciones pero no elimina límites del análisis estático; requiere revisión humana.

    Introducción

    Hacer post sobre los MCPs de angular 21 empieza por entender que no hablamos de una feature menor: hablamos de cómo los agentes de IA leerán, razonan y propondrán cambios en tu código sin romper la arquitectura. En Angular 21, donde Signals, Standalone Components y la migración zoneless son la norma, el Model Context Protocol (MCP) pasa de ser un extra a una herramienta de gobernanza técnica indispensable.

    Resumen rápido (lectores con prisa)

    Qué es: Un protocolo que estandariza cómo los modelos de lenguaje interactúan con repositorios para descubrir topología, consultar documentación y aplicar reglas antes de sugerir cambios.

    Cuándo usarlo: En monorepos, pipelines automatizados y entornos donde agentes de IA pueden proponer cambios en código base (migraciones, refactors, PRs).

    Por qué importa: Evita propuestas que compilan pero introducen deuda técnica; garantiza trazabilidad y reglas específicas por versión.

    Cómo funciona (resumen): Ejecuta inspectores en orden (list_projects → get_best_practices → search_documentation → find_examples → onpush_zoneless_migration) y adjunta referencias oficiales a cada recomendación.

    Por qué importa ahora

    Angular 21 consolida patrones que rompen supuestos antiguos: la inyección por constructor deja paso a inject(), la reactividad local se orienta a Signals y zone.js tiende a desaparecer. Un LLM no contextualizado propondrá soluciones que compilan pero introducen deuda técnica. El MCP asegura que el agente primero lea la topología y las reglas del proyecto y luego proponga —no al revés.

    Componentes del flujo MCP en Angular 21

    • Descubrimiento de topología: el agente usa Nx para mapear aplicaciones, librerías y dependencias mediante list_projects.
    • Inyección de prácticas por versión: get_best_practices detecta la versión y aplica reglas (p. ej. evitar NgModules cuando no proceden).
    • Validación documental en tiempo real: search_documentation consulta angular.dev antes de afirmar APIs o signaturas.
    • Ejemplos concretos y actualizados: find_examples recupera implementaciones modernas (Signals, inject(), formularios reactivos).
    • Coaching contextual: ai_tutor ajusta el nivel técnico según el rol del usuario.
    • Auditoría zoneless: onpush_zoneless_migration analiza compatibilidad al eliminar zone.js.

    Ejemplo práctico (flujo mínimo aplicable)

    1) Ejecuta list_projects: el agente devuelve el mapa del monorepo con apps y librerías.

    2) Ejecuta get_best_practices: se cargan reglas específicas para Angular 21 (uso de Signals, restricciones sobre RxJS local).

    3) Pide search_documentation para la API concreta (p. ej. Signals API).

    4) Solicita find_examples para ver implementaciones validadas.

    5) Si el objetivo es migrar, corre onpush_zoneless_migration y compila la lista de refactorizaciones.

    Este orden evita que el agente proponga cambios destructivos en zonas equivocadas del repo.

    Casos de uso concretos y recomendaciones

    • Revisiones automáticas de PR: integra MCP en pipelines de CI para que el agente haga una pre-auditoría. Usa n8n o tu runner de CI para ejecutar los inspectores en cada PR.
    • Onboarding y documentación viva: ai_tutor puede generar guías de cambios y checklist de migración adaptados al repositorio. Útil para equipos nuevos que deben adoptar Signals y patrones zoneless.
    • Auditorías zoneless: no confíes en una única ejecución. Los detectores estáticos identifican patrones vulnerables (suscripciones sin limpieza, efectos colaterales) pero requieren revisión humana en casos límite.

    Criterio técnico que debes aplicar

    • Nunca concedas permisos de escritura antes de ejecutar list_projects y get_best_practices.
    • Exige trazabilidad: cada recomendación debe venir con la referencia a la documentación oficial (angular.dev).
    • Valida migraciones zoneless con pruebas E2E y monitoreo en staging; los cambios en detección de cambios pueden aparecer solo en escenarios complejos.
    • Mantén una “zona de seguridad” en la que la IA puede proponer cambios no destructivos (documentación, tests, refactorizaciones no críticas) y otra donde solo humanos aprueban (cambios en librerías compartidas, infraestructuras críticas).

    Integración con herramientas (práctico)

    • IDEs con IA: plug-ins que implementen MCP deben ejecutar inspectores antes de ofrecer snippets.
    • Automatización: orquesta inspectores con n8n para que cada PR dispare una auditoría RAG (Read-Only).
    • Registro y auditoría: guarda outputs de inspectores (mapa de topología, reglas aplicadas, fragmentos de doc) junto al PR para trazabilidad histórica.

    Riesgos y límites reales

    MCP reduce alucinaciones, no las elimina totalmente. Hay límites del análisis estático: efectos en tiempo de ejecución, race conditions y casos complejos de detección de cambios pueden escapar. Además, dar permisos de escritura sin límites en monorepos empresariales sigue siendo una superficie de riesgo alta.

    Conclusión (lo que ganas)

    Hacer post sobre los MCPs de angular 21 no es solo hablar de una integración técnica; es establecer un contrato de confianza entre IA y equipo. Con MCP, los agentes dejan de ser generadores indiscriminados y pasan a ser asistentes que conocen tu repo, tus reglas y tus límites. Implementados con disciplina (orden de inspectores, trazabilidad y revisión humana), los MCPs reducen deuda técnica, aceleran migraciones y convierten la IA en parte fiable del flujo de desarrollo.

    Dominicode Labs

    Para equipos que orquestan agentes y pipelines, una referencia práctica de investigación y experimentación es Dominicode Labs. Integrar MCP con flujos de trabajo y pruebas reproducibles ayuda a mantener trazabilidad y mejorar la adopción de prácticas zoneless.

    FAQ

    ¿Qué es exactamente un MCP?

    Un Model Context Protocol (MCP) es un conjunto de inspectores y flujos estandarizados que permiten a modelos de lenguaje interactuar con un repositorio de forma gobernada: descubrir topología, cargar reglas de práctica por versión y validar documentación antes de generar cambios.

    ¿Cuándo debo ejecutar inspectores en mi flujo?

    Siempre antes de conceder permisos de escritura a un agente: al menos ejecutar list_projects y get_best_practices. Para migraciones, añadir search_documentation, find_examples y onpush_zoneless_migration.

    ¿Cómo garantiza el MCP que no se rompa la arquitectura?

    No lo garantiza por completo, pero reduce riesgos al exigir que el agente conozca la topología y las reglas específicas del proyecto antes de proponer cambios. Además obliga a adjuntar referencias y un plan de refactorización verificable.

    ¿Qué referencias documentales se deben adjuntar a las recomendaciones?

    Las referencias deben ser enlaces a la documentación oficial pertinente en angular.dev (por ejemplo la Signals API) y, cuando corresponda, recursos técnicos como repositorios oficiales (p. ej. zone.js).

    ¿Puede un MCP eliminar la necesidad de revisión humana?

    No. MCP reduce alucinaciones y añade trazabilidad, pero las decisiones críticas (cambios en librerías compartidas, infraestructuras) deben seguir pasando por revisión humana.

    ¿Cómo integrar MCP en CI con n8n?

    Orquesta los inspectores como pasos en la pipeline: cada PR dispara un flujo de RAG (Read-Only) en el que list_projects y get_best_practices se ejecutan primero, seguidos por validaciones documentales y generación de un reporte adjunto al PR. Una opción práctica es usar n8n para encadenar esos inspectores.

    ¿Qué precauciones tomar en migraciones zoneless?

    Validar compatibilidad con onpush_zoneless_migration, ejecutar pruebas E2E en staging y monitorizar cambios en detección de cambios. No confiar exclusivamente en análisis estático: casos de race conditions y efectos en tiempo de ejecución requieren supervisión humana.

  • Cómo diagnosticar errores CORS en Angular con responseType

    Cómo diagnosticar errores CORS en Angular con responseType

    responseType en HttpResponse: diagnóstico programático de CORS y Fetch API en Angular

    Tiempo estimado de lectura: 3 min

    • Diagnóstico preciso: responseType expone la clasificación de Fetch (basic, cors, opaque, error, opaqueredirect) para convertir status: 0 en información accionable.
    • Observabilidad: Usar interceptores para registrar fetchType permite distinguir fallos de red, bloqueos CORS y respuestas opacas.
    • Estrategia de reintentos: No aplicar reintentos genéricos; combinar responseType con límites y circuit breakers.
    • Compatibilidad: Habilitar Fetch con provideHttpClient(withFetch()) para acceder a esta propiedad; XHR no la expone.

    Introducción

    responseType en HttpResponse es la nueva propiedad que Angular expone en HttpResponse y HttpErrorResponse para reflejar el tipo de respuesta de la Fetch API (‘basic’, ‘cors’, ‘opaque’, ‘error’, ‘opaqueredirect’). En las primeras líneas: esto permite diagnosticar programáticamente fallos de red y bloqueos de CORS sin depender de DevTools ni de mensajes genéricos con status: 0.

    Resumen rápido (lectores con prisa)

    Qué es: una propiedad en HttpResponse/HttpErrorResponse que refleja Response.type de la Fetch API.

    Cuándo usarlo: cuando uses Fetch como motor en Angular (provideHttpClient(withFetch())).

    Por qué importa: convierte status: 0 en señales accionables (p. ej. distinguir ‘opaque’ de ‘error’).

    Cómo funciona: el navegador categoriza la respuesta (basic/cors/opaque/error/opaqueredirect) y Angular la expone en HttpResponse/HttpErrorResponse.

    responseType en HttpResponse: qué es y por qué importa

    La propiedad es la representación de Response.type de la Fetch API (documentada en MDN). Angular la hace accesible cuando el HttpClient usa Fetch como motor (activar con provideHttpClient(withFetch())). Si tu app sigue con XHR, no tendrás esta clasificación semántica porque XHR no expone esos metadatos.

    No confundas esto con la opción de petición responseType que define ‘json’|’blob’|’text’, ni con HttpEventType. Aquí hablamos de cómo el navegador trató la respuesta desde la perspectiva de seguridad/origen.

    Fuentes:

    Valores y significado práctico

    basic

    ‘basic’ — Same-origin. No hay CORS. Acceso completo a cabeceras y cuerpo.

    cors

    ‘cors’ — Cross-origin aprobado; el servidor ha respondido con las cabeceras CORS correctas.

    opaque

    ‘opaque’ — Petición cross-origin en modo no-cors: el navegador ejecuta la petición pero oculta cuerpo y cabeceras (respuesta inaccesible).

    error

    ‘error’ — Falla de red total: DNS, conexión rechazada o bloqueo de CORS severo que impidió la entrega.

    opaqueredirect

    ‘opaqueredirect’ — Redirección cross-origin en modo manual.

    Interpretar correctamente evita reintentos inútiles y mejora observabilidad: un ‘opaque’ no se arregla reintentando; es probable que la petición haya sido enviada en modo incorrecto o que falten cabeceras CORS.

    Implementación práctica: interceptor de diagnóstico

    Un interceptor global es el lugar natural para enriquecer logs y tomar decisiones automáticas:

    import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
    import { catchError, throwError } from 'rxjs';
    
    export const corsDiagnosticInterceptor: HttpInterceptorFn = (req, next) => {
      return next(req).pipe(
        catchError((error: HttpErrorResponse) => {
          if (error.status === 0) {
            // En versiones antiguas puede requerirse "as any" si no está tipado aún
            const fetchType = (error as any).responseType as string | undefined;
    
            if (fetchType === 'opaque' || fetchType === 'error') {
              // Log estructurado para observabilidad
              const payload = {
                tag: 'network:cors',
                fetchType,
                url: req.url,
                method: req.method,
                timestamp: new Date().toISOString()
              };
              // Ej: enviar a Sentry/Datadog/YourLogger
              console.error('[Network/CORS]', payload);
            }
          }
          return throwError(() => error);
        })
      );
    };

    Detalles prácticos: añade contexto (userAgent, entorno, versiones) y evita logs verbosos en clientes con alto tráfico. Etiqueta adecuadamente para filtrar incidentes de red en tu SIEM.

    Decisiones automáticas y recomendaciones

    Cómo actuar según responseType:

    • ‘error’ + status 0: marcar como fallo de infraestructura; no reintentar automáticamente; alertar al equipo infra.
    • ‘opaque’: auditar la configuración de la petición (¿se envía mode: ‘no-cors’ accidentalmente?), revisar proxies y CDN que puedan transformar la petición.
    • ‘cors’ con payload inválido: tratar como error de backend normal y aplicar reintentos controlados si procede.
    • ‘basic’: investigar conectividad local u origen compartido.

    Evita políticas de reintento genérico: una estrategia inteligente combina responseType con límites de reintentos y circuit breakers.

    Requisitos, tipado y compatibilidad

    • Habilita Fetch: provideHttpClient(withFetch()). (Ver: Angular HttpClient)
    • Tipado: en versiones intermedias de Angular puede ser necesario castear (error as any). Revisa las notas de versión si la propiedad aún no aparece en .d.ts.
    • Testing: en E2E/Browsers reales verifica valores de Response.type. En unit tests, simula HttpErrorResponse con responseType para validar rutas de logging.

    Observabilidad y tiempo de resolución

    La granularidad que aporta responseType reduce el time-to-detect y time-to-resolve. En entornos donde integras APIs de terceros, proxies corporativos o autenticación centralizada (OAuth), distinguir entre ‘opaque’ y ‘error’ te ahorra reproducir errores en local y te deja respuestas accionables en dashboards.

    Conclusión

    responseType en HttpResponse no es solo un campo más; es una palanca para convertir errores opacos en señales operativas. Si manejas integraciones cross-origin en producción, habilitar Fetch y aprovechar esta propiedad en interceptores y pipelines de observabilidad es una mejora tangible en resiliencia y diagnóstico.

    FAQ

    ¿Qué es exactamente responseType en HttpResponse?

    Es la representación de Response.type de la Fetch API expuesta por Angular en HttpResponse y HttpErrorResponse cuando HttpClient usa Fetch como motor.

    ¿Necesito cambiar a Fetch para verlo?

    Sí. Habilita Fetch con provideHttpClient(withFetch()). Si tu app sigue con XHR, esa clasificación no estará disponible.

    ¿Cómo distingue ‘opaque’ de ‘error’?

    ‘opaque’ indica una petición cross-origin en modo no-cors con cuerpo y cabeceras ocultas; ‘error’ indica una falla de red total (DNS, conexión rechazada o bloqueo severo de CORS).

    ¿Debo reintentar cuando veo status 0?

    No automáticamente. Usa responseType para decidir: por ejemplo, no reintentar en ‘error’ y auditar la configuración en ‘opaque’.

    ¿Dónde conviene registrar fetchType?

    En un interceptor global, con logs estructurados que incluyan contexto (userAgent, entorno, versiones) y etiquetas para filtrar en tu SIEM.

    ¿Cómo pruebo esto en tests?

    En E2E y navegadores reales verifica Response.type. En unit tests simula HttpErrorResponse con responseType para validar rutas de logging y comportamiento del interceptor.

  • Cómo redactar especificaciones efectivas para IA en desarrollo de software

    Cómo redactar especificaciones efectivas para IA en desarrollo de software

    ¿Quieres que la IA escriba código que aguante en producción o prefieres pagar la reescritura con horas de sueño robadas?

    Tiempo estimado de lectura: 6 min

    • Sin una spec sólida, la IA falla: la salida suele ser “lo más probable” y no lo que tu sistema necesita.
    • Una spec funciona como contrato: entradas, salidas y reglas inmutables (TS, DB, validadores).
    • Proceso y repo: coloca SPEC.md y reglas globales en el repo; pide tests antes de código.
    • Diseña para fallos: idempotencia, retries, observabilidad y mocks de LLM en CI.

    Poca gente dice esto claro: sin una spec sólida, la IA no te ayuda —te traiciona con estilo. Te da un PR brillante, lo mergeas, y dos semanas después estás en modo bombero arreglando incoherencias, dependencias raras y bugs que solo existen porque nadie le dijo al modelo las reglas del juego.

    Esto no es teoría. Es un manual corto y agresivo para escribir specs que conviertan a la IA en ejecutora precisa, no en improvisadora talentosa.

    Resumen rápido (lectores con prisa)

    La IA no entiende contexto técnico; genera lo más probable. Para usarla en producción necesitas specs como contratos: define entradas, salidas, validadores y versiones exactas del stack. Pon la spec en el repo, exige tests (mock de LLM en CI) y diseña idempotencia, retries y observabilidad desde el inicio.

    Primera verdad incómoda: la IA no piensa, predice

    Los modelos son máquinas de probabilidades. No entienden GDPR, SLAs o el negocio que hay detrás del botón. Si no les das límites, rellenan con lo más probable de su entrenamiento. Y lo más probable suele ser un parche bonito… que no encaja en tu arquitectura.

    Qué hace una spec que realmente funcione con IA

    1) Contexto de negocio (el “por qué”) — 1 párrafo

    No le cuentes la historia de tu vida. Di en una frase qué problema resuelve esta feature y qué sería un fallo. Ejemplo: “Crear usuarios con verificación por email. Éxito = usuario activo; fracaso = intento de signup duplicado.” Con eso la IA prioriza seguridad y unicidad, no UX glam.

    2) Contratos de datos inmutables — el núcleo

    Define TODAS las formas de datos:

    • Interfaces TypeScript (ej. CreateUserRequest, UserResponse).
    • Esquema de DB (SQL/Prisma).
    • Validadores (Zod schemas).

    Si el código espera un JSON con { email: string, password: string } dilo. Congela esos contratos. Si cambian, cambia la spec. Esto transforma a la IA en un generador que cumple un contrato, no en un novelista.

    3) Stack y versiones exactas — sin ambigüedades

    “Usa Next.js” es basura. Di “Next.js 14 — App Router — Node 20 — Postgres 15 — pgvector”. Lista librerías permitidas y las prohibidas. Los modelos tienden a usar patrones históricos; dar versión evita sorpresas.

    4) Reglas negativas — lo que NO se debe hacer

    La IA ama instrucciones. Si le dices “No hagas X”, lo recuerda. Lista antipatrones:

    • No exponer variables de entorno en cliente.
    • No añadir dependencias sin revisión CVE.
    • No implementar persistencia eventual en endpoints críticos.

    5) Criterios de aceptación comprobables

    Exige tests. Define qué pruebas deben pasar:

    • Unit tests (ej. hashing de password).
    • Integration tests (ej. createUser -> DB -> verify hash).
    • Tests de resiliencia (reintentos en worker).

    Pedir tests antes que código hace que la IA produzca implementaciones testables.

    Cómo estructurar la spec en el repo (hazlo ya)

    No metas la spec en Google Docs o Notion y esperes que la IA la lea. Ponla en el repo. Que el agente la tenga al lado del código. Dos archivos mínimos:

    Archivos mínimos

    • .cursorrules / .github/copilot-instructions.md — Reglas globales: stack, estilos, convenciones de nombres, políticas de seguridad. Que el agente lo lea siempre.
    • SPEC.md (micro-spec por feature) — Contexto corto, contratos TS, endpoints, criterios de aceptación, reglas negativas, responsables.

    Micro-spec vs contexto global: menos es más

    Saturar la ventana de contexto con miles de archivos confunde. Alimenta a la IA con:

    • SPEC.md del módulo.
    • Tipos globales que realmente importan.
    • Un archivo de reglas globales.

    Menos ruido, más precisión. La IA trabaja mejor con densidad técnica, no con bibliotecas de historia.

    Patrón de trabajo: plan antes de código

    Nunca pidas “haz el CRUD”. Pide un plan en pasos:

    1. Interfaces + DB schema.
    2. Contratos OpenAPI.
    3. Tests de aceptación.
    4. Implementación por sprint.

    Aprueba cada fase. Así evitas que la IA genere código que contradiga los contratos que aprobaste.

    Herramientas que convienen y por qué

    – TypeScript + Zod: transforma respuestas en contratos verificables.

    – Prisma/SQL: esquemas claros y migraciones.

    – OpenAPI: contratos de endpoint.

    – pgvector (si usas vectores): evita añadir otro servicio.

    – n8n para orquestación: sacas la lógica de integración fuera del repo y manejas retries visuales.

    RAG y seguridad: nunca lo tomes a la ligera

    Si vas a indexar documentos para chatear con ellos, cada vector debe llevar tenant_id. Punto. No mezcles tenants. Nunca. El filtro por tenant debe aplicarse en la consulta, no en la app. Si mezclas vectores, estás invitando a fugas de datos.

    Idempotencia, retries y jobs: diseña para fallos

    Asume que la IA y los servicios fallarán. Diseña:

    • Jobs con estado (pending, processing, success, failed).
    • Workers idempotentes por job_id.
    • Dead-letter queues para errores irreparables.
    • Retries con backoff exponencial y circuit breaker.

    No idempotencia = facturación duplicada + datos duplicados. No es elegante. Es caro.

    Observabilidad desde el minuto cero

    Si no mides, no mejoras. Instrumenta:

    • Traces distribuidos (OpenTelemetry).
    • Métricas: latencia por modelo, tokens por job, coste por tenant.
    • Logs estructurados con context_id.
    • Dashboards y alertas (picos de coste, aumentos de error rates).

    Tests: mockea la IA

    No dependas de la API real en CI. Mockea respuestas de LLM —positivas y negativas— y tests que simulen timeouts, respuestas malformadas y ataques de prompt injection. Así la spec y los tests te protegen cuando la IA se sale del carril.

    Plantilla mínima de SPEC.md (rápida y usable)

    Pon esto en la raíz del módulo. No lo copies sin adaptar, pero úsalo como base.

    • Título: Objetivo en una frase.
    • Contexto: 2 párrafos máximos.
    • Stack: versiones exactas.
    • Contratos: interfaces TS + esquemas SQL/Prisma.
    • Endpoints: método, path, payloads (ej. OpenAPI snippet).
    • Regla negativas: lista corta.
    • Criterios de aceptación: tests concretos.
    • Responsables: quién aprueba merge.

    El nuevo rol del senior: menos héroe, más guardián

    El valor del senior hoy no es teclear más rápido. Es decidir fronteras. Es escribir specs que no fallen en producción. Si no tienes eso, la IA solo acelera el desastre.

    Checklist rápido antes de pedir código a la IA

    • ¿SPEC.md está en la raíz del módulo?
    • ¿Interfaces TS y esquemas DB están definidos?
    • ¿Reglas negativas claras?
    • ¿Tests de aceptación definidos?
    • ¿El prompt obliga a devolver JSON validable?

    Si respondes no a cualquiera, no pidas código.

    CTA

    Si quieres la plantilla SPEC.md lista para pegar y un prompt maestro para Claude que funcione hoy, respóndeme “Quiero la plantilla”.

    Te la envío lista para pegar en el repo y para que la IA empiece a generar código que no te rompa la vida.

    Para quienes trabajan en automatización, agentes y workflows este enfoque encaja con prácticas de laboratorio y experimentación. Más recursos y experimentos vinculados a estos patrones están disponibles en Dominicode Labs, que complementan las plantillas y ejemplos prácticos descritos arriba.

    FAQ

    Respuesta: ¿Por qué necesito una spec si la IA puede escribir código por mí?

    Porque la IA genera lo más probable, no lo correcto para tu negocio. Una spec transforma requisitos en contratos verificables que la IA puede cumplir de forma repetible.

    Respuesta: ¿Qué debe contener obligatoriamente un SPEC.md?

    Título objetivo, contexto corto, stack con versiones exactas, contratos (TS + DB), endpoints, reglas negativas, criterios de aceptación y responsables.

    Respuesta: ¿Cómo evito fugas de datos en sistemas RAG?

    Indexa vectores con tenant_id, aplica el filtro por tenant en la consulta y evita mezclar índices entre tenants.

    Respuesta: ¿Qué pruebas debo pedir antes de revisar un PR generado por IA?

    Unit tests, integration tests que verifiquen contratos y tests de resiliencia (timeouts, retries, respuestas malformadas).

    Respuesta: ¿Cómo integro mocks de LLM en CI sin perder cobertura realista?

    Mockea escenarios positivos y negativos, timeouts y prompt injections. Mantén casos representativos que reflejen errores reales observados en producción.

    Respuesta: ¿Qué reglas negativas son las más críticas?

    No exponer env vars en cliente; no añadir dependencias sin revisión CVE; no usar persistencia eventual en endpoints críticos; exigir tests antes del merge.

  • Cómo Vitest se convierte en el test runner por defecto en Angular 21

    Cómo Vitest se convierte en el test runner por defecto en Angular 21

    Vitest como test runner por defecto en Angular 21

    Tiempo estimado de lectura: 3 min

    • Ideas clave:
    • Angular 21 define a Vitest como runner de tests por defecto, unificando pipeline con Vite/esbuild.
    • Ventajas técnicas: pipeline unificado, ESM-first, feedback más rápido en –watch, menos dependencias puente.
    • Riesgos a validar: compatibilidad con TestBed, zone.js, elección de entorno DOM y migración incremental en monorepos.
    • Estrategia recomendada: probar en branch, alinear vite.config.ts, migrar por iteraciones y mantener Karma/Jest hasta completar la transición.

    Vitest como test runner por defecto cambia algo más que un paquete en package.json: alinea el pipeline de pruebas con el mismo motor que compila y sirve tu aplicación (Vite/esbuild). En las primeras líneas: esto reduce discrepancias entre entorno de desarrollo y entorno de tests, acelera el feedback en modo watch y simplifica la gestión de módulos ESM. Angular 21 fija Vitest por defecto; Karma y Jest siguen soportados, pero la dirección es clara.

    Resumen rápido (lectores con prisa)

    Vitest es un runner sobre Vite optimizado para ESM y esbuild.

    Significa un pipeline unificado entre dev y tests, menos transformaciones duplicadas y feedback más rápido en –watch.

    Valida TestBed, zone.js y entornos DOM (jsdom vs happy-dom) antes de migrar.

    Migración recomendada por fases; mantener Karma/Jest hasta completar la cobertura en Vitest.

    Vitest como test runner por defecto: qué significa para tu arquitectura

    Vitest es un runner construido sobre Vite y optimizado para flujos ESM y esbuild. Al adoptar Vitest por defecto, Angular deja de tener dos pipelines distintos (uno para build/serve y otro para tests), lo que elimina una fuente frecuente de errores: transforms distintos, alias no replicados o compatibilidades ESM que “se rompen” solo en CI.

    Ventajas técnicas (no marketing)

    Pipeline unificado

    Same toolchain para dev y tests. Menos config duplicada = menos fallos de integración.

    ESM-first

    Vitest trata paquetes ESM nativos sin hacks; adiós a transformIgnorePatterns interminables.

    Feedback más rápido en –watch

    Vite conoce el grafo de módulos y re-ejecuta solo lo necesario, reduciendo tiempos de feedback en desarrollo.

    Menos “glue” y dependencias puente

    Menos presets y adaptadores como los que Jest requería en proyectos Angular.

    Cuando la herramienta de testing comparte transformaciones exactas con tu dev server, tus tests reflejan la realidad del runtime.

    Ejemplo mínimo de integración y scripts

    Un ejemplo práctico de lo que cambias en un proyecto Angular:

    package.json (scripts)

    {
      "scripts": {
        "test": "vitest",
        "test:watch": "vitest --watch",
        "test:ci": "vitest --run"
      }
    }

    vite.config.ts (fragmento)

    import { defineConfig } from 'vite';
    import { angular } from '@analogjs/vite-plugin-angular'; // ejemplo de integración si aplica
    
    export default defineConfig({
      test: {
        environment: 'happy-dom', // o 'jsdom' según tus necesidades
        globals: true
      }
    });

    Estos archivos muestran la convergencia: tu vite.config.ts puede centralizar transformaciones y alias que antes había que duplicar para Jest o Karma.

    Riesgos y puntos a validar antes de migrar

    • TestBed y APIs específicas de Angular: sigue funcionando, pero revisa utilidades que dependan de polyfills o zone.js. Algunas configuraciones de test legacy pueden requerir ajustes.
    • Entornos DOM: Vitest soporta jsdom y happy-dom; valida cuál reproduce mejor tu suite (render tests, componentes con animaciones, etc.).
    • Monorepos y grandes bases de tests: migrar toda la suite puede ser costoso de golpe; planifica migraciones por paquetes o por dominios funcionales.
    • Cold starts en CI: aunque Vitest suele ser rápido, en suites masivas el rendimiento en cold start depende mucho de la configuración y del entorno del runner (compara con tus números reales).

    Estrategia práctica de migración (tech-lead friendly)

    1. Probar en un branch: instala Vitest y configura un ejemplo mínimo (un módulo o paquete).
    2. Alinear vite.config.ts: centraliza las transformaciones que usas en dev (alias, plugins).
    3. Comparar modos: ejecutar la suite en modo watch y en CI (run) para comparar tiempos y fallos.
    4. Migración por iteraciones: migrar grupos de tests por feature o carpeta, ajustando mocks y environment según sea necesario.
    5. Mantener Karma/Jest activos: mantenerlos durante la transición; eliminar cuando el 100% de tests pasen en Vitest y la monitorización confirme estabilidad.

    Si quieres una herramienta rápida para estimar el impacto, mide:

    • Tiempo total de test en CI antes/después.
    • Tasa de falsos negativos/positivos detectados por cambio de runner.
    • Tiempo medio de feedback en dev (–watch).

    CI/CD: ganancias reales

    En CI obtendrás beneficios prácticos:

    • Menor complejidad en runners (menos paquetes, menos instalación).
    • Startup más rápido y menor consumo de memoria en contenedores.
    • Pipeline más predecible al usar el mismo empaquetador que en dev.

    Ejemplo breve (GitHub Actions step):

    - name: Run tests
      run: npm ci && npm run test:ci

    Sin Webpack en la ecuación, la instalación y ejecución suelen ser más ágiles.

    Cuándo no migrar aún

    • Si tienes una suite de tests con integración muy fina en Jest (configuraciones Nx o monorepos con dependencias internas) y el coste de migración supera el beneficio inmediato.
    • Si dependes de plugins de Jest que no tienen equivalentes en Vitest y que son críticos para tu flujo.

    En esos casos, planifica la migración como iniciativa de medio plazo: arranca con nuevos proyectos y módulos para ganar experiencia.

    Conclusión

    Vitest como test runner por defecto en Angular 21 no es solo una nueva opción: es la consolidación de una decisión de coherencia técnica. Para proyectos nuevos, adopta Vitest. Para proyectos con Karma, planifica la migración cuanto antes. Para entornos Jest maduros, valora ROI y migra por fases. La apuesta central aquí es menos complejidad operativa, menos errores por discrepancias de herramientas y tests que realmente reflejan el comportamiento en producción.

    Lecturas y recursos:

    FAQ

    Respuesta: Vitest es un test runner construido sobre Vite, optimizado para flujos ESM y esbuild. Comparte transformaciones con el dev server de Vite, lo que reduce discrepancias entre desarrollo y tests.

    Respuesta: Angular 21 fija Vitest por defecto para alinear pipelines, reducir duplicación de configuración y mejorar la coherencia entre runtime de desarrollo y entorno de tests.

    Respuesta: Validar compatibilidad de TestBed y APIs específicas de Angular, dependencia en zone.js o polyfills, y elegir el entorno DOM adecuado (jsdom vs happy-dom).

    Respuesta: Depende de tu suite. jsdom puede ser más completo en APIs DOM; happy-dom suele ser más ligero. Probar ambos según componentes y animaciones es la vía correcta.

    Respuesta: Migrar por paquetes o dominios funcionales, no todo de golpe. Medir impacto en cada iteración y mantener herramientas legacy activas hasta validar cobertura completa en Vitest.

    Respuesta: Sí. Mantener Jest o Karma durante la transición es recomendable. Eliminar solo cuando todos los tests pasen en Vitest y la monitorización confirme estabilidad.

    Respuesta: Medir tiempo total de test en CI antes/después, tasa de falsos negativos/positivos por cambio de runner y tiempo medio de feedback en dev (–watch).

  • Cómo aplicar la regla del 60% en la gestión de contexto para LLMs

    Cómo aplicar la regla del 60% en la gestión de contexto para LLMs

    Gestión de contexto: la regla del 60% para sesiones en Claude Code

    Tiempo estimado de lectura: 5 min

    • Regla operativa: nunca dejes que una sesión consuma más del 60% de la ventana de contexto sin persistir el estado y limpiar la memoria.
    • Patrón de trabajo: dividir tareas en Research → Plan → Implement → Validate, con artefactos en disco y limpieza de contexto entre fases.
    • Artefactos clave: /CLAUDE.md, /RESEARCH.md, /PLAN.md, /TASK_STATE.md, /VALIDATION_REPORT.md y commits atómicos por módulo.
    • Señales y métricas: observar contradicciones, repeticiones de contexto y fallos por “olvidos”; medir % de tareas con rework y tiempo de retoma.

    Introducción

    La frase “gestión de contexto: la regla del 60%” no es un eslogan. Es la regla operativa que evita que sesiones largas con agentes como Claude Code produzcan código coherente hoy y deuda técnica mañana. Si trabajas con LLMs en ingeniería, aplica esto desde el primer día: nunca dejes que una sesión consuma más del 60% de la ventana de contexto sin persistir el estado y limpiar la memoria.

    Resumen rápido (lectores con prisa)

    La regla del 60% limita cuánto de la ventana de contexto puede usar una sesión antes de persistir el estado. Úsala para fragmentar trabajo en sesiones controladas y guardar artefactos versionados (archivos en el repo). Aplica especialmente con agentes que leen/escriben repositorios como Claude Code.

    Qué significa “Gestión de contexto: la regla del 60%” y por qué importa

    Los modelos de lenguaje tienen una ventana finita de tokens. Cuando esa ventana se aproxima a su límite —y en la práctica cuando supera el 60%— el modelo comienza a priorizar lo más reciente. Eso no produce errores ruidosos: produce decisiones de diseño que olvidan criterios definidos al inicio, bugs detectados temprano y validaciones que ya no se tienen en cuenta.

    La regla del 60% obliga a fragmentar el trabajo en sesiones controladas y a externalizar el estado en artefactos versionados (archivos en el repo). Con Claude Code esto es práctico y repetible porque el agente puede leer/escribir el repositorio: https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview y https://www.anthropic.com/claude.

    El patrón operativo: 4 fases limpias por sesión

    Divide cualquier tarea compleja en cuatro fases: Research → Plan → Implement → Validate. Cada fase debe terminar con un artefacto en disco y una limpieza explícita del contexto antes de pasar a la siguiente.

    1) Research — auditoría

    – Objetivo: mapear dependencias, puntos de dolor y deuda técnica sin cambiar nada.

    – Salida: RESEARCH.md con módulos auditados, preguntas abiertas y riesgos priorizados.

    – Acción: cerrar sesión. No cargar más archivos que los estrictamente necesarios.

    2) Plan — diseño acotado

    – Objetivo: con RESEARCH.md + CLAUDE.md (contrato del proyecto) definir módulos, orden y criterios de aceptación.

    – Salida: PLAN.md con tareas atómicas y criterios verificables.

    – Acción: validar el plan con un humano; cerrar sesión.

    3) Implement — sesiones por módulo

    – Objetivo: una sesión por módulo. Cargar solo PLAN.md, CLAUDE.md y archivos del módulo.

    – Salida por módulo: commit atómico + actualización de TASK_STATE.md (estado por módulo) y tests unitarios.

    – Acción: limpiar contexto entre módulos (reiniciar sesión o instanciar subagente nuevo).

    4) Validate — verificación objetiva

    – Objetivo: sesión en blanco que lea PLAN.md y ejecute validaciones (tests unitarios, integración, contratos).

    – Salida: VALIDATION_REPORT.md con pass/fail y pasos de corrección.

    – Acción: abrir PR / merge si pasa; en caso contrario, agregar tareas correctivas al plan y repetir ciclo.

    Ejemplo práctico (prompt y artefactos)

    Estructura de archivos mínima:

    /CLAUDE.md
    /RESEARCH.md
    /PLAN.md
    /TASK_STATE.md
    /VALIDATION_REPORT.md
    /tasks/auth-migration.md
    

    Prompt de recuperación inicial (Research → Plan):

    Lee /RESEARCH.md y /CLAUDE.md. Propón un PLAN.md que divida la migración de Auth en módulos atómicos,
    cada uno con criterios de aceptación y tests mínimos. No implementes código.
    Guarda PLAN.md y termina la sesión.

    Prompt para Implement (módulo user-service):

    Lee PLAN.md y CLAUDE.md. Trabaja únicamente en src/services/user-service.* según el criterio de la tarea "UserService".
    Agrega tests unitarios que validen los criterios. Actualiza TASK_STATE.md antes de hacer commit.
    No toques otros módulos.

    Regla inquebrantable: actualizar TASK_STATE.md y hacer commit antes de terminar la sesión.

    Señales de que estás cruzando el 60% (y qué hacer)

    – Necesitas repetir contextos largos en prompts para que el agente recuerde una regla inicial.

    – El agente empieza a contradecir decisiones anteriores sin justificación.

    – Validaciones fallan por “olvidos” de requisitos que estaban en el RESEARCH.md.

    Si ves cualquiera de estas señales: persiste el estado en disco, cierra la sesión y reinicia con el artefacto correspondiente.

    Ventajas prácticas y métricas que importan

    Aplicar la regla del 60% reduce ruido y mejora trazabilidad:

    • Menos reverts por decisiones olvidadas.
    • Mayor porcentaje de tasks que pasan CI en el primer commit.
    • Tiempo de retoma por sesión < 5 minutos (leer artefacto) en vez de re-auditar todo.

    Mide: % de tareas con rework, número de bugs registrados en TASK_STATE.md, tiempo desde apertura de sesión hasta reanudación efectiva.

    Límites y advertencias

    Esto no sustituye especificaciones claras ni revisiones humanas. Si la planifica es ambigua, la IA persistirá ambigüedades más rápido. El patrón reduce riesgos operativos, no el riesgo conceptual de malas decisiones de diseño. Además, no necesitas este overhead para fixes rápidos o scripts aislados: aplica la regla cuando el alcance y la duración lo justifiquen.

    La regla del 60% es una disciplina: no es bonita, pero evita que la IA genere parches brillantes que fallan en integración. Si automatizas en serio, diseña tu flujo con RESEARCH.md, PLAN.md, TASK_STATE.md y VALIDATION_REPORT.md, obliga a commits atómicos y reinicia sesiones a tiempo. Con eso, la memoria del modelo deja de ser un talón de Aquiles y se convierte en parte auditable de tu pipeline.

    Continuación práctica y recursos: Dominicode Labs

    FAQ

    ¿Qué es la regla del 60%?

    Es una regla operativa que limita el uso de la ventana de contexto: nunca permitir que una sesión consuma más del 60% sin persistir estado y limpiar la memoria.

    ¿Cuándo debo aplicarla?

    Aplica siempre en sesiones largas con LLMs y agentes que manejan proyectos no triviales; evita su uso solo en fixes rápidos o scripts aislados.

    ¿Por qué importa con Claude Code?

    Porque Claude Code puede leer y escribir el repositorio; fragmentar el trabajo y persistir artefactos hace el flujo práctico y repetible.

    ¿Cuáles son los artefactos mínimos?

    /CLAUDE.md, /RESEARCH.md, /PLAN.md, /TASK_STATE.md, /VALIDATION_REPORT.md y archivos de tareas (por ejemplo /tasks/auth-migration.md).

    ¿Cómo se mide el éxito?

    Métricas: % de tareas con rework, número de bugs registrados en TASK_STATE.md y tiempo desde apertura de sesión hasta reanudación efectiva.

    ¿Qué hacer si detecto que crucé el 60%?

    Persistir el estado en disco, cerrar la sesión y reiniciar con el artefacto correspondiente.

  • Cómo migrar a Temporal en TypeScript 6.0 y evitar problemas con fechas

    Cómo migrar a Temporal en TypeScript 6.0 y evitar problemas con fechas

    ¿Cansado de que las fechas te arruinen la noche? Bienvenido a Temporal

    Tiempo estimado de lectura: 6 min

    • Temporal reemplaza a Date para lógica de negocio: menos bugs y contratos más claros.
    • Almacena Instants en DB (ISO UTC canonical) y convierte a zonas locales solo en UI.
    • Polyfill hoy, tipos con TypeScript 6.0: feature-detect y carga condicional.
    • Migración por capas y tests: evita PR monstruo, prioriza fronteras y añade reglas ESLint.

    Introducción

    Voy directo: Temporal no es una nueva API bonita para mirar. Es el fin del “setDate + pray”. Si adoptas esto con criterio, reduces bugs, clarificas contratos y dejas de escribir parsers para timestamps por toda la app. Te explico cómo hacerlo sin romper producción.

    Resumen rápido (lectores con prisa)

    Temporal es la API moderna para manejar tiempo en JS. Usa Instant para puntos absolutos (DB/logs), ZonedDateTime para eventos con zona y PlainDate para fechas sin hora. TypeScript 6.0 trae tipos; usa el polyfill donde el runtime no lo implemente.

    Configuración y polyfill

    TypeScript 6.0 trae los tipos de Temporal, pero el runtime puede no implementarlo aún en todos los motores.

    Para usarlo hoy en Node o navegadores, instala el polyfill oficial:

    npm install @js-temporal/polyfill

    En el punto de entrada (server o client) haz feature-detect y carga el polyfill solo si hace falta:

    if (!globalThis.Temporal) {
      await import('@js-temporal/polyfill');
    }

    Asegura tsconfig:

    {
      "compilerOptions": {
        "target": "esnext",
        "lib": ["esnext"],
        "strict": true
      }
    }

    Qué cambia en tu arquitectura (reglas rápidas)

    • No más new Date() para lógica de negocio.
    • Almacena timestamps en DB como Instant (ISO) — UTC canonical.
    • Muestra/convierte a zonas locales con ZonedDateTime solo donde importe (UI, emails, calendarios).
    • En tests y serialización: convierte a strings para persistir; rehidrata con Temporal.from() al cargar.

    Casos prácticos y patrones — copia, pega y aplícalo

    1) Obtener “ahora” correctamente

    // Instant (UTC preciso, para auditoría/logs)
    const nowInstant = Temporal.Now.instant();
    
    // ZonedDateTime (evento con zona)
    const nowZoned = Temporal.Now.zonedDateTimeISO();
    
    // PlainDate (cumpleaños, sin hora ni zona)
    const today = Temporal.Now.plainDateISO();

    2) Sumar y restar sin mutar

    const hoy = Temporal.Now.plainDateISO();
    const dentroDe7Dias = hoy.add({ days: 7 }); // creado nuevo, hoy no cambia

    3) Guardar en BD (mejor práctica)

    • Guarda Instants como strings: instant.toString() → “2024-05-01T12:00:00Z”.
    • Razonamiento: Instant es un punto absoluto; si reconstituyes en otro país, sigues teniendo el mismo momento.
    const timestamp = Temporal.Now.instant().toString();
    // INSERT INTO events (created_at) VALUES (timestamp);

    Recuperación:

    const instantFromDb = Temporal.Instant.from(dbValue);
    const zonedInMadrid = instantFromDb.toZonedDateTimeISO('Europe/Madrid');

    4) Mostrar en UI (zona del usuario)

    const instant = Temporal.Instant.from(event.created_at);
    const inUserTZ = instant.toZonedDateTimeISO(user.timeZone);
    const formatted = inUserTZ.toLocaleString('es-ES', { dateStyle: 'medium', timeStyle: 'short' });

    5) Schedules y DST (sin manualidades)

    const vuelo = Temporal.ZonedDateTime.from('2024-10-15T14:30:00+09:00[Asia/Tokyo]');
    const llegadaMadrid = vuelo.withTimeZone('Europe/Madrid');
    // Temporal aplica reglas de DST correctamente.

    Migración práctica y estrategia (no pegues un PR monstruo)

    Plan corto y efectivo:

    1. Detecta usos

    • grep/rg por new Date(, Date.now(), .toISOString(), getUTC*, setUTC*.
    • Haz una lista priorizada: endpoints, parsers de JSON, jobs, filas de cola.

    2. Protege el repo

    Añade rule de ESLint que prohíba new Date en código nuevo:

    // .eslintrc.json
    "rules": {
      "no-restricted-syntax": [
        "error",
        {
          "selector": "NewExpression[callee.name='Date']",
          "message": "Usa Temporal en lugar de Date"
        }
      ]
    }

    3. Cambia en capas

    • Fronteras primero: parsers de requests, handlers, webhooks.
    • Library layer: utilidades de fecha centralizadas.
    • UI: formateadores y locales.

    4. Persistencia y API contract

    • Define y documenta: “todos los timestamps en la DB son Instant ISO strings”.
    • Añade validaciones en los endpoints que aceptan timestamps (Zod / Zod schemas o runtime checks).

    5. Tests y CI

    • En jest/mocha, añade el polyfill en setupTests: import '@js-temporal/polyfill';
    • Añade pruebas para zona horaria, DST y serialización.

    Peculiaridades y errores que verás (y cómo arreglarlos)

    • Serialización: Temporal types no siempre serializan como esperas en JSON.stringify. Convierte a string explícitamente.
    • Redux / Hydration: almacena ISO strings en store si necesitas serialización. Temporal objects son inmutables pero no pensados para serializar automáticamente.
    • Comparaciones: usa Temporal.PlainDate.compare o Instant.avoid numeric timezone math.
    • Interoperabilidad con libs: elimina gradualmente date-fns/moment; si dependes de ellas, mantén adaptadores hasta reemplazar lógica.

    Decisiones de diseño: Instant vs ZonedDateTime vs PlainDate

    • Instant → logs, audit, DB primary timestamp.
    • ZonedDateTime → eventos programados que dependen de la hora local.
    • PlainDate → cumpleaños, fechainterna sin hora.
    • Duration → expiraciones, TTLs, duraciones humanas.

    Ejemplo real: reserva de vuelo (correcto)

    • Guardar en DB: Vuelo.departureInstant (Instant)
    • Guardar metadatos: Vuelo.departureTZ = 'Asia/Tokyo'
    • Mostrar en UI: instant.toZonedDateTimeISO(tz).toLocaleString(...)

    Performance y bundle

    El polyfill tiene coste. Si tu app es frontend, lazy-load the polyfill: solo usuarios que lo necesiten (browsers sin Temporal nativo) lo cargarán.

    En server (Node), añade polyfill en arranque. No suele ser un problema de perf si lo colocas correctamente.

    Checklist rápido antes de mergear cambios de fecha

    • Todos los endpoints aceptan/retornan ISO Instant cuando corresponde.
    • Tests cubren conversiones entre zonas y casos límites (fin de mes, cambio DST).
    • No quedan new Date() en la lógica de negocio.
    • Documentación para frontend/backend: cómo serializar y rehidratar.

    Metáfora breve: por qué vale la pena

    Date era un martillo con un tornillo. Temporal es el juego de herramientas correcto para el tiempo. No es más trabajo: es menos debugging.

    Cierre (CTA claro)

    ¿Quieres el script que escanea tu repo, lista todas las ocurrencias de Date y genera un plan de migración automático por prioridad? Respóndeme con “MIGRAR FECHAS” y te lo entrego: branch de prueba, report con 100 entradas ordenadas, y PR template para cada cambio.

    Esto no acaba aquí. La siguiente nota: cómo reescribir utilidades de date-fns a Temporal con transformaciones seguras y codemods semi-automáticos. ¿Lo hacemos?

    Si te interesa integrar estas prácticas con flujos de trabajo y automatización de repos, revisa Dominicode Labs para plantillas y herramientas que aceleran migraciones y codemods.

    FAQ

    ¿Por qué usar Temporal en lugar de Date?

    Temporal proporciona tipos específicos (Instant, ZonedDateTime, PlainDate) que aclaran contratos y evitan errores comunes asociados a zonas y mutabilidad de Date.

    ¿Debo cambiar todo el código de golpe?

    No. La estrategia recomendada es migrar por capas: fronteras primero (parsers/handlers), luego librerías internas y finalmente UI. Evita PRs monolíticos.

    Cómo debo almacenar timestamps en la base de datos?

    Almacena Instants como ISO strings en UTC (ej. “2024-05-01T12:00:00Z”). Reconstituye con Temporal.Instant.from() al leer.

    Qué pasa con la serialización y Redux?

    Temporal objects no siempre serializan con JSON.stringify. Guarda ISO strings en el store si necesitas serializar/hidratar.

    Necesito un polyfill en producción?

    Sí si tus entornos (navegadores/Node) no implementan Temporal nativamente. Usa feature-detect y lazy-load en frontend; carga en arranque en server.

    Cómo asegurar que no queden Date en el repo?

    Usa búsquedas (grep/rg) y añade una regla ESLint que prohíba new Date. Prioriza endpoints y parsers para corregir primero las fronteras.

  • Migración a Signal Forms en Angular 22: Mejorando formularios reactivos

    Migración a Signal Forms en Angular 22: Mejorando formularios reactivos

    Signal Forms estable: el nuevo estándar de formularios en Angular 22

    Tiempo estimado de lectura: 4 min

    • Signal Forms reemplaza Observables por Signals nativos para exponer valor, validez y estados de control.
    • Mejora ergonomía y rendimiento al evitar suscripciones manuales y emitir reactividad síncrona y dirigida.
    • Encaja con una arquitectura Zoneless para re-rendering quirúrgico y menor sobrecarga en formularios complejos.
    • Migración pragmática: usar toSignal() y desacoplar validadores reduce el coste de adopción.

    Introducción

    Signal Forms estable aparece como la evolución natural que consolida el manejo de formularios basado en Signals en Angular 22. Signal Forms estable reemplaza la dependencia de RxJS en la capa de interfaz por un modelo de reactividad síncrono y explícito, alineado con la arquitectura Zoneless y Signals centrales del framework.

    La propuesta no es solo sintaxis; es un cambio de ergonomía y rendimiento. Aquí explico qué cambia, por qué importa y cómo preparar una migración pragmática en proyectos reales.

    Resumen rápido (lectores con prisa)

    Signal Forms expone estado de formularios como Signals nativos en lugar de Observables. Use Signals para leer estado y computed() para derivar valores síncronos. Migración pragmática: convertir valueChanges a Signals con toSignal() y desacoplar validadores.

    ¿Qué es Signal Forms estable y qué problema resuelve?

    Signal Forms estable expone el estado del formulario —valor, validez, touched/dirty— como Signals nativos en lugar de streams Observables. Los problemas que resuelve de forma directa:

    • Evita gestión manual de suscripciones (memory leaks).
    • Elimina desfases causados por emisiones asíncronas en validaciones cruzadas.
    • Encaja de forma nativa con una arquitectura Zoneless, donde Signals notifican de forma quirúrgica qué partes del DOM actualizar.

    Fuente y discusión activa sobre el diseño: discusiones en GitHub. Para contexto sobre Signals y reactividad en Angular: guía de Signals en Angular.

    Cambio conceptual: de observar eventos a leer estado derivado

    Con ReactiveFormsModule hoy suelen usarse propiedades como valueChanges o statusChanges (Observables). Signal Forms cambia el patrón: en lugar de suscribirte, lees un Signal o creas computed() que derive estados complejos.

    Comparativa rápida:

    // ReactiveForms (actual)
    readonly isValid$ = this.form.statusChanges.pipe(
      map(s => s === 'VALID'),
      distinctUntilChanged()
    );
    
    // Signal Forms (conceptual)
    readonly isValid = computed(() => this.form.status() === 'VALID');
    

    computed() es síncrono, no requiere teardown manual y se integra con el grafo de dependencias para reevaluar solo cuando los valores relevantes cambian.

    Validaciones cruzadas y tracking de dependencias

    Las validaciones cruzadas son donde RxJS más fricción introduce: operadores para evitar bucles, distinct checks, y micro-delays. Con Signals, el runtime realiza dependency tracking: si una validación depende de A y B, se reevaluará solo cuando A o B cambien, sin operadores adicionales ni emisiones redundantes.

    Esto reduce tanto complejidad como carga en el hilo principal en formularios con muchos campos interrelacionados (CRMs, ERPs).

    Integración con Zoneless y pipeline de rendimiento

    La llegada de Signal Forms completa el modelo Zoneless (ver: guía Zoneless). En una app Zoneless:

    • Cada actualización de control escribe en un Signal.
    • Angular identifica qué templates dependen de ese Signal.
    • Solo esos nodos se re-renderizan.

    Resultado: menos trabajo innecesario en eventos de alta frecuencia y trazas de depuración limpias (sin contaminación por Zone.js). Para contexto sobre migraciones Zoneless y Signals, consulta: guía de Signals en Angular.

    Ejemplo práctico de interoperabilidad temporal

    Antes de la estabilización completa, la forma pragmática de probar el patrón es convertir valueChanges a Signal con toSignal (rxjs-interop).

    import { toSignal } from '@angular/core/rxjs-interop';
    
    this.formValue = toSignal(this.form.valueChanges, { initialValue: this.form.value });
    
    computed(() => {
      const value = this.formValue();
      // derivaciones y validaciones sincronas aquí
    });
    

    Esto ofrece un puente entre ReactiveForms y lo que Signal Forms hará nativo.

    Guía de rxjs-interop: guía de rxjs-interop.

    Estado de la API y compatibilidad futura

    La API está en RFC y discusión, y lo más probable es que conviva con ReactiveFormsModule durante varias versiones para minimizar rupturas. El equipo de Angular apunta a compatibilidad con validadores existentes y a proporcionar herramientas de migración (schematics) en el momento del lanzamiento estable.

    Sigue las discusiones oficiales: discusiones en GitHub.

    Estrategia práctica para Tech Leads y equipos

    No reescribas todo hoy. Sí aplica estas medidas para reducir el coste de migración:

    • Desacopla la lógica de validación y transformación del FormGroup. Mantén funciones puras o servicios para reglas de negocio.
    • Introduce toSignal() donde tenga sentido para que los templates y la lógica consuman estado de forma síncrona.
    • Establece ChangeDetectionStrategy.OnPush en componentes nuevos para asegurar un modelo de render predecible.
    • Automatiza pruebas E2E que cubran flujos de validación cruzada y efectos secundarios.
    • Reserva una fase de migración por componentes: empezar por formularios sencillos y luego los complejos.

    Checklist mínimo antes de activar Signal Forms en producción

    • Lógica desacoplada (validadores fuera del FormGroup).
    • Cobertura de pruebas para validación y envíos.
    • Observabilidad en producción para comparar métricas (TTI, LCP).

    Conclusión: por qué importa para tu arquitectura

    Signal Forms estable no es solo una API nueva: es la culminación de la transición de Angular hacia reactividad explícita y rendimiento previsiblemente escalable. Para proyectos a largo plazo, representa menos boilerplate, menor riesgo de fugas de memoria y una integración natural con la estrategia Zoneless.

    Prepara tu código hoy —desacopla, prueba y adopta interoperabilidad con toSignal— y tu equipo tendrá una migración suave cuando Angular 22 estabilice Signal Forms. La mejora no será estética: será tangible en rendimiento y mantenibilidad.

    Fuentes y recursos

    FAQ

    Respuesta: ¿Qué es Signal Forms?

    Signal Forms expone el estado del formulario —valor, validez, touched/dirty— como Signals nativos en lugar de Observables, permitiendo lecturas síncronas y derivaciones con computed().

    Respuesta: ¿Cuándo debería considerar migrar a Signal Forms?

    Considéralo cuando busques reducir suscripciones manuales, eliminar desfases en validaciones cruzadas, o al adoptar una arquitectura Zoneless para mejoras de rendimiento predecible.

    Respuesta: ¿Cómo afecta Signal Forms a las validaciones cruzadas?

    El runtime de Signals realiza dependency tracking, por lo que las validaciones que dependen de múltiples campos solo se reevaluarán cuando cambien esas dependencias, evitando emisiones redundantes y operadores adicionales de RxJS.

    Respuesta: ¿Puedo mezclar ReactiveForms y Signal Forms?

    Sí. Antes de la estabilización completa, una estrategia pragmática es convertir valueChanges a Signal con toSignal() (rxjs-interop) para interoperabilidad temporal.

    Respuesta: ¿Qué beneficios de rendimiento puedo esperar?

    Menos re-renderings innecesarios, menos trabajo en eventos de alta frecuencia y menor riesgo de fugas por manejo de suscripciones. La integración Zoneless permite re-rendering quirúrgico de los nodos que dependen de un Signal.

    Respuesta: ¿Qué precauciones antes de activar en producción?

    Asegura lógica desacoplada (validadores fuera del FormGroup), cobertura de pruebas para validación y envíos, y observabilidad en producción para comparar métricas (TTI, LCP).

  • Cuándo usar WebMCP y MCP: diferencias y criterios técnicos

    Cuándo usar WebMCP y MCP: diferencias y criterios técnicos

    Cuándo usar WebMCP y MCP: diferencias, casos de uso y criterio técnico

    Tiempo estimado de lectura: 5 min

    • Idea clave: MCP expone datos y herramientas de forma programática; WebMCP aporta semántica de UI para agentes en navegador.
    • Idea clave: Si la tarea vive en datos/APIs usa MCP; si vive en la interfaz web y necesita lógica visual, añade WebMCP.
    • Idea clave: La mayoría de flujos reales cruzan ambas capas; diseñar límites, autorización y auditoría evita inconsistencias.
    • Idea clave: Evita usar WebMCP como scraping del DOM o exponer operaciones sensibles solo vía WebMCP.

    Introducción

    Cuándo usar WebMCP y MCP es la pregunta que aparece en equipos de producto y arquitectura tras el anuncio de la vista previa de WebMCP. No es una elección técnica trivial: ambos protocolos resuelven capas distintas del mismo problema. Elegir el adecuado requiere entender la responsabilidad que vive la tarea del agente: datos o interfaz.

    Referencias útiles: Anthropic — documentación general, Claude (Anthropic)

    Resumen rápido (lectores con prisa)

    MCP es el protocolo para exponer datos y herramientas a modelos en backends y servicios automatizados. WebMCP añade semántica sobre la UI en el navegador para que agentes entiendan acciones y flujos visuales. Usa MCP para operaciones centradas en datos/APIs; usa WebMCP cuando la tarea requiere comprensión de la interfaz.

    Cuándo usar WebMCP y MCP: el criterio básico

    MCP (Model Context Protocol) y WebMCP no son intercambiables. Cada uno atiende una capa distinta:

    • MCP es el protocolo de contexto y herramientas pensado para exponer datos y capacidades de manera programática a modelos. Funciona en backends, pipelines y servicios automatizados.
    • WebMCP es una capa específica para navegador que añade semántica a la UI: explica qué hace cada elemento, qué secuencias son válidas y qué intenciones soporta la interfaz.

    Regla simple: si la tarea “vive” en datos y APIs, usa MCP. Si la tarea “vive” en la interfaz web y requiere comprender lógica visual o flujos humanos, añade WebMCP. La mayoría de flujos reales cruzan ambas capas; entonces ambos protocolos deben coexistir en la arquitectura.

    ¿Qué problema resuelve cada uno?

    MCP

    • Acceso programático a recursos: bases de datos, APIs, servicios internos.
    • Orquestación de herramientas y ejecución de operaciones sin interfaz (CI, backend, bots).
    • Reutilización: un mismo MCP sirve a agentes en CLI, servidores y apps.

    WebMCP

    • Traducción de UI a semántica: campos, opciones, relaciones de pasos.
    • Desambiguación de acciones visuales que el DOM por sí solo no comunica (¿este botón envía o guarda? ¿este panel es lectura o edición?).
    • Permite que un agente interactúe de forma segura con la experiencia de producto sin “adivinar” intenciones.

    Piensa en MCP como el sistema central de información y herramientas; WebMCP es el manual semántico de la tienda que obliga al agente a seguir los caminos definidos por el equipo de producto.

    Casos de uso concretos

    MCP es la opción cuando:

    • El agente debe crear eventos en calendarios corporativos, leer CRM, actualizar inventarios o ejecutar jobs en un pipeline.
    • Automatizas procesos en n8n, Airflow o sistemas de backend donde la UI no existe.
    • Necesitas consistencia de datos y gobernanza centralizada (auditoría, permisos, logs).

    WebMCP encaja cuando:

    • El agente necesita completar formularios complejos dentro de tu app SaaS (onboarding, configuración avanzada).
    • El producto es la UI y quieres que agentes de navegador ejecuten acciones sin romper flujos o introducir comportamientos no contemplados.
    • Quieres exponer ayuda contextual, tooltips y secuencias válidas para que el agente no interprete el DOM de forma errónea.

    Ejemplo real: “Programar una reunión”

    MCP se usa para consultar calendarios, proponer franjas y crear el evento en el backend. WebMCP se usa para verificar y ajustar preferencias visuales del usuario en el panel de configuración del calendario dentro del sitio (zona horaria específica, visibilidad de invitados).

    Arquitectura práctica: cómo combinarlos

    No se trata de elegir uno u otro, sino de diseñar límites claros:

    1. Define los contratos MCP — qué operaciones y datos expone el backend (endpoints, credenciales, scopes).
    2. Publica una capa WebMCP que mapea componentes UI a acciones seguras y semánticas (ej. checkout.submit, profile.update).
    3. Diseña autorización cruzada: acciones WebMCP deben validar permisos contra MCP antes de ejecutar cambios críticos.
    4. Registra y audita: todo cambio iniciado por WebMCP que afecte datos sensibles pasa por MCP para persistencia y trazabilidad.

    Esto evita dos errores frecuentes: agentes que manipulan la UI sin persistir cambios en backend, y agentes que modifican datos sin respetar la UX (rompiendo expectativas de usuario).

    Checklist de arquitectura antes de implementar

    • ¿La tarea requiere acceso a datos centralizados o a la UI? (MCP vs WebMCP)
    • ¿Tienes contratos claros y versionados en MCP? (endpoints, scopes, rate limits)
    • ¿Has documentado la semántica UI en WebMCP? (acciones autorizadas, flujos válidos)
    • ¿Existe validación cruzada entre WebMCP y MCP para evitar inconsistencias?
    • ¿Se auditan todas las acciones ejecutadas por agentes en una capa centralizada?

    Riesgos y anti-patrones

    • Tratar WebMCP como atajo para “scraping” del DOM. Sin semántica declarada, el agente va a fallar con cambios menores de UI.
    • Exponer operaciones sensibles solo vía WebMCP sin pasar por MCP: pérdida de control y trazabilidad.
    • Diseñar agentes que dependen de un único protocolo cuando las tareas cruzan capas; eso genera fragilidad.

    Conclusión técnica

    Cuándo usar WebMCP y MCP no es una disputa de protocolos: es diseño de responsabilidades. MCP administra datos y herramientas de forma agnóstica al entorno; WebMCP aporta la semántica que convierte interfaces humanas en elementos ejecutables y seguros para agentes. Diseña ambos desde el inicio cuando tus agentes deben operar en el mundo real: la combinación adecuada reduce errores, mejora la experiencia del usuario y protege los invariantes del sistema.

    Para equipos interesados en experimentar con patrones de integración entre agentes, UI y backend, una continuación natural es explorar prototipos y guías prácticas en Dominicode Labs. Allí se pueden encontrar ejemplos de contratos MCP y mapeos WebMCP aplicables a flujos reales.

    FAQ

    ¿Qué es MCP y para qué sirve?

    MCP (Model Context Protocol) es un protocolo para exponer contexto, datos y operaciones a modelos de forma programática. Sirve para orquestar herramientas, acceder a recursos y ejecutar operaciones en backend sin depender de la UI.

    ¿Qué es WebMCP y cuándo debería usarlo?

    WebMCP es una capa semántica para navegador que describe la intención y el comportamiento de elementos de UI. Debes usarlo cuando agentes en el navegador necesiten entender flujos visuales, acciones permitidas y relaciones entre campos.

    ¿Puedo usar solo WebMCP para todo?

    No. WebMCP no reemplaza la necesidad de un backend bien gobernado. Exponer operaciones sensibles únicamente vía WebMCP lleva a pérdida de gobernanza y trazabilidad. WebMCP y MCP deben coexistir según las responsabilidades.

    ¿Cómo debo gestionar permisos entre WebMCP y MCP?

    Diseña validaciones cruzadas: cualquier acción iniciada desde WebMCP que afecte datos sensibles debe validar permisos contra MCP antes de persistir. Mantén contratos claros y scopes en MCP para control centralizado.

    ¿Qué errores debo evitar al diseñar agentes que interactúan con la UI?

    Evita depender del scraping del DOM sin semántica, exponer operaciones críticas solo en la capa de UI y diseñar agentes acoplados a un único protocolo cuando la tarea cruza capas.

    ¿Dónde encuentro documentación adicional sobre protocolos y agentes?

    Consulta la documentación oficial de proveedores y recursos sobre diseño de agentes y contratos API. En este artículo se citaron las guías de Anthropic — documentación general y la página de Claude (Anthropic) como puntos de partida.

  • Automatiza tareas avanzadas con Claude Code sin programar

    Automatiza tareas avanzadas con Claude Code sin programar

    Claude Code no es solo para devs: 3 cosas que puedes hacer sin escribir una línea de código

    Tiempo estimado de lectura: 4 min

    • Claude (modelo) permite resolver problemas técnicos sin instalar herramientas.
    • Puedes orquestar flujos en n8n, transformar datos y generar documentación técnica sin escribir JS.
    • La diferencia clave: la CLI modifica repos locales; el modelo responde a instrucciones conceptuales.

    Introducción

    Claude Code no es solo para devs: 3 cosas que puedes hacer sin escribir una línea de código. Si leíste “CLI” y cerraste la pestaña, vuelve. La herramienta CLI existe y exige terminal, Git y permisos. Pero el ecosistema Claude —el modelo razonador accesible vía web y API— te permite resolver problemas técnicos reales sin teclear una sola línea de código. Aquí explico cómo, con ejemplos y enlaces para que lo pruebes.

    Resumen rápido (lectores con prisa)

    Qué es: Claude Code (CLI) es una herramienta para desarrolladores; Claude como modelo es un motor de razonamiento accesible vía web y API.

    Cuándo usarlo: Usa la CLI cuando necesites que un agente toque tu repo y ejecute tests; usa el modelo web/API para diseño de flujos, limpieza de datos, diagramas o specs.

    Por qué importa: Si sabes describir un problema técnico con precisión, puedes extraer valor sin instalar nada.

    Cómo funciona: El CLI actúa sobre repos locales; el modelo responde a instrucciones bien formuladas y genera artefactos accionables.

    1) Orquestar automatizaciones avanzadas en n8n — sin tocar JS

    Problema común

    Un webhook llega con JSON irregular y el flujo se rompe. Solución habitual: pedir a un dev un snippet de JavaScript. Alternativa real: usar Claude.

    Qué pedirle al modelo

    • “Este es el payload (pega ejemplo). Necesito extraer user.id, normalizar created_at a ISO y crear un campo active (true/false) según status. Dame el fragmento listo para pegar en un Code Node de n8n.”

    Qué obtendrás

    • Código listo para pegar que itera arrays, maneja nulos y transforma fechas.
    • Instrucciones de configuración del nodo HTTP (headers, auth).
    • Un plan de manejo de errores: retry con backoff exponencial, alertas en caso de 500/429.

    Por qué importa

    Reduces la fricción de integración y acortas el tiempo desde idea a flujo en producción. Documentación n8n: Documentación n8n

    2) Transformar datos y generar consultas SQL sin abrir una hoja de cálculo

    Caso real

    Recibes CSV/XML legacy y necesitas convertirlo a un esquema usable o sacar métricas complejas.

    Lo que puedes pedir

    • “Toma estas 50 filas (pega muestra). Genera un JSON Schema y un script de transformación (pseudocódigo) que normalice fechas, campos anidados y valores por defecto.”
    • “Explícame la regex para extraer IDs que empiezan por TX- seguido de 8 dígitos.” (Ejemplo: TX-\d{8})

    Qué devuelve Claude

    • JSON Schema validado y reglas de transformación.
    • Consultas SQL optimizadas para tu motor (Postgres, BigQuery), con JOINs, window functions y filtros temporales.

    Por qué importa: eliminas horas de limpieza manual y reduces errores humanos en pipelines de datos. Si necesitas precisión, adjunta la estructura de tablas y el motor SQL para que la query sea ajustada.

    3) Generar documentación técnica y diagramas antes de la implementación

    Usos prácticos

    • Describe el flujo de registro y pide código Mermaid.js para un diagrama de secuencia; pega el resultado en Notion o GitHub y obtén el gráfico inmediato. (Mermaid.js (diagramas))
    • Describe un endpoint (inputs, outputs, errores) y pide un contrato OpenAPI/Swagger listo para revisión. (OpenAPI Spec)
    • Pide un mapa de infraestructura cloud (colas, bases, funciones) con puntos de fallo y recomendaciones de mitigación.

    Qué ganas

    Conversaciones técnicas más cortas, menos malentendidos y decisiones con criterios concretos en lugar de intuición.

    Cómo decidir: CLI o modelo web/API

    Usa Claude Code (CLI) cuando quieras que un agente toque tu repo, ejecute tests o refactorice código localmente. Requiere desenvoltura con terminal y control de versiones.

    Usa Claude Web/API o integraciones (p. ej. n8n) cuando necesites diseño de flujos, limpieza de datos, diagramas o specs. Necesitas claridad conceptual, no sintaxis.

    La ventaja real no es escribir código: es estructurar problemas. Si puedes describir el estado actual, los invariantes y el resultado esperado, Claude lo transforma en artefactos técnicos accionables.

    Dominicode Labs

    Si quieres explorar integración práctica de automatizaciones y artefactos generados por IA en procesos de ingeniería, considera profundizar con recursos adicionales en Dominicode Labs. Es una continuación lógica para llevar los fragmentos y especificaciones que genera Claude hacia pruebas reproducibles y gobernanza de despliegue.

    FAQ

    ¿Necesito instalar algo para usar Claude como modelo?

    No. Claude como modelo está accesible vía web y API, por lo que puedes usarlo sin instalar la CLI ni herramientas locales.

    ¿Cuándo debo preferir la CLI de Claude?

    Prefiérela cuando necesites que un agente modifique repositorios locales, ejecute tests o interactúe con tu entorno de desarrollo. Requiere terminal y control de versiones.

    ¿Puedo usar Claude para generar código listo para n8n?

    Sí. Puedes pedir fragmentos listos para pegar en Code Nodes, junto con configuración HTTP y planes de manejo de errores.

    ¿Claude puede generar consultas SQL optimizadas?

    Sí. Claude devuelve queries ajustadas por motor (Postgres, BigQuery) incluyendo JOINs, window functions y filtros temporales si proporcionas la estructura de tablas.

    ¿Es seguro usar el modelo para datos sensibles?

    El artículo no añade recomendaciones de seguridad concretas, pero sugiere integrar artefactos en procesos de gobernanza y despliegue para que la automatización sea segura y mantenible.

    ¿Dónde encuentro documentación oficial de Claude y herramientas relacionadas?

    Referencias citables en el artículo: Anthropic – Claude Code overview, Claude (Anthropic), n8n (automatización), Mermaid.js (diagramas) y OpenAPI Spec.