Ingeniería de software sin poder reiniciar
El software espacial no puede fallar con elegancia. Así programan los ingenieros sistemas donde un error cuesta una misión de miles de millones de dólares.

Tu servidor web se cae a las 3 de la mañana. Kubernetes lo reinicia. Los usuarios ven una página de error breve. Nadie pierde el trabajo. Ahora imagina que tu servidor orbita Marte, el reinicio tarda 45 minutos (durante los cuales no tienes control de actitud, ni regulación térmica, ni comunicación), el «usuario» es una nave espacial de 2.500 millones de dólares y no hay Kubernetes, solo tu código y la CPU endurecida contra la radiación en la que se ejecuta.
El software espacial opera bajo restricciones que hacen que la ingeniería de software normal parezca un juego de niños. No puedes desplegar un hotfix. No puedes conectarte por SSH para revisar los logs. No puedes añadir servidores cuando aumenta la carga. Cada línea de código debe ser correcta antes del lanzamiento, porque después el software queda solo durante años o décadas, funcionando en hardware que la radiación degrada poco a poco, con un enlace de comunicación que tiene retrasos de varios minutos y un ancho de banda de kilobits por segundo.
Las restricciones que lo condicionan todo
Radiación. En el espacio, partículas de alta energía bombardean constantemente la electrónica. Una sola partícula puede invertir un bit en memoria (un «single-event upset», o SEU), corromper un registro o hacer que un procesador se bloquee. No es algo raro: los satélites en órbita baja sufren miles de inversiones de bits al día. El hardware para el espacio usa componentes endurecidos contra la radiación, que son más lentos, más caros y van generaciones por detrás del hardware de consumo. El procesador del rover Perseverance de Marte es un RAD750, más o menos equivalente a un PowerPC de 1998 a 200 MHz.
Retrasos de comunicación. Marte está a entre 4 y 24 minutos por radio (según su posición orbital). Júpiter, a entre 33 y 54 minutos. Esto no es solo latencia: significa que la nave debe gestionar cualquier problema de forma autónoma durante al menos el tiempo de ida y vuelta antes de que el control en tierra siquiera vea el problema, y mucho menos envíe un comando. Cuando las sondas Voyager encuentran una anomalía a más de 22 horas-luz de la Tierra, el software toma sus propias decisiones durante casi dos días.
Sin acceso físico. No puedes reemplazar un componente averiado, añadir RAM ni cambiar un disco duro. Si el ordenador principal falla y el de respaldo tampoco funciona, la misión ha terminado. Cada modo de fallo debe anticiparse en el software antes del lanzamiento.
En qué se diferencia el código espacial
El software espacial usa técnicas que en el desarrollo de software normal se considerarían absurdamente sobrediseñadas.
Redundancia modular triple (TMR). Los cálculos críticos se ejecutan tres veces en tres procesadores independientes. Un votante compara los tres resultados y se queda con la respuesta mayoritaria. Si un procesador obtiene un resultado erróneo por radiación, los otros dos lo superan en votos. Algunos sistemas usan cinco copias (redundancia quíntuple) para mayor seguridad.
Scrubbing de memoria. Un proceso en segundo plano lee la memoria continuamente, la verifica con códigos de corrección de errores (ECC) y corrige los errores de un solo bit antes de que se acumulen en errores de varios bits no corregibles. Esto se ejecuta constantemente: cada byte de memoria se comprueba y se corrige varias veces por segundo.
Temporizadores watchdog. Son temporizadores hardware que el software debe reiniciar periódicamente. Si el software se cuelga (quizá por un bloqueo causado por radiación), el temporizador expira y dispara un reinicio por hardware. El software debe diseñarse para sobrevivir a reinicios inesperados en cualquier punto de su ejecución: cualquier cálculo puede interrumpirse y volver a empezar.
// Simplified space software patterns
// Watchdog — must be kicked regularly or hardware resets
void main_loop(void) {
while (1) {
kick_watchdog(); // Reset the timer — we're alive
// All operations must complete within watchdog timeout
read_sensors();
kick_watchdog();
run_attitude_control();
kick_watchdog();
check_thermal_limits();
kick_watchdog();
process_ground_commands();
kick_watchdog();
}
}
// Critical value stored with redundancy
typedef struct {
int32_t value_a; // Primary copy
int32_t value_b; // Redundant copy
int32_t value_c; // Third copy for voting
} RedundantInt;
int32_t read_redundant(RedundantInt *r) {
// Majority vote — tolerates one corrupted copy
if (r->value_a == r->value_b) return r->value_a;
if (r->value_a == r->value_c) return r->value_a;
if (r->value_b == r->value_c) return r->value_b;
// All three differ — flag anomaly
raise_anomaly(MEMORY_CORRUPTION);
return r->value_a; // Best guess
}
Las pruebas son el producto
El Jet Propulsion Laboratory de la NASA calcula que las pruebas de software espacial consumen entre el 60 y el 80 % del esfuerzo total de desarrollo. No el 60 % del tiempo, sino el 60 % del coste total. Las pruebas cuestan más que el desarrollo porque tienen que demostrar la corrección en un grado que las pruebas de software normales ni se acercan a alcanzar.
Hay que probar cada camino de código. No el «alto cubrimiento de código» en el sentido que le dan los desarrolladores web, sino literalmente cada camino por cada función, incluidos los caminos de error, los de timeout y los que gestionan fallos de hardware. Una cobertura de ramas del 100 % es el punto de partida, no la meta.
Más allá de las pruebas unitarias, el software espacial pasa por pruebas hardware-in-the-loop (ejecutar el software real en el hardware de vuelo real, simulando el entorno espacial), pruebas de estrés de larga duración (funcionar durante meses para encontrar errores dependientes del tiempo) y pruebas de inyección de fallos (corromper memoria a propósito, matar procesadores y cortar enlaces de comunicación para verificar que el software se recupera).
La verificación formal se usa cada vez más en los componentes más críticos. En lugar de probar que el código funciona para entradas concretas, la verificación formal demuestra matemáticamente que el código funciona para todas las entradas posibles. Es cara y lenta, pero para el código que controla la actitud (orientación) de una nave o gestiona su propulsión, el coste está justificado.
Lo que sale mal de todos modos
A pesar de este rigor, el software espacial falla. Los fallos son instructivos porque revelan los límites incluso de la ingeniería más cuidadosa.
- Mars Climate Orbiter (1999) se estrelló porque un equipo usó unidades imperiales y otro, métricas. El software era correcto; los requisitos estaban mal. Ninguna cantidad de pruebas detecta una especificación errónea.
- Ariane 5, vuelo 501 (1996) explotó porque un float de 64 bits se convirtió en un entero de 16 bits y desbordó. El código se reutilizó del Ariane 4, donde el valor nunca superaba el rango de 16 bits. El código era correcto para el Ariane 4 y catastróficamente erróneo para el Ariane 5.
- Mars Polar Lander (1999) probablemente se estrelló porque la vibración de un sensor durante el despliegue de las patas se interpretó como contacto con el suelo, lo que apagó los motores a 40 metros de altura. Un problema de interpretación de sensor dependiente del tiempo que las pruebas no detectaron porque no replicaban con precisión las características de la vibración.
- El defecto inicial del espejo del Hubble (1990) no fue un error de software: el espejo se pulió con la forma incorrecta debido a un instrumento de medición mal calibrado. La herramienta de pruebas en sí tenía un error.
El hilo común: el código era correcto según su especificación, pero la especificación no coincidía con la realidad. Es el tipo de error más difícil de prevenir, porque existe en la brecha entre el modelo y el mundo.
Lo que el software terrestre puede aprender
La mayoría de nosotros no escribe software espacial. Pero algunas de estas prácticas se trasladan directamente a la construcción de sistemas fiables en la Tierra.
Diseña para el reinicio. El software espacial asume que puede reiniciarse en cualquier momento y debe recuperar un estado conocido y correcto. Los servicios web deberían tener esta propiedad también: si tu servidor se cae y se reinicia, ¿se recupera sin intervención manual? ¿Retoma el procesamiento donde lo dejó o pierde trabajo? Los patrones de ingeniería defensiva que los ingenieros espaciales consideran obligatorios suelen ser opcionales en el desarrollo web, y no deberían serlo.
Prueba los modos de fallo, no solo los caminos felices. Las pruebas de software espacial inyectan fallos de forma específica: matar un proceso, corromper memoria, cortar conexiones de red, devolver códigos de error en cada llamada al sistema. La mayoría de las pruebas de aplicaciones web se centran en si las funciones funcionan, no en si el sistema gestiona los fallos con elegancia.
Redundancia para los datos críticos. Si tu aplicación almacena datos caros de recrear (registros financieros, contenido de usuarios, estado de configuración), guárdalos de forma redundante y verifícalos con regularidad. La replicación de bases de datos es el ejemplo obvio, pero la redundancia dentro de la aplicación (checksums, validación, comprobaciones periódicas de integridad) detecta corrupciones que la replicación propaga.
Watchdogs para procesos críticos. Si un proceso no puede quedarse colgado, vigílalo. No basta con «¿el proceso está en ejecución?», sino «¿el proceso avanza?». Los health checks que verifican que el sistema realmente funciona (procesando peticiones, actualizando estado, cumpliendo plazos) detectan fallos que la monitorización a nivel de proceso no ve.
El nuevo software espacial
La industria espacial comercial (SpaceX, Rocket Lab, Planet) está cuestionando algunas de estas tradiciones. SpaceX usa Linux y C++ en las computadoras de vuelo de su Falcon 9, una herejía según los estándares aeroespaciales tradicionales. Planet Labs opera cientos de satélites pequeños y los trata más como un sistema distribuido que como hardware a medida: si un satélite falla, la constelación compensa.
Este cambio refleja una pregunta más amplia: ¿cuánta fiabilidad necesitas de verdad? Un rover de 2.500 millones de dólares para Marte justifica cinco años de pruebas. Un satélite de comunicaciones de 500.000 dólares, uno de cientos en una constelación, justifica mucho menos. La práctica de ingeniería debe ajustarse al perfil de riesgo, no seguir a ciegas tradiciones nacidas en otra época.
Pero la lección central se mantiene sin importar el presupuesto: el software al que no se puede acceder físicamente después del despliegue debe ser más fiable que el que sí se puede. Tanto si lanzas una nave espacial como si desplegarás una flota de IoT o gestionas una red de edge computing, el principio es el mismo: si no puedes conectarte por SSH para arreglarlo, el software tiene que resolverlo por sí mismo. Esa mentalidad, aplicada con criterio, mejora todo el software.


