~/codigoagente
Agentes de IA

Auditoría legal de un blog real: lo que encontramos en codigoagente y cómo lo corregimos

En la primera parte repasamos qué leyes de EE. UU., Europa y Ecuador afectan a una app o web hecha con IA y armamos un prompt de auditoría. Aquí lo aplicamos a un caso real: este mismo blog, un sitio en Next.js 16 y Sanity desplegado en Vercel, montado en buena parte con Claude Code. Verás el inventario, las pruebas con curl, las capturas del antes y el después y el código que cambiamos.

El inventario: qué hace realmente el sitio

Antes de corregir nada, listamos lo que el sitio hace con los datos de quien lo visita:

PreguntaRespuesta en codigoagente
¿Registro, formularios o comentarios?No
¿Newsletter o emails de marketing?No
¿Suscripciones o pagos?No
¿Analítica, publicidad o grabación de sesiones?No
¿Recursos de terceros?Imágenes desde `cdn.sanity.io` (CDN de Sanity)
¿Enlaces de afiliado?Sí, a Contabo en la guía de Paymenter
¿Contacto?Un correo, `contacto@codigoagente.com`
¿Público?Ecuador, resto de Latinoamérica, España y lectores en inglés
¿Funciones de IA para el lector?No (el contenido se escribe con ayuda de IA, pero el lector no habla con ninguna)

Con eso, varias normas quedan fuera: COPPA (no es un servicio para niños ni pide datos), CIPA (no hay grabación ni chat), CAN-SPAM y el art. 50 de la Ley de Comercio Electrónico de Ecuador (no hay emails), ROSCA (no hay suscripciones) y DMCA (los lectores no publican nada). Siguen en juego la LOPDP de Ecuador, el RGPD por los lectores de España y las guías de la FTC sobre afiliados.

Prueba 1: fuentes y recursos de terceros

El sitio usa las tipografías Geist con next/font/google. Ese módulo descarga las fuentes durante el build y las sirve desde el propio dominio, así que el navegador del lector nunca contacta con Google. Lo comprobamos sobre la versión publicada:

terminalsh
curl -s https://codigoagente.vercel.app/ | grep -c "fonts.googleapis.com\|fonts.gstatic.com"
# 0

curl -s https://codigoagente.vercel.app/ | grep -oE '[^"]*\.woff2' | head -2
# /_next/static/immutable/media/797e433ab948586e-s.p.1v5bejj26fx9h.woff2
# /_next/static/immutable/media/caa3a2e1cccd8315-s.p.0zr6hhvz-h9nw.woff2

Resultado: correcto. Cero llamadas a Google; las fuentes salen de /_next/static/.

Listando todos los dominios externos de un artículo con imágenes apareció otro tercero:

terminalsh
curl -s https://codigoagente.vercel.app/blog/instalar-paymenter-vps-coolify-docker \
  | grep -oE '(src|href)="https?://[^"/]+' | sort | uniq -c
#   3 href="https://contabo.com
#   1 href="https://github.com
#   2 href="https://safebuildlabs.com
#   9 src="https://cdn.sanity.io

Los href son enlaces que el lector decide pulsar. Los src de cdn.sanity.io no: el navegador los carga solo y Sanity recibe la IP del lector, igual que Google con las fuentes. Tenemos dos opciones: servir las imágenes a través del propio dominio (por ejemplo con next/image, a cambio de consumir cuota de optimización de Vercel) o declararlo con transparencia. Elegimos lo segundo por ahora: Sanity ya era encargado del tratamiento y ahora la política dice exactamente qué recibe.

Prueba 2: cookies

terminalsh
curl -sI https://codigoagente.vercel.app/ | grep -ci "set-cookie"
# 0

El sitio público no instala cookies ni usa localStorage (lo confirmamos buscando document.cookie, localStorage y cookies() en src/). Pero la política de cookies decía otra cosa: describía un banner de consentimiento que no existe, cookies de AdSense que nunca se activaron y dejaba huecos como [PROVEEDOR PENDIENTE].

Política de cookies de codigoagente antes y después: el inventario pasa de proveedores pendientes y AdSense a declarar que no hay cookies y que las imágenes vienen de cdn.sanity.io
Arriba, la política generada con plantilla; abajo, la que describe lo que el sitio hace hoy · codigoagente

Corrección: reescribimos src/app/(es)/cookies/page.tsx con un inventario real (páginas y fuentes desde Vercel, imágenes desde Sanity, sin analítica ni publicidad) y explicamos por qué no hay banner. Si mañana se añade analítica, la página ya dice que se pedirá consentimiento antes.

Prueba 3: la política de privacidad

El mismo problema, más grave porque la LOPDP (art. 12) obliga a informar con lealtad y transparencia. La versión anterior hablaba de "analítica agregada" y "publicidad mediante Google AdSense" con base en el consentimiento, de un banner y de conservar logs "un máximo de [N] días".

Política de privacidad antes y después: desaparecen AdSense, la analítica y el plazo sin rellenar; aparecen los proveedores reales Vercel y Sanity
Secciones de finalidades, encargados y conservación, antes y después · codigoagente

Corrección en src/app/(es)/privacidad/page.tsx:

  • Datos tratados: solo los técnicos de la conexión y los correos que recibimos.
  • Proveedores con nombre: Vercel (alojamiento), Sanity (contenido y CDN de imágenes) y el reenvío de correo del dominio.
  • Plazo concreto para atender derechos: 15 días, el que fija la LOPDP.
  • Reclamo ante la Superintendencia de Protección de Datos Personales.
  • Compromiso de actualizar la política antes de añadir analítica, publicidad o formularios.

También quitamos el "[N] días laborables" de la página de contacto y la mención a "espacios publicitarios" de los términos, porque el sitio no muestra anuncios.

Prueba 4: enlaces de afiliado

La guía de Paymenter enlaza a Contabo con enlace de afiliado. El sitio ya marcaba esos enlaces con rel="sponsored" para Google y mostraba una caja "Herramientas mencionadas" con la divulgación, pero al final del artículo. El lector que pulsaba el enlace del tercer párrafo no había visto ningún aviso, y la FTC pide la divulgación cerca del enlace.

Corrección 1: un aviso al principio de cada artículo que tenga afiliados.

Aviso de enlaces de afiliado al inicio de un artículo de codigoagente, debajo del índice de la guía
El aviso aparece solo en los artículos con enlaces de afiliado · codigoagente

Corrección 2: una marca «afiliado» junto a cada enlace pagado dentro del texto.

Antes y después de un enlace a Contabo dentro del texto: después lleva la marca afiliado a su lado
El mismo párrafo antes y después · codigoagente

El cambio está en src/components/organisms/post-body.tsx: el componente que pinta los enlaces de Portable Text ya sabía si un enlace era sponsored, así que basta con añadir la etiqueta al lado:

src/components/organisms/post-body.tsxtsx
link: ({ value, children }) => {
  const href: string = value?.href ?? "#";
  const external = href.startsWith("http");
  const sponsored = Boolean(value?.sponsored);
  const rel = sponsored ? "sponsored noopener noreferrer" : "noopener noreferrer";
  return (
    <>
      <a href={href} {...(external ? { target: "_blank", rel } : {})}>
        {children}
      </a>
      {sponsored ? (
        <span className="ml-1 rounded border px-1 align-middle font-mono text-[0.7em] text-muted-foreground no-underline">
          {affiliateMark}
        </span>
      ) : null}
    </>
  );
},

El texto de la marca y del aviso sale del diccionario src/lib/i18n.ts, así que en inglés aparece «affiliate». El aviso superior se añade en src/components/templates/post-template.tsx cuando el artículo tiene affiliateLinks.

Lo que queda pendiente (y por qué no lo arreglamos solos)

Una auditoría honesta también deja por escrito lo que no se cierra en el código:

  1. Datos del responsable. La LOPDP (art. 12, numeral 8) pide informar domicilio, teléfono y correo del responsable del tratamiento. codigoagente es una marca anónima y hoy solo publica el correo y la ciudad. Cumplirlo sin exponer a una persona pasa, por ejemplo, por operar el blog desde una empresa o con una dirección comercial. Es una decisión de negocio, no de código.
  2. Políticas en inglés. Las páginas legales solo existen en español y el pie del sitio en inglés lo avisa. Para lectores de EE. UU. y la UE conviene tener una versión en inglés.
  3. Imágenes desde el CDN de Sanity. Está declarado, pero si el sitio crece con lectores en la UE, servirlas desde el propio dominio elimina la cuestión de raíz.
  4. Contenido escrito con IA. El AI Act obliga a avisar del texto generado con IA que se publica para informar sobre asuntos de interés público, salvo que pase revisión humana con responsabilidad editorial. Este blog es técnico y se revisa antes de publicar, pero una nota sobre cómo se escriben los artículos suma transparencia.

Resumen de cambios

RiesgoNorma¿Aplica?CambioArchivo
Fuentes de GoogleRGPDSíYa cumplía con `next/font``src/app/layout.tsx`
Imágenes de tercerosRGPD / LOPDPSíDeclarado en privacidad y cookies`privacidad/page.tsx`, `cookies/page.tsx`
Política que no coincide con la realidadLOPDP art. 12SíReescrita`privacidad/page.tsx`, `cookies/page.tsx`
Huecos en contacto y términosLOPDPSíPlazo de 15 días, sin publicidad`contacto/page.tsx`, `terminos/page.tsx`
Afiliados sin aviso cercaFTCSíAviso arriba y marca junto al enlace`post-body.tsx`, `post-template.tsx`, `i18n.ts`
MenoresCOPPA / LOPDP art. 21No——
Grabación de sesionesCIPANo——
Emails de marketingCAN-SPAM / LCE art. 50No——
SuscripcionesROSCA / ARL CaliforniaNo——
Contenido de usuariosDMCANo——

Antes de subir los cambios pasamos pnpm lint y pnpm build sin errores, y comprobamos en un servidor local de producción que el aviso y las marcas aparecen solo en los artículos con afiliados.

Preguntas frecuentes

¿Cuánto se tarda en hacer una auditoría así?

Para un blog como este, el inventario y las pruebas con curl llevan menos de una hora. Las correcciones de código, otra hora. Lo que más tiempo lleva es decidir los pendientes que no son técnicos.

¿Puedo usar el mismo prompt en mi proyecto?

Sí, es el de la primera parte. Lo importante es el paso 1: que Claude haga el inventario antes de tocar nada y te pregunte lo que no puede deducir.

¿Por qué no añadir un banner de cookies "por si acaso"?

Porque un banner sin cookies que gestionar confunde al lector y obliga a mantener un componente más. Si no hay cookies no esenciales, lo correcto es decirlo en la política.

Conclusión

La mayoría de los problemas no eran técnicos sino de coherencia: páginas legales generadas desde una plantilla que describían un sitio que no existe. Las correcciones fueron pequeñas: dos políticas reescritas, dos huecos eliminados y un aviso de afiliado donde el lector lo ve. Si tu proyecto está hecho con IA, empieza por el inventario de la primera parte y revisa tus propias páginas legales con la misma lupa.

// kit para agencias

¿Haces webs para clientes con Claude Code?
5 skills que preparan la propuesta, crean la web, la revisan antes de entregarla y auditan la de tus prospectos, con una guía de 24 páginas probada en un caso real. Lo vende Safe Build Labs, la agencia que patrocina codigoagente.

// implementación

¿Necesitas implementar esta automatización en tu negocio?
No pierdas semanas configurando servidores, APIs y agentes. Safe Build Labs, la agencia que patrocina codigoagente, lo construye por ti, listo para producción.
Probamos mcp-builder, la skill de Anthropic para crear servidores MCP: hicimos uno para una tienda en 99 segundos por 0,25 USD y hallamos dos fallos de versión.
  • Skills para tus agentes
  • Claude Code
leer artículo
Probamos webapp-testing, la skill oficial de Anthropic que prueba tu web local con Playwright: instalación, with_server.py, dos trampas reales y cuánto cuesta.
  • Skills para tus agentes
  • Claude Code
leer artículo
video-shotcraft es una skill Apache-2.0 con 150 planos para que Claude Code haga el vídeo promo de tu web en Remotion. Cómo funciona y cuánto cuesta.
  • Skills para tus agentes
  • Claude Code
leer artículo