# Precisão dos cálculos

## TL;DR

A API AstroWay usa o **Swiss Ephemeris** (código C oficial da Astrodienst,
criadores do astro.com) — o mesmo motor que os profissionais astraólogos usam há
mais de 30 anos em **Solar Fire ($495), Kepler ($995), Astro Gold ($29.99/mês) e
Janus**. Compilámo-lo para WebAssembly e expusemos uma camada REST, sem
intermediação de margens. Cada endpoint de cálculo básico é coberto por testes
regressivos de *snapshots*; a precisão do motor é verificada por **triangulação**
com três fontes independentes + contra o **NASA 5-Millennium Eclipse Catalog**:

- **Posições planetárias**: `< 0.1 arco-seg` vs o swetest CGI oficial da Astrodienst
- **Cúspides de casas Placidus**: `0.000"` correspondência exata
- **Eclipses**: `< 1 minuto` vs o Catálogo de Eclipses da NASA
- **Linhas ACG**: `< 1.5 km` no equador vs swetest
- **Nascer/por do Sol**: `< 10 segundos` vs timeanddate.com
- **VOC da Lua, ingressos e conjunções planetárias**: precisão até uma fração de segundo

## Motor

| Componente | Valor |
|------------|-------|
| Biblioteca | Swiss Ephemeris C code (aloistr/swisseph) |
| Versão | código C upstream da Astrodienst |
| Bindings | swisseph-wasm (WebAssembly no Node.js) |
| Efemérides | DE431 JPL ephemeris (via ficheiros .se1) |
| Fallback | Moshier analítico (para datas fora de 1800-2399) |
| Partilha de código | Shared `@/core` com app.astroway.info — um motor, dois transportes |

## Metodologia

A precisão é verificada por **triangulação** — comparação com três fontes
independentes:

### 1. swetest CGI (referência)

Implementação oficial de referência do Swiss Ephemeris da própria Astrodienst —
os criadores do **Astro.com** e que serve milhões de astrólogos em todo o mundo.
A fonte pública mais autoritativa. O nosso motor é **idêntico** (0.00–0.07
segundos de arco de desvio).

### 2. Kerykeion (Python)

Biblioteca Python independente que usa *bindings* `pyswisseph` em vez do nosso
WASM. Confirma que a nossa camada WASM não distorce os dados.

### 3. Prokerala API

API remota do Swiss Ephemeris (Lahiri sidereal). Desvio sistemático de 8–17
segundos de arco está relacionado com diferentes versões da fórmula Lahiri
ayanamsa, e **não** com a precisão do motor.

## Resultados da triangulação

| Carta | vs swetest (Astrodienst) | vs Kerykeion (Python) | vs Prokerala API |
|-------|---------------------------|------------------------|------------------|
| Monroe 1926   | **0.00"** | 0.19" | 16.95" (sistemático) |
| Diana 1961    | **0.00"** | 0.69" | 8.18" (sistemático)  |
| Einstein 1879 | 0.07"     | Artefacto LMT do Kerykeion | 14.96" (sistemático) |

## Conjunto regressivo ao nível dos endpoints

Cada endpoint de cálculo básico é coberto por testes *snapshots* congelados em 3
cartas de referência (Monroe / Diana / Einstein) = **{siteMeta.snapshotCount}
*snapshots***.

A suíte de *snapshots* deteta:

- **Erros de mapeamento de dados de entrada** — ID incorreto do planeta, UT,
  sistema de casas
- **Pós-processamento** — arredondamentos, conversão de unidades, perda de sinal
- **Divergência de valores padrão** — nó médio vs nó verdadeiro, geocêntrico vs
  topocêntrico
- **Desvio de *schema*** — validação que deixou passar uma forma incorreta
- **Implantação desatualizada** — dist da produção não corresponde ao código

Tolerância: `5e-5°` (≈0.18 segundos de arco) por defeito para todos os campos
numéricos.

## *Benchmarks* detalhados

### Posições planetárias (trópico, vs swetest)

| Carta | Data | Desvio máximo |
|-------|------|---------------|
| Marilyn Monroe  | 1926-06-01 | **0.00"** |
| Princesa Diana  | 1961-07-01 | **0.00"** |
| Albert Einstein | 1879-03-14 | 0.07"     |

### Cúspides de casas Placidus (vs swetest)

| Carta | desvio ASC | desvio MC | Desvio máximo da cúspide |
|-------|------------|-----------|--------------------------|
| Monroe | 0.000" | 0.000" | 0.000" |
| Diana  | 0.000" | 0.000" | 0.000" |

### Eclipses (vs NASA 5-Millennium Catalog)

| Evento | NASA máximo | Nosso máximo | Desvio |
|-------|-------------|--------------|--------|
| 2025-03-14 Lua Total  | 06:58 UT | 06:58 UT | 0.8 min |
| 2025-03-29 Sol Parcial | 10:47 UT | 10:47 UT | 0.5 min |
| 2025-09-07 Lua Total  | 18:11 UT | 18:11 UT | 0.8 min |
| 2025-09-21 Sol Parcial | 19:41 UT | 19:42 UT | 1.0 min |

### Astrocartografia (vs fórmula RA do swetest)

Todas as linhas MC/IC/ASC/DSC usam a fórmula correta `longitude = RA − GMST`
(padrão Kenneth Bowser). Desvio do padrão: **< 1.5 km** no equador para todos
os planetas.

### Nascer / Pôr do Sol (vs timeanddate.com)

| Localização | Data | Parâmetro | Desvio |
|-------------|------|-----------|--------|
| Londres | 2026-04-15 | Nascer do Sol | 0.6 s |
| Londres | 2026-04-15 | Pôr do Sol  | 9 s   |

**Localizações polares** (|lat| > 66.5°) devolvem automaticamente `polarState` +
aviso de que as horas planetárias comuns não estão definidas.

### Orbes de aspetos

O AstroWay usa **orbes variáveis** por planeta (regra MÍN de dois planetas),
como no ZET9 e astro.com. Orbes por defeito (para carta natal):

| Aspeto | Sol | Lua | Interior | Júpiter | Exterior |
|--------|-----|-----|----------|---------|----------|
| Conjunção | 12°  | 10° | 5° | 8° | 5° |
| Sextil   | 6.5° | 6°  | 5° | 5° | 5° |
| Quadratura | 10°  | 8°  | 5° | 7° | 5° |
| Trígono  | 12°  | 8°  | 5° | 5° | 5° |
| Oposição | 12°  | 10° | 5° | 8° | 5° |

Aspetos menores (36°, 40°, 45°, 72°, 108°, 135°, 144°) **estão desativados por
defeito**. Ativam-se explicitamente via `ALL_ASPECTS`.

## Latitudes polares

Para |lat| > 66.5° os sistemas Placidus / Koch / Regiomontanus não estão
matematicamente definidos. Nestes casos, o Swiss Ephemeris devolve automaticamente
Porphyry, e a nossa API adiciona um aviso:

```json
{
  "system": "P",
  "warning": "O sistema Placidus não está definido para lat=68.96° (> 66.5°). O Swiss Ephemeris substituiu por Porphyry..."
}
```

## Verificação contínua

A regressão é verificada **em cada PR** via CI:

- `api-calc/tests/endpoints/` — {siteMeta.snapshotCount} *snapshots* contra cartas
  de referência (Monroe / Diana / Einstein) + sinastria / composta / Davison
- `.github/workflows/api-accuracy.yml` — execução automática no PR
- Triangulação contra swetest CGI + Kerykeion — semanalmente
- Monitorização do Swiss Ephemeris upstream via Dependabot

## Limitações conhecidas

- **Datas fora do intervalo** (antes de 1800 e depois de 2399): usa-se o analítico
  Moshier, precisão ~0.1" (vs < 0.01" para SWIEPH com ficheiros DE431)
- **Lilith Verdadeira (id=13) vs Lilith Média (id=12)**: diferença até 12° — por
  defeito usa-se Lilith Média (comportamento estável), Lilith Verdadeira está
  disponível via `planetIds: [13]`
- **Topocêntrico vs geocêntrico**: por defeito geocêntrico

## Ligações

- Swiss Ephemeris: https://www.astro.com/swisseph/
- swetest CGI: https://www.astro.com/swisseph/swetest.htm
- Catálogo de Eclipses da NASA: https://eclipse.gsfc.nasa.gov/
- Kerykeion: https://github.com/g-battaglia/kerykeion
- Astrodienst: https://www.astro.com/

## Contactos

Para questões de precisão: escreve para support@astroway.info com os dados da
carta e a referência esperada (astro.com ou outra fonte autoritativa).
