Diez mil estrellas y un solo commit

El 14 de julio xAI publicó el código fuente de Grok Build bajo licencia Apache 2.0, y esta mañana el repositorio ya pasaba de diez mil estrellas. La publicación llegó después de una prueba a nivel de red que detectó que la versión 0.2.93 de la herramienta subía un repositorio rastreado, con todo su historial de git empaquetado en un bundle, a un almacenamiento en la nube controlado por xAI, incluido un repositorio que al asistente se le había ordenado no leer. Cubrimos ese hallazgo el 14 de julio, y la instrucción entonces fue rotar todos los secretos que la herramienta hubiera visto alguna vez. Esa instrucción sigue en pie.

Publicar el código parece la respuesta más contundente posible a un hallazgo así. Es lo que hace una organización de ingeniería cuando cree que el registro la exonera, y así se está leyendo. Por eso la pregunta útil no es si xAI acertó al publicar. Es más estrecha y más práctica: si usted entrara hoy en ese repositorio para quedarse tranquilo sobre lo que la herramienta hizo en sus máquinas, ¿qué podría establecer realmente?

Muy poco, según resulta, y las razones son estructurales más que siniestras. El repositorio tiene un solo commit, cuyo autor es un bot, fechado el 16 de julio a las 05:46 UTC, con el mensaje de que publica el harness y la TUI como código abierto. Un commit significa que no hay historial. No hay un antes, no hay diff, no hay secuencia de cambios, no hay nada con lo que comparar. Diez mil estrellas en un repositorio sin historial son diez mil personas respaldando un gesto.

Lo que el repositorio no puede contarle

Empiece por la única pregunta que el hallazgo planteaba de verdad: ¿adónde fue el código? Las subidas iban a un bucket de Google Cloud Storage cuyo nombre figura en el binario distribuido. En el código fuente publicado ese nombre no aparece. Se lee de una variable de entorno de tiempo de compilación, que se resuelve al construir el binario. Quien compila la versión pone el destino, y el código fuente calla sobre a qué apuntaba la compilación que se distribuyó. El código publicado no puede responder a la pregunta, ni en un sentido ni en el otro.

Fíjese ahora en la función que hacía las subidas. Sigue ahí, en el crate del shell, y ya no hace nada. Toma sus parámetros, los marca como no utilizados, espera en el canal, tira el resultado y devuelve un fallo que avisa de que la subida del estado de sesión no está disponible. Le han quitado el cuerpo y han dejado todo lo de alrededor: los puntos de llamada están intactos, el manifiesto sigue listando las dependencias, las funciones auxiliares de almacenamiento se siguen compilando dentro. Lo que se puede leer es el esqueleto del mecanismo sin el mecanismo.

Es además la segunda vez que el arreglo se hace en un sitio que usted no puede inspeccionar. Las subidas originales se cortaron el 13 de julio con un flag en el servidor, no con una versión del cliente, y ese fue el punto más incisivo de la primera historia: el binario que su equipo revisó y fijó nunca fue lo que decidía qué salía de la máquina. Ahora el código es público, el destino sigue siendo una entrada de tiempo de compilación y el interruptor sigue en el servidor. La superficie auditable y la superficie que decide no se han acercado ni un paso.

Cuatro archivos se mudaron, uno no llegó

Hay un detalle más, y conviene enunciarlo con cuidado porque se presta a leer de más. Las cadenas del binario 0.2.93 distribuido nombran un crate llamado xai-data-collector, con cinco archivos fuente: el cliente de almacenamiento, la capa de almacenamiento en la nube, la cola, un observador de circuit breaker y un rastreador de acceso a archivos. El repositorio publicado no contiene ningún crate con ese nombre. El mismo conjunto de archivos vive en un crate llamado xai-file-utils, y cuatro de los cinco se corresponden. El quinto, el rastreador de acceso a archivos, no está en el código fuente publicado en absoluto.

Lo que eso establece y lo que no establece es justo la cuestión. No establece intención. Renombrar un crate que decía recopilar datos por otro que dice manejar archivos es exactamente lo que hace un equipo en la limpieza previa a una publicación, y retirar un módulo que ya no está conectado a nada es mantenimiento corriente. Aquí no hay pruebas de ocultamiento y no estamos alegando ninguna. Conviene señalar además la asimetría de la propia evidencia: el lado del binario descansa en la extracción de cadenas de un tercero, mientras que el lado del código fuente lo puede verificar cualquiera que clone el repositorio.

Lo que sí establece es que la publicación no puede funcionar como registro. El componente cuyo nombre describe de la forma más directa el seguimiento del acceso de un usuario a sus archivos no está, sus hermanos están presentes bajo otro nombre, y no hay historial de commits en el que examinar ninguna de las dos cosas. Las explicaciones inocentes y las culpables producen un repositorio idéntico. Ese es el problema de tratar una publicación como una prueba: solo sirve si el artefacto distingue entre las dos, y este no distingue.

La afirmación que nunca se hizo

Hay que reconocerle el mérito al investigador, porque la disciplina de ese lado de la historia es la razón de que se sostenga. El análisis a nivel de red se hizo con un proxy de interceptación sobre un binario fijado, en un repositorio desechable sembrado de archivos canario, y es reproducible: hay un harness público y cualquiera puede ejecutarlo. La medición fue rotunda. Un repositorio de doce gigabytes generó 5,10 gibibytes de tráfico de subida frente a 192 kilobytes de conversación real con el modelo, una proporción cercana a veintiocho mil a uno. El archivo canario que al asistente se le dijo que no leyera salió intacto del bundle capturado.

Y después el investigador dejó por escrito lo que la prueba no demostraba. Que subir no es entrenar, porque solo se midió la transmisión. Que una captura de tres gigabytes no se conservó. Que una conclusión anterior era errónea, porque una lectura de red limitada al ámbito del proceso pasó por alto subidas que iban directas a direcciones de Google, y esa conclusión se retiró. Un hallazgo que publica sus propios límites y su propia retractación es un hallazgo que usted puede usar.

Compare eso con las respuestas. xAI ha dicho que la privacidad le importa profundamente, que respeta la elección del cliente y que, para los equipos con retención cero de datos, no se conserva nunca ningún rastro ni ningún dato de código. Elon Musk dijo que todos los datos de usuario subidos hasta ahora se borrarán completa y absolutamente, y que no quedará absolutamente nada. Puede que sea cierto. Nada de ello es comprobable, y el borrado no se puede verificar desde fuera. El patrón de todo el episodio es constante: las afirmaciones que se pueden poner a prueba vinieron de quien tenía el proxy, y las que no, del proveedor.

Tres preguntas antes de darlo por resuelto

La lección generalizable no tiene nada que ver con xAI, y hará falta otra vez antes de que acabe el mes. Abrir el código se ha convertido en la respuesta estándar a un hallazgo de seguridad, y es una buena respuesta cuando el artefacto aporta evidencia. No lo es de forma automática. Así que cuando un proveedor responda con código publicado a un hallazgo sobre sus datos, hágale tres preguntas antes de cerrar el ticket.

¿Puedo ver el historial? Un commit inicial aplastado es una fotografía, no un registro. Si el repositorio empieza el día de la publicación, no puede mostrar qué cambió, y lo que se investiga es precisamente un cambio. ¿Se corresponde el artefacto publicado con el binario distribuido? Si algún comportamiento que importa se fija en tiempo de compilación o vive en un servidor, el código fuente describe una posibilidad, no lo que se ejecutó en sus máquinas. ¿Contiene el código el componente que nombraba el hallazgo? Si lo concreto que se encontró no está en el repositorio, su ausencia no es una respuesta, sea cual sea la causa.

Nada de esto aboga por mantener el código cerrado, y nada de esto es una acusación. Aboga por una distinción que su proceso de compras seguramente todavía no traza: publicar es un acto de divulgación, y una auditoría es un proceso que produce una conclusión. No son sustitutos, ni siquiera son parientes cercanos, y un proveedor que ha hecho lo primero no ha hecho lo segundo. Los equipos que tratan un enlace a un repositorio como caso cerrado cometen un error de categoría, y es de esos errores que solo se ven en retrospectiva, después del siguiente hallazgo.