2.1 KiB
2.1 KiB
Ephemeris Adapter Contract - 2026-06-23
Purpose: define the real engineering gate before xalen_ephemeris, vedastro, or any other candidate_backend can become a selectable runtime ephemeris source.
Contract
The executable contract lives in:
python3 scripts/ephemeris_adapter_contract.py
It defines EphemerisAdapterContract, PARITY_CASES, and JSON output fields that every backend must satisfy:
- input fields: UTC-adjusted birth date/time, latitude, longitude, timezone,
ayanamsa_policy,node_policy, andbody_list - output fields: sidereal longitude, sign, degree in sign, speed,
retrograde, nakshatra metadata when available,ayanamsa_value, backend name, and source metadata - baseline:
swisseph_python - candidate slot:
candidate_backend
acceptance_thresholds
The first parity gate is sun_moon_asc_nodes:
| Body | Max longitude_delta_arcsec |
|---|---|
| Sun | 1.0 |
| Moon | 1.0 |
| Ascendant | 5.0 |
| Rahu | 2.0 |
| Ketu | 2.0 |
These thresholds are strict enough to catch accidental tropical/sidereal, timezone, node, and ayanamsa mismatches, while leaving a small practical tolerance for backend representation differences.
Parity Matrix
Current PARITY_CASES:
| Case | Why it exists |
|---|---|
beijing_first_use_demo |
Reuses the first-use demo chart so product smoke and ephemeris smoke share a reference |
delhi_lagna_boundary |
Guards Ascendant, Lahiri ayanamsa, timezone, and mean-node behavior in an India-centered case |
new_york_moon_boundary |
Guards western timezone conversion and Moon/nakshatra boundary behavior |
Current decision:
swisseph_pythonremains the production baseline.swisseph_wasmremains the browser fallback and can later be compared through the same matrix.xalen_ephemerisremainsspike_onlyuntil a local adapter can produce this exact contract.vedastroremains a product/API benchmark unless used behind a service boundary that emits this contract.pyjhora_benchmarkremains AGPL benchmark-only and should provide oracle expected values, not copied implementation code.