Honest disclosure
The Moon ceiling, in full.
Kriya's geocentric Moon residual against JPL Horizons is 0.87″ in apparent mode — the production path every consumer hits — and ~21″ in geometric mode(mean-only output, internal). Apparent mode is sub-arcsecond, better than the catalog's worst non-Moon body (Pallas at 2.84″). This page is the formal close on the “push the geometric Moon to sub-arcsec” question — the decision, the reasoning, and the two paths that could still get there.
Engine version: 9.31.1. Decision: ship the current Moon as the engine's stable baseline; further closure of the geometric residual is parked indefinitely.
What ships
lib/ephemeris/bodies/moon.ts
ELP/MPP02 (Chapront & Francou 2003, A&A 404, 735) + IAU 1980 nutation. Worst |Δλ| 0.87″ across 1899–2100 vs. Horizons (DE441).
Same MPP02 series without nutation. ~21″ residual — internal cross-validation only, never the production path.
moonMeanEclipticMeeus47 (truncated Meeus ch. 47, ~8″), moonMeanEclipticELP2000_82B (~30″ vs. DE441), and moonMeanEclipticLEA406 (LEA-406 Poisson-series; 20.97″ vs. Horizons, same DE405-fit ceiling).
The physics
Why the geometric residual is 21″ — and won't move with current methods.
Both MPP02 and LEA-406 were originally fit to JPL DE405/406. DE441 (the modern reference Horizons uses) shifts the lunar trajectory by 10–21″ depending on epoch — Lunar Laser Ranging accumulated a decade more data, and the fit moved.
No analytical lunar theory in the world fitted to DE405 can close the gap to DE441. This isn't a bug in our implementation — it's the published MPP02-vs-DE441 ceiling.
Two paths that could push past
Both multi-week. Both scoped, not hand-waved.
Path D — DE-441 binary refit of MPP02 amplitudes
- Download the JPL DE-441 SPK file (~3 GB binary).
- Implement a Chebyshev decoder for the SPK format — the file is a piecewise-Chebyshev representation; readers exist in C/Python/Fortran, but a home-grown one is required to honor the no-third-party-astronomy-data rule.
- Run a least-squares pipeline over MPP02's 25,000–35,000 perturbation amplitudes against DE-441 anchor dates spanning a multi-decade window.
- Validate the refit against held-out Horizons points.
- Wire the new coefficient table into
lib/ephemeris/bodies/mpp02/.
Why we haven't done this: the home-grown rule means we can't ship DE-441 as a binary at runtime — that's what “no third-party astronomy libraries or data” means as a product position. We canfit our analytical theory against DE-441 numbers — the binary stays a build-time input, not a runtime dependency — but writing the SPK decoder plus the least-squares pipeline is genuinely a multi-week build. A narrower attempt (refitting MPP02's 19 fit parameters) was tried and ruled out — those parameters control polynomial drift, not the 35k-amplitude perturbation series where the DE441 residual actually lives. A LEA-406 port was tried and shipped as the importable alternative; it hits the same DE405-fit ceiling.
Path C — Numerical n-body integration of the Moon
- Moon figure perturbation (J2 of the Moon) — currently absent.
- Solar tidal terms beyond a simple point-mass Sun.
- General-relativistic correction (Schwarzschild metric for the Sun-Earth-Moon system).
- Lunar Laser Ranging observation fit — the ~10–100 free parameters in the integrator's initial conditions need solving against decades of LLR range data.
- Validation against Horizons over 1899–2100.
- Wire as the production Moon path; retire MPP02 to importable-fallback status.
The integrator core (lib/ephemeris/integrator/dopri8.ts) is already proven on Pluto, the extended asteroids, and the TNOs at sub-arcsecond accuracy — the scaffold for this exists at scripts/integrate-moon.mjs and runs cleanly today (a documented rotation-matrix defect was fixed and verified by spin-axis roundtrip). Plugging the Moon in is feasible; the figure/tides/GR/LLR-fit physics above is the genuinely multi-week remainder.
When to revisit
Not a hypothetical ceiling to route around later.
Production callers hit the apparent path, where the Moon is already sub-arcsecond — the 21″ residual only surfaces if a caller specifically requests the geometric mean position, which is not the default anywhere in the API. We'll pick this back up if a customer specifically requires sub-arcsecond geometricMoon astrometry. Astrology consumers are on the apparent path and don't see the gap — as of this writing, no one has asked.
