Serie: Aprender a programar con IA

El sábado en que el build dejó de discutir

Limpieza poco vistosa que hizo que el build dejara de discutir.

El build dejó de discutir Dieciocho DLL en verde en Linux, namespace estable, seguridad ante nulos aplicada 18 / 18 DLL en verde -fvisibility=hidden en todo el build de GCC /api/v2/ a /api/raku/ en todas partes verificaciones de puntero nulo en el límite de fallos silenciosos a errores ruidosos y acotados
Sin captura de pantalla. Solo permiso para lanzar durante los próximos ocho meses.

Las correcciones que no generan una captura de pantalla son las que deciden si tu runtime llega a producción. RakuAI pasó una semana eliminando los puntos débiles para que los próximos ocho meses de desarrollo nunca vuelvan a discutir con el build.

Hay una categoría de trabajo que no produce una captura de pantalla. Produce un build que se pone en verde en máquinas que antes lo ponían en rojo. Produce una ejecución de CI que deja de agotar el tiempo. Produce un stack trace que ya no se materializa porque el puntero nulo que lo causaba ahora se captura en el límite. La semana que terminó este sábado fue de ese tipo.

Dieciocho DLL en verde en Linux

El runtime se distribuye como dieciocho DLL nativas. Hasta hace dos semanas, esas DLL compilaban limpiamente en Windows, compilaban limpiamente en macOS y fallaban en Linux por un error de visibilidad de símbolos. La corrección llegó en el PR #1463 el 11 de abril.

La historia es del tipo poco vistoso. GCC hace visibles por defecto todos los símbolos en las bibliotecas compartidas. MSVC hace ocultos por defecto todos los símbolos a menos que se exporten explícitamente. El código del runtime se escribió asumiendo el comportamiento por defecto de MSVC, con __declspec(dllexport) en los símbolos que necesitaban cruzar el límite de la DLL. En Linux esas declaraciones son no-ops, lo que significa que todos los símbolos quedaban visibles, lo que significa que el enlazador no podía determinar los bindings intra-DLL correctos, lo que significa que varias de las dieciocho DLL no compilaban.

La corrección es -fvisibility=hidden como flag del compilador para los builds de GCC, con atributos de visibilidad explícitos en los símbolos que necesitan exportarse. El diff es pequeño. El radio de impacto es grande. El build de Linux es ahora un objetivo de primera clase. El agente que envía un cambio al runtime puede ahora hacerlo probar automáticamente en Linux mediante la matriz de CI. Despliegues en servidor, imágenes de contenedor, granjas de compilación en la nube: todo eso está ahora al alcance.

Este es el tipo de corrección que se siente como una deducción fiscal. No hace avanzar el producto. Pero tampoco lo bloquea más. Con eso basta.

Guardas de longitud de prompt en cada invocador de LLM

El otro commit de abril que merece registrarse es el barrido de guardas de longitud de prompt. El runtime ahora invoca a Claude en varios lugares: el cerebro de comportamiento de los NPC, el modelo de diálogo, el narrador de eventos del mundo, el sembrador de contenido procedural. Cada uno de esos invocadores construye un prompt concatenando contexto, instrucciones y el estado actual. Cada uno de esos invocadores puede producir un prompt que exceda la ventana de entrada del modelo si el contexto crece lo suficiente.

El modo de fallo ingenuo es que la llamada al LLM devuelve un error. El modo de fallo peligroso es que la llamada al LLM devuelve una respuesta truncada, el invocador no detecta el truncamiento y el motor actúa sobre una respuesta malformada. NPC que se detienen a mitad de frase. Árboles de diálogo que se bifurcan hacia la nada. Eventos del mundo que se disparan con los parámetros equivocados.

El PR #1465 añadió una guarda a cada invocador de LLM: estimar el recuento de tokens antes de la llamada, negarse a enviar si el recuento excede el presupuesto y emitir un error estructurado ante el que el invocador pueda reaccionar. El PR #1466 auditó toda la base de código para verificar que la guarda está presente en cada punto de llamada. El PR #1467 añadió documentación para que el próximo invocador conozca la disciplina.

La razón por la que esto importa es que las llamadas a IA dentro de un runtime no son ocasionales. Ocurren muchas veces por fotograma en los picos de carga. Un bug en la construcción del prompt que hace crecer un prompt en unos pocos tokens por llamada es invisible durante cien fotogramas y catastrófico en mil. La guarda hace que el fallo sea ruidoso y acotado en lugar de silencioso e ilimitado.

Estabilización del namespace de la API

El tercer commit es el más silencioso de los tres y posiblemente el más trascendente. El runtime expone una API REST para que herramientas externas, paneles de control y el SDK se comuniquen con él. Esa API ha vivido bajo /api/v2/ durante los últimos seis meses porque sucedió a un /api/v1/ anterior que era solo interno.

/api/v2/ es el nombre equivocado. Implica que la v1 fue pública y quedó reemplazada, lo cual no fue el caso. También implica que una v3 está en camino, lo cual tampoco es cierto. El PR #1464 recorrió cada referencia en la base de código y cada referencia en la documentación y renombró el namespace de /api/v2/ a /api/raku/. El nombre es ahora estable. No hay número de versión que negociar más adelante. La compatibilidad hacia atrás dentro del namespace es el contrato.

Este es el tipo de renombrado que tiene que ocurrir exactamente una vez y tiene que ocurrir antes de que cualquier desarrollador externo escriba código contra el namespace. Lo detectamos a tiempo. La próxima vez que alguien fuera del equipo escriba un script que llame a la API, verá /api/raku/ y no tendrá que rehacer su trabajo dentro de seis meses.

Seguridad ante punteros nulos como barrido

El commit más reciente en el runtime, hace dos días el 30 de abril, es 58c3a806: “fix(build): resolve all build errors, warnings, and null-pointer safety”. La frase “seguridad ante punteros nulos” hace mucho trabajo en ese título. El cambio que hay detrás es un barrido por toda la base de código en busca de cada lugar donde un puntero pudiera ser nulo y se estuviera desreferenciando sin comprobación.

El patrón que disparó el barrido fue un reporte de fallo de una de las aplicaciones de ejemplo. Un cargador de texturas recibió un puntero nulo para el manifiesto de assets, lo desreferenció y falló. La corrección fue una comprobación en el punto de entrada. La auditoría fue la pregunta: en cuántos otros lugares de la base de código aparece el mismo patrón.

La respuesta fue varias decenas. No todos eran explotables. Muchos eran rutas de código que nunca se habían activado porque el código que las invocaba nunca llegaba a pasar un nulo. Eso no es una defensa. La defensa es la comprobación en el límite.

El barrido añadió las comprobaciones. No cambió el comportamiento en la ruta feliz. Sí añadió un valor de retorno (RAKU_ERR_INVALID_PARAM) y una línea de registro para la ruta de fallo. El runtime es ahora más ruidoso en los casos que antes eran fallos silenciosos. Ruidoso es mejor que silencioso. Los fallos silenciosos en un runtime de RA son el peor tipo de bug.

Por qué este tipo de semana es el tipo correcto de semana

La tentación, cuando gestionas un proyecto de motor con una cadencia de fin de semana y una flota de agentes, es seguir lanzando funciones nuevas. Cada sábado por la mañana la cola se rellena. Cada sábado por la noche el diff es más grande de lo que era la semana anterior. La cadencia premia el avance.

La cadencia también tolera la deuda técnica. Cada PR que se fusionó durante los últimos ocho meses hizo una pequeña suposición sobre el entorno de build, la superficie de la API, la ventana de entrada del LLM o el contrato de seguridad ante nulos. Ninguna de esas suposiciones era incorrecta por sí sola. Juntas eran una lista de puntos débiles que, eventualmente, se romperían.

Una semana en la que se detiene el avance para corregir los puntos débiles no es tiempo perdido. Es la semana después de la cual los próximos ocho meses de avance pueden ocurrir sin discutir con el build, con la API, con la entrada del LLM o con el puntero nulo. La discusión es lo que desperdicia el tiempo. La discusión es lo que la limpieza terminó.

Qué sigue

Los agentes están de vuelta en la cola este fin de semana. La próxima tanda de issues es la que estoy registrando este sábado por la mañana. Ya no son issues de limpieza. Son issues de funcionalidades. El build no va a discutir con ellas.

Eso es lo que compra un build limpio. No una captura de pantalla. Permiso para lanzar.

Un runtime que se gana la confianza en lo aburrido

En verde en cada objetivo, APIs estables, fallos ruidosos en lugar de fallos silenciosos. RakuAI es el runtime espacial construido con la disciplina que exige la producción. Descubre por qué los socios construyen sobre él.

← Todas las entradas