Ir al contenido
14 ago 2026·8 min de lectura

Un plan de migración de sistemas heredados antes del código

Cree un plan de migración de sistemas heredados basado en pruebas, orden de extracción, controles de paridad y decisiones de ingeniería.

Un plan de migración de sistemas heredados antes del código

Una migración heredada fracasa mucho antes de que el código generado parezca incorrecto. Fracasa cuando el equipo pide a un modelo que deduzca el sistema, elija una arquitectura nueva, preserve el comportamiento oculto, programe el trabajo y juzgue su propio resultado dentro de un único prompt. Ese prompt puede producir un repositorio impresionante. No puede producir una cadena defendible de decisiones.

El plan tiene que existir antes del primer archivo en el lenguaje de destino. Me refiero a algo más que un backlog con casillas llamadas "convertir facturación" y "migrar informes". Un plan útil indica las pruebas de cada comportamiento, el orden en que el equipo las extraerá, el límite de destino que lo sustituirá y la prueba que permite el siguiente cambio. Si alguno de esos campos está vacío, la generación debe esperar.

Esta distinción importa porque un modelo de lenguaje genera a partir del contexto que recibe, mientras que un ingeniero es responsable de encontrar el contexto que nadie pensó incluir. Los sistemas antiguos esconden reglas en el control de trabajos, los disparadores de bases de datos, los hábitos de operadores, los formatos de archivo, la configuración de impresoras, los scripts de reintento y las excepciones del cierre mensual. El trabajo difícil consiste en decidir qué cuenta como comportamiento y demostrar que el sustituto lo mantiene.

Inventaríe el comportamiento antes que los archivos

Un inventario de migración debe describir el comportamiento observable, no limitarse a los archivos de origen y el recuento de lenguajes. Las listas de archivos ayudan a calcular el trabajo de análisis, pero apenas dicen nada del contrato del que dependen usuarios y sistemas conectados. Un paso JCL de doce líneas puede decidir si se vuelve a procesar el archivo de liquidación de ayer. Un gran módulo de informes puede producir una salida que nadie lee.

Empiece en el límite del sistema. Registre cada entrada, salida, evento programado, acción del operador, llamada externa, almacén persistente y señal de fallo. Para cada elemento, capture un ejemplo real e identifique quién puede confirmar si es correcto. Así se crea una superficie de comportamiento que puede probar. Solo entonces debe asignar las unidades de código fuente a esa superficie.

Uso cuatro clases de pruebas porque los equipos las mezclan con frecuencia:

  • Pruebas ejecutadas: solicitudes de producción, entradas por lotes, cambios en bases de datos, archivos, mensajes y salidas que el sistema actual procesó realmente.
  • Comportamiento declarado: manuales, acuerdos de interfaces, copybooks, esquemas, textos de ayuda y procedimientos que dicen qué debería ocurrir.
  • Rutas implementadas: ramas, consultas, trabajos, disparadores y controladores de errores presentes en el código.
  • Práctica operativa: horarios, correcciones manuales, puntos de reinicio y excepciones que los operadores aplican fuera del programa.

Estas clases pueden discrepar. Esa discrepancia es un hallazgo, no una molestia que deba suavizarse. Si el manual dice que un campo es obligatorio pero el tráfico registrado contiene valores vacíos, el plan de migración debe decidir si prevalece la compatibilidad o la regla escrita. Una sola generación suele elegir el artefacto que parece más autorizado dentro de su contexto. Un ingeniero registra el conflicto, encuentra al responsable y convierte la decisión en una prueba.

Cree una tabla de límites antes de escribir el código de destino. Una versión pequeña podría ser así:

LímitePruebasResponsableRegla de compatibilidadVerificación
Archivo nocturno de cuentasTres archivos aceptados y uno rechazadoResponsable de operacionesConservar anchos fijos y código de rechazo 17Reproducir los cuatro archivos
Cálculo de impuestosSolicitudes registradas más tabla de tipos actualResponsable de sistemas financierosIgualar el total redondeado y los campos de auditoríaComparar respuesta y filas del registro
Impresión de extractosMuestras de spool y configuración de impresoraResponsable de atención al clienteConservar saltos de página y ordenRenderizar e inspeccionar casos nombrados

La tabla deja al descubierto pronto las pruebas que faltan. También evita el error habitual de tratar un esquema de base de datos como si fuera todo el modelo de dominio. Una columna puede aceptar valores nulos porque una importación fallida deja allí datos parciales, mientras que toda transacción normal exige un valor. La forma del esquema y el significado de negocio son hechos distintos.

El registro de migración es el plan real

Un plan útil de migración de sistemas heredados es un registro ejecutable de afirmaciones, dependencias y controles. Debe permitir que otro ingeniero responda a cinco preguntas sobre cualquier tarea: qué cambiamos, qué pruebas definen su comportamiento actual, qué debe existir antes, cómo compararemos lo antiguo y lo nuevo y quién acepta una diferencia deliberada.

Un tablero de tickets por sí solo no lo consigue. Los tickets cambian, las notas de aceptación se convierten en prosa y las dependencias quedan en la memoria. Mantenga un registro legible por máquina en el repositorio y haga que las revisiones se refieran a sus identificadores. El formato puede ser YAML, JSON o una tabla de base de datos. Lo importante es que las pruebas ausentes sigan siendo visibles.

- id: CALC-014
  boundary: POST /interest/accrue
  evidence:
    traffic_set: traffic/interest/month_end_2025_01.ndjson
    state_snapshot: snapshots/ledger_before.sql.zst
  depends_on: [DATA-006, CLOCK-002]
  target: services/interest/accrual.go
  invariants:
    - response.status == legacy.response.status
    - ledger.delta_cents == legacy.ledger.delta_cents
    - audit.event_type == legacy.audit.event_type
  allowed_differences:
    - field: response.request_id
      rule: compare_presence_only
      approved_by: architecture-review-27
  gate: parity/CALC-014

Este fragmento evita tres fallos. Impide que un desarrollador pruebe el cálculo sin el estado que lo determina. Convierte los identificadores de solicitud no deterministas en una regla de comparación explícita, en lugar de una lista de exclusiones que crece. También vincula la aprobación a una diferencia concreta, de modo que nadie pueda ampliar la excepción en silencio más adelante.

El registro debe separar los descubrimientos de las decisiones. "El servicio heredado devuelve 200 para una solicitud duplicada" es una observación. "El sustituto conservará esa respuesta" es una decisión de compatibilidad. "Deberíamos devolver 409" es una preferencia de diseño. Mezclar esas frases permite que una limpieza deseable pase por una migración fiel.

No incluya porcentajes como "módulo migrado al 80 %" en el registro. Los porcentajes de progreso ocultan qué comportamiento falta. Cuente controles cerrados frente a límites con nombre. Diez variantes menores de informes no compensan una sola ruta de contabilización sin verificar, y el plan debe mostrarlo.

El plan también necesita condiciones de parada. La generación se detiene cuando faltan pruebas, una dependencia no tiene un destino verificado, la comparación produce una diferencia sin explicar o un responsable no ha aprobado un cambio deliberado. Sin condiciones de parada, la presión de fechas convierte cada resultado rojo en una tarea de limpieza futura.

Extraiga desde los límites hacia el centro

El orden de extracción más seguro comienza con límites observables, sigue por la semántica de los datos y la orquestación y solo después llega a los algoritmos internos. Este orden da a cada generación posterior un contrato y una forma de medir su salida. Empezar por el módulo más independiente parece eficiente, pero suele crear una isla cuyas interfaces se han adivinado.

Primero capture entradas y salidas en uniones estables. En un servicio en línea, pueden ser cuerpos de solicitudes, cuerpos de respuestas, cabeceras, efectos en bases de datos y mensajes emitidos. En un sistema por lotes, incluye generaciones de entrada, tarjetas de control, códigos de retorno, salida de spool, archivos creados y comportamiento de reinicio. En una aplicación de escritorio, incluya acciones de usuario, archivos locales, informes, estado del registro o la configuración y llamadas a bases de datos compartidas.

Después extraiga el significado de los datos. Asigne identificadores, unidades, codificaciones, reglas de nulos, escala decimal, reglas de fechas y ciclos de vida de registros. No normalice todavía. Un campo decimal empaquetado, un código rellenado con espacios y una marca temporal en hora local pueden parecer feos, pero cada uno puede contener comportamiento. Registre cómo entra cada valor en el sistema y dónde se observa antes de elegir una representación más limpia.

En tercer lugar, reconstruya la orquestación. Los sistemas antiguos suelen colocar el orden de negocio fuera de los módulos de negocio. JCL define qué programa se ejecuta después de un código de retorno. Los scripts CL cambian bibliotecas. Un envoltorio de shell reintenta un comando pero no el siguiente. Un planificador proporciona una fecha de negocio distinta del reloj de la máquina. Si la generación ve los programas llamados sin esa orquestación, crea funciones plausibles por separado en el orden equivocado.

En cuarto lugar, identifique transiciones de estado e invariantes. Describa una transacción como estado previo, estímulo, estado posterior y efectos emitidos. Es más preciso que traducir procedimientos uno por uno. También revela el tratamiento de duplicados, las confirmaciones parciales, las acciones compensatorias y los puntos de recuperación.

Solo cuando existan esas capas debe el equipo generar implementaciones internas y arquitectura de destino. Los límites de los servicios de destino deben seguir la responsabilidad, las necesidades de coherencia y los patrones de cambio. No deben copiar el árbol de directorios del origen. Una traducción módulo por módulo conserva un acoplamiento accidental y lo llama modernización.

Existe una excepción práctica. A veces se necesita pronto un analizador o emulador ligero para leer pruebas encerradas en un formato propietario. Constrúyalo como herramienta de extracción, márquelo como desechable y pruébelo con muestras conocidas. No permita que ese componente conveniente se convierta en la arquitectura de producción sin que nadie lo decida.

Separe pruebas, interpretación y decisiones

Los ingenieros necesitan registros separados de lo que hizo el sistema, de lo que creen que significa y de lo que el proyecto decide conservar. Un prompt largo colapsa las tres cosas en una prosa fluida. Una vez mezcladas, el lector no puede saber si un requisito generado procede del tráfico, del código fuente o de una inferencia.

Use un registro de afirmación para cada comportamiento que controle la implementación. No necesita ceremonia. Necesita procedencia y estado.

{
  "claim_id": "BATCH-031",
  "statement": "A rerun skips records already posted for the same business date",
  "kind": "observed",
  "evidence": ["run-884/input.dat", "run-884/ledger-after.csv", "ops-runbook-4.2"],
  "confidence": "confirmed",
  "decision": "preserve",
  "tests": ["parity/batch_031_first_run", "parity/batch_031_rerun"]
}

La distinción entre comportamiento observado e inferido parece fácil de descartar hasta que provoca un error de datos. Suponga que el código comprueba una tabla de "ya contabilizado" antes de escribir. Un generador puede inferir idempotencia. Las pruebas de producción pueden mostrar que la tabla se vacía durante un procedimiento concreto de recuperación, lo que hace que algunos reinicios contabilicen de nuevo a propósito. La ruta de código, la práctica operativa y el contrato previsto no encajan. El registro obliga al equipo a resolver esa discordancia.

Trate los comentarios como afirmaciones, no como verdad. Lo mismo se aplica a nombres de variables, ramas muertas, documentos de diseño antiguos y pruebas que no se han ejecutado con un estado similar al de producción. Todos pueden guiar la investigación. Ninguno debe imponerse a pruebas ejecutadas sin una decisión identificada.

Las etiquetas de confianza deben tener significado operativo. "Confirmado" podría exigir dos tipos independientes de pruebas y la revisión de un responsable. "Provisional" podría permitir el trabajo del analizador, pero bloquear la implementación de destino. "Desconocido" debería crear una tarea de extracción. Si las etiquetas solo comunican una sensación, cederán ante la presión de los plazos.

Mantenga las mejoras deliberadas en un registro de cambios vinculado a la afirmación de compatibilidad. Algunos ejemplos son rechazar una fecha no válida que el sistema antiguo acepta, sustituir un método de autenticación débil o cambiar el diseño de un informe. Pruebe por separado la ruta conservada y el nuevo comportamiento. De lo contrario, un fallo de paridad y una mejora intencionada resultan indistinguibles, lo que dificulta tanto la revisión como la reversión.

Cada generación termina en un control de paridad

Ponga las pruebas antes de generar
CodeHero lee todo el árbol heredado antes de reescribir el comportamiento conectado en la pila de destino.

Cada paso de generación debe terminar con un control de paridad que compare los efectos observables con el sistema actual. La revisión de código y las pruebas unitarias del lenguaje de destino son necesarias, pero no demuestran compatibilidad. Indican si el código nuevo parece razonable internamente, no si se comporta como el sistema que la gente usa.

Un ciclo útil tiene cinco movimientos:

  1. Seleccione una entrada del registro cuyas dependencias hayan pasado.
  2. Reúna solo su contexto aprobado: afirmaciones, esquemas, muestras de pruebas, restricciones de destino y diferencias permitidas.
  3. Genere o revise la parte de destino más pequeña que pueda satisfacer el límite.
  4. Reproduzca el mismo estímulo contra los sistemas antiguo y nuevo desde un estado equivalente.
  5. Clasifique cada diferencia y después apruebe, revise, eleve o modifique el registro de decisión.

El estado equivalente merece atención. Si la ejecución heredada empieza con treinta años de historial de clientes y el sustituto con fixtures construidas a mano, las respuestas coincidentes demuestran poco. Tome una instantánea del estado pertinente, enmascárelo cuando sea necesario, preserve las relaciones referenciales y documente cualquier estado que no pueda reproducir. En sistemas que no pueden ejecutarse dos veces contra el mismo estado, clone el estado o registre los efectos en un punto de unión.

La comparación debe ser semántica, no una diferencia de texto sin procesar. Normalice campos solo por motivos escritos en el registro. Puede comparar marcas temporales dentro de una tolerancia aprobada, ignorar identificadores generados mientras exige que existan, ordenar canónicamente objetos JSON o comparar un PDF mediante el texto extraído y la geometría de página. Nunca añada una regla global de exclusión porque haga que una compilación roja pase a verde.

Un informe de paridad debe mostrar el elemento, el conjunto de pruebas, el resultado antiguo, el resultado nuevo, las reglas de normalización, las diferencias y su disposición. Esta forma compacta basta para automatización y revisión:

gate=CALC-014 evidence=month_end_2025_01
cases=184 matched=183 different=1 errored=0
difference[1].path=ledger.entries[2].amount_cents
difference[1].legacy=1250
difference[1].target=1249
difference[1].rule=exact
status=FAIL

La diferencia de un céntimo no está "lo bastante cerca". Señala el orden de redondeo, la representación decimal o un desajuste de estado. Un ingeniero la sigue por los valores intermedios, comprueba la semántica aritmética del origen y añade la prueba más pequeña que aísle la causa. Volver a generar todo el módulo con una instrucción más estricta suele cambiar comportamientos no relacionados y destruye el rastro de pruebas.

Ejecute los controles continuamente, no en una fase final de aceptación. Un límite aprobado se convierte en una restricción para el trabajo posterior. Cuando cambia una asignación de datos compartida, el grafo de dependencias identifica qué controles deben ejecutarse otra vez. Por eso el registro y el arnés van unidos: uno dice qué puede cambiar y el otro muestra qué cambió.

Un prompt gigante falla de formas previsibles

Aporte el monolito completo
Los sistemas de más de un millón de líneas se leen como una base conectada, no como fragmentos de prompt.

Un único prompt de migración falla porque sus tareas entran en conflicto y su contexto no tiene mecanismo de aplicación. Más contexto puede mejorar el recuerdo, pero no crea procedencia de pruebas, orden de dependencias, juicio independiente ni un control de prueba duradero. El repositorio generado puede ser coherente y seguir equivocado en todos los límites ausentes del prompt.

Piense en una cadena nocturna de facturación. El planificador proporciona una fecha de negocio. Un paso JCL ordena transacciones con una intercalación específica de la configuración regional. Un programa contabiliza las filas válidas y escribe los rechazos. Un código de retorno decide si se generan los extractos. Operaciones puede reiniciar después de contabilizar sin repetirlo. Los módulos de origen contienen partes de este comportamiento, pero ningún módulo posee todo el contrato.

Un prompt grande pide una reescritura en Go e incluye los programas, copybooks, archivos de muestra y una frase que dice "preservar el comportamiento". La salida usa la fecha de la máquina, ordena cadenas con el valor predeterminado del entorno de destino, envuelve el lote en una transacción de base de datos y trata cualquier rechazo como un error fatal. Cada elección se puede defender en un sistema nuevo. Juntas rompen el cierre mensual.

El primer archivo de prueba contiene registros normales, por lo que ambos sistemas calculan los mismos totales. El equipo lo celebra. El primer reinicio repite contabilizaciones porque el destino no tiene un punto de control equivalente al paso heredado. Un archivo con un sufijo de cuenta en blanco se ordena de otro modo y cambia la agrupación. Una sola fila incorrecta revierte ahora trabajo válido que la cadena antigua habría contabilizado. Ninguno de estos errores parece un defecto de sintaxis ni un diseño evidentemente absurdo.

Una extracción planificada los habría detectado por orden. La captura de límites registra la fecha de negocio y los códigos de retorno. El análisis de datos registra la intercalación y el relleno con espacios. El análisis de orquestación registra los puntos de confirmación y reinicio. La reproducción incluye ejecuciones normales, rechazadas y reanudadas. La arquitectura de destino puede mejorar la implementación, pero no puede borrar esos contratos por accidente.

La respuesta popular consiste en alargar el prompt. Solo ayuda si la omisión es el único problema. Dificulta resolver conflictos, oculta qué pruebas respaldaron cada instrucción y aún permite que el generador juzgue su propio trabajo. Dividir el prompt entre agentes tampoco lo arregla por sí mismo. Varios generadores necesitan el mismo registro, las mismas reglas de responsabilidad y los mismos controles de paridad o se limitan a distribuir más deprisa suposiciones sin seguimiento.

Use la generación como una operación de implementación acotada. Entréguele una parte de destino, restricciones explícitas, las pruebas necesarias para esa parte y la salida de paridad fallida del intento anterior. Inspeccione luego el cambio y ejecute el control fuera del proceso de generación. Esa división mantiene productivo al modelo sin concederle una autoridad que no puede asumir responsablemente.

El ingeniero se responsabiliza de lo no resuelto

Un ingeniero hace el trabajo que no puede reducirse a producir código plausible: encontrar pruebas ausentes, decidir qué contradicción importa, elegir un límite, negociar cambios deliberados y aceptar riesgos. No son lagunas temporales que desaparezcan cuando los modelos crezcan. Son actos de responsabilidad dentro de una organización concreta.

El ingeniero pregunta quién sufre cuando dos artefactos discrepan. Si el código fuente permite un descubierto pero la política financiera lo prohíbe, la respuesta necesita una decisión de producto y cumplimiento, no una síntesis ponderada por probabilidad. Si los operadores dependen de un truco de reinicio que el nuevo diseño debería eliminar, el ingeniero debe entender por qué existe, diseñar una ruta de recuperación más segura y obtener acuerdo para romper la compatibilidad de forma deliberada.

El ingeniero también controla la descomposición. Un generador tiende a seguir la estructura que ve. El ingeniero puede reconocer que seis programas forman un solo límite de coherencia o que un monolito contiene cuatro capacidades con responsables independientes. Ese juicio procede de la semántica de transacciones, las necesidades de despliegue, el historial de incidentes y las personas que mantendrán el destino.

La revisión debe centrarse en las afirmaciones y los efectos antes que en el estilo. Pregunte qué entrada del registro cierra el cambio, qué pruebas usa, qué decisión de destino encarna y qué dice el informe de paridad. Un servicio perfectamente idiomático con una diferencia de salida sin explicar sigue incompleto. Un adaptador incómodo que preserve un límite difícil puede ser justo el componente temporal correcto.

Los ingenieros también deben proteger el arnés para que no se convierta en un sello de goma. Cada regla de normalización necesita un motivo. Cada archivo de referencia necesita procedencia. Cada resultado esperado modificado necesita la misma revisión que un cambio de comportamiento de producción. Si el equipo actualiza instantáneas cada vez que falla una prueba, ha creado una máquina de aprobación, no un arnés de paridad.

Todavía hay espacio para la velocidad. Genere analizadores, adaptadores, pruebas, código de asignación y candidatos de implementación en paralelo cuando las dependencias del registro lo permitan. Mantenga centralizadas la adquisición de pruebas y los resultados de los controles. La producción de código en paralelo es útil; una verdad paralela es una contradicción.

La arquitectura cambia solo tras contratos probados

Convierta la paridad en control
El tráfico de producción registrado comprueba el comportamiento sustituto antes de entregar el sistema reescrito.

La modernización debe cambiar la arquitectura detrás de contratos preservados, no traducir la estructura antigua línea por línea. Cuando un límite ya tiene pruebas y un control de paridad, el equipo puede sustituir el estado compartido por servicios explícitos, aislar núcleos numéricos, mover datos a Postgres o construir un cliente TypeScript sin adivinar si la forma nueva cambió el comportamiento visible.

Decida la arquitectura en el nivel más pequeño donde disponga de pruebas suficientes. Algunas decisiones corresponden al principio: restricciones del entorno de destino, límites de seguridad, entorno de despliegue, residencia de datos y qué sistemas deben coexistir durante el cambio. Otras deben esperar: las divisiones de servicios, la ubicación de cachés, los límites asíncronos y la limpieza del esquema suelen depender del comportamiento descubierto durante la extracción.

Evite dos extremos. Congelar todos los detalles del destino antes del descubrimiento produce un plan elegante para un sistema imaginario. Dejar que cada generación invente la arquitectura produce límites incoherentes e infraestructura duplicada. Registre las decisiones vinculantes, mantenga visibles las decisiones aplazadas e indique qué pruebas las cerrarán.

La planificación del cambio pertenece al mismo registro. Nombre la fuente de verdad durante la transición, la dirección de sincronización, la consulta de conciliación, el punto de reversión y la interrupción máxima aceptada. Un sustituto que pase pruebas aisladas de paridad puede fallar en operación si ambos sistemas escriben los mismos registros o si la reversión no puede recuperar cambios que solo existen en el destino.

CodeHero aplica esta forma de trabajo cuando lee un árbol heredado completo, lo reescribe en Go, Rust, TypeScript y Postgres y comprueba el comportamiento con un arnés de paridad frente al tráfico de producción registrado. Su promesa de entrega en menos de 30 días depende de ordenar de cerca extracción y verificación; no hace opcional el plan.

Antes de aprobar el primer archivo de destino generado, exija una entrada completa del registro con pruebas reales, dependencias explícitas, una regla de comparación y un responsable identificado para las diferencias. Si el equipo no puede producir esa entrada, no está listo para migrar. Solo está listo para generar código que parece migrado.

Preguntas frecuentes

¿Por qué un único prompt largo no puede migrar un sistema heredado?

Un prompt largo puede generar una base de código que parezca coherente, pero no puede establecer qué pruebas tienen autoridad ni aprobar conflictos entre código, operaciones y políticas. Tampoco puede emitir un juicio independiente sobre la compatibilidad cuando evalúa su propio resultado.

¿Qué debe contener un plan de migración de sistemas heredados?

Para cada límite de comportamiento, registre sus pruebas, dependencias, destino, invariantes, diferencias permitidas, control de verificación y responsable de la decisión. El plan también debe definir condiciones de parada para que las pruebas ausentes o las diferencias sin explicar bloqueen la generación.

¿Qué debe extraer primero un equipo del código heredado?

Empiece por entradas, salidas, eventos programados, acciones de operadores, efectos persistentes y señales de error observables. Extraiga después la semántica de datos y la orquestación antes de implementar los algoritmos internos, porque esos límites dan un contrato al trabajo posterior.

¿Cómo se verifica la reescritura de un sistema heredado?

Reproduzca el mismo estímulo en el sistema antiguo y el nuevo desde estados equivalentes y compare cada efecto observable con reglas de normalización escritas. Clasifique cada diferencia como defecto, cambio aprobado, problema de pruebas o problema del entorno.

¿Bastan las pruebas unitarias para una migración heredada?

No. Las pruebas unitarias muestran que el código de destino se comporta como esperan sus autores, mientras que las pruebas de paridad muestran si coincide con el sistema sustituido. Necesita ambas, porque una implementación limpia puede aplicar fielmente una suposición equivocada.

¿Pueden los agentes de IA planificar una migración completa de código?

Los agentes pueden inventariar código, proponer correspondencias, generar partes acotadas e investigar pruebas fallidas. Los ingenieros siguen siendo responsables de la calidad de las pruebas, el orden de dependencias, las decisiones de arquitectura, la resolución de conflictos y la aceptación de cambios deliberados de comportamiento.

¿Debe una modernización conservar todos los comportamientos heredados?

No, pero cada diferencia debe ser intencionada. Conserve la ruta antigua en una prueba de paridad, registre por separado el cambio aprobado y pruebe la nueva regla para que una mejora deseada no oculte otro defecto de compatibilidad.

¿Cómo se tratan los campos no deterministas en las pruebas de paridad?

Escriba una regla de comparación limitada, como exigir que exista un identificador sin exigir su valor exacto o permitir una tolerancia temporal documentada. Nunca use una lista amplia de elementos ignorados, porque ocultará diferencias relevantes en otros lugares.

¿Cuándo debe decidirse la arquitectura de destino?

Fije pronto las restricciones firmes y los límites de seguridad, y aplace las decisiones que dependan del comportamiento descubierto. Decida las divisiones de servicios, la limpieza de datos y los flujos asíncronos solo cuando las pruebas muestren los límites de coherencia y responsabilidad que deben respetar.

¿Cuál es el primer control antes de generar código de migración?

Complete una entrada del registro con pruebas reales de entrada y salida, dependencias conocidas, invariantes explícitas, reglas de comparación y un responsable de los resultados en disputa. Si el registro está incompleto, el equipo debe seguir extrayendo en lugar de generar código de producción.