EN

Claude reescribió el compilador de TypeScript en Rust sin que nadie leyera el código: por qué funcionó

Leo G.7 minLeer en inglés

La fachada de un edificio completamente cubierta por un andamio de caños metálicos y barandas amarillas.
La fachada de un edificio completamente cubierta por un andamio de caños metálicos y barandas amarillas.

Seguro tenés en tu proyecto una migración que venís pateando porque toca todo: cambiar la librería de fechas en doscientos archivos, pasar de un framework viejo a uno nuevo, mover la base de datos. Sabés que un agente de código podría hacer gran parte, pero no te animás a dejarlo solo con algo tan grande, porque después vas a tener que revisar cada línea.

El 7 de octubre alguien hizo eso mismo con algo mucho más grande: dejó a Claude Opus 5.5 traducir el compilador entero de TypeScript a otro lenguaje. El resultado pasa las 184.749 pruebas del original, y su autor escribió en la portada del proyecto: “nunca leí una línea de este código”. Abajo está qué pasó, qué tiene de exagerado y, sobre todo, por qué funcionó, porque la clave no fue el modelo. Fue cómo se armó el trabajo alrededor, y esa estructura la podés usar en tu próxima migración. Armarla cuesta más que escribir el código; es justamente donde tiene que ir tu tiempo.

Qué pasó

El proyecto se llama ts-rust (abre en una pestaña nueva) y es de Ping, la empresa de Theo Browne, conocido por la plantilla T3 y su canal de YouTube. Para entenderlo hace falta un poco de contexto.

El compilador de TypeScript es el programa que revisa los tipos de tu código y le da al editor el autocompletado y los subrayados en rojo. Microsoft lo reescribió en Go para TypeScript 7, y quedó varias veces más rápido que el anterior. ts-rust traduce esa versión en Go a Rust, otro lenguaje, para ver si se podía hacer todavía más rápido.

Los números, según el propio README del proyecto:

  • El primer intento fue con modelos de OpenAI (GPT-5.6 Sol y GPT-6 Astra). Durante varios meses escribieron más de 1,3 millones de líneas, gastaron el equivalente a más de 400.000 dólares en uso del modelo y nunca pasaron del 84 % de compatibilidad.
  • Después probó con Claude Opus 5.5, que no siguió el trabajo anterior: empezó de cero. Tuvo una primera versión funcionando en 10 horas.
  • En dos semanas gastó unos 24.000 dólares, entre nueve y diez veces el límite semanal de una suscripción de 200 dólares.
  • El resultado pasa las 184.749 pruebas del compilador en Go. En 60 proyectos de código abierto da exactamente los mismos errores que el original, y revisa los tipos en la mitad del tiempo.

Lo que tiene de exagerado

Antes de sacar conclusiones, conviene bajar un poco el entusiasmo, como hicieron muchos en la discusión en Hacker News (abre en una pestaña nueva).

No es un compilador nuevo: es una traducción. Lo más difícil, que es decidir cómo tiene que funcionar el compilador, ya lo había hecho el equipo de Microsoft. El modelo tenía delante el código en Go y tenía que hacer lo mismo en otro lenguaje. Un comentario lo resumió con ironía: el título justo sería “versión en Rust de la reescritura en Go del compilador de TypeScript”.

La ganancia real es chica. En un proyecto tan grande como VS Code, la revisión de tipos baja de 9,6 a 4,8 segundos; en aplicaciones medianas, el ahorro es de menos de un segundo. Y no es el más rápido: el verificador de Bun le gana en cuatro de las seis aplicaciones que midieron.

Nadie sabe si se puede mantener. El propio autor avisa: “no tengo idea de si esto va a funcionar”. Uno de los comentarios lo dijo sin vueltas: “Ahora tenés un código que nadie leyó. Suerte agregándole código nuevo”. Otro apuntó algo más fino: las pruebas cubren lo que los autores originales creyeron que hacía falta probar, y puede haber agujeros justo donde pensaron que era obvio.

Aun así, Daniel Rosenwasser, del equipo de TypeScript, escribió en la misma discusión: “Es un trabajo impresionante, y es una locura que hayan aparecido tres de estas traducciones solo en la última semana”.

Por qué funcionó

La pregunta interesante es por qué el mismo tipo de herramienta fracasó durante meses con un modelo y funcionó en semanas con otro. Una parte es el modelo. Pero el repositorio tiene documentadas las reglas con las que trabajaron los agentes, y ahí está la otra parte.

1. Una referencia que decide qué está bien

En las pruebas de software se llama oráculo a algo que, para cualquier entrada, te dice cuál es el resultado correcto. Acá el oráculo era el compilador en Go: le das el mismo proyecto a los dos y comparás. Si el de Rust da un error que el de Go no da, está mal. No hay discusión posible sobre qué es “correcto”, y el agente no tiene que adivinar nada.

2. Pruebas que nadie puede tocar

Las reglas dicen que toda prueba que pasaba tiene que seguir pasando, una por una. Si un cambio hace pasar diez pruebas nuevas pero rompe una vieja, se rechaza: “las que empiezan a pasar no compensan las que dejan de pasar”. Y los agentes tienen prohibido cambiar lo que una prueba espera como resultado. Es la trampa más común de un agente apurado: si la prueba falla, “arreglarla” cambiando lo que espera.

3. El que escribe no es el que aprueba

Cada tanda de trabajo tiene tres agentes con roles distintos: uno escribe el código, otro lo revisa por separado y un tercero busca qué se rompió. Ni el revisor ni el auditor pueden editar código. Es lo mismo que en un equipo humano: el que escribió el cambio no se aprueba a sí mismo.

4. La memoria vive en archivos

Un trabajo de semanas no entra en una conversación. Los agentes guardan el estado en dos archivos: uno con la situación actual y otro donde solo se agregan líneas, con cada decisión y cada resultado. Cuando un agente arranca de cero, lo primero que hace es leerlos.

5. Reglas sacadas de lo que salió mal

Muchas reglas tienen la fecha del problema que las originó. Un ejemplo: cuando el agente trabaja solo, tiene prohibido hacer preguntas y tiene que anotar la decisión que tomó, porque “tres preguntas frenaron todo 4,3 horas”.

El primer intento muestra qué pasa sin esto. Según la historia del proyecto, los modelos de OpenAI sumaron cientos de cambios antes de que existiera el sistema para comparar contra Go. Cuando lo armaron, había 70 pruebas fallando y el compilador era hasta 3,4 veces más lento que el original.

Cómo usar la misma idea en tu proyecto

No necesitás un compilador para aprovechar esto. Sirve para cualquier migración grande: cambiar una librería en todo el proyecto, pasar una API de un framework a otro, reemplazar consultas escritas a mano por un ORM.

1. Primero la red, después el código. Antes de que el agente toque nada, armá pruebas que registren lo que el sistema hace hoy, esté bien o mal. Se llaman pruebas de caracterización. Si migrás una API, por ejemplo, guardá las respuestas de cincuenta pedidos reales y compará contra ellas después de cada cambio. Si cambiás de librería de fechas, escribí una prueba que pase cien fechas reales de tu base por cada función de formato y guarde cómo se ven hoy, incluidas las raras: fin de mes, años bisiestos, cambio de horario. La versión vieja del código es tu oráculo.

2. Definí “terminado” con un número. “Que ande” no sirve. “Las 312 pruebas pasan y las cincuenta respuestas son idénticas” sí.

3. Que el agente no pueda tocar las pruebas. Decilo en el archivo de instrucciones del proyecto y, si usás Claude Code, bloquealo con una regla de permisos en .claude/settings.json:

{
  "permissions": {
    "deny": ["Edit(tests/**)"]
  }
}

4. Que revise otro. Abrí una sesión nueva, sin el historial de la anterior, y pedile que compare el cambio contra la versión vieja sin editar nada. Un agente que no escribió el código encuentra cosas que el que lo escribió da por buenas.

5. Guardá el avance en un archivo. Una lista de qué está migrado, qué falta y qué decisiones se tomaron. Si la sesión se corta o el contexto se llena, la siguiente arranca leyéndolo.

Alguien sí leyó: los que escribieron las pruebas

La frase “nunca leí una línea” es cierta, pero engaña un poco. Esas 184.749 pruebas las escribieron personas durante años, y cada una es una decisión sobre cómo tiene que comportarse el compilador. El autor no se saltó la revisión: la cambió de lugar. En vez de leer el código, confió en pruebas que otros ya habían pensado con cuidado.

Eso conecta con el estudio que mostró que la revisión es el nuevo cuello de botella cuando se trabaja con agentes. Si no querés leer cada línea que escribe tu agente, la salida no es leer menos: es poner ese esfuerzo antes, en pruebas que valgan la pena y en una referencia clara de qué está bien. Sin eso, lo que hizo ts-rust no es una hazaña: es una apuesta.

Comentarios