La precisión es lo que el usuario comprueba en silencio contra Astrodienst. Si una carta natal se desvía un minuto de arco, la queja llega rápido. Y lo peor es que la precisión se rompe fácilmente sin que nadie lo note: una refactorización del código de efemérides y la mitad de los endpoints se desplazan en silencio unos segundos de arco.
Así es como evitamos que ocurra.
Un núcleo para dos entornos
Sección titulada «Un núcleo para dos entornos»Las posiciones planetarias las calcula Swiss Ephemeris. Lo esencial: nuestra aplicación y la API comparten el mismo núcleo de cálculo, la misma base de código. No hay dos implementaciones que puedan divergir, así que no hay nada que diverja.
Para fechas fuera del rango principal de las efemérides existe un fallback analítico (Moshier), algo más tosco pero sin saltos en los límites. Una honestidad deliberada: no anunciamos públicamente una versión concreta del motor, porque la versión real del núcleo es anterior al upstream más reciente, y poner una cifra llamativa sería mentir.
Snapshots congelados
Sección titulada «Snapshots congelados»Cada endpoint de cálculo tiene un conjunto de snapshots congelados: 888 fixtures JSON en el momento de esta build. El runner ejecuta el endpoint sobre cartas de referencia y lo compara byte a byte (dentro de una tolerancia) con el fixture. Cualquier desviación de la longitud de un planeta superior a 5e-5° (0.18″) hace fallar el test.
Las cartas de referencia están elegidas para golpear en los bordes, no solo en el centro “cómodo”:
- Monroe, Diana, Einstein, Bowie: cartas históricas con datos de nacimiento conocidos
- latitud polar: donde los sistemas de casas degeneran
- ecuatorial: donde se comportan de otra manera
- hemisferio sur: comprobación de la simetría especular
Los casos límite atrapan justo las regresiones que no se ven en la carta de alguien nacido en Kyiv.
Triangulación frente a fuentes externas
Sección titulada «Triangulación frente a fuentes externas»Los snapshots detectan regresiones respecto a sí mismos. Para comprobar la verdad absoluta, cada release se coteja con fuentes independientes:
| Contra qué | Qué comprueba | Diferencia |
|---|---|---|
| swetest CGI (Astrodienst) | longitudes planetarias, cúspides de las casas | 0.000″ |
| Kerykeion (Python, pyswisseph) | implementación independiente de SwEph | < 0.2″ |
| Prokerala (sidereal Lahiri) | posiciones siderales | 8-17″, diferencia sistemática en la fórmula del ayanamsa, no del motor |
| NASA 5-Millennium Eclipse Catalog | hora y tipo de los eclipses | < 1 хв |
La diferencia con Prokerala no es un error: son implementaciones distintas de la fórmula Lahiri, y lo documentamos explícitamente en lugar de ocultarlo. Con swetest, que es la referencia del sector, la deriva es cero.
Las líneas de astrocartografía se comprueban aparte de forma geométrica: la precisión en el ecuador es mejor que 1.5 km.
Qué se ejecuta en cada PR
Sección titulada «Qué se ejecuta en cada PR»La precisión es un gate de CI, no una comprobación puntual:
api-accuracy.yml: en cada PR al código del backend ejecuta todo el conjunto de snapshots más la triangulación. Un test en rojo bloquea el merge.check-eclipse-accuracy.yml: una vez al año coteja los eclipses con el catálogo de la NASA; una diferencia por encima del umbral abre un issue automáticamente.check-sweph-updates.yml: cada semana vigila el upstream de Swiss Ephemeris; una versión nueva abre un issue para revisión, sin automerge (actualizar el motor de efemérides es algo demasiado delicado para hacerlo automáticamente).
Qué le aporta esto al integrador
Sección titulada «Qué le aporta esto al integrador»La garantía es sencilla: posiciones planetarias a < 0.1 segundos de arco de la referencia Swiss Ephemeris, y ese límite lo protege la automatización, no una promesa en el README. Si algún día aparece una regresión, fallará en nuestro CI y no en la queja de tu usuario.
La versión pública de estas cifras, con la tabla de diferencias carta por carta, está en la página Precisión.
Posiciones al segundo de arco en 4 líneas de código.
Clave gratuita sin tarjeta. 5 000 llamadas al mes antes del primer pago.