A precisão é aquilo que o utilizador verifica em silêncio no Astrodienst. Se um mapa natal divergir num minuto de arco, a reclamação chega depressa. E o pior é que a precisão se estraga facilmente sem ninguém dar por isso: uma refatoração no código das efemérides e metade dos endpoints desliza em silêncio alguns segundos de arco.
É assim que evitamos que isso aconteça.
Um núcleo para dois ambientes
Seção intitulada “Um núcleo para dois ambientes”As posições planetárias são calculadas pelo Swiss Ephemeris. O essencial: a nossa aplicação e a API partilham o mesmo núcleo de cálculo, a mesma base de código. Não há duas implementações que possam divergir, portanto não há nada que possa divergir.
Para datas fora do intervalo principal das efemérides existe um fallback analítico (Moshier), um pouco menos preciso, mas sem descontinuidades nas fronteiras. Honestidade deliberada: não anunciamos publicamente a versão concreta do motor, porque a versão real do núcleo é inferior à mais recente do upstream, e escrever um número vistoso seria mentir.
Snapshots congelados
Seção intitulada “Snapshots congelados”Cada endpoint de cálculo tem um conjunto de snapshots congelados: 873 fixtures JSON no momento deste build. O runner executa o endpoint sobre mapas de referência e compara o resultado byte a byte (dentro da tolerância) com a fixture. Qualquer desvio da longitude planetária superior a 5e-5° (0.18″) faz o teste falhar.
Os mapas de referência foram escolhidos para atingir os extremos, e não apenas o centro “confortável”:
- Monroe, Diana, Einstein, Bowie: mapas históricos com dados de nascimento conhecidos
- latitude polar: onde os sistemas de casas degeneram
- equatorial: onde se comportam de outra forma
- hemisfério sul: verificação do espelhamento
São precisamente os casos-limite que apanham as regressões que não se veem no mapa de um habitante típico de Kyiv.
Triangulação contra fontes externas
Seção intitulada “Triangulação contra fontes externas”Os snapshots apanham regressões em relação a si próprios. Para verificar a verdade absoluta, cada release é comparada com fontes independentes:
| Contra quê | O que verifica | Divergência |
|---|---|---|
| swetest CGI (Astrodienst) | longitudes planetárias, cúspides das casas | 0.000″ |
| Kerykeion (Python, pyswisseph) | implementação independente do SwEph | < 0.2″ |
| Prokerala (sidereal Lahiri) | posições siderais | 8-17″, diferença sistemática na fórmula da ayanamsa, não no motor |
| NASA 5-Millennium Eclipse Catalog | hora e tipo dos eclipses | < 1 min |
A divergência em relação ao Prokerala não é um erro: são implementações diferentes da fórmula de Lahiri, e documentamos isso explicitamente em vez de o esconder. Com o swetest, que é a referência da indústria, o desvio é zero.
As linhas de astrocartografia são verificadas à parte, geometricamente: a precisão no equador é melhor do que 1.5 km.
O que corre em cada PR
Seção intitulada “O que corre em cada PR”A precisão é um gate de CI, não uma verificação pontual:
api-accuracy.yml: em cada PR ao código do backend, executa todo o conjunto de snapshots + a triangulação. Um teste vermelho bloqueia o merge.check-eclipse-accuracy.yml: uma vez por ano compara os eclipses com o catálogo da NASA; uma divergência acima do limiar abre automaticamente uma issue.check-sweph-updates.yml: todas as semanas acompanha o upstream do Swiss Ephemeris; uma nova versão dá origem a uma issue para revisão, sem automerge (atualizar o motor de efemérides é demasiado sensível para uma atualização automática).
O que isto dá ao integrador
Seção intitulada “O que isto dá ao integrador”A garantia é simples: posições planetárias dentro de < 0.1 segundo de arco do Swiss Ephemeris de referência, e esse limite é protegido por automação, não por uma promessa no README. Se alguma vez surgir uma regressão, ela vai falhar no nosso CI, e não na reclamação do teu utilizador.
A versão pública destes números, com a tabela de divergências por mapa concreto, está na página Precisão.
O mesmo Swiss Ephemeris que no Solar Fire - em 4 linhas de código.
Chave gratuita sem cartão. 5 000 chamadas por mês até o primeiro pagamento.