pyswisseph to rozszerzenie C, a na PyPI (2.10.3.2) gotowe wheels koncza sie
na cp311 i obejmuja wylacznie i686/x86_64. Obraz stoi na python:3.12-slim,
wiec pip ZAWSZE kompilowal ze zrodel - a slim nie ma kompilatora. Stad fail.
- Dockerfile wieloetapowy: kompilacja w etapie builder (build-essential),
do runtime trafia juz tylko gotowy wheel - obraz zostaje czysty i maly.
Dziala tez na arm64, gdzie wheeli linuksowych nie ma dla zadnej wersji.
- sanity check (import swisseph) na etapie builda, zeby niedzialajacy silnik
wywracal build, a nie dopiero pierwszy request.
- CI: nowy job swisseph-image - realny docker build + smoke test /health
i /positions na horoskopie referencyjnym.
- README: udokumentowany powod wieloetapowego builda.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pierwszy increment implementacji warstwy logicznej (ścieżka A).
LOG-24: interfejs EphemerisEngine z dwoma backendami — SkyfieldEngine
(własny, permisywny: Skyfield MIT + dane JPL public domain) oraz
RemoteEngine (klient izolowanej usługi swisseph). Fabryka + leniwa
inicjalizacja; endpointy /chart/positions i /chart/compare.
LOG-01: pozycje obiektów (długość/szerokość ekliptyczna, prędkość,
kierunek, formaty: w znaku / absolutny / dziesiętny).
LOG-25/28: harness porównawczy (compare.py) z progami tolerancji oraz
wspólny kontrakt parzystości; pełen zestaw testów.
LOG-27: services/engine-swisseph — osobna, opcjonalna usługa AGPL
(pyswisseph, tryb Moshiera), licencjonowana osobno, w compose pod
profilem "comparison"; nie wchodzi do zamkniętego produktu.
Walidacja: SkyfieldEngine zgadza się ze Swiss Ephemeris co do ~1" dla
wszystkich 10 obiektów na horoskopie referencyjnym (30.04.1984, Warszawa);
12 testów przechodzi (silnik B pomijany gdy nieskonfigurowany).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>