Esta es la versión larga de cómo reconstruimos dsti.school y de por qué una pequeña escuela de ingeniería selectiva, ubicada en la Riviera Francesa, terminó escribiendo su propia cadena de build de un sitio estático, su propio validador de schema.org y su propio motor de geolocalización en el edge. La versión corta cabe en una frase: gran parte de lo que parece marketing es en realidad ingeniería, y gran parte de la ingeniería solo cobra sentido cuando se entiende para qué sirve. Por eso este artículo presenta ambas cosas: los sistemas, completos, y las razones que los sustentan.
Dos esfuerzos avanzan en paralelo a lo largo de esta historia. Uno corresponde a dieciocho meses de construcción de una red mundial de socios, viajando y trabajando con una institución a la vez. El otro son tres semanas de reconstrucción completa del sitio web. Parecen no tener relación. Sin embargo, forman parte del mismo proyecto: un esfuerzo sostenido por ganar la confianza de una familia en una escuela de la que muchas veces nunca ha oído hablar, en un país que rara vez figura entre sus primeras opciones. El sitio web continúa ese esfuerzo mientras todos duermen, así que tiene que estar a la altura.
01Por qué existe: una red, no un mercado nacional
Antes de escribir una sola línea de código: el sitio web se reconstruyó debido al origen real de nuestros estudiantes. Durante los últimos dieciocho meses, la red de socios consejeros de estudios en el extranjero de DSTI pasó de unas cuantas decenas de relaciones a 92 socios aprobados en 78 países y territorios. Ese crecimiento ocurrió en persona —ferias, visitas a campus, conversaciones largas— y cambió lo que el sitio web debe hacer. Ya no es un folleto para personas que ya nos conocen. Cada vez más, es el primer encuentro serio que un futuro estudiante de Lagos, La Paz, Hanói o Bogotá tiene con la escuela, desde un teléfono, con una conexión irregular y en un idioma que quizá no sea el suyo.
Ese solo hecho determina casi todas las restricciones técnicas que siguen: el sitio debe ser rápido en dispositivos móviles, legible para las máquinas tanto como para las personas, estar disponible en más de un idioma, cada uno tratado como un idioma de pleno derecho y ser imposible de publicar si está roto, porque rara vez habrá alguien despierto para detectarlo. Ninguna de estas decisiones es estética. Son consecuencias de quién está al otro lado.
02La apuesta: el oficio como única forma de competir en igualdad
Somos una institución pequeña. No tenemos un nombre famoso ni un presupuesto enorme, y no vamos a adquirir ninguno de los dos este trimestre. Lo que un equipo pequeño sí puede controlar es la calidad de lo que realmente publica. Por eso, la apuesta de la reconstrucción fue deliberadamente clásica: resolver el problema con mejor ingeniería. Hacer que el sitio sea más rápido, más limpio, más preciso y más legible para las máquinas que los de escuelas cien veces más grandes, porque esta competencia se decide por el cuidado y la disciplina, no por el gasto.
También por eso la reconstrucción creó un ciclo de mejora acumulativa en lugar de un rediseño aislado. Cada propiedad de calidad que buscábamos —velocidad, validez, legibilidad automática— se convirtió en algo que el build puede comprobar en cada versión, para mantener el estándar sin depender de que alguien recuerde hacerlo.
03Velocidad, porque los milisegundos cuentan en el reclutamiento
Un futuro estudiante con una conexión inestable en una zona de gran altitud no espera a que cargue una página lenta: se va. Por eso nos medimos en dispositivos móviles, donde realmente importa, frente a las escuelas de ingeniería más famosas del mundo; no para afirmar que enseñamos mejor, sino para establecer un orden de magnitud técnico.
Una captura rápida puede ser cuestión de suerte; un sitio rápido de forma constante es ingeniería. Las tres métricas que realmente utilizan los Core Web Vitals de Google —la rapidez con que aparece el contenido principal, la velocidad de respuesta de la página a una interacción y cuánto se desplaza visualmente durante la carga— se encuentran dentro de la categoría «buena», y el build mantiene ese nivel en cada versión. El HTML pregenerado en S3 detrás de un CDN elimina por completo el renderizado por solicitud; además, utilizamos imágenes AVIF, indicaciones de precarga específicas, una ruta crítica deliberadamente ligera y una optimización que merece destacarse porque parece trivial, pero no lo es.
La continuación en V308: eliminar trabajo evitable antes de cambiar la arquitectura
La primera versión posterior a la reconstrucción aún mostraba una advertencia intermitente de Lighthouse en nuestro propio runtime: un controlador de desplazamiento podía escribir la barra de progreso de lectura y después pedir al navegador una geometría actualizada de las secciones durante el mismo ciclo. V308 reorganizó ese flujo alrededor de un solo requestAnimationFrame: la altura del encabezado sticky y las posiciones de las secciones se almacenan en caché, la geometría se lee una sola vez y las clases de progreso o estado activo se escriben después. La misma versión colocó las hojas de estilo enlazadas antes de los bloques JSON-LD extensos en las páginas mantenidas, las páginas generadas y los flujos de build de los materiales, preservando el orden de las hojas de estilo. Fue deliberadamente la opción conservadora: sin separar el CSS crítico, sin trucos de carga asíncrona de hojas de estilo y sin una nueva cascada que demostrar.
La primera ejecución móvil de laboratorio después del despliegue reflejó el cambio sin fingir que una sola prueba equivale a datos de campo: First Contentful Paint se mantuvo en 0.9 s; Largest Contentful Paint pasó de 2.9 s a 2.7 s; Total Blocking Time bajó de 190 ms a 30 ms; Speed Index pasó de 1.1 s a 0.9 s; y Cumulative Layout Shift se mantuvo en 0. La ruta crítica máxima medida se redujo de 159 ms a 98 ms. Lighthouse todavía reporta correctamente una solicitud que bloquea el renderizado —la hoja de estilo reducida de 19.5 KiB de la página— porque preferimos un primer renderizado predecible a eliminar una advertencia a cualquier costo.
Una hoja de estilo por página y por qué es difícil
La forma habitual de construir un sitio es utilizar una gran hoja de estilo compartida, lo que hace que cada página descargue, analice y aplique miles de reglas que nunca usará. Nosotros hacemos lo contrario: cada página entrega una hoja de estilo reducida a las reglas que realmente necesita. Menos datos que enviar y menos trabajo para el navegador antes de poder mostrar el contenido. El problema es que no se puede depurar únicamente a partir de lo que aparece en el HTML de la página.
La versión ingenua —«elimina cualquier regla cuyo selector nunca aparezca en esta página»— rompe el sitio de forma silenciosa, porque las clases más importantes ni siquiera están en el HTML guardado. JavaScript las añade en tiempo de ejecución: un menú se vuelve open al tocarlo, un encabezado se vuelve sticky y scrolled al desplazarse, un cuadro de diálogo pasa a active, el banner de cookies alterna consent y un elemento se vuelve selected o loading. Si se eliminan esas reglas «no utilizadas», todas las interacciones pierden su estilo. Por eso el optimizador conserva una lista permitida deliberadamente conservadora de estos marcadores de estado dinámico y nunca los elimina. Hay otras tres dificultades: los selectores no se leen de izquierda a derecha (:is(), :where() y :has() anidan otros selectores, por lo que la coincidencia es recursiva); las reglas precedidas por @ se dividen en dos tipos (@media/@container envuelven reglas y deben recorrerse, mientras que @font-face/@keyframes se referencian por nombre y se mantienen opacas); y parte del CSS moderno que realmente utilizamos —consultas de contenedor con container-type y unidades cqi— es tan reciente que el propio validador HTML/CSS lo reporta como una propiedad que «no existe». El pipeline conserva estos casos como falsos positivos conocidos y revisados. Como eliminar CSS es riesgoso, cada página con CSS reducido se vuelve a comparar con la original mediante un verificador independiente antes de publicarse.
04Alcance: tres idiomas con la misma prioridad
El sitio nació bilingüe: inglés y francés. El español (es-MX) es la incorporación más reciente, y conviene explicar la lógica porque se trata de una decisión de negocio, no de un ejercicio de traducción. El español es el idioma que abre un continente entero: una sola edición da acceso a toda América Latina, excepto Brasil, mientras que cada uno de los muchos idiomas de Asia abriría solo una parte. Por eso el español merece su lugar no por ser, en abstracto, el «segundo idioma de los negocios», sino por el alcance excepcional que ofrece una sola versión lingüística.
hreflang recíprocos para que los motores de búsqueda entreguen la versión correcta; las URLs nunca se traducen automáticamente. El siguiente capítulo explica con más detalle los gemelos legibles para máquinas.Lo esencial es que los idiomas no se organizan como un sitio principal al que se le añadieron traducciones. Cada uno es un destino de pleno derecho producido a partir de una sola fuente, con reciprocidad hreflang correcta, un x-default y una lista estricta de elementos que no deben traducirse: nombres de programas, marcas, nombres de certificadores y campus, y nombres de modalidades de estudio; todo lo que debe permanecer idéntico en cada idioma para seguir siendo fácil de encontrar y correcto.
La gobernanza de traducción se convirtió en parte de la memoria del build
La traducción al francés del relato largo de Team DSTI hizo visible una distinción importante: una buena guía de traducción necesita tanto reglas normativas como la evidencia que las produjo. Desde V308, el paquete de continuidad incluye una autoridad de traducción mantenida, junto con archivos de procedencia separados para francés y español mexicano. La autoridad establece lo que debe preservarse —identificadores, URLs, nombres oficiales de programas y modalidades de estudio, atribución de la primera persona, marcado y significado legible para máquinas—. Los archivos de procedencia registran cómo se expresa de forma natural el contenido público en cada idioma: francés internacional neutro con vous; español mexicano profesional con tú; convenciones numéricas distintas; terminología recurrente; controles de falsos amigos y variantes propias de España.
Esos archivos no son notas sueltas. Son elementos obligatorios del paquete curado para el siguiente modelo y forman parte de su orden de lectura, sumas de verificación, manifiestos y reporte de estructura. Así, un futuro traductor —humano o modelo— recibe no solo la regla, sino también su procedencia y el vocabulario de QA necesario para comprobar el resultado. La localización se convierte en otra superficie de ingeniería reproducible, en lugar de depender de la memoria de quien haya traducido la última página.
05Legible para las personas y para las máquinas
Por primera vez en la historia de la web importan dos tipos de lectores: las personas y los sistemas de IA que cada vez responden más a sus preguntas. Una escuela que desea ser descubierta debe ser legible para ambos, así que cada página contiene más de lo que se ve.
llms.txt entregan a los sistemas de IA una copia clara y sin ambigüedades. No estamos adivinando cómo ser citados: lo exponemos de forma explícita.El HTML visible está destinado a las personas y a los rastreadores; schema.org JSON-LD indica con precisión a las máquinas qué es un programa, una colegiatura o una fecha; un gemelo Markdown fiel de cada página y un índice llms.txt entregan a los sistemas de IA una copia clara y sin ambigüedades. Cuando un futuro estudiante pregunta a un asistente «¿dónde puedo estudiar data engineering en Francia, en inglés?», los sistemas que responden leen datos estructurados y texto limpio, no intentan interpretar una página bonita. La mayoría de las instituciones no ha publicado versiones de sí mismas legibles para máquinas. Nosotros sí.
El control de schema.org es nuestro y no hace trampa
Conviene precisar dos aspectos. Primero, ese validador de schema.org es desarrollado internamente. El vocabulario es público y existe un verificador interactivo en la web, pero no hay una herramienta que pueda ejecutarse sin supervisión dentro de un build como ocurre con el validador HTML. Por eso escribimos un verificador específico que obtiene el vocabulario oficial de schema.org y reproduce, página por página y sin intervención humana, lo que mostraría el Schema Markup Validator en línea. Segundo, y más importante: nunca buscamos un resultado superficial de «cero errores, cero advertencias» eliminando marcado. schema.org es deliberadamente un vocabulario abierto, así que una propiedad que no declara formalmente genera una advertencia, no un error. La forma fácil de silenciar esas advertencias es eliminar los campos correspondientes, lo que también elimina significado. En cambio, los errores bloquean la versión por completo, mientras que las advertencias se revisan y se conservan cuando el marcado es realmente correcto y útil. Validamos la estructura sin amputarla.
llms.txt válido. La página de inicio de DSTI supera las tres: un resultado claro de 3/3. Google todavía indica que no utiliza llms.txt para Search, y la categoría está abiertamente «en desarrollo», por lo que no es un trofeo de clasificación; es la señal más clara hasta ahora de que las plataformas avanzan hacia páginas preparadas para lectores automáticos antes de que sea obligatorio. No predijimos esa auditoría. Simplemente ya la superábamos.06Construido para no romperse
Estático no significa frágil; cuando se hace correctamente, significa lo contrario. Todo el sitio es HTML prerenderizado en almacenamiento de objetos, bloqueado para que solo pueda servirse mediante el CDN, con un firewall de aplicaciones web, protección DDoS administrada en el edge y DNS al frente. No existe un servidor de aplicaciones que pueda fallar a las 2 a. m., porque no hay servidor de aplicaciones.
La única migración realmente delicada fue el comportamiento de las URLs. La configuración anterior dependía de la lógica try_files de un servidor web para asociar URLs limpias, sin extensión, con archivos; el nuevo edge tuvo que reproducirla mediante una pequeña función de CDN y manejar la particularidad de que un origen bloqueado devuelve un estado distinto del esperado cuando falta un objeto. Conseguir que esa lógica de reescritura fuera exacta —para que todos los enlaces antiguos resolvieran correctamente y nada produjera un 404 por accidente— ocupó la mayor parte del trabajo verdaderamente minucioso de esas tres semanas, junto con un mapa de redirecciones desde los sitemaps del sitio anterior hacia la nueva estructura.
07Validez demostrable: nueve controles y la negativa a publicar
Esta es la parte que más sorprende. El sistema se niega a publicar una versión que no supera sus propias comprobaciones. No se trata de una recomendación de «ten cuidado al desplegar», sino de una máquina que no permite que una página rota o sin validar llegue al entorno público. En esencia, la publicación es una máquina de estados finitos.
Nunca se publica algo parcial: cuando falla un control de validación, el sistema vuelve a un candidato conservado, y una versión puede revertirse a una versión anterior etiquetada. Los controles bloqueantes, en orden, son: build (esbuild analiza y minifica cada archivo externo .js y .css, mientras el minificador HTML se ejecuta con la minificación de JavaScript inline expresamente desactivada para que ningún script sea reescrito) → VNU HTML y CSS (la salida debe estar vacía) → validez del JavaScript inline (cada <script> ejecutable, controlador on* y URL javascript: debe poder analizarse) → preservación exacta byte por byte del JavaScript inline durante la minificación → optimización conservadora del CSS por página (solo reescrituras incluidas en la lista permitida, con equivalencia demostrada para cada página) → validez JSON-LD / schema.org → prueba de reconstrucción idéntica byte por byte → autoridad de versión entre fuentes (cinco documentos deben coincidir en la versión activa) → publicación, con un marcador que impide el despliegue y etiquetado de versión para permitir la reversión.
# publish() — simplified; every step is a hard gate def publish(candidate): stage(candidate) # into a verified temp tree for gate in [ build, # esbuild parses/minifies every .js and .css; inline JS untouched vnu_html, vnu_css, # W3C/VNU must print nothing — HTML and CSS alike inline_js_valid, # every inline script, on-handler, javascript: URL must parse inline_js_preserve, # inline JS byte-identical, before vs after minification css_allowlist, # per-page CSS pruned; only allow-listed rewrites, proven equivalent schemaorg, # JSON-LD validates against the live vocabulary byte_identical, # published == validated source, to the byte version_authority]: # five documents agree on the active version if not gate(candidate).ok: mark("DO_NOT_DEPLOY"); keep(candidate) # retained for retry; nothing ships return Blocked aws_publish(candidate); tag_version(candidate) # transactional; rollback enabled return Published
Un control que se ejecuta en cada versión debe ser rápida. Por eso aceleramos de forma considerable la validación HTML y CSS y, lo más importante, demostramos que la ruta rápida produce exactamente los mismos veredictos que la ruta de referencia, incluso con casos de prueba deliberadamente defectuosos y rutas Unicode complicadas. La velocidad sin esa prueba sería hacer trampa; con ella, es simplemente buena ingeniería.
08El sistema completo, de principio a fin
Antes del «cómo», aquí está todo el sistema en una sola página: cada lenguaje y herramienta de la cadena que convierte una fila de una hoja de cálculo en una página servida desde el edge. Es deliberadamente políglota y lleva sus dependencias dentro del proyecto: el núcleo de Python tiene cero dependencias de terceros, y las herramientas más pesadas viajan dentro del proyecto, con versiones fijadas, tanto para Windows como para macOS. Así, cualquier computadora puede reproducir un build sin instalaciones globales.
Un orquestador Python sin dependencias de terceros dirige la cadena de herramientas: una herramienta de inventario de contenido en .NET 8, un verificador interno de schema.org en Python, el Nu Html Checker basado en Java, que valida tanto HTML como CSS, un minificador Node acompañado en la misma etapa de build por un validador de JavaScript inline y un optimizador conservador de CSS por página, además de un motor de geolocalización XML/XSD. El resultado es un sitio estático con archivos versionados mediante huellas criptográficas —cada byte queda contabilizado mediante sumas de verificación y un manifiesto por archivo— servido desde almacenamiento de objetos a través del CDN. Los dos componentes heredados que aún se están migrando son una instalación de WordPress que aporta imágenes durante el build, no en tiempo de ejecución, y un único formulario de postulación con persistencia de estado.
Un motor de contenido para todos, no solo para ingenieros
El objetivo de toda esta disciplina es que quienes no son ingenieros puedan contribuir con seguridad. La superficie de edición es una hoja de cálculo; una herramienta de inventario de contenido la lee; el orquestador Python dirige cada paso; y las puertas anteriores impiden que un colega que edita una colegiatura o una fecha publique por accidente algo inválido. El ciclo está cerrado y se verifica a sí mismo.
09Dinámico donde importa
Un sitio estático no tiene que ser inerte. Cuando realmente ayuda a una persona visitante, la página se adapta, pero mediante un pequeño motor de reglas validado, no con scripts improvisados. El enrutamiento por región, por ejemplo para enviar a una persona del sur de Asia con el representante regional adecuado, se expresa como un conjunto de reglas XML validado contra su propio XSD antes de poder ejecutarse. El mismo principio aparece en todo el build: los parámetros de despliegue también se validan contra un esquema antes de que cualquier comando pueda actuar, por lo que un destino de despliegue mal formado se detecta antes de que comience el despliegue y no a mitad del proceso. Verificar y después continuar, tanto en el edge como en el pipeline.
10Construido con IA y deliberadamente portable
Gran parte de este trabajo se construyó con ayuda de IA, pero no de la manera desechable de copiar y pegar desde un chatbot. El principio es sencillo: la memoria del proyecto vive en el proyecto, no en una conversación ni en un modelo concreto. Cada decisión importante se registra en archivos de continuidad versionados que viajan con el repositorio: uno para el contenido —versión de referencia, reglas de traducción, invariantes de UI/UX, URLs, medios y decisiones de no regresión— y otro para las herramientas —validaciones, procedimientos de AWS e incidentes conocidos—. Quien se incorpora al proyecto, sea una persona o un modelo, comienza con esos archivos y con el paquete que se verifica a sí mismo, no con el historial de chat de alguien.
Esto no es teórico: la entrega se ha probado con distintos modelos, y un segundo modelo reconstruyó de manera independiente la versión activa y verificó cada suma de comprobación antes de proponer un cambio. Desde V308, la entrega compacta es una lista permitida estrictamente seleccionada en lugar de un volcado indiscriminado de carpetas: fuente y salida mantenidas, ContentInventory activo, autoridad de traducción y evidencia específica de cada idioma, fuente de herramientas, estructura generada del paquete, manifiesto por archivo y una línea base de sumas de comprobación verificada de forma independiente. Vincular el sitio web de una escuela a la memoria de un solo proveedor de IA solo crearía una nueva dependencia y un nuevo punto único de falla, así que lo eliminamos desde el diseño. Retomar el proyecto tampoco debe costarle a un colega una semana de configuración: un solo comando comprueba las herramientas que necesita el build, instala los componentes incluidos y se niega a declararse «listo» hasta que los parámetros del proyecto se validen contra su esquema.
11Por qué el mundo y no el mercado nacional
Es razonable preguntar por qué una escuela francesa invierte tanto en el mundo y comparativamente poco en el mercado nacional. La respuesta honesta está en la naturaleza de lo que construimos. DSTI es una institución diseñada desde el primer día para el mercado internacional: un cuerpo docente deliberadamente mixto de más de 50 académicos y profesionales; una Dirección de Estudios que, en realidad, es una función operativa y de control de calidad que Francia apenas reconoce como disciplina y mucho menos valora; modalidades de estudio extremadamente flexibles; becas por mérito; programas y evaluaciones exigentes; certificaciones profesionales; y enseñanza completamente en inglés. Nada de esto está diseñado para un mercado estrictamente nacional.
Por razones estructurales —no por una cuestión de calidad— los mercados franceses de licenciatura y posgrado son en gran medida insensibles precisamente a esas características. Por eso hacemos lo más francés imaginable: exportamos. Francia es una de las grandes economías exportadoras del mundo; nosotros también. Llevamos al mundo lo mejor que Francia y DSTI pueden ofrecer, y atraemos estudiantes de calidad para que lo aprovechen al máximo.
12Con franqueza: invertir durante un año difícil
Hablemos con franqueza, porque corresponde hacerlo. El mercado de la educación superior atraviesa un momento difícil para todos. Lo estamos afrontando mejor que la mayoría, pero sería deshonesto maquillarlo: el número de estudiantes se ha mantenido estable, en lugar de crecer, desde 2024. En este contexto, mantenerse estable es algo que muchas instituciones no han logrado; pero no es crecimiento, y toda esta reconstrucción es una apuesta a que el crecimiento regrese.
La opción fácil en un año difícil es recortar y esperar. Nosotros hicimos lo contrario: invertimos en programas, personas, cuerpo docente y visibilidad internacional; la red de socios, el sitio web y los materiales. Esto fue posible gracias al respaldo paciente de nuestro Presidente y de nuestros accionistas, todos particulares, ingenieros y científicos; un apoyo que no damos por sentado.
13Para qué sirve realmente todo esto
La red en 78 países, las páginas rápidas, el marcado limpio, las versiones demostrables y los tres idiomas no son fines en sí mismos. Lo importante es para qué sirven: que una persona joven, en algún lugar al que todavía no hemos llegado, con talento y pocos recursos, tenga una oportunidad real de acceder a una educación seria, una profesión sólida y una carrera duradera. Somos una escuela pequeña y joven, sin un nombre famoso ni un presupuesto enorme. Lo que sí tenemos es la decisión de hacer el mejor trabajo posible con el mayor nivel de calidad que podamos alcanzar y, cada vez más, la ingeniería para demostrar que lo hicimos.
El resumen honesto
Una escuela pequeña resolvió con ingeniería un problema que no podía resolver gastando más: un build de sitio estático sin dependencias de terceros, completamente validado, portable entre modelos de IA, disponible en tres idiomas, rápido en un teléfono, legible para las máquinas e imposible de publicar si está roto; todo para ganar, familia por familia, la confianza necesaria para enseñar. Eso resume el artículo y todo su propósito.
Las figuras se producen a partir del build real; algunos detalles técnicos se simplifican para un público general interesado en la ingeniería. Las cifras de rendimiento son mediciones de laboratorio de las ejecuciones indicadas y no sustituyen los datos de campo.