Reescritura en Rust impulsada por IA de Bun: Manual de verificación para la migración de un millón de líneas de código
Un manual de verificación inspirado en la práctica asistida por IA de Bun al migrar de Zig a Rust, que abarca contratos de comportamiento, agentes de codificación aislados, pruebas diferenciales, pruebas difusas, revisión de código unsafe, métricas de progreso y lanzamientos seguros.

Reescritura de Bun impulsada por IA en Rust: Un manual de verificación para migraciones de millones de líneas
Introducción
El titular es difícil de ignorar: Bun supuestamente migró una implementación importante de Zig a Rust en 11 días utilizando un flujo de trabajo dinámico con Claude Code. Los relatos publicados describen miles de commits, hasta 64 agentes de Claude, aproximadamente 780.000 líneas de Rust, dos revisores adversariales por cada unidad de implementación, y una progresión desde código que no compilaba hasta un puerto que podía pasar el conjunto de pruebas y ser lanzado.
La lección equivocada es que las reescrituras de lenguajes se han convertido en tareas de un solo clic. La lección útil es que el rendimiento de implementación y el rendimiento de verificación ahora son problemas de ingeniería separados.
Los agentes de IA pueden generar código más rápido de lo que un equipo humano puede leerlo. Una vez que esto ocurre, la revisión convencional de solicitudes de extracción ya no puede servir como el mecanismo de seguridad principal. Los equipos necesitan un sistema que convierta un cambio probabilístico masivo en afirmaciones pequeñas respaldadas por evidencia verificable por máquina.
El informe de producción posterior de Bun hizo esto excepcionalmente concreto. El equipo reportó 19 regresiones conocidas, todas posteriormente corregidas; 11 rondas de revisión de seguridad; fuzzing continuo guiado por cobertura en todos los analizadores sintácticos; y aproximadamente 27.000 líneas de Rust dentro de bloques unsafe de un total de aproximadamente 780.000 líneas. Estos hechos no debilitan la historia de la migración. Muestran cómo es el trabajo de migración serio una vez que termina la impresionante demostración.
Esta guía convierte esa experiencia en un manual de verificación reutilizable. El objetivo no es copiar la escala de Bun. Es proporcionar un método para cualquier migración—puertos de lenguaje, reemplazos de frameworks, modernización de APIs, conversiones de bases de datos o refactorizaciones en todo el repositorio—donde los agentes de codificación de IA puedan escribir más código del que el equipo pueda inspeccionar responsablemente línea por línea.
Conclusiones clave
- La reescritura de Bun muestra que los agentes de IA pueden comprimir el tiempo de implementación. No muestra que se pueda eliminar el tiempo de verificación.
- El activo transferible es el sistema de migración: contratos de comportamiento escritos, mapas de riesgo, pilotos pequeños, trabajadores aislados, revisores independientes, puertas deterministas y commits recuperables.
- Los compiladores y los conjuntos de pruebas heredados detectan diferentes clases de fallos. Ninguno detecta cada desajuste semántico entre lenguajes, diferencia en modo de lanzamiento, regresión de rendimiento o límite inseguro.
- Los diffs grandes requieren revisión orientada a la evidencia. Los humanos deben inspeccionar contratos, puntos calientes de riesgo, contraejemplos, brechas de pruebas y decisiones de despliegue, en lugar de pretender que cada línea generada recibe el mismo escrutinio.
- Los equipos pueden adoptar el mismo patrón sin intentar una reescritura de un millón de líneas: requerir que los agentes demuestren el comportamiento una parte a la vez, luego otorgar mayor autonomía solo después de resultados medidos.
Lo que Bun realmente hizo—y lo que el titular omite
El relato de ingeniería comenzó antes de la generación de código a gran escala.
Jarred Sumner supuestamente dedicó aproximadamente tres horas a crear PORTING.md, que mapeaba patrones recurrentes de Zig a Rust. Un flujo de trabajo separado analizaba campos de estructuras, proponía tiempos de vida en Rust, enviaba esas elecciones a dos revisores adversariales y serializaba los resultados en LIFETIMES.tsv. Estos artefactos también fueron revisados manualmente.
El primer
Traducción
La prueba de implementación cubrió tres archivos, no todo el repositorio. Para cada archivo:
- Un agente implementó la versión en Rust.
- Dos agentes nuevos revisaron la equivalencia de comportamiento y el cumplimiento de la documentación de migración.
- Otro agente aplicó las correcciones aprobadas.
Solo después de este piloto, el trabajo se expandió a 1,448 archivos Zig.
La primera ejecución a gran escala falló. Los agentes compartían un espacio de trabajo y utilizaban comandos como git stash, git stash pop y git reset --hard. Sus cambios interferían entre sí. Luego se modificó el flujo de trabajo para prohibir comandos de coordinación inseguros y usar cuatro árboles de trabajo, cada uno con 16 agentes.
Ese detalle importa más que la tasa máxima de generación de líneas. La codificación en paralelo es un problema de sistemas distribuidos. El estado compartido, los escritores en conflicto, las operaciones globales costosas, la propiedad y la recuperación necesitan reglas explícitas.
El código generado no funcionó de inmediato. Bun utilizó los errores del compilador como una cola y avanzó un crate a la vez. En un momento, se asignaron alrededor de 16,000 errores del compilador a los agentes. El bucle usaba un corrector, dos revisores y un agente de aplicación, mientras limitaba la frecuencia con la que podían ejecutarse comandos costosos como cargo check y operaciones de Git.
Esto no fue una traducción mágica. Fue una convergencia por etapas impulsada por retroalimentación determinista.
El anuncio del flujo de trabajo dinámico de Anthropic reportó que el 99.8% del conjunto de pruebas existente pasó en el momento de la redacción inicial, señalando explícitamente que el puerto aún no estaba en producción. El artículo posterior de Bun cubrió el trabajo que siguió: revisiones de seguridad, fuzzing, regresiones en producción, correcciones semánticas y reducción de código inseguro.
Leídos juntos, las fuentes describen dos hitos diferentes:
- Implementación lo suficientemente completa para fusionar
- Evidencia lo suficientemente completa para ejecutar de manera segura
Términos que Necesitas Conocer: Puerto, Oráculo, Pruebas Diferenciales y Superficie Insegura
Estas definiciones importan porque un equipo no puede verificar una migración hasta que acuerde lo que la evidencia debe probar. También separan la declaración de confianza de un agente de un resultado verificable externamente.
Puerto
Un puerto reimplementa software en un nuevo lenguaje, tiempo de ejecución, plataforma o marco mientras preserva un conjunto definido de comportamientos.
"Preservar comportamiento" necesita un límite. Un puerto puede preservar APIs públicas y salidas mientras cambia intencionalmente la arquitectura interna, las características de rendimiento, los mensajes de error o los casos límite no soportados.
Contrato de Comportamiento
Un contrato de comportamiento es una lista explícita de propiedades que la nueva implementación debe preservar.
Puede incluir:
- Entradas y salidas
- Comportamiento de errores
- Ordenamiento
- Efectos secundarios
- Semántica de concurrencia
- Límites de recursos
- Plataformas soportadas
- Presupuestos de rendimiento
- Requisitos de observabilidad
El código existente contiene comportamiento, pero no todo comportamiento existente es intencional. El contrato separa los requisitos de los accidentes históricos.
Oráculo de Prueba
Un oráculo de prueba determina si una salida es correcta.
Una aserción de prueba unitaria es un oráculo. Una implementación de referencia, especificación de protocolo, archivo dorado, invariante de base de datos o regla creada por humanos también puede actuar como oráculo.
La guía de Anthropic sobre ejecución prolongada
La codificación científica enfatiza que el trabajo autónomo necesita referencias, objetivos medibles o conjuntos de pruebas para que los agentes puedan determinar si están progresando.
Pruebas Diferenciales
Las pruebas diferenciales envían las mismas entradas a las implementaciones antigua y nueva, y luego comparan los resultados observables.
Son especialmente útiles cuando la implementación antigua es confiable pero no existe una especificación formal completa. La coincidencia no demuestra que ambas implementaciones sean correctas, pero la discrepancia crea una cola de investigación precisa.
Pruebas Metamórficas
Las pruebas metamórficas verifican relaciones entre múltiples ejecuciones cuando es difícil escribir resultados esperados exactos.
Los ejemplos incluyen:
- Serializar y analizar un valor debería preservarlo.
- Reordenar entradas independientes no debería cambiar un resultado de tipo conjunto.
- Ejecutar dos veces una migración idempotente no debería cambiar el estado en la segunda ejecución.
- Reintentar la misma clave de idempotencia no debería producir un efecto secundario duplicado.
Superficie Insegura
La superficie insegura es código donde las garantías normales del lenguaje de destino se debilitan o eluden.
En Rust, unsafe puede ser necesario en los límites de la interfaz de funciones externas (FFI) con C o C++, dentro de asignadores personalizados, o para la integración de tiempo de ejecución de bajo nivel. El recuento bruto no es un veredicto. El equipo necesita propiedad, invariantes, pruebas y un plan explícito para cada límite inseguro.
Defecto Escapado
Un defecto escapado es un error inducido por la migración descubierto después de la compuerta que debería haberlo detectado—después de la fusión, la implementación canary, las pruebas de candidato a lanzamiento o el despliegue en producción.
Los defectos escapados son retroalimentación sobre el sistema de verificación, no solo sobre la implementación.
La Cadena Causal: Por Qué una Generación Más Rápida Requiere una Verificación Más Fuerte
El paralelismo de agentes cambia la economía de la implementación. Si 64 trabajadores traducen archivos al mismo tiempo, el tiempo de generación de código puede reducirse drásticamente. El grafo de dependencias, la semántica del lenguaje de destino y el entorno de pruebas compartido no desaparecen. El rendimiento simplemente traslada el cuello de botella a la corriente abajo.
Cuello de Botella 1: Integración
Archivos individualmente razonables pueden fallar cuando se compilan juntos.
Los aproximadamente 16 000 errores de compilación y dependencias cíclicas de crates de Bun ilustran la brecha entre la traducción local y la consistencia global. El compilador es un oráculo determinista excelente para tipos, propiedad, tiempos de vida, nombres y algunas propiedades de flujo de control. No es un oráculo para el comportamiento del producto.
Cuello de Botella 2: Equivalencia Semántica
Bun documentó errores donde el código parecía casi idéntico entre idiomas pero se comportaba de manera diferente.
Los ejemplos incluían:
- Efectos secundarios colocados dentro de
debug_assert!de Rust que desaparecen en compilaciones de lanzamiento, mientras que una aserción comparable de Zig aún evaluaba sus argumentos. - Una expresión ansiosa
unwrap_orque desencadenaba un comportamiento que debería haber permanecido perezoso. - Semánticas de segmentos de bytes y límites que diferían entre implementaciones.
- Entradas UTF-16 de longitud impar que exponían un bloqueo.
Estos son exactamente los fallos que la revisión superficial omite porque el código traducido parece plausible.
Cuello de Botella 3: Correlación de Revisión
Si el mismo modelo escribe y revisa un cambio utilizando el mismo contexto y suposiciones, puede reproducir el
error original.
La documentación de mejores prácticas de Claude Code de Anthropic recomienda utilizar un contexto de revisor limpio. El revisor ve el diff y el estándar sin heredar el razonamiento del autor. La independencia no garantiza la corrección, pero reduce el sesgo del contexto compartido.
Cuello de botella 4: Evidencia operativa
Las pruebas pueden pasar mientras la latencia se duplica, el uso de memoria crece, un objetivo del sistema operativo se rompe o la observabilidad desaparece.
Cuanto mayor es el cambio, más probable es que el equipo descubra un requisito violado solo después del despliegue. Por eso, un plan de migración debe incluir canarios, reversión, comparación de telemetría y un proceso que convierta cada defecto escapado en una nueva regla contractual o prueba.
La conclusión causal es simple:
La IA no elimina el costo de la migración. Traslada el costo de la escritura hacia la especificación, el diseño de arneses, la revisión de evidencia y el control del despliegue.
Un equipo que ignore este cambio puede terminar de generar código rápidamente y luego pasar meses determinando si la reescritura realmente funciona.
Una arquitectura de verificación para migraciones impulsadas por IA
La arquitectura tiene cuatro planos.
1. Plano de contratos
El plano de contratos almacena:
- Comportamiento público
- Promesas de compatibilidad
- Cambios intencionales
- Matriz de plataformas soportadas
- Presupuestos de rendimiento
- Restricciones de seguridad
- Requisitos de observabilidad
Los humanos mantienen este plano, y el repositorio lo versiona.
2. Plano de ejecución
El plano de ejecución contiene agentes de implementación aislados.
Cada agente recibe:
- Una unidad de migración
- Archivos fuente relevantes
- El contrato aprobado
- El mapa semántico
- Herramientas de alcance limitado
- Verificaciones específicas
El agente no puede cambiar el contrato ni las pruebas globales. Solo edita su alcance asignado y devuelve tanto un commit como evidencia.
3. Plano de verificación
El plano de verificación es independiente de la implementación.
Puede:
- Compilar el candidato
- Ejecutar pruebas específicas y globales
- Realizar comprobaciones diferenciales entre lo antiguo y lo nuevo
- Hacer fuzzing de analizadores sintácticos y límites de protocolo
- Escanear código sensible a la seguridad
- Evaluar cargas de trabajo representativas
- Pedir a revisores frescos que busquen contraejemplos
Los agentes de verificación pueden proponer pruebas, pero el CI determinista decide si una puerta se supera.
4. Plano de lanzamiento
El plano de lanzamiento controla la integración y la exposición en producción.
Este:
- Fusiona en orden de dependencias
- Produce artefactos reproducibles
- Identifica compilaciones con versiones inmutables o hashes
- Ejecuta tráfico espejo cuando es posible
- Expande canarios gradualmente
- Monitorea indicadores de nivel de servicio
- Preserva una ruta de reversión probada
We0 AI puede situarse entre estos planos como una capa de orquestación y evidencia. Los equipos pueden usar tareas para asignar fragmentos de migración, aislar árboles de trabajo, adjuntar contratos, recopilar resultados de pruebas y requerir revisión antes de que el trabajo avance.
El límite importante es que la orquestación coordina la evidencia. No convierte la afirmación de éxito de un agente en permiso de lanzamiento.
Escenario de ejemplo: Migración de un servicio de pagos de Python a Go
Considere un servicio de pagos de Python de 120,000 líneas que se migra a Go. El objetivo comercial es reducir
latencia de cola y simplificar el despliegue.
Una indicación peligrosa sería:
Reescribe este servicio en Go y haz que todas las pruebas pasen.
Esa indicación deja sin definir la semántica de transacciones, el comportamiento de errores, la precisión monetaria, la idempotencia y el despliegue gradual.
Paso 1: Redactar el Contrato
Para cada endpoint, el equipo registra:
- Esquemas de solicitud y respuesta
- Reglas de autorización
- Comportamiento de la clave de idempotencia
- Redondeo de moneda
- Semántica de reintentos
- Transacciones de base de datos
- Orden de eventos
- Códigos de error
- Requisitos de telemetría
También marca cambios intencionales, como eliminar un encabezado de depuración específico de Python. El equipo define la plataforma compatible y la matriz de dependencias, luego establece presupuestos de latencia p95 y p99, y un límite máximo de memoria.
Paso 2: Elegir Tres Fragmentos Piloto
El equipo selecciona:
- Un módulo puro de formateo de moneda
- Un repositorio de idempotencia con efectos secundarios en la base de datos
- Un endpoint HTTP de solo lectura
El primero prueba la traducción mecánica. El segundo prueba transacciones y concurrencia. El tercero prueba la compatibilidad HTTP.
Un agente de implementación maneja cada fragmento. Los revisores nuevos reciben únicamente el contrato, el código fuente antiguo, el diff propuesto y los comandos de validación.
Paso 3: Usar el Servicio Antiguo como Oráculo Diferencial
Se reproduce un corpus saneado de solicitudes históricas contra ambas versiones.
Las respuestas se normalizan solo donde el contrato permite diferencias y luego se comparan. Para las rutas de escritura, ambas implementaciones se ejecutan contra instantáneas de base de datos desechables. Se comparan las filas resultantes y los eventos emitidos.
Luego, las pruebas metamórficas:
- Repiten la misma clave de idempotencia
- Cambian el orden inofensivo de las claves JSON
- Introducen variaciones en los tiempos de reintento
- Ejercitan valores monetarios límite
Paso 4: Sombrear y Canary el Nuevo Servicio
Antes de habilitar las escrituras en producción, el servicio Go recibe tráfico sombra con escrituras deshabilitadas o redirigidas a un sumidero aislado.
El equipo compara:
- Distribuciones de latencia
- Clasificaciones de errores
- Llamadas a dependencias
- Formas de trazas
- Uso de memoria
- Comportamiento de eventos
Luego, el equipo envía un 1% de tráfico canary de un grupo de comerciantes de bajo riesgo.
La expansión requiere:
- Cero discrepancias financieras inexplicadas
- Paridad en la tasa de errores
- Latencia dentro del presupuesto acordado
- Un ejercicio de reversión exitoso
La implementación aún puede avanzar rápidamente. La seguridad proviene de transformar "reescribir el servicio" en afirmaciones observables.
Este ejemplo también muestra por qué la experiencia en el dominio sigue siendo esencial. Los agentes pueden traducir código, pero los expertos en pagos saben que los eventos duplicados, las diferencias de redondeo y el comportamiento de reintentos son requisitos comerciales.
Fase 0: Definir el Contrato de Migración y las Condiciones de Parada
Antes de que cualquier agente edite código, decide qué cuenta como el mismo producto.
Inventario:
- APIs públicas
- Comportamiento de la CLI
- Formatos de archivo
- Efectos en la base de datos
- Variables de entorno
- Telemetría
- Mensajes de error visibles para el usuario
- Plataformas compatibles
- Características de rendimiento
Marca cada propiedad como una de las siguientes:
- Conservar
- Cambiar intencionalmente
- Depreciar
- Desconocido
Los desconocidos no son permiso para adivinar. Se convierten en tareas de descubrimiento.
Ejecuta el sistema antiguo, busca en problemas y registros de cambios, inspecciona trazas de producción o pregunta a los mantenedores. El árbol fuente previo a la migración de Bun
reorganización preservó el historial de Git mediante confirmaciones de solo movimiento, haciendo que la procedencia sea un requisito intencional en lugar de un daño colateral.
Definir condiciones de parada estricta. Detener la expansión cuando:
- Las tasas de desajuste del piloto superen el umbral.
- Los trabajadores modifiquen repetidamente pruebas globales protegidas.
- La cola de errores del compilador crezca más rápido de lo que se cierra.
- El rendimiento objetivo no cumpla con el presupuesto.
- No se pueda construir un artefacto de reversión.
- La evidencia esté incompleta o sea ilegible.
Detenerse protege el proyecto de la escalada de costos hundidos.
El contrato debe controlarse por separado de la ejecución. Un agente no debe "arreglar" una prueba fallida debilitando el requisito. Los cambios en el contrato requieren una enmienda revisada por humanos que explique por qué el comportamiento anterior es obsoleto o incorrecto.
Fase 1: Construir un mapa semántico antes de la generación a gran escala
Crear mapeos explícitos para patrones comunes, sutiles o peligrosos de origen a destino.
Cubrir áreas como:
- Reglas de propiedad y duración
- Nulabilidad
- Excepciones y manejo de errores
- Desbordamiento de enteros
- Cálculos de tiempo
- Codificación de cadenas
- Primitivas de concurrencia
- Propiedad del asignador
- FFI
- Comportamiento de depuración frente a producción
- Código específico de plataforma
El PORTING.md y LIFETIMES.tsv de Bun cumplieron este propósito.
Su valor no se limitó a mejores indicaciones. Dieron a cientos de trabajadores una estrategia semántica compartida. Sin dicho mapa, cada agente inventa su propio enfoque de traducción, y la inconsistencia se convierte en un problema de integración.
Pedir a agentes independientes que ataquen el mapa:
- Dar a un revisor la semántica del lenguaje fuente.
- Dar a otro los riesgos del lenguaje destino.
- Dar a un tercero ejemplos de código representativos.
- Exigir contraejemplos concretos.
Los humanos deben inspeccionar las reglas de mayor riesgo, especialmente aquellas que involucran propiedad de memoria, concurrencia, límites de seguridad, persistencia y comportamiento solo en producción.
Versionar el mapa. Cada desajuste recién descubierto debe actualizar las reglas, identificar unidades de migración afectadas y desencadenar una revalidación dirigida.
El mapa semántico es una especificación viva, no una indicación pegada una vez al inicio.
Fase 2: Diseñar pilotos deliberadamente difíciles
No elegir solo los archivos más fáciles.
Un piloto útil incluye tres formas:
- Una unidad simple y representativa
- Una unidad con muchas dependencias
- Un punto crítico semántico
Bun utilizó tres archivos para validar el ciclo de implementación-revisión-corrección antes de traducir 1,448 archivos. El número exacto importa menos que la gama de modos de fallo cubiertos.
Medir el proceso del piloto, no solo su resultado:
- ¿Respetaron los trabajadores la propiedad del archivo?
- ¿Fueron atómicas las confirmaciones?
- ¿Encontraron los revisores defectos reales o produjeron principalmente ruido?
- ¿Pudo el corrector aplicar sugerencias sin violar el contrato?
- ¿Seguía siendo legible la evidencia?
- ¿Cuánto contexto y cómputo consumió cada unidad aceptada?
Sembrar fallos deliberadamente. Añadir una diferencia sutil en modo de producción, un accesorio de caso límite o un umbral de rendimiento y confirmar que el sistema de verificación lo detecta.
Un arnés que solo ha pasado ejemplos limpios aún no ha sido probado.
La expansión debe comenzar solo cuando el piloto produzca evidencia estable y repetible. Si las indicaciones, modelos o políticas de herramientas cambian sustancialmente después, volver a ejecutar el piloto pequeño. Flujo de trabajo
La configuración es código de producción y merece pruebas de regresión.
Fase 3: Expansión con Aislamiento, Propiedad y Commits Atómicos
Cree unidades de migración alineadas con el grafo de dependencias.
La partición a nivel de archivos es conveniente, pero puede ser el límite incorrecto cuando el comportamiento cruza módulos. Asigne un escritor por unidad y haga que la propiedad sea legible por máquina. Los trabajadores pueden leer dependencias, pero solo pueden editar su ámbito a menos que soliciten un cambio coordinado.
Utilice árboles de trabajo separados, contenedores o máquinas virtuales efímeras cuando sea práctico.
El fallo del espacio de trabajo compartido de Bun demuestra por qué. Restrinja comandos destructivos de Git y comandos de compilación global costosos para los trabajadores hoja. Permita que un coordinador realice la integración ordenada.
Las credenciales de corta duración y las listas de permisos de red reducen el impacto de la inyección de comandos o la exfiltración de dependencias. La guía de aislamiento de Anthropic describe los límites del sistema de archivos y la red como fundamentos para una autonomía más segura.
Cada unidad aceptada debe producir un commit atómico que contenga:
- Identificador de la fuente
- Reglas contractuales aplicables
- Comandos ejecutados
- Resultados de pruebas y verificaciones
- Resultados del revisor
- Excepciones aprobadas
Git se convierte tanto en un mecanismo de coordinación como de recuperación.
La guía de flujos de trabajo de larga duración de Anthropic recomienda commits significativos y pruebas antes de cada commit, porque un historial recuperable evita que una ejecución prolongada de un agente se convierta en un artefacto opaco.
No optimice por líneas por minuto. Optimice por unidades verificadas por hora.
Un alto rendimiento de generación combinado con una cola de integración creciente es un progreso negativo.
Fase 4: Trate los Errores del Compilador y las Pruebas como Colas, no como Pruebas
La salida del compilador crea trabajo estructurado.
Agrupe los errores por unidad de propiedad o capa de dependencia, elimine cascadas duplicadas y corrija las causas raíz antes que los síntomas secundarios.
Prohíba los atajos a menos que el contrato lo permita explícitamente, incluyendo:
- Stubs vacíos
- Resultados ignorados
- Atributos
allowamplios - Afirmaciones deshabilitadas
- Implementaciones placeholder
- Pruebas modificadas solo para hacer pasar el candidato
Ejecute las pruebas en círculos crecientes:
- Pruebas unitarias para el módulo modificado
- Pruebas de contrato en los límites públicos
- Pruebas de integración entre dependencias
- Suites multiplataforma
- Pruebas de regresión completas
Mantenga la salida fallida como un artefacto. Una ejecución final verde sin historial puede ocultar si los trabajadores debilitaron repetidamente las comprobaciones en el proceso.
Cuando sea posible, separe la autoría de las pruebas de la implementación.
Un agente puede derivar casos límite del contrato y la implementación anterior, mientras que otro escribe el puerto. Bloquee las pruebas de compatibilidad aprobadas para que los trabajadores de implementación no puedan modificarlas. Los revisores nuevos deben preguntar si el código pasa por la razón prevista.
Las regresiones de producción de Bun demuestran la brecha entre una suite verde y la completitud semántica.
Un fallo de HMR solo en la publicación provino de un efecto secundario dentro de debug_assert!. Un fallo de UTF-16 de longitud impar reflejó un comportamiento de división diferente. Cada defecto escapado debe convertirse tanto en una prueba de regresión permanente como en una nueva regla de mapa semántico.
Fase 5: Agregue Pruebas Diferenciales, Fuzzing y Presupuestos de Rendimiento
Ejecute las implementaciones antiguas y nuevas contra el mismo corpus.
Compare:
Códigos de salida
Salida normalizada
Categorías de error
Efectos secundarios
Estado de la base de datos
Eventos emitidos
Trazas
Construir generadores de condiciones límite para:
- Entradas vacías
- Tamaños máximos
- Codificaciones mal formadas
- Tiempos alrededor de la época Unix
- Condiciones de carrera concurrentes
- Rutas específicas de plataforma
- Agotamiento de recursos
Difuminar analizadores y límites de protocolo de forma continua.
Bun informó que sus difusores guiados por cobertura ejecutaron el código del analizador aproximadamente 100 mil millones de veces y generaron alrededor de 15 solicitudes de extracción de correcciones. El número absoluto depende de la carga de trabajo. El patrón transferible es conectar el descubrimiento de fallos con pruebas reproducibles, correcciones propuestas por agentes y solicitudes de extracción revisadas por humanos.
Cuando los usuarios dependen del rendimiento, el rendimiento es parte del comportamiento.
Evaluación comparativa:
- Arranque en frío
- Rendimiento
- Latencia p50
- Latencia p95
- Latencia p99
- Memoria máxima
- Tamaño del binario
- Tiempo de compilación
- CPU bajo cargas de trabajo representativas
Comparar distribuciones en lugar de promedios. Establecer presupuestos antes de la migración para que el equipo no pueda justificar regresiones después de invertir mucho en la reescritura.
Ejecutar también pruebas de resistencia. Las fugas de memoria, fugas de descriptores, crecimiento de colas, fragmentación del asignador y condiciones de carrera raras pueden requerir horas o días para manifestarse.
Un lenguaje con garantías de seguridad de memoria más sólidas puede eliminar clases enteras de errores, al mismo tiempo que introduce un comportamiento diferente de asignación, planificación o rendimiento.
Revisar Código Inseguro, FFI y Límites de Seguridad por Separado
Tratar cada uno de los siguientes como una clase de revisión separada:
- Bloques
unsafe - Llamadas FFI
- Punteros sin procesar
- Asignadores personalizados
- Límites criptográficos
- Analizadores
- Deserializadores
- Comprobaciones de permisos
- Lógica de autenticación
- Límites de persistencia
En el momento del informe fuente, Bun describió aproximadamente 27,000 líneas dentro de bloques unsafe de aproximadamente 780,000 líneas en Rust, gran parte relacionada con la integración de C y C++.
Esa superficie necesita más que una revisión de código ordinaria.
Requerir un comentario de invariante cerca de cada límite inseguro:
- ¿Qué debe ser cierto?
- ¿Quién establece la invariante?
- ¿Cuánto tiempo sigue siendo válido el puntero?
- ¿Qué hilo posee el valor?
- ¿Qué prueba ejercita la condición?
Agrupar patrones inseguros repetidos detrás de envoltorios revisados. Rastrear líneas y bloques inseguros por propietario en lugar de tratar el total como una métrica de vanidad.
Usar:
- Análisis estático
- Saneadores
- Auditorías de dependencias
- Difuminación
- Revisión de seguridad manual
Las 11 rondas de revisión de seguridad de Bun son evidencia de un endurecimiento continuo, no evidencia de que no hubiera defectos.
La revisión de seguridad automatizada debe complementar la revisión del dominio, especialmente en torno a autenticación, escape de entornos limitados, secretos y cambios en la cadena de suministro.
Revisar el mecanismo de migración en sí mismo. Los agentes ejecutan contenido del repositorio, scripts de compilación y salida de herramientas. Una dependencia comprometida o una instrucción oculta en el código fuente puede influir en la ejecución.
El aislamiento del sistema de archivos, las restricciones de red, los tokens con ámbito y las comprobaciones inmutables de CI reducen este riesgo.
Publicar por Etapas y Practicar la Reversión Antes de que Sea Necesaria
Fusionar no es publicar.
Construir artefactos versionados a partir de confirmaciones conocidas, cadenas de herramientas, bloqueos de dependencias y manifiestos de evidencia. Mantener la implementación anterior compilable.
Si los binarios antiguos y nuevos pueden coexistir, añadir un interruptor en tiempo de ejecución o una capa de enrutamiento.
en lugar de reemplazar irreversiblemente la ruta.
Comience con la ejecución en modo sombra cuando los efectos secundarios puedan aislarse.
Luego realice un canario mediante:
- Usuarios internos
- Inquilinos de bajo riesgo
- Plataforma
- Región
- Porcentaje de tráfico
Defina umbrales de reversión automática para:
- Discrepancias de corrección
- Tasa de fallos
- Latencia
- Memoria
- Categorías de errores
- Señales de soporte
Los humanos deben conservar la capacidad de detener la expansión incluso cuando los umbrales automatizados no se hayan activado.
Practique la reversión.
Confirme que:
- El artefacto antiguo se inicia correctamente.
- Los esquemas siguen siendo compatibles.
- El trabajo en cola puede drenarse.
- La observabilidad identifica qué implementación atendió cada solicitud.
- El tiempo de reversión medido cumple con el objetivo operativo.
La documentación de reversión que nunca se ha ejecutado es solo una hipótesis.
Después de cada defecto que escape, actualice el contrato, el mapa semántico, el corpus de pruebas y el modelo de riesgos.
Las 19 regresiones conocidas de Bun son útiles porque exponen peligros de traducción recurrentes. Una migración está completa cuando la nueva implementación es operativa y el equipo ha aprendido de ella—no cuando se fusiona el diff generado.
Política de migración reutilizable con IA y manifiesto de evidencias
El siguiente YAML está diseñado como un artefacto de equipo reutilizable. Adapte comandos, umbrales y propietarios al repositorio.
We0 AI u otro sistema de orquestación puede adjuntar esta política a las tareas de migración y exigir el manifiesto de evidencias antes de la revisión.
ai_migration:
name: payments-python-to-go
contract: docs/MIGRATION_CONTRACT.md
semantic_map: docs/PORTING_RULES.md
old_reference: artifacts/payments-python@sha256:OLD
new_candidate: artifacts/payments-go@sha256:NEW
worker_policy:
isolation: ephemeral_worktree
one_writer_per_unit: true
forbidden_commands:
- "git reset --hard"
- "git stash"
- "git push --force"
editable_paths: ["cmd/", "internal/", "tests/migration/"]
protected_paths: ["tests/contracts/", "docs/MIGRATION_CONTRACT.md"]
required_gates:
compile: "go build ./..."
unit: "go test ./..."
contracts: "./scripts/run-contract-tests.sh"
differential: "./scripts/compare-old-new.sh --corpus fixtures/replay"
fuzz: "./scripts/fuzz.sh --hours 24 --unique-crashes 0"
security: "./scripts/security-scan.sh --severity high"
performance:
p99_latency_regression_pct: 5
peak_memory_regression_pct: 10
platforms: [linux-amd64, linux-arm64]
independent_review:
fresh_context: true
reviewers_per_unit: 2
require_counterexample_search: true
rollout:
shadow_hours: 48
canary_percentages: [1, 5, 20, 50, 100]
rollback_artifact_required: true
rollback_drill_required: true
evidence_manifest:
include:
- contract_version
- source_and_target_commits
- changed_units
- commands_and_exit_codes
- differential_mismatches
- fuzzing_summary
- benchmark_distributions
- unsafe_or_ffi_inventory
- reviewer_findings
- approved_exceptions
- rollback_drill_result
Esta política impide deliberadamente que los trabajadores de implementación editen el contrato o las pruebas de contrato aprobadas.
Requiere:
- Artefactos de referencia
- Revisión independiente
- Cuantificadores
límites de rendimiento
- Evidencia de despliegue progresivo
- Una ruta de reversión probada
Son posibles excepciones, pero deben documentarse y aprobarse, no ocultarse dentro de un mensaje.
Mida el Progreso Verificado, No el Volumen Generado
Líneas de código, cantidad de agentes y días transcurridos son métricas de capacidad interesantes. No miden el éxito del producto.
Utilice un cuadro de mando de migración equilibrado.
Rendimiento de Unidades Verificadas
Realice un seguimiento de las unidades de migración que:
- Compilan
- Pasan verificaciones de contratos específicas
- Reciben revisión independiente
- Se integran sin regresiones
Mida las unidades aceptadas por unidad de tiempo.
Cierre de Desajustes
Realice un seguimiento de las diferencias descubiertas y de si cada una está:
- Explicada
- Corregida
- Aprobada como intencional
- Aún sin resolver
Defectos Escapados
Realice un seguimiento de los defectos que pasan un control que debería haberlos detectado.
Cada defecto escapado debe identificar una regla de contrato, prueba, oráculo, paso de revisión o umbral de despliegue faltante.
Atención Humana
Mida el tiempo que los humanos dedican a:
- Definir contratos
- Resolver ambigüedades
- Revisar código de alto riesgo
- Investigar desajustes
- Operar el despliegue
La IA puede reducir el tiempo de implementación mientras mejora la calidad de las especificaciones. Es un buen intercambio, no un fallo de automatización.
Coste de Cómputo y Herramientas
Mida el coste total de modelo, cómputo y herramientas por unidad aceptada.
Los flujos de trabajo dinámicos pueden consumir más tokens que las sesiones ordinarias. El paralelismo está justificado cuando reduce el tiempo de espera para trabajos de alto valor sin crear una acumulación mayor de verificación.
Mantenibilidad Posterior a la Migración
Realice un seguimiento de:
- Tiempo de inicio
- Velocidad de compilación
- Tasa de fallos por cambios
- Latencia de revisión
- Densidad de defectos
- Responsabilidad de módulos inseguros
- Facilidad de depuración
- Calidad de la documentación operativa
Un puerto que se entrega rápidamente pero permanece opaco para el equipo ha movido la deuda, no la ha eliminado.
Cómo Puede Comenzar un Equipo Sin una Reescribir de un Millón de Líneas
Elija una migración acotada con una implementación de referencia en vivo, como:
- Un cambio de versión de SDK
- Un subsistema del marco de trabajo
- Un comando de CLI
- Un punto final de servicio
Escriba un contrato de comportamiento de una página y tres casos piloto centrados en riesgos.
Utilice tareas de agente separadas para la implementación y la revisión, de modo que sus contextos permanezcan independientes.
Antes de la implementación:
- Bloquee las comprobaciones de aceptación.
- Exija que el implementador devuelva una confirmación y evidencia, no una afirmación en prosa.
- Pida al revisor que busque contraejemplos e identifique pruebas faltantes.
- Ejecute las comprobaciones en CI fuera del modelo.
- Expanda solo a la siguiente capa de dependencia después de que el piloto tenga éxito.
Mantenga un registro completo de la ejecución:
- Mensaje
- Modelo
- Alcance de la herramienta
- Confirmación de origen
- Confirmación de destino
- Rutas cambiadas
- Comprobaciones
- Fallos
- Hallazgos del revisor
- Excepciones
- Coste
- Decisión final
Este registro permite al equipo comparar versiones del arnés e investigar defectos sin adivinar lo que vio el agente.
Utilice una regla de adopción simple:
La autonomía debe ganarse.
Un flujo de trabajo que produce unidades verificadas repetidamente puede recibir un ámbito de archivo más amplio o un tiempo de ejecución no supervisado más largo. No recibe automáticamente permiso de despliegue.
Capacidad, evidencia y autoridad permanecen separadas.
Limitaciones: Lo Que El Caso Bun No Demuestra
Bun es un proyecto inusual.
Su creador lideró el
migración, tenía un conocimiento profundo de la base de código y poseía autoridad arquitectónica directa. La implementación anterior contaba con un amplio conjunto de pruebas, Rust ofrecía una retroalimentación sólida del compilador y el proyecto podía aprovechar un cómputo paralelo sustancial.
La mayoría de los equipos no compartirán todas esas ventajas.
El caso también fue presentado a través de Anthropic, y el artículo fuente indica que el trabajo utilizó un modelo prerelease Claude Fable 5. Es una valiosa evidencia primaria, pero no es una comparación independiente de proveedores.
Las afirmaciones sobre cuánto tiempo habría necesitado un equipo humano son estimaciones contrafácticas. Los equipos no deberían tomar decisiones de adquisición basándose en una migración exitosa.
Las 19 regresiones reportadas son regresiones conocidas, no una garantía del recuento completo. Las ejecuciones de fuzzing y las rondas de revisión de seguridad miden el esfuerzo, no la ausencia de defectos.
La conclusión más sólida y defendible es modesta:
Las migraciones a gran escala impulsadas por IA son factibles cuando se combinan con una retroalimentación determinista sólida y una orquestación experta, pero su riesgo sigue siendo un problema de ingeniería una vez completada la generación de código.
Esa conclusión sigue siendo significativa. Los equipos pueden intentar proyectos de modernización que antes se retrasaban por el costo, siempre que presupuesten especificación, verificación y despliegue controlado a la misma escala que la implementación.
Lista de Verificación Práctica para la Migración
- Definir comportamientos preservados, modificados, obsoletos y desconocidos.
- Inventariar contratos de plataforma, rendimiento, telemetría, errores y efectos secundarios.
- Construir un mapa semántico para patrones de origen a destino riesgosos.
- Proteger contratos y pruebas aprobadas de los trabajadores de implementación.
- Ejecutar unidades piloto difíciles antes de la expansión en todo el repositorio.
- Aislar a los escritores y restringir operaciones destructivas de Git y red.
- Requerir commits atómicos con comandos, salidas y referencias de contratos.
- Usar revisores adversariales con contexto nuevo para unidades de alto riesgo.
- Ejecutar compuertas de compilador, unidad, contrato, integración y multiplataforma.
- Comparar implementaciones antiguas y nuevas en corpus representativos.
- Agregar verificaciones metamórficas, de fuzzing, sanitizador y rendimiento.
- Inventariar límites de
unsafe, FFI, autenticación, analizador sintáctico y persistencia. - Preservar un artefacto de reversión reproducible y realizar un simulacro de reversión.
- Desplegar a través de etapas shadow y canary con umbrales de parada automáticos.
- Convertir cada defecto escapado en una mejora de contrato o verificación.
- Medir unidades verificadas, desajustes, atención humana, costo y mantenibilidad.
Preguntas Frecuentes
¿Qué reescribió Bun en Rust?
Bun migró una implementación importante que anteriormente estaba escrita en Zig a Rust. El relato publicado describe aproximadamente 780,000 líneas de Rust y un flujo de trabajo altamente paralelo asistido por IA, seguido de pruebas exhaustivas, revisión de seguridad, fuzzing y endurecimiento de producción.
¿Completó la IA la reescritura de Bun en Rust sin revisión humana?
No. Las reglas de migración escritas por humanos, la revisión manual de artefactos, los flujos de trabajo aislados, la retroalimentación del compilador, los revisores agentes independientes, la revisión de seguridad, el fuzzing y los controles de despliegue en producción desempeñaron papeles importantes. El caso se entiende mejor como ingeniería acelerada por IA que como conversión de código no supervisada.
¿Por qué las pruebas existentes no son suficientes
¿Migración de lenguaje?
Las pruebas existentes suelen cubrir solo una parte del comportamiento observado. Pueden omitir semánticas exclusivas del lanzamiento, diferencias de plataforma, regresiones de rendimiento, límites inseguros, cambios de telemetría o casos extremos que nunca fueron codificados en el conjunto.
¿Qué son las pruebas diferenciales en una migración de código?
Las pruebas diferenciales ejecutan las implementaciones antigua y nueva con las mismas entradas y comparan sus salidas observables y efectos secundarios. Son particularmente útiles cuando el sistema antiguo es confiable pero no existe una especificación formal completa.
¿Por qué los agentes de implementación y revisión deberían usar contextos separados?
Un revisor con una perspectiva nueva tiene menos probabilidades de heredar los supuestos y errores de razonamiento del agente autor. El revisor puede centrarse en el contrato, el diff, las pruebas y los contraejemplos, en lugar de defender la ruta de implementación que generó el cambio.
¿Cómo deberían los equipos revisar el código unsafe de Rust durante la migración?
Cada bloque unsafe o límite FFI debe tener un propietario designado, invariantes documentados, pruebas específicas y una explicación clara de la validez de los punteros, la vida útil y la propiedad del hilo. El análisis estático, los sanitizadores, el fuzzing, la revisión de dependencias y la revisión de seguridad manual deben aplicarse por separado de la revisión de código ordinaria.
¿Qué métricas debería rastrear una migración asistida por IA?
Rastree el rendimiento de unidades verificadas, el cierre de discrepancias, los defectos escapados, la atención humana, el costo computacional, la salud del despliegue y la mantenibilidad posterior a la migración. Las líneas generadas y el número de agentes son métricas de capacidad, no pruebas de corrección.
¿Puede un equipo pequeño usar este manual sin ejecutar docenas de agentes?
Sí. Comience con un componente acotado, un contrato de comportamiento escrito, tres pilotos centrados en riesgos, contextos separados de implementación y revisión, puertas CI deterministas y una ruta de reversión probada. Escale el flujo de trabajo solo después de que produzca repetidamente resultados verificables.
Herramientas relacionadas
- Bun: Un conjunto de herramientas integral para JavaScript y TypeScript cuya migración a Rust proporciona el caso de estudio principal de este manual.
- Rust: Un lenguaje de programación de sistemas con fuertes garantías de seguridad en tiempo de compilación y límites
unsafeexplícitos. - Claude Code: El entorno de codificación agéntico de Anthropic, utilizado en el flujo de trabajo dinámico descrito por el material fuente.
- GitHub Actions: Una plataforma CI/CD adecuada para compilación determinista, pruebas, seguridad, evaluación comparativa y puertas de evidencia.
- cargo-fuzz: Una herramienta de fuzzing estándar para proyectos Rust construida sobre libFuzzer.
- Miri: Un intérprete de Rust que puede detectar ciertas formas de comportamiento indefinido en código inseguro.
Enlaces relacionados
Bun: Reescribiendo Bun en Rust: El relato oficial de ingeniería de Bun sobre la reescritura, el endurecimiento en producción, el fuzzing y las regresiones conocidas.
Repositorio fuente de Bun: El repositorio oficial de Bun que contiene la implementación en Rust, problemas, pruebas e historial de migración.
[Anthropic: Introducción a los flujos de trabajo dinámicos](https://claude.
Presentación de flujos de trabajo dinámicos en Claude Code: La descripción de Anthropic sobre el flujo de trabajo multiagente utilizado durante la migración de Bun.
Mejores prácticas de Claude Code: Guía oficial sobre estructura de tareas, contextos de revisión nuevos, pruebas y flujos de trabajo de codificación de larga duración.
Aislamiento en espacio aislado de Claude Code: Explicación de Anthropic sobre el aislamiento del sistema de archivos y la red para una codificación autónoma más segura.
The Rustonomicon: Conoce Safe y Unsafe: Guía oficial de Rust sobre el límite entre código seguro e inseguro.
Documentación de CODEOWNERS de GitHub: Documentación de GitHub sobre propiedad legible por máquina y flujos de trabajo de revisión requeridos.
Resumen
La reescritura de Bun en Rust demuestra que los agentes de codificación de IA pueden comprimir drásticamente el tiempo de implementación, pero también muestra por qué la verificación debe convertirse en un sistema de ingeniería de primera clase. Los contratos, mapas semánticos, trabajadores aislados, revisión independiente, pruebas diferenciales, fuzzing, presupuestos de rendimiento y despliegue por etapas son lo que convierte el código generado en evidencia de migración creíble.
La lección práctica no es copiar el número de agentes o líneas de código. Es dividir una migración en afirmaciones acotadas, requerir prueba determinista para cada afirmación y expandir la autonomía solo después de que el flujo de trabajo produzca repetidamente resultados fiables.
Una reescritura asistida por IA a gran escala está completa solo cuando el nuevo sistema está verificado, operable, recuperable y comprendido, no cuando el código generado ha sido fusionado.