Skip to main content

High-precision HDC reference instrument for the Sol Star System based on JPL DE441 (native C backend, runtime kernel patching, 52-body roster including Lagrange trojans + retrograde irregulars; per-body Sol Geodetic / Electromagnetic / Magnetic-Multipole catalogs; resonance-graph ITN-chain search + spectral body-architecture surfaces; SPICE-free runtime)

Project description

ephemerides-spectral

High-precision HDC reference instrument for the Sol Star System.

Status: v0.21.0 — production-ready. Two-stage architecture: three interchangeable integer-ALU phase-residue encoders (bip Python / c native / complex128 Python reference) feeding an FPU complex64 HD pipeline (syzygy / observer-bind / eclipse-probability); 52-body roster (v0.16.0 Tier-1 expansion: +4 Saturnian Lagrange trojans (Telesto/Calypso at Tethys L4/L5; Helene/Polydeuces at Dione L4/L5 — first L4/L5 entries in BODIES, multiplicity-2 Laplacian degeneracy at host frequency) + 3 Jovian irregulars (Himalia/Pasiphae/Sinope) + Proteus/Nereid (Neptune sub-graph completion); resonance-graph multi-leg find_itn_chains (v0.17.0 — Dijkstra-style graph search over the (body, epoch) state space generalising the v0.8.1 closed-form Hohmann anchor to multi-leg pathways with small-integer (p, q) gear-ratio resonance signatures per leg; pure-Python addition built on top of find_itn_pathways, no ABI bump); bridge.body_architecture (v0.18.0 — first spectral-architecture surface, classifying heliocentric bodies into the canonical inner-8 / outer-5 partition via the resonance-weighted gateway-graph Laplacian Fiedler vector; the cyclic-group encoder discovers the asteroid-belt boundary without being told it exists; Pluto and Neptune share the deepest outer entry via their 2:3 mean-motion lock; pure-Python addition, no ABI bump; research origin notebook §13.8); bridge.predict_itn_accessibility (v0.18.1 → v0.18.2 — closed-form spectral Δv estimate from the §13.9 hybrid Fiedler-distance regression; v0.18.2 upgraded to a 2-D (f₂, f₃) embedding with R² 0.51 → 0.64 and LOOCV MAE 4.24 → 3.12 km/s; useful for fast first-pass triage at microseconds-per-query vs ~1.5 s for the full Dijkstra; not for trajectory design; research origin notebook §13.9 / §13.10 / §14); Sol Electromagnetic Instrument (v0.19.0 — state-at-epoch query surface for the EM sector with bridge.get_em_state(jd_tdb) / list_em_couplings() / em_architecture(target=None); 16-body roster (1 star + 7 magnetised + 4 induced + 4 unmagnetised) + 7 pairwise EM couplings (Jupiter–Io flux tube headliner at ~10¹² W; Saturn–Enceladus, Saturn–Titan, Sun–Earth IMF, Jupiter–Europa, Jupiter–Ganymede, Sun–asteroid radiation pressure); not a BIP encoder — EM clocks don't form a low-order rational lattice with orbital periods so the cyclic-group discipline doesn't transplant; research origin notebook §16); full Sol Symphony Times; Sol Terra-Luna Time (STLT) with Meton's 432 BCE solstice as the default epoch; Sol Proper Time (SPrT) with --proper; Sol Kinematics (v0.12.0) with --state and kinematics query; Sol Dynamics (v0.13.0) with --dynamics and dynamics query — system energy / per-body energy budgets / pair-wise gravitational forces, validated against the textbook 3.54×10²² N Earth-Sun figure to 0.01 % and the virial theorem to 0.5 %; adaptive ("breathing") couplings under their mainstream-literature name (Gross & Blasius 2008); JPL Power-of-Ten audit baseline (v0.11.2) with all ten rules satisfied (v0.13.4 + v0.13.5 + v0.13.6 + v0.13.7 + v0.13.9 — Rules 1, 3, 4, 5 source-side ratchet-pinned; Rule 10 enforced via cross-platform pedantic-build CI matrix; Rules 6+7 manual audits clean); pre-merge docs+parity hygiene check (v0.13.3) as a soft-warning GitHub Actions workflow. See the Status section below for the version-by-version landing record.

Overview

ephemerides-spectral is a hyperdimensional-computing instrument that encodes the barycentric state of our star system using high-precision ephemeris data (NASA JPL DE441 / DE442) as resonant phases over a graph Laplacian.

Two-stage architecture: integer-ALU phase residues, then FPU HD lift

The package separates the phase-residue computation (integer ALU, no FPU on the hot path) from the HD operations (syzygy projection, observer-bind, eclipse-probability — necessarily FPU because channel bases are unit-magnitude complex). The phase-residue stage has three interchangeable encoders; the HD stage runs complex64 natively or complex128 as the reference.

Phase-residue encoders (integer ALU)

  • bip (default) — bit-serialised integer ALU in pure Python. Phase composition lives in the cyclic group Z_{2^32}; binding is (φ_1 + φ_2) mod 2^32, which is implicit uint32 overflow — no FPU in the hot path. 305× faster than the FPU reference; 256 KB state at D=65536. Always available.
  • c (v0.3.1+) — native C library (libephemerides_spectral.{so,dll,dylib}) bundled in the platform wheel under _native/, loaded via ctypes. Byte-for-byte identical phase residues to bip; ~1000× speedup on the chunk loop (encode at +20 yr: 46 ms Python → 0.04 ms C). Falls back transparently to bip if the binary isn't loadable (sdist installs without a C toolchain, Pyodide / WASM, the pure-Python fallback wheel).

All three phase-residue encoders implement the same algebraic substrate (cyclic-group representation of celestial phase-space, graph-Laplacian eigenbasis) and produce identical uint32[38] residues at any JD; they trade precision for speed (the integer-ALU encoders are exact in Z_{2^32}; the complex128 reference is float-ULP-quantised).

HD pipeline (FPU, complex64 production / complex128 regression)

Once the integer phase residues are computed, the HD operations (syzygy operator, observer-bind, eclipse-probability) lift them to a D-dimensional hypervector. This stage is necessarily FPU because the channel bases are (cos(φ), sin(φ)) complex pairs.

  • backend="auto" (default for get_local_view / get_eclipse_probability) — selects c if the native binary is loaded (Tier 2b ABI v6), else falls back to bip integer phases lifted via the Python complex64 shim.
  • backend="c" — Tier 2b in C (es_encode_state_hd / es_bind_observer / es_get_eclipse_probability); complex64 storage (single-precision); ABI v6 since v0.7.0; parity smoke pins both paths to within float-ULP.
  • backend="fpu-ref" — Python complex128 reference encoder with unit-norm complex Gaussian bases. Regression baseline only; used to validate the c and bip paths against double-precision ground truth, not as the production HD path. Kept for the same reason scientific software keeps reference implementations alongside production ones.

TL;DR on "pure ALU": phase residues are integer ALU end-to-end (BIP encoder hot path is uint64/int64/uint32, no floats); HD operations (syzygy / observer-bind / eclipse) lift those residues to complex64 and run on FPU. The package is not pure-ALU end-to-end — the HD pipeline can't be, because complex-magnitude bases require trigonometric channels. The integer-ALU discipline applies to the encoder hot path and is enforced by the JPL Power-of-Ten audit (Rule 10 pedantic-build matrix).

Companion Project

ephemerides-spectral lives in the same docs/antikythera-maths/ folder as antikythera-spectral because the two share the spectral / cyclic-group framing and the Pyodide bridge contract. They are not consolidated: antikythera-spectral encodes a specific bronze-age mechanism (940-tooth Callippic gear DAG) while ephemerides-spectral encodes the live JPL DE441 ephemeris with phase-dependent (breathing) gravitational couplings. The chess-spectral notebook §20.13–§20.17 calls out the cross-pollination — chess uses Z_{640} (paying an explicit % 640 per op); ephemerides uses Z_{2^32} (free uint32 overflow).

Key Capabilities

  • Graph Laplacian Propagator: Diagonal content = Newtonian mean motions + Mercury 43"/century post-Newtonian correction. Off-diagonal = gravitational fiber couplings (planet-sun, moon-planet, mean-motion resonances, asteroid-Jupiter).
  • Phase 9 Adaptive Couplings (a.k.a. "breathing") (v0.9.2 CLI rename): Off-diagonal weights modulate with the resonant phase difference cos(n_a·φ_a − n_b·φ_b). Formally a state-dependent (non-autonomous) graph Laplacian / adaptive Kuramoto-family network with phase-difference-dependent coupling (Gross & Blasius 2008, "Adaptive coevolutionary networks") — see the research notebook §1.4 for the full positioning across spectral-graph-theory / dynamical-systems / DNLS-on-a-graph vocabularies. CLI: ephemerides-spectral adaptive --jd ... (canonical) or ephemerides-spectral breathing --jd ... (visual-metaphor synonym; same handler, identical output). Implemented end-to-end without FPU using a 1024-entry int32 cosine LUT (Q1.14 amplitude, 4 KB).
  • Sol Star System Roster (v0.5.0+): 38 bodies — Sun, 9 planets (incl. Pluto), 24 moons, 4 main-belt asteroids. The moon set covers Earth's Moon, Mars's Phobos / Deimos, all 4 Galileans (Io, Europa, Ganymede, Callisto) plus the 4 inner regulars (Metis, Adrastea, Amalthea, Thebe), the canonical 9 Saturnians (Mimas, Enceladus, Tethys, Dione, Rhea, Titan, Hyperion, Iapetus, Phoebe) plus the Janus / Epimetheus co-orbitals, Uranus's Titania, and Neptune's Triton.
  • Mean-motion resonances (v0.5.0+): 7 entries in RESONANCES — Jupiter–Saturn 5:2, Neptune–Pluto 3:2, Io–Europa 2:1, Europa–Ganymede 2:1, Mimas–Tethys 4:2 (Cassini Division), Enceladus–Dione 2:1 (powers Enceladus tidal heating), Titan–Hyperion 4:3 (Hyperion's chaotic rotation). Natural-resonance gear group: Z_60 = Z_4 × Z_3 × Z_5.
  • Runtime kernel patching (v0.4.0+): Diagnosed-fiber overlay — patches sit beside the published kernel as DATA, not code edits, and contribute per-body residue deltas at encode time. Inspired by Linux ksplice / kpatch; the kernel's published bytes never change. Bridge surface: apply_patch(name) / apply_custom_patch(...) / clear_patches(). Three patches in the bundled CATALOG authored from the v0.3.1 FFT residual analysis. v0.5.1 patch-shrinks-residual benchmark measured the catalog and showed partial vindication: J–S coupled patch shrinks both bodies' residuals by ~77% with phase-recovered authoring (research-side; stays out of the v0.5.x catalog until ≥80% on every body); Mars stays stuck at 3% due to FFT bin leakage. v0.5.2 adds windowed FFT + multi-bin patches for full predictive power.
  • SPICE-free runtime (v0.5.0+): pip install works out of the box — both backends use codegen-baked initial phases shipped in _data/initial_phases.json. No SPICE kernel staging required for basic encoding. Skyfield + jplephem stay as optional [ephemeris] extras for callers who want runtime recalibration against custom kernels.
  • Observer-Agnostic Views: Unitary binding to generate topocentric "Local View" hypervectors at any (lat, lon) on any body.
  • Spectral Syzygy Window Search (v0.3.1+): find-syzygies --from-jd ... --to-jd ... enumerates candidate syzygies in closed form via the natural cyclic-group decomposition (synodic + draconic month), then confirms each by spectral projection. ~1000× faster than the v0.3.0 point-evaluation eclipse --jd pattern for window queries.
  • ITN Pathway / Lagrange-Tube Query (v0.8.1+): find-tubes --from-jd ... --to-jd ... --departure terra --target mars enumerates Hohmann transfer windows via the same closed-form find-syzygies discipline. "Surfing the perturbations" — the natural cyclic structure tells you when launch windows open without integrating any trajectories. First-cut Hohmann math; future versions layer low-energy / heteroclinic-tube candidates under the same surface (transfer_kind field reserves room). References: Koon-Lo-Marsden-Ross 2011; Lo's Genesis trajectory work.
  • Sol Symphony Times (v0.3.0 + v0.5.4 + v0.8.0 + v0.9.1): every body in the Sol Star System has a "Sol Time" exposing its rotational + orbital cycles anchored to a conventional epoch — Mars Sol Date / Mars Coordinated Time (Allison & McEwen 2000), Sol Lunar Time (Luna's synodic + sidereal phase observed from Terra), Sol Uranian Time (USD/SUT, anchored at the 2007 northern equinox), Sol Venus / Sol Mercury / Sol Pluto / Sol Terra / Sol Luna (rocky bodies + Sun + Luna in direct Latin proper-noun form), Sol Sol (the Sun, Carrington rotation system), Sol Jovian / Sol Saturnian / Sol Neptunian (gas/ice giants in established adjective form). The Solar System is a natural symphony of overlapping clocks; Sol Time is just the package telling you what time it is on each body so you can correlate that body's local clock with JD. Naming hierarchy for future moon ports: Sol <Parent>-<Body> Time (e.g., Sol Pluto-Charon Time).

Naming convention (v0.9.x)

The body-identity strings use Latin proper nouns: terra, luna. The generic English words earth (= soil, ground) and moon (= any natural satellite) return to their generic meanings.

"Returning to the giants whose shoulders we stand on. We've always had a lunar orbit and a lunar eclipse. We've all had terrain and terrestrial animals. We're just putting the books back in their dewey decimal spot. We no longer kow tow for the sake of leaning forward."

The adjective forms lunar, terran, terrestrial always derived from Luna and Terra — the language already carried the convention. v0.9.0 made the body-identity strings reflect what the language always implied. v0.9.1 extends this to the Sol Time series itself: rocky bodies + Sun + Luna use direct Latin proper nouns; gas/ice giants keep the established astronomical adjective forms (Jovian, Saturnian, Uranian, Neptunian).

Body Sol Time Abbrev CLI
Mercury Sol Mercury Time SMeT time-mercury
Venus Sol Venus Time SVT time-venus
Terra Sol Terra Time STT time-terra
Mars Sol Mars Time (= MSD/MTC) SMaT time-mars
Luna Sol Terra-Luna Time STLT time-terra-luna
Jupiter Sol Jovian Time SJT time-jupiter
Saturn Sol Saturnian Time SST time-saturn
Uranus Sol Uranian Time SUT time-uranus
Neptune Sol Neptunian Time SNT time-neptune
Pluto Sol Pluto Time SPT time-pluto
Sol Sol Sol Time SSoT time-sol

Moons follow the Sol <Parent>-<Body> Time convention — Luna's primary Sol Time is Sol Terra-Luna Time (STLT) because Luna is gravitationally bound to Terra; the Parent-Body name keeps the moon-stuck-to-parent relationship visible in the time hierarchy. STLT counts synodic months from a historically-significant epoch (default: Meton's 432 BCE summer solstice). The future Pluto-Charon, Jupiter-Io, Saturn-Titan, etc. moon Sol Times will follow the same Sol <Parent>-<Body> Time pattern — see task #86.

A separate, lower-level Sol Luna Time (SLT) also exists — Luna's tidally-locked surface clock (sidereal=orbital=27.32 d, solar=synodic=29.53 d) anchored at J2000. SLT is queryable via time-luna and bridge.jd_to_sol_luna_time; it's the right surface for "what time is it on Luna's prime meridian" rather than "how many synodic months since a Greek-historical event." The two are complementary, not redundant: STLT is anchored Lunar time (count); SLT is Luna's clock (rate).

Resolution Scaling

Temporal resolution of a residue shift scales inversely with hypervector dimension D:

D Earth resolution Use case
2^16 ~8 minutes default; long-term mapping
2^19 ~1 minute medium-cadence events
2^25 ~1 second high-cadence local readout

Installation

pip install ephemerides-spectral

For full ephemeris support (skyfield + JPL DE-kernels):

pip install "ephemerides-spectral[ephemeris]"

CLI Usage

The package ships a rich ephemerides-spectral console script. Use --help on the top-level or any sub-command:

ephemerides-spectral --help
ephemerides-spectral encode --help
ephemerides-spectral adaptive --help

Sub-command Cheat-Sheet

# Package version + frozen-data manifest
ephemerides-spectral version

# All 38 bodies in the Sol Star System Laplacian
ephemerides-spectral bodies

# Earth temporal resolution at the default D=65536
ephemerides-spectral resolution --body terra

# Encode J2000 with the integer ALU backend (default)
ephemerides-spectral encode --jd 2451545.0

# Same JD with the FPU complex128 reference encoder
ephemerides-spectral encode --jd 2451545.0 --backend complex128

# Topocentric view from London at J2000
ephemerides-spectral local-view --jd 2451545.0 --body terra --lat 51.5 --lon -0.1

# Syzygy alignment probability AT a JD (point evaluation; encode-then-check).
# For window queries, see `find-syzygies` below (closed-form spectral search,
# ~1000× faster than encode-then-check across long windows).
ephemerides-spectral eclipse --jd 2451545.0

# Off-diagonal couplings (Laplacian fiber bundle)
ephemerides-spectral couplings

# Phase 9 adaptive (a.k.a. "breathing") coupling modulation
# (Jupiter-Saturn 5:2 by default). Both `adaptive` and `breathing`
# work — `adaptive` is the canonical name (matches the adaptive-
# networks / adaptive-Kuramoto literature, Gross & Blasius 2008);
# `breathing` is the visual-metaphor synonym, kept for users who
# learned the couplings as inhaling/exhaling with the resonant phase.
ephemerides-spectral adaptive --jd 2458850.0

# Override resonance: 3:2 Neptune-Pluto
ephemerides-spectral adaptive --jd 2451545.0 \
    --pair-a neptune --pair-b pluto --n-a 3 --n-b 2

# Synonym (same handler, identical output):
ephemerides-spectral breathing --jd 2458850.0

# Mars Sol Date / Mars Coordinated Time at a JD (v0.3.0)
ephemerides-spectral time-mars --jd 2451549.5     # → MSD ≈ 44795.99
ephemerides-spectral time-mars --msd 50000        # invert: MSD → JD_UTC

# Mean lunar synodic + sidereal age/phase at a JD (v0.3.0)
ephemerides-spectral time-lunar --jd 2451545.0

# Sol Uranian Time (v0.5.4) — third planetary time system alongside Mars + Lunar
# USD (sidereal-day count since 2007 northern equinox), SUT (Uranian time-of-day),
# orbital phase + season, retrograde flag.
ephemerides-spectral time-uranus --jd 2454451.0   # → USD = 0.0 at SUT epoch
ephemerides-spectral time-uranus --usd 4046       # invert: USD → JD_TDB

# Sol Symphony Times (v0.8.0) — Venus, Mercury, Pluto, Sol (the Sun!),
# Jupiter, Saturn, Neptune each have their own "Sol Time" exposing rotational + orbital phase.
# Each handles its body's quirks: Mercury's 3:2 spin-orbit resonance, Venus's
# retrograde rotation (sidereal day > year!), Sol's differential rotation
# (Carrington system), Jupiter System III, Saturn Cassini-revised System III.
ephemerides-spectral time-venus --jd 2451545.0
ephemerides-spectral time-mercury --jd 2451545.0  # 3:2 resonance: solar day = 2 × year
ephemerides-spectral time-pluto --jd 2457217.0    # New Horizons closest approach
ephemerides-spectral time-sol --jd 2451545.0      # Sun's own Carrington Rotation Number
ephemerides-spectral time-jupiter --jd 2444000.5
ephemerides-spectral time-saturn --jd 2451545.0
ephemerides-spectral time-neptune --jd 2451545.0

# Sol Terra Time (v0.9.1) — Terra's surface clock
# Sidereal day 23h 56m 4s (rotation rel. stars), solar day 24h (rel. Sun)
ephemerides-spectral time-terra --jd 2451545.0    # J2000 anchor

# Sol Luna Time (v0.9.1) — Luna's surface clock
# Tidally locked: sidereal=orbital=27.32d, solar=synodic=29.53d
# DISTINCT from Sol Lunar Time (time-lunar) which gives Luna's phase observed from Terra
ephemerides-spectral time-luna --jd 2451545.0     # J2000 anchor

# ITN pathway / Lagrange-tube query (v0.8.1) — Hohmann transfer windows
# "surfing the perturbations" via closed-form synodic enumeration
ephemerides-spectral find-tubes --from-jd 2451545.0 --to-jd 2470000.0 \
    --departure terra --target mars
# Output: 23 Terra->Mars windows over ~50 years, each with transfer time
# (~258.9 days) + total Δv (~5.59 km/s)

# Lunar-time kernel metadata (LTE440 + LTC status; v0.3.0)
ephemerides-spectral lunar-kernels

# Resonance-derived natural cyclic group (v0.3.0; expanded to Z_60 in v0.5.0)
ephemerides-spectral natural-group     # → Z_60 = Z_4 × Z_3 × Z_5

# Spectral-native syzygy window search (v0.3.1+)
# Replaces the v0.3.0 point-evaluation `eclipse --jd` for window queries.
# ~1000× faster than encode-then-check; uses the closed-form Saros /
# Metonic / synodic / draconic-month enumeration.
ephemerides-spectral find-syzygies --from-jd 2460311 --to-jd 2460676

# Diagnosed-fiber runtime kernel patching (v0.4.0+)
# Patches sit beside the published kernel as DATA, not code edits, and
# contribute per-body residue deltas at encode time. The kernel's
# published bytes never change. Bundled catalog (11 patches as of v0.5.5):
#   v0.4.0 originals (3): mars-7.96yr-diagonal, mercury-10.69yr-diagonal,
#                         jupiter-saturn-9.56yr-coupled
#   v0.5.2 LS-fit recovered (3, planets ≥96% shrinkage): same names with -v2 suffix
#   v0.5.5 LS-fit moons (5, ≥93% shrinkage): dione/tethys/enceladus/titan/iapetus -v2
ephemerides-spectral patches catalog
ephemerides-spectral patches apply --name jupiter-saturn-9.56yr-coupled-v2
ephemerides-spectral patches active
ephemerides-spectral patches clear

All sub-commands emit JSON to stdout; pass --no-pretty (top-level flag, before the sub-command) for compact single-line output suitable for piping into jq or downstream tooling. Every response carries an ok field; ok: false returns exit code 1 with an error message.

Python API

from ephemerides_spectral import default_encode, bridge

# One-liner: encode a JD as a system state under the default backend.
state = default_encode(jd=2451545.0)            # uint32[52] residues (BIP)
state = default_encode(jd=2451545.0, backend="complex128")  # complex128[D]

# JSON-friendly bridge surface (Pyodide / web frontend)
bridge.get_version()                             # version + manifest
bridge.list_bodies()                             # 52-body roster (v0.16.0+)
bridge.get_resolution(body="mars", D=65536)      # sec/residue
bridge.get_system_state(jd_tdb=2451545.0)        # encode + per-body residues
bridge.get_local_view(jd_tdb=2451545.0, body="terra", lat=51.5, lon=-0.1)
bridge.get_eclipse_probability(jd_tdb=2451545.0)
bridge.list_couplings()                          # Laplacian fibers
bridge.find_itn_pathways(2451545.0, 2470000.0,
                         departure="terra", target="mars")  # v0.8.1 single-leg Hohmann
bridge.find_itn_chains(2451545.0, 2470000.0,
                       departure="terra", target="jupiter",
                       intermediates=["venus", "mars"])     # v0.17.0 multi-leg ITN
bridge.body_architecture(target="terra")          # v0.18.0 inner/outer Fiedler partition
bridge.predict_itn_accessibility(departure="terra",
                                 target="jupiter") # v0.18.1 spectral Δv estimate
bridge.get_breathing_modulation(jd_tdb=2451545.0)  # Phase 9 LUT inspector

# v0.3.0 surface
bridge.jd_to_mars_time(jd_utc=2451549.5)         # MSD + MTC (Allison & McEwen 2000)
bridge.mars_time_to_jd(msd=50000)                # MSD → JD_UTC inverse
bridge.get_lunar_phase(jd_tdb=2451545.0)         # mean synodic + sidereal phase
bridge.list_lunar_kernels()                      # LTE440 metadata + LTC status
bridge.get_natural_resonance_group()             # Z_60 = Z_4 × Z_3 × Z_5 (v0.5.0+)

# v0.4.0 surface — runtime kernel patching (overlay on the spectral kernel)
# Catalog grows over time; v0.6.1 ships 11 entries:
#   v0.4.0 originals (3): mars/mercury/jupiter-saturn at FFT-magnitude amplitudes
#   v0.5.2 LS-fit recovered (3, planets at ≥96% shrinkage): -v2 suffix
#   v0.5.5 LS-fit moons (5, ≥93% shrinkage): dione/tethys/enceladus/titan/iapetus -v2
bridge.list_catalog_patches()                    # bundled CATALOG (11 patches)
bridge.apply_patch("jupiter-saturn-9.56yr-coupled-v2")  # vindicated v0.5.2 entry
bridge.apply_custom_patch(name="my-patch", kind="sinusoid",
                          body="terra", amplitude_deg=0.93,
                          period_days=1940.2)    # FFT-diagnosed custom patch
bridge.list_active_patches()                     # what's currently overlaid
bridge.clear_patches()                           # wipe back to byte-exact baseline

# v0.5.4 surface — Sol Uranian Time
bridge.jd_to_sol_uranian_time(jd_tdb=2454451.0)  # USD + SUT + season + retrograde
bridge.sol_uranian_time_to_jd(usd=4046.0)        # USD → JD_TDB inverse

# v0.6.0 Tier 1 parity surface — both methods accept backend={"auto","bip","c"}
bridge.find_syzygies(jd_lo=2451545.0, jd_hi=2451545.0+365.25, backend="c")
bridge.get_breathing_modulation(jd_tdb=2451545.0, pair=("jupiter","saturn"),
                                n_lobes=(5, 2), backend="c")

Every bridge method returns a Pyodide-JSON-serialisable dict with ok: True/False. Caller-side errors return {ok: False, error: "..."} rather than raising — designed for crossing the Python/JS boundary cleanly.

Performance & Footprint

ephemerides-spectral is designed for high-performance galactic mapping on edge devices where large SPICE kernels (the 3.3 GB DE441) are prohibitive.

Memory Footprint

Component Format RAM / Flash Description
State (BIP) uint32[D] 256 KB At D=65536; pure cyclic-group residues.
State (complex128) complex128 1.0 MB At D=65536; FPU reference encoder.
Channel Bases mixed ~52 MB Full 52-body roster (v0.16.0+); pageable from Flash.
Laplacian (L) complex128 < 45 KB 52 × 52 interaction matrix.
Cosine LUT (Phase 9) int32[1024] 4 KB Off-diagonal adaptive ("breathing") modulation.
DE441 Truth BSP 3,300 MB Original JPL source (calibration only).

Compression vs DE441: > 100:1. Once calibrated, the HDC instrument functions as standalone algebraic truth — no kernel needed for propagation, local-view extraction, or syzygy detection.

Microcontroller Compatibility

The BIP backend is the natural production target for embedded use:

  • ESP32-S3 / ESP32-C6 (8 MB+ PSRAM): full 52-body BIP state in PSRAM, microsecond-latency phase updates via uint32 adds.
  • ARM Cortex-M7 (Teensy 4.1, etc.): integer multiply-accumulate suits the omega * delta_t step path natively; cosine LUT fits in tightly-coupled memory.
  • RISC-V / Edge AI accelerators: (φ_1 + φ_2) mod 2^32 is a single uint32 add — directly mappable to vector-extension lanes.

Instead of searching 3.3 GB of Chebyshev coefficients, these devices evolve the entire Sol Star System phase-space using integer additions and a 4 KB cosine table.

Honest accuracy: DE441 full-epoch sweep (v0.3.0)

research/de441_sweep.py runs the BIP integer-ALU encoder at 15 sample points spanning J2000 ± 14,000 yr (just inside DE441's ~30,000-yr coverage window) and compares per-body ecliptic-longitude residues against DE441 ground truth. Results — sorted by max error, descending:

Body n median (rad) p95 (rad) max (rad) max (deg)
jupiter 15 1.357 2.937 3.070 175.92
saturn 15 1.415 2.990 3.062 175.46
neptune 15 0.691 2.748 2.778 159.18
pluto 15 0.791 2.524 2.721 155.92
moon 15 1.084 2.559 2.670 153.00
mercury 15 0.356 1.444 1.461 83.74
mars 15 0.117 0.250 0.253 14.52
uranus 15 0.047 0.120 0.141 8.06
venus 15 0.024 0.114 0.124 7.11
earth 15 0.011 0.104 0.115 6.59

Earth phase error scales roughly linearly with horizon:

Δt (yr) Earth err (deg)
0 0.000
±1 0.001–0.004
±10 0.006–0.008
±100 0.065–0.069
±1000 0.65–0.68
±5000 2.93–3.31
±10000 4.70–5.71
±14000 5.48–6.59

Three regimes, honestly named

  • Sub-10° at multi-millennium horizons (Earth, Venus, Uranus): bodies whose mean motion + small eccentricity + the static gravitational fiber couplings approximate the actual orbit well. Earth benefits from being the calibration body for Mercury's PN diagonal.
  • Tens of degrees (Mars 14.5°, Mercury 83.7°): dynamics include eccentricity + long-period perturbations the Phase-9 model captures only partially. Mars has no resonance entry; Mercury's PN diagonal is linear whereas its actual perihelion precession at multi-millennium scales has higher-order terms.
  • Phase-scrambled (Jupiter, Saturn, Neptune, Pluto, Moon all hit >150°): bodies whose secular drift is dominated by resonant perturbations the Phase-9 model approximates phenomenologically. The α = 0.1 modulation depth is the right order of magnitude but wrong-in-detail; over ±14,000 yr that wrong-detail accumulates to a ~3 rad phase deficit.

This measures how much of multi-millennium ephemeris our v0.3.0 model captures, not how accurate the BIP encoder is at its design horizon. v0.3.0 is calibrated for the ±20-yr horizon (0.0002 rad ≈ 0.012° Earth phase floor); the multi-millennium errors are the cost of running a model trained for short-horizon dynamics far past its design point. The v0.4+ first-principles per-resonance α derivation is the planned fix — see ROADMAP.

Encoding timings (BIP integer-ALU path, default D = 65536)

Δt (yr) encode wall time
0 0.2 ms
±1 0.7–1.3 ms
±10 4.2–6.8 ms
±100 44.7–45.8 ms
±1000 447–483 ms
±5000 2.38–2.44 s
±10000 4.34–4.44 s
±14000 6.18–6.37 s

Linear in |Δt| — one 30-day chunk per integration step. At the v0.1.0 design horizon (±20 yr, ~243 chunks) the encode is ~1.85 ms; at ±14,000 yr (~170k chunks) it's ~6.4 s. Median across the sweep: 447 ms; max: 6.4 s.

v0.4.1+ C native path drops these by ~1000× (encode at +20 yr: 46 ms BIP → 0.04 ms C). The full DE441 FFT-residual sweep (1024 samples) takes ~14 seconds on the C native path versus ~5 minutes on Python BIP — the truth-lookup against skyfield is the new bottleneck.

Patch-shrinks-residual benchmark — VINDICATED on planets (v0.5.2)

Earn the right to predict the missing data. — measured.

The v0.4.0 catalog patches claimed to predict missing physics; v0.5.1 audited them and surfaced two authoring bugs (amplitude off by 2×, phase=0 assumption wrong); v0.5.2 fixed both with least-squares fitting at the exact target period. Result: VINDICATED on every targeted planet body.

Patch v0.4.0 (mag-only) v0.5.1 (phase-recovered) v0.5.2 (LS-fit)
Mars 7.96 yr +2.5% +2.7% +99.2%
Mercury 10.69 yr −49.9% (peak GREW) +39.6% +99.9%
Jupiter 9.56 yr +30.9% +77.1% +97.6%
Saturn 9.56 yr −0.4% +76.4% +96.0%

The vindicated patches ship as CATALOG_V2 alongside the original v0.4.0 CATALOG. Use the -v2 suffix:

bridge.apply_patch("mars-7.96yr-diagonal-v2")              # 99.2% shrinkage
bridge.apply_patch("mercury-10.69yr-diagonal-v2")          # 99.9%
bridge.apply_patch("jupiter-saturn-9.56yr-coupled-v2")     # 97.6% J / 96.0% S

Empirical findings worth noting:

  • J–S correlation = +1 (in-phase), not −1 as v0.4.0 assumed. Anti-correlated-libration intuition was empirically wrong.
  • LS-fit amplitudes are 25–55% larger than FFT-bin extraction — the energy that was leaking into adjacent bins.
  • Mars's true residual amplitude is 10.69° (LS) vs 3.45° (FFT-bin rank-1) — a 3× underestimate, the worst leakage case in the catalog.

See the v0.5.2 patch-shrinks-residual analysis on the project docs for the full math derivation, methodology, and moon-residual open question.

Status

See the project CHANGELOG and package CHANGELOG for the authoritative version-by-version detail. Headline summary:

  • v0.21.0 (current)Sol Spherical Harmonic Catalog — unification refactor across the v0.20.0 gravity sector (4π-normalised Stokes coefficients) and the v0.20.1 magnetic sector (Schmidt-quasi-normalised g_n^m / h_n^m). Promotes notebook §17.4.2 to a stable ship surface. This is a unification refactor, not a new data store — the underlying records still live in geodetic_catalog_data (gravity) and magnetic_multipole_catalog_data (magnetic); the v0.20.0 / v0.20.1 surfaces (bridge.get_geodetic_state, bridge.get_magnetic_multipoles) continue to work unchanged. The unification is a NEW query surface that lets consumers ask "what spherical-harmonic representations does the catalog have for body X, across all channels?" with one call instead of two. Each returned record carries an explicit normalisation_convention field — "4pi-Stokes" (geodesy) or "Schmidt-quasi-norm" (geomagnetic) — so consumers know which conversion factors to apply when crossing channels. Two new query surfaces + one math helper: bridge.get_spherical_harmonics(body, channel="both") (single-body query across {"gravity", "magnetic", "both"}; bodies absent from a requested channel return that channel as None); bridge.list_spherical_harmonic_models() (full enumeration: 56 gravity models + 7 magnetic models + the 7 both-channels intersection bodies = terra / mercury / jupiter / saturn / uranus / neptune / ganymede + the merged 76-entry SOURCES citation dict spanning both sectors); bridge.convert_spherical_harmonic_normalisation(coefficient_value, n, m, from_convention, to_convention) (Winch et al. 2005 closed-form: C̄_nm = g_n^m / sqrt((2 - δ_0m) * (2n + 1)); round-trip identity to float-machine precision). Three new CLI subcommands: spherical-harmonics, spherical-harmonic-models, convert-normalisation. No regression on v0.20.0 / v0.20.1 surfaces — back-compat tests pin both surfaces continue to return their original shapes. Pure-Python additive; no ABI bump (ninth consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged). Research origin notebook §17.4.2. New tests/test_spherical_harmonic_catalog.py (30 tests pinning the unification logic + back-compat invariants + Winch et al. 2005 conversion math + bridge surfaces + CLI surfaces). 922 tests pass, 41 skipped (was 889 + 41 in v0.20.2; +33 net new — 30 in test_spherical_harmonic_catalog.py + 3 parity-smoke entries).
  • v0.20.2Sol Fluid Instrument — climatology + archive index + state-at-epoch query surface for the solar-system fluid envelope (atmospheres, oceans, cryospheres, exospheres). Promotes the v0.20.x research output (notebook §17.3 + §17.4.2) to a stable ship surface, mirroring the v0.19.0 EM Instrument / v0.20.0 Sol Geodetic Catalog / v0.20.1 Sol Magnetic Multipole Catalog patterns. Ships all three Option-D layers together per the §17.4.2 full-coverage commitment — no MVP subset, no deferred layer. Layer 1 — climatological summary scalars per body (mean surface temperature K, mean surface pressure Pa, dominant gas top-3 mole fractions, obliquity deg, orbital eccentricity, Bond albedo) for 17 atmospheric bodies + 4 airless small bodies = 21 entries (terra / mars / venus / titan / triton / pluto / io / europa / ganymede / enceladus / mercury / luna / sun / jupiter / saturn / uranus / neptune + ceres / vesta / bennu / ryugu). Headline numerics include the surprising results: Titan 94 K + 1.45 bar (denser atmosphere than Earth's despite the cold; only moon with a thick atmosphere); Triton 38 K + 1.4 Pa (one of the coldest known surfaces in the solar system); Venus 737 K + 92 bar; Uranus 97.77° obliquity (extreme axial tilt → 42-yr seasonal cycles). Gas giants ship at the 1-bar reference level by convention. Layer 2 — archive-pointer index (10 entries) per atmospheric body with file format + access protocol + temporal coverage + endpoint URL: ERA5 (terra, ECMWF Copernicus 1940-present), MCD v6.1 (mars, LMD MY 24-present), VIRA + Akatsuki (venus), Cassini PDS-PPI (titan + saturn), Juno PDS (jupiter), MAVEN PDS (mars-upper-atmosphere), Voyager 2 PDS (uranus + neptune flyby snapshots), New Horizons PDS (pluto). Layer 3 — state-at-epoch coverage flags (21 entries) — only terra (ERA5 reanalysis, JD ≈ 2429630.5 onward = 1940-01-01) and mars (MCD v6.1, MY 24-start ≈ JD 2450545.5 onward = 1997-04-07 vernal equinox) have the True flag; all 19 other bodies fall back to the climatological summary with explicit out-of-coverage-fallback-to-climatology query_type. Three new bridge surfaces: bridge.get_fluid_state(body=None, jd_tdb=None, lat=None, lon=None) (with coverage_status triage when jd_tdb given: in_coverage / before_archive / future / no_state_at_epoch), bridge.list_fluid_archives(), bridge.fluid_architecture(target=None). Three new CLI subcommands: fluid-state, fluid-archives, fluid-architecture. No outbound network calls — the package ships pointers + the climatological-summary fallback in a self-contained dict; consumers fetch the actual reanalysis field via the archive's own API (CDS-API for ERA5; Python wrapper for MCD). HIGH/MEDIUM/LOW/NONE data-quality partition is the fluid-channel sibling of the v0.20.0/v0.20.1 partitions — a fourth orthogonal data-quality classification axis: {HIGH: 13, MEDIUM: 8, LOW: 0, NONE: 1} (HIGH = current-best published climatology with multi-mission coverage; MEDIUM = single-mission limited or transient observations; LOW reserved for Voyager-only flyby snapshots in the archives layer; NONE = mars-upper-atmosphere appears as an archive-only body string). Every numeric value carries a source_key pointing into a 24-entry SOURCES citation dict; ratchet tests pin both directions (every key resolves; no unused entries). Pure-Python additive; no ABI bump (eighth consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged). Research origin notebook §17.3. New tests/test_fluid_instrument.py (50 tests). 889 tests pass, 41 skipped (was 834 + 41 in v0.20.1; +55 net new — 50 in test_fluid_instrument.py + 3 parity-smoke entries + 2 README-freshness tests that flipped GREEN after the Status banner update).
  • v0.20.1Sol Magnetic Multipole Catalog — state-lookup query surface for the published-internal-field roster across the solar system. Promotes the v0.20.x research output (notebook §17.2 + §17.4.2) to a stable ship surface, mirroring the v0.19.0 EM Instrument and v0.20.0 Sol Geodetic Catalog patterns. Not a BIP encoder — per §17.4.1 the rhythm-mismatch finding generalises across magnetic multipoles alongside solid-body geodesy and fluid-envelope channels: internal-field Schmidt-quasi-normalised g_n^m / h_n^m coefficients are static at their epoch (IGRF main field updates every 5 years on a published schedule; JRM33 is a Juno-prime-mission snapshot; Voyager-derived AH5/O8 are single-flyby fits), so the cyclic-group encoder discipline does not transplant. 7-body main-field roster — every body in the published refereed literature with a multipole expansion: Earth IGRF-13 (deg 13, Alken 2021); Jupiter JRM33 (deg 18, Connerney 2022; Great Blue Spot resolved); Saturn Cao 2020 (deg 14, Cassini Grand Finale; the famous dipole tilt < 0.007° axisymmetric result as first-class structural_flag); Mercury Thébault 2018 (deg 5, MESSENGER reanalysis; ~484 km northward offset dipole); Uranus Holme & Bloxham AH5 (deg 3, Voyager-only; tilt 58.6° + offset); Neptune Holme & Bloxham O8 (deg 3, Voyager-only; tilt 47°); Ganymede Kivelson 2002 (dipole-only — the only solar-system moon with a confirmed intrinsic dipole; "higher-degree pending JUICE 2034" flag). Plus 1 crustal field model — Earth EMM2017 (deg 720, ~30 MB lazy-load via crustal=True flag) — and 1 solar synoptic reference — Stanford HMI synoptic-magnetograms (Carrington-rotation cadence, coverage 2010-present) accessible via bridge.get_solar_synoptic_state(jd_tdb); the Sun's time-varying field lives behind a different surface than the static catalog. Five new bridge surfaces: get_magnetic_multipoles(body=None, crustal=False), evaluate_magnetic_field(body, r_km, lat_deg, lon_deg, jd_tdb=None) (closed-form Schmidt-quasi-normalised dipole synthesis), get_solar_synoptic_state(jd_tdb=None), list_magnetic_multipoles(), magnetic_architecture(target=None). Five new CLI subcommands: magnetic-multipoles, magnetic-field, solar-synoptic, magnetic-models, magnetic-architecture. HIGH/MEDIUM/LOW/NONE data-quality partition (per §17.1.6 ship-readiness convention) is the magnetic-channel sibling of v0.20.0's geodetic partition: HIGH = current-best (Earth/Jupiter/Saturn); MEDIUM = single-mission limited (Mercury/Ganymede); LOW = Voyager-only single flyby (Uranus/Neptune); NONE = synoptic-only (Sun, no static record). Every numeric value carries a source_key pointing into a 9-entry SOURCES citation dict; ratchet tests pin resolution at CI time. Also refreshes the package pyproject.toml description (was advertising the obsolete v0.5-era 38-body roster + omitting all the v0.16-v0.20.x catalog work) — now lists 52-body roster + per-body Sol Geodetic / Electromagnetic / Magnetic-Multipole catalogs + resonance-graph ITN-chain search + spectral body-architecture surfaces. Pure-Python additive; no ABI bump (seventh consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged). Research origin notebook §17.2. New tests/test_magnetic_multipole_catalog.py (59 tests). 834 tests pass, 41 skipped (was 769 + 41 in v0.20.0; +65 net new — 59 in test_magnetic_multipole_catalog.py + 5 parity-smoke entries + 1 reconciliation).
  • v0.20.0Sol Geodetic Catalog — state-lookup query surface for the solar-system solid-body geodetic stack (gravity multipoles + topography / shape models + interior structure). Promotes the v0.20.x research output (notebook §17.1 + §17.4.2) to a stable ship surface, mirroring the v0.19.0 Sol Electromagnetic Instrument pattern. Not a BIP encoder running on geodetic rhythms — per §17.4.1 the rhythm-mismatch finding generalises across solid-body geodesy alongside magnetic multipoles and fluid-envelope channels: solid-body geodetic observables (Stokes coefficients, DEM spectra, layered density profiles) are static parameters with no native rhythm, so the cyclic-group encoder discipline does not transplant. The Sol Geodetic Catalog is therefore a state-lookup surface (no JD-advance mechanic) holding three internal channels per body: gravity — published spherical-harmonic multipole expansions (full Stokes coefficients for terrestrial bodies + the Moon; zonal-only J_n series for the gas + ice giants; point-mass GM for Lagrange trojans + Jovian irregulars); topography — DEM / shape-model metadata (full-coverage DEMs for the inner solar system + the Moon; Cassini SARTopo for Titan; polyhedral shape models for the small-body roster); interior — radial density profiles + layered models + moment-of-inertia constraints (PREM / GRAIL+Apollo / InSight / Mankovich-Fuller ring-seismology / Voyager-derived for the ice giants). 56 gravity + 32 topography + 26 interior entries across the catalog with 22 fully-characterised triple-channel bodies (terra / luna / mars / mercury / venus / io / europa / ganymede / callisto / mimas / enceladus / dione / rhea / iapetus / titan / triton / pluto / charon / ceres / vesta / bennu / ryugu) — full-coverage per the §17.4.2 commitment, no "minimum-viable" subset deferred. Three new bridge surfaces: get_geodetic_state(body=None), list_geodetic_models(), geodetic_architecture(target=None). Three new CLI subcommands: geodetic-state, geodetic-models, geodetic-architecture. HIGH/MEDIUM/LOW/NONE data-quality partition (median of per-channel precision_flag per the §17.1.6 ship-readiness convention) is a third orthogonal classification axis alongside v0.18.0's inner/outer Fiedler partition (orbital position) and v0.19.0's magnetised/induced/unmagnetised split (intrinsic-field presence) — this one is by published-data quality, not physical body class. Every numeric value carries a source_key pointing into a 67-entry SOURCES citation dict (DOIs / mission archives / journal refs); ratchet tests pin the resolution at CI. Forward sequence committed in §17.4.2: v0.20.1 MagneticMultipoleCatalog (full published high-degree internal-field roster); v0.20.2 SolFluidInstrument (climatological summary + archive index + Earth/Mars state-at-epoch); v0.21.0 SphericalHarmonicCatalog unification refactor across gravity + magnetic + fluid sectors; v0.21.1+ cross-channel coupling surfaces (one per minor version). Pure-Python additive; no ABI bump (sixth consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged). Research origin notebook §17. New tests/test_geodetic_catalog.py (35 tests). 769 tests pass, 41 skipped (was 730 + 41 in v0.19.0; +39 net new — 35 in test_geodetic_catalog.py + 3 parity-smoke entries + 1 reconciliation).
  • v0.19.0Sol Electromagnetic Instrument — state-at-epoch query surface for the solar-system EM sector. Promotes the v0.19.x research output (notebook §16.9) to a stable ship surface. Not a BIP encoder — the §16.3 / §16.9.1 rhythm-mismatch finding established that EM clocks (rotational, Carrington, solar cycle, plume duty cycles) don't form a low-order rational lattice with each other or with orbital periods, so the cyclic-group encoder discipline doesn't transplant. The Sol EM Instrument is therefore a state-at-epoch lookup surface holding per-body EM observables (intrinsic dipole moment, rotation phase advanced from J2000, synchrotron power, plasma source rate, photoelectric potential) plus a static catalog of pairwise EM couplings. 16-body roster (strict subset of the v0.16.0 52-body celestial roster): 1 star (sun) + 7 magnetised (mercury / terra / jupiter / ganymede / saturn / uranus / neptune) + 4 induced (venus / europa / callisto / titan) + 4 unmagnetised (luna / mars / io / enceladus). 7 pairwise EM couplings: Jupiter↔Io flux tube (~10¹² W, dominant; Saur 2007 / Hess et al. 2010); Saturn↔Enceladus plasma mass loading (~5×10⁹ W; Pontius & Hill 2006); Saturn↔Titan induced magnetosphere (~10⁹ W); Sun↔Terra IMF reconnection (~5×10⁹ W; Lockwood 2022); Jupiter↔Europa induced magnetosphere (~10¹⁰ W; Khurana 1998); Jupiter↔Ganymede intrinsic-field-to-intrinsic-field (~10¹⁰ W — the unique mini-magnetosphere case); Sun↔asteroid-belt-bulk radiation pressure (~10¹⁵ W — Yarkovsky/YORP scoping anchor; Bottke 2006). Saturn rotation-period uncertainty (~1% between Voyager and Cassini SKR) flagged explicitly per §16.3 disclaimer. Three new bridge surfaces: get_em_state(jd_tdb), list_em_couplings(), em_architecture(target=None). Three new CLI subcommands: em-state, em-couplings, em-architecture. Magnetised/induced/unmagnetised partition is a different classification axis than v0.18.0's body_architecture inner/outer Fiedler partition (orbital position) — this one is by intrinsic-field presence (lookup, not eigendecomposition). Every numeric value carries a source_key pointing into a 19-entry SOURCES citation dict for verifiable provenance. Pure-Python additive; no ABI bump (fifth consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged). Research origin notebook §16; user course-correction widened scope from "magnetic-only" to "electromagnetic" (the Io flux tube is a current loop, not magnetic-dipole-dipole; solar wind is plasma-mediated; radiation pressure is photon momentum). New tests/test_em_instrument.py (46 tests). 730 tests pass, 41 skipped (was 685 + 41 in v0.18.2; +45 net new on top of the v0.18.2 baseline).
  • v0.18.22-D (f₂, f₃) Fiedler-embedding upgrade for bridge.predict_itn_accessibility. Replaces the v0.18.1 1-D |f₂[i] − f₂[j]| distance with a 2-D Euclidean distance on the (f₂, f₃) embedding of the same hybrid Laplacian. Spearman ρ unchanged (1-D: +0.857 / 2-D: +0.849 — rank ordering already strong) but R² lifts 0.51 → 0.64 and in-sample MAE drops 4.11 → 3.00 km/s (−27 %) + LOOCV MAE drops 4.24 → 3.12 km/s (−26 %) + LOOCV median absolute error drops to 2.20 km/s. The second eigenvector f₃ adds an axis that distinguishes within-cluster pairs (e.g., Earth/Venus + main-belt asteroids cluster on f₃ > 0; outer planets on f₃ < 0; mercury isolated on f₃ ≈ −0.28) that the 1-D Fiedler vector collapsed. Bridge response shape unchanged (predicted_dv_kms, calibration provenance) but adds new embedding_distance_2d and calibration.lambda_3 + calibration.embedding_dim + calibration.loocv_median_abs_error_kms fields. The 1-D Fiedler distance is preserved as the fiedler_distance field for back-compat with v0.18.1 callers. Calibration constants change (intercept 8.68 → 4.90, slope 15.62 → 17.32) — the v0.18.1 1-D constants are exposed under *_1D_HISTORICAL names for traceability. New research/two_eigenvector_fiedler_embedding.py (the calibration-comparison script) lives alongside the existing calibrate_predict_itn_accessibility.py. Notebook §13.10 documents the 2-D embedding result. Pure-Python additive improvement; no ABI bump (fourth consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged from v0.17.0/v0.18.0/v0.18.1). New 5 tests (calibration-pin update + 1-D-historical-preservation + 2-D-distance-presence + embedding-dim metadata). 685 tests pass, 41 skipped (was 681 + 41 in v0.18.1; +4 net new).
  • v0.18.1bridge.predict_itn_accessibility: closed-form spectral Δv estimate from the §13.9 hybrid Fiedler-distance regression. Promotes the v0.17.x research output (notebook §13.9) — the multiplicative inv_dv × resonance gateway-graph Laplacian's Fiedler distance as a continuous predictor of multi-leg ITN-chain Δv — to a stable ship surface. Calibrated by OLS regression against ground truth from a 50-yr find_itn_chains sweep at J2000 (max_legs=3, dv_budget=30 km/s, threshold=0.1) on the v0.16.0 13-body heliocentric Tier-1 roster: slope ≈ 15.62 km/s per Fiedler-distance unit, intercept ≈ 8.68 km/s, Spearman ρ = +0.857, in-sample R² ≈ 0.51, LOOCV MAE ≈ 4.24 km/s. Use case: fast first-pass triage (microseconds vs ~1.5 s for the full Dijkstra) — not trajectory design (the absolute MAE is ~4 km/s on a 2–28 km/s domain, useful for ranking pairs but too coarse for mission-budget purposes). New bridge.predict_itn_accessibility(departure, target) Python entry + new predict-itn-accessibility CLI subcommand. Calibration provenance returned in every response (Spearman ρ, R², MAE, LOOCV MAE, n_finite, n_inf, window) so callers can decide whether the prediction is precise enough for their use case. New offline calibration script research/calibrate_predict_itn_accessibility.py (re-fits the regression against a re-sampled ground truth — useful for non-default search windows). Pure-Python addition; no ABI bump (third consecutive ship since v0.13.x with no ABI movement; ES_ABI_VERSION = 8 unchanged from v0.17.0/v0.18.0). Notebook §14 (the holographic-principle-at-macro-scale section, also added in v0.18.1) re-reads the §13.9 / v0.18.1 result as the bulk-boundary correspondence's "real" empirical payload — the spectral boundary (13-D Fiedler vector) anticipates the trajectory bulk (78-pair × 3-leg Dijkstra) at calibrated Spearman 0.857. New tests/test_predict_itn_accessibility.py (22 tests). 681 tests pass, 41 skipped (was 658 + 41 in v0.18.0; +23 new — 22 predict_itn_accessibility + 1 parity-smoke entry).
  • v0.18.0Body Architecture: inner/outer system classification of heliocentric bodies via the resonance-weighted gateway-graph Laplacian Fiedler partition. First spectral-architecture surface in the bridge — the v0.17.x research output (notebook §13.8) promoted to a stable ship API. The cyclic-group encoder discovers the canonical asteroid-belt boundary without being told it exists: outer 5 (jupiter / saturn / uranus / neptune / pluto) all negative; inner 8 (mercury / venus / terra / mars / vesta / ceres / pallas / hygiea) all positive. Pluto and Neptune share the deepest negative Fiedler entry (≈ −0.585) via their well-known 2:3 mean-motion lock dragging both deep into the outer cluster. New bridge.body_architecture(target=None) Python entry + new body-architecture CLI subcommand (full partition by default; --target terra etc. for single-body class lookup). The Fiedler-vector sign is anchored to the shortest-period body (mercury) being positive — class labels are reproducible across platforms regardless of LAPACK pivoting. Pure-Python addition; no ABI bump (second consecutive ship since v0.13.x with no ABI movement — v0.17.0 added find_itn_chains, v0.18.0 adds body_architecture, both leave ES_ABI_VERSION = 8 unchanged). Notebook §13.9 also lands the hybrid inv_dv × resonance Laplacian research follow-up: Spearman ρ = +0.857 (clears the §13.7 0.85 ship bar) but Matthews φ = +0.298 (below the 0.6 partition bar) — vindicates the multiplicative-hybrid hypothesis for a continuous Fiedler-distance Δv predictor while leaving the partition-only ship surface to the resonance-only weighting. A bridge.predict_itn_accessibility continuous-Δv predictor is queued for v0.18.x or v0.19.0 (gated on Fiedler-distance → Δv regression calibration). New tests/test_body_architecture.py (34 tests). 658 tests pass, 41 skipped (was 622 + 41 in v0.17.0; +36 new — 34 body_architecture + 2 parity-smoke entries).
  • v0.17.0Resonance-graph multi-leg find_itn_chains (advanced Lagrange-highway search). Generalises the v0.8.1 closed-form Hohmann-window enumeration (find_itn_pathways) to multi-leg pathways via Dijkstra-style graph search over the (body, epoch) state space. Each leg is a closed-form Hohmann window from find_itn_pathways; legs stitch end-to-end at intermediate bodies; cumulative Δv and time-of-flight are budget-bounded. Each leg carries a small-integer (p, q) gear-ratio resonance signature (period_dep / period_tgt reduced to lowest terms via _best_rational_approx) — the natural cross-pollination point between the closed-form transfer-window machinery and the BIP cyclic-group encoder. The Dijkstra invariant on cumulative Δv guarantees the first chain emitted is the optimal-Δv path; subsequent chains are emitted in monotonically non-decreasing total-Δv order. Canonical witnesses verified in tests: Earth/Mars 8:15 synodic-resonance anchor (the well-known 8-Earth-yr / 15-Mars-orbit tile), Earth/Jupiter 1:12 Jupiter-orbit anchor, Jupiter/Saturn 2:5 great-inequality. New bridge.find_itn_chains Python entry + new find-chains CLI subcommand (intermediates / max-legs / Δv budget / TOF budget / threshold / max-chains flags). Pure-Python addition built on top of find_itn_pathways: no ABI bump (the C wire-format is unchanged; this is the first ephemerides ship since v0.13.x to leave the ABI alone — v0.14.0/v0.14.1/v0.14.2 added bodies, v0.15.0 + v0.16.0 expanded BODIES, all of which moved the ABI). Sets up the v0.17.x research thesis on Gateway-graph Laplacian + Fiedler-partition empirical-low-Δv-accessibility correspondence (notebook §12). New test_find_itn_chains.py (21 tests: rational-approximation invariants + direct-chain consistency with v0.8.1 + Dijkstra optimal-first invariant + Δv/TOF/max-legs budget enforcement + bridge surface + CLI surface). 622 tests pass, 41 skipped (was 601 + 41 in v0.16.0; +21 new).
  • v0.16.0BODIES Tier-1 expansion (43 → 52): Lagrange trojans + retrograde irregulars + Neptune sub-graph completion. Themed per the post-v0.15.0 audit (notebook §11). Adds 9 bodies: 4 Saturnian Lagrange trojans (Telesto + Calypso at Tethys L4/L5 with SSaTeT2 / SSaCaT; Helene + Polydeuces at Dione L4/L5 with SSaHeT / SSaPoTfirst L4/L5 entries in BODIES, the body-graph Laplacian acquires a multiplicity-2 eigenvalue at the host moon's frequency); 3 Jovian irregulars (Himalia SJuHiT largest prograde, Pasiphae SJuPaT and Sinope SJuSiT retrograde — second retrograde marker beyond Triton); Neptune sub-graph completion (Proteus SNePrT Neptune's second-largest moon at 1.122 d period, fills the gap between Triton at 5.88 d and the deferred inner-Neptunian close-packed cluster; Nereid SNeNeT most eccentric major-moon orbit in the solar system at e=0.749, 360.13 d period extends the low-frequency tail dramatically). First invocation of the v0.14.1-reserved suffix-disambiguation policy: Telesto's SSaTeT2 distinguishes from Tethys's SSaTeT (both share moon-prefix Te under the same parent). C-side wire-format change: ES_N_BODIES 43 → 52; ABI v7 → v8; native binary rebuilt + parity-smoke ratchet ratcheted. The Saturnian trojans are the spectral headliner — their period equals their host moon's, giving the Laplacian eigenbasis a degeneracy that's the natural intersection point with v0.16.x's resonance-graph multi-leg find_itn_chains work. Pure-additive on the Python bridge; Native callers need ABI 8 (the rebuilt native ships in the v0.16.0 wheel). New test modules test_saturnian_trojan_sol_moon_times.py (4 trojans, 12 tests) + test_jovian_irregular_sol_moon_times.py (3 irregulars, near-resonance pin) + extended test_neptunian_sol_moon_times.py (Triton + Proteus + Nereid). 601 tests pass, 41 skipped (was 514 + 41 in v0.15.0; +87 new — parametrize amplification across 4 trojans + 3 irregulars + 3 Neptunians).
  • v0.15.0Sol Moon Times: classical-roster completion (Pluto-Charon + remaining major Uranian moons) — 38-body roster expanded to 43. Closes task `#86` for the IAU-major moon roster: every classical moon discovered between 1787 and 1948 now has a Sol Time wrapper. Adds 5 new bodies + 5 forward + 5 inverse bridge wrappers + 5 CLI subcommands: Miranda SUrMiT, Ariel SUrArT, Umbriel SUrUmT, Oberon SUrObT (the four classical Uranian moons not in v0.14.2), and Charon SPlChT (Pluto's largest moon — mutually tidally locked, the only such 1:1:1 spin-orbit lock in the solar system; mass ratio Charon:Pluto ≈ 0.12 → Pluto-Charon barycentre lies outside Pluto, making the pair more like a binary planet than a planet-with-moon). SUrMiT vs SSaMiT is the v0.15.0 second-instance disambiguation case — same shared-moon-prefix pattern as the v0.14.2 SUrTiT/SSaTiT pair, exactly the disambiguation the v0.14.1 6-letter policy was designed to provide. C-side wire-format change: ES_N_BODIES 38 → 43; ABI v6 → v7; native binary rebuilt + parity smoke ratchet ratcheted. New test module test_plutonian_sol_moon_times.py for the binary-planet edge case (mutual tidal lock means sidereal == synodic == spin period; no separate synodic correction needed). 512 tests pass, 41 skipped (was 497 + 4; +56 new — 5 Plutonian + 4 expanded Uranian + 10 parity-smoke entries + parity-smoke tier shape variations). With v0.15.0 the Sol Moon Times series covers all 5 classical Uranian moons + every IAU-named moon in the 43-body roster except those that don't yet have BODIES entries (Pluto's smaller satellites Nix, Hydra, Kerberos, Styx are queued; the small Saturnian and Jovian satellites past the v0.14.x ships likewise queued).
  • v0.14.2Sol Moon Times: remaining 8 moons across 4 parent families (Mars, Jovian inner regulars, Uranus, Neptune). Closes task `#86` for the current 38-body roster. Adds 8 Sol Moon Times: Phobos SMaPhT + Deimos SMaDeT (Mars); Metis SJuMeT + Adrastea SJuAdT + Amalthea SJuAmT + Thebe SJuThT (Jupiter inner regulars — ring-shepherd + Voyager-discovery moons); Titania SUrTiT (Uranus — only Uranian moon currently in BODIES); Triton SNeTrT (Neptune — captured Kuiper Belt object, only large retrograde moon in the solar system). All 8 follow the v0.14.1 6-letter S<Planet2><Moon2>T convention; SUrTiT vs SSaTiT (Uranus's Titania vs Saturn's Titan) is exactly the disambiguation the policy was designed to provide. Encoder convention documented for Triton: period_days is positive (we encode omega = +2π/P for ALL bodies regardless of prograde/retrograde direction; retrograde-ness is metadata, not a sign flip — same convention as v0.5.4 Sol Uranian Time). Generic _add_moon_subparser CLI helper supersedes the v0.14.0/v0.14.1 family-specific helpers. Built via 4 parallel subagent worktrees (one per family) integrated by the parent agent into a single bridge.py / cli.py / parity-smoke ship — first multi-agent ship in this repo. Pure-additive; no API / encoder / ABI / encoder-test changes. 497 tests pass, 4 skipped (was 399 + 4; +98 new — 2 Martian + 4 Jovian-inner + 1 Uranian + 1 Neptunian moon-test modules + parity-smoke entries).
  • v0.14.1Sol Moon Times: Saturnians (11 moons) + abbreviation policy switch (4-letter → 6-letter). Second slice of `#86`. The contingency policy from v0.14.0's ROADMAP fired exactly as predicted: Saturnians introduced two collisions under the v0.14.0 4-letter S<Planet><Moon>T pattern (Tethys + Titan both 'T' → both SSTT; Enceladus + Epimetheus both 'E' → both SSET). Per the policy, the switch applies uniformly across all Sol Moon Times — Galileans retroactively renamed (SJIT → SJuIoT, SJET → SJuEuT, SJGT → SJuGaT, SJCT → SJuCaT); 11 Saturnians ship with 6-letter abbreviations (Mimas SSaMiT, Enceladus SSaEnT, Tethys SSaTeT, Dione SSaDiT, Rhea SSaRhT, Titan SSaTiT, Hyperion SSaHyT, Iapetus SSaIaT, Phoebe SSaPhT, Janus SSaJaT, Epimetheus SSaEpT). Python function names + CLI subcommand names + return-shape unchanged; only the epoch.abbreviation string changes. Resonance witnesses verified in tests: Mimas-Tethys 4:2 (Cassini Division), Enceladus-Dione 2:1 (tidal heating), Titan-Hyperion 4:3 (chaotic rotation), Janus-Epimetheus co-orbital. Hyperion footnote: chaotic rotation means sidereal_period_days references the orbital period; rotation-phase coupling decoupled (open research). 399 tests pass, 4 skipped (was 294 + 4; +105 new).
  • v0.14.0Sol Moon Times: Galileans (Io / Europa / Ganymede / Callisto). First slice of task `#86` — extends the Sol Time hierarchy to non-Luna moons under the moons-stuck-to-parent Sol <Parent>-<Body> Time naming convention from v0.9.1. New generic MoonTime primitive in _research/time_scales.py (body-agnostic; caller-supplied parent + sidereal period) + four per-Galilean bridge wrappers (jd_to_sol_jupiter_io_time, ..._europa, ..._ganymede, ..._callisto) with abbreviations SJIT, SJET, SJGT, SJCT + four CLI subcommands (time-jupiter-io, time-jupiter-europa, time-jupiter-ganymede, time-jupiter-callisto) sharing a _add_galilean_subparser helper for consistency. Default epoch is J2000.0 — STLT's Greek-historical anchors don't generalise to non-Luna moons; Galileo's 1610 telescopic discovery is a candidate non-default for a future ship. Galilean Laplace-resonance witness (canonical form n_Io − 3·n_Europa + 2·n_Ganymede ≈ 0) verified in the test module; Callisto correctly identified as the only Galilean NOT in the resonance. Naming convention contingencies added to ROADMAP: if moon-letter collisions arise in future ships (Saturnians, etc.), the fallback policy switches uniformly across all Sol Moon Times to a 6-letter S<Planet2><Moon2>T pattern (e.g., SJuGaT). Pure-additive; no API / encoder / ABI / encoder-test changes. 294 tests pass, 4 skipped (was 251 + 4; +43 new — 35 Galilean tests + 8 parity-smoke entries).
  • v0.13.10Drop edited from docs-check workflow trigger types — fixes post-merge double-fire. User-flagged on PR `#214` (v0.13.9 ship): the docs-check workflow was double-firing at every merge time. Two pull_request events fired at the same second ~3 seconds before merge committed; concurrency-cancel caught it (one CANCELLED, one SUCCESS) but the wasted CI churn + confusing run-history was observable. Root cause: GitHub web UI's "Squash and merge" fires pull_request: edited (merge-commit dialog populates title/body) near-simultaneously with pull_request: synchronize (GitHub recomputes the refs/pull/N/merge preview ref). Fix: drop edited from the trigger types — now [opened, synchronize, reopened, labeled], matching the narrower trigger list used by ephemerides-spectral-ci.yml (which never had this issue). Trade-off: [skip-docs-check] opt-out added retroactively (by editing the PR body post-open) no longer triggers a re-run; user pushes a synchronizing commit or accepts the stale advisory. Acceptable — opt-out should be set up-front. CI-only change; no code / API / encoder / ABI / test changes. 251 tests pass, 4 skipped.
  • v0.13.9JPL Power-of-Ten Rules 6 + 7 manual audits — final patch in the v0.13.4-v0.13.9 rule-fix sequence; ALL TEN RULES NOW SATISFIED. Audit-only release; no code changes; 0 violations found for both Rule 6 (smallest possible scope for data) and Rule 7 (check return values, validate parameters). The v0.11.2 spot-check estimates of "5-10 violations across es_encode.c + es_parity.c" (Rule 6) and "5-15 sites where rc is assigned but not checked" (Rule 7) didn't survive the incremental tightening in v0.13.4-v0.13.6: long-function splits relocated state into helper-scope; assertion work added const-near-use patterns throughout; cleanup-on-error refactor unified the rc-check pattern (es_status_t rc = ...; if (rc != ES_OK) return rc;). Audit walked every variable declaration (loop iterators block-scoped; const declarations near use; remaining function-scope declarations are intentional accumulators / sqrt caches / output buffers / result variables) and every es_status_t assignment (8 sites, each checked on the next line). All ten JPL Power-of-Ten rules now satisfied (Rules 1, 3, 4, 5 pinned in test_jpl_audit.py; Rule 10 enforced by pedantic-build 3-cell CI matrix; Rules 6+7 manual audits clean; Rules 2, 8, 9 already-passing at v0.11.2 baseline). 251 tests pass, 4 skipped (unchanged).
  • v0.13.8README accuracy patch — two-stage architecture clarification. User-flagged misunderstanding about "pure ALU": the previous README listed three backends as if they were full alternatives, with complex128 annotated as "used for syzygy operator, observer binding" — but since v0.7.0 (Tier 2b) the production HD path is C-side complex64, with complex128 retained as backend="fpu-ref" for regression. The README now splits the architecture into two stages: (1) integer-ALU phase-residue encoders (bip / c / complex128 reference) producing uint32[38] residues, and (2) FPU HD pipeline (complex64 production / complex128 regression baseline) for syzygy / observer-bind / eclipse-probability — which is necessarily FPU because channel bases are unit-magnitude complex. Adds a "TL;DR on pure ALU" callout: phase residues are integer ALU end-to-end; HD operations can't be (complex bases require trigonometric channels). Docs-only release; no API / encoder / ABI / test changes. 251 tests pass, 4 skipped.
  • v0.13.7JPL Power-of-Ten Rule 10 fixes — cross-platform pedantic-build CI matrix. Fourth code-quality patch in the v0.13.4-v0.13.8 rule-fix sequence. New ES_PEDANTIC=ON CMake option elevates the existing -Wall -Wextra -Wpedantic (gcc/clang) and /W4 (MSVC) flags to errors via -Werror / /WX. Default OFF (casual local builds stay friendly); the new pedantic-build job in .github/workflows/ephemerides-spectral-ci.yml turns it ON across a 3-cell matrix (Linux gcc, macOS clang, Windows MSVC) so any new compiler warning fails CI. Always-on (not gated by the wheel-check label) — Rule 10 is a permanent invariant, not a per-PR opt-in. Per Holzmann: "All code must compile, from the first day of development, with all compiler warnings enabled at the compiler's most pedantic setting. All code must compile with these settings without any warnings." Local MSVC /W4 /WX build verified clean. All five mechanically-enforceable JPL rules now satisfied (Rules 1, 3, 4, 5, 10). Remaining JPL roadmap: Rules 6+7 (manual scope + return-value audits, v0.13.8). No public API change, no ABI change (still v6); CI-only addition. 251 tests pass, 4 skipped.
  • v0.13.6JPL Power-of-Ten Rule 5 fixes — assertion density at 2/function average. Third code-quality patch in the v0.13.4-v0.13.8 rule-fix sequence. 88 assertions added across 42 functions = 2.10/function average (target ≥2.0). Assertions are gated behind standard <assert.h> NDEBUG semantics — production builds (compiled with -DNDEBUG) strip them entirely; assertions are a development-time documentation tool, not a runtime cost. Coverage: pre-conditions on parameters (assert non-NULL after runtime ptr-check; assert index in range), post-conditions on results (assert output finite/bounded where applicable), invariants (assert D > 0, assert n_patches <= ES_MAX_PATCHES, assert loop-iteration bounds). The test_rule_5_density_meets_2_per_function ratchet test flips from SKIP to PASS. PIN_RULE_5_ASSERTIONS ratcheted UP 0 → 88. Total mechanically-detectable violations: 102 → 0 — every Rule 1-5 violation in the v0.11.2 audit baseline now cleared in three ships. Remaining JPL roadmap: Rule 10 (pedantic-build matrix, v0.13.7), Rules 6+7 (manual scope + return-value audits, v0.13.8). No public API change, no ABI change (still v6); pure additive instrumentation. Encoder math byte-identical — parity smoke green. 250 tests pass, 4 skipped (was 5; Rule 5 density test no longer skips).
  • v0.13.5JPL Power-of-Ten Rule 4 fixes — long-function splits. Second code-quality patch in the v0.13.4-v0.13.8 rule-fix sequence. The 4 functions over 60 lines from the v0.11.2 audit (es_encode_state 109; es_find_syzygies 99; es_bind_observer 78 post-v0.13.4; es_get_eclipse_probability 65 post-v0.13.4) split into JPL-compliant factors via 10 new static internal helpers along natural algorithm seams: apply_one_chunk + apply_subchunk_remainder (encoder), select_syzygy_targets + score_syzygy_event + validate_syzygy_args + emit_syzygy_event (parity), observer_coord_shift + apply_observer_bind + build_syzygy_operator + complex64_vdot_magnitude (HD pipeline). Rule 4 count drops 4 → 0. No public API change, no ABI change (still v6); pure refactor. Encoder math byte-identical — parity smoke pins both backends to within float-ULP and stays green. Total mechanically-detectable violations: 102 → 64 (37% of audit baseline cleared across v0.13.4 + v0.13.5). Remaining: Rule 5 (assertion density, v0.13.6), Rule 10 (pedantic-build matrix, v0.13.7), Rules 6+7 (manual scope + return-value audits, v0.13.8). 250 tests pass, 5 skipped.
  • v0.13.4JPL Power-of-Ten Rule 1 + Rule 3 fixes — first code-quality patch in the v0.13.4-v0.13.8 rule-fix sequence. Caller-supplied-scratch refactor of c/src/es_hd_state.c eliminates both classes of violation in a single pass: goto count drops 5 → 0 (Rule 1 cleared) and malloc/free count drops 29 → 0 (Rule 3 cleared). The C library no longer calls dynamic allocators after init; <stdlib.h> is no longer included. The HD pipeline's three entry points (es_encode_state_hd, es_bind_observer, es_get_eclipse_probability) gain caller-supplied scratch-buffer parameters; the Python ctypes shim allocates them alongside the existing out_state buffer (no observable heap-pressure change — Python was already heap-allocating the output). ABI v5 → v6 (mechanical wire-format change; encoder math byte-identical to v0.13.3 — parity smoke pins both backends to within float-ULP). Total mechanically-detectable violations: 102 → 68 (33% of audit baseline cleared in one ship). Remaining: Rule 4 long functions (v0.13.5), Rule 5 assertion density (v0.13.6), Rule 10 pedantic-build matrix (v0.13.7), Rules 6+7 manual audits (v0.13.8). User-facing Python bridge surface unchanged. 250 tests pass, 5 skipped.
  • v0.13.3Pre-merge docs+parity hygiene check (soft-warning GitHub Actions workflow). Closes task `#98` (consolidated; absorbs `#87` + `#88`). New .github/workflows/ephemerides-spectral-docs-check.yml runs on every PR touching the package; classifies code-side changes (version bumps, bridge.py, cli.py, _research/*.py, c/src/*.c / c/include/*.h) against the five PyPI-facing docs files (python/README.md, python/CHANGELOG.md, CHANGELOG.md, ROADMAP.md, ephemerides_spectral_research_notebook.md); posts (or updates in place) a single PR comment summarising the gap. Soft-warning, never fails the build — the existing pytest freshness ratchet (test_native_version_string_matches, test_parity_smoke::PARITY_TARGETS, test_readme_freshness, test_jpl_audit) hard-fails on the highest-value drift modes; this workflow surfaces the next tier — prose-and-narrative drift that humans should review but a regex can't authoritatively adjudicate. Opt-out: [skip-docs-check] in the PR body silences on cosmetic / typo / formatting-only diffs. Comment idempotence: peter-evans/find-comment + peter-evans/create-or-update-comment update one advisory in place rather than spamming the PR. Concurrency: cancel-in-progress: true keyed by workflow + ref absorbs the opened+labeled double-fire pattern documented in ephemerides-spectral-ci.yml. CI-only addition; 250 tests pass, 5 skipped.
  • v0.13.2Add _native/ to repo .gitignore; renumber JPL rule-fix roadmap to v0.13.4-v0.13.8. Quick-win patch addressing task `#85` (_native/ directory holds compiled DLL/SO files that rebuild on every cmake --build; never belongs in source control). One line added to .gitignore. Also patches c/JPL_AUDIT.md's roadmap section: the original v0.11.3-v0.11.7 numbering is obsolete since the project moved past v0.11.x; the rule-fix patches are renumbered to v0.13.4 (Rule 1+3), v0.13.5 (Rule 4), v0.13.6 (Rule 5), v0.13.7 (Rule 10), v0.13.8 (Rules 6+7). v0.13.3 reserved for `#98` (consolidated docs+parity hygiene check; absorbs `#87` + `#88`). 248 tests pass, 5 skipped.
  • v0.13.1SPICE feature-gap audit + STLT-naming hygiene. Docs-only release; no API / encoder / ABI changes. New figures/spice_feature_audit.md answers "what does SPICE do that we don't, and is a compat bridge worth shipping?" — three-column comparison + recommendation (skip the compat-bridge; document the gap). Spawns a v0.14.x backlog: light-time + stellar-aberration corrections, frame transformations, full Kepler elements, per-body pole orientation. STLT naming hygiene: the abbreviation table promotes Luna's primary Sol Time from SLT (surface clock) to STLT (anchored Lunar synodic count) per the moons-stuck-to-parent Sol <Parent>-<Body> Time convention; SLT is preserved as a secondary alternative for the surface-clock case. Drops "system clock for the Terra-Luna pair" framing throughout active code (CHANGELOG history entries preserved as artefacts of how v0.10.0 was framed at the time). Tests unchanged at 248 + 5 skipped.
  • v0.13.0Sol Dynamics — system energy budget, per-body energies, pair-wise gravitational forces. Augmented onto every time-* subcommand via --dynamics. Counterpart to v0.12.0's Kinematics; mirrors chess-spectral's qm_*_dynamics.py dynamics layer (Hamiltonian + evolution + force/energy queries). New bridge.get_dynamics() (system aggregate), bridge.get_force_between(a, b) (Newtonian pair force, validated against the textbook 3.54×10²² N Earth-Sun figure to 0.01 %), bridge.get_body_energies(body) (per-body KE + PE + total), and bridge.apply_dynamics_correction() (CLI post-processor). New standalone dynamics CLI subcommand with three modes: system aggregate (default), per-body (--body X), pair-force (--body X --from Y). Total system energy −1.98×10³⁵ J (gravitationally bound; virial theorem holds to 0.5 %). All three augmenting flags --proper + --state + --dynamics compose without conflict. 248 tests pass (was 212 + 34 new dynamics tests + 2 freshness drift catches).
  • v0.12.0Sol Kinematics — per-body orbital state, transparently augmented onto every time-* subcommand via --state. Mirrors chess-spectral's qm_*.py kinematics layer (static observables, no time-evolution; the dynamics counterpart ships as v0.13.0). New bridge.get_kinematic_state(body, ...) + bridge.get_full_system_state(...) primitives + standalone kinematics --body X / kinematics --all CLI subcommand. Validated against NASA fact-sheet orbital velocities: Mercury 47.87 vs. 47.36 (1.1 %), Earth 29.785 vs. 29.78 (0.02 %), Mars 24.13 vs. 24.07 (0.25 %), Jupiter 13.06 vs. 13.07 (0.08 %), Pluto 4.741 vs. 4.74 (0.02 %). System totals reproduce the famous "Jupiter holds 61 % of total angular momentum" and "outer planets hold 99.84 % of planetary L" facts to within 0.02-2.5 %. Phase A research script + markdown report (figures/kinematics_dynamics_audit.md) committed first; Phase B canonical primitive ships with two independent implementations agreeing on the 9 published values. New _research/kinematics.py codegened into the package alongside proper_time.py. 212 tests pass (was 182 + 30 new kinematics tests).
  • v0.11.2JPL Power-of-Ten audit baseline for the C library (audit-only; no code changes yet). Documents 102 mechanically-detectable violations rule-by-rule in c/JPL_AUDIT.md: 5 goto (Rule 1), 29 malloc/free (Rule 3), 4 functions over 60 lines (Rule 4), 64-assertion shortfall (Rule 5). Pins the counts in tests/test_jpl_audit.py as a one-way ratchet — counts can only go DOWN; PRs that increase them fail loudly. Same modular discipline as test_native_version_string_matches_package_version, test_parity_smoke.py::PARITY_TARGETS, and test_readme_freshness.py. Rules 2 (fixed loop bounds), 8 (limited preprocessor), 9 (no function pointers) already pass clean. Rule-by-rule fixes ship in v0.11.3+ as separate code-quality minors. Reference: Holzmann 2006, IEEE Computer. 182 tests pass.
  • v0.11.1Research notebook hygiene: backfill §7.4 (STLT) and §7.5 (SPrT) sections + refresh Status banner. v0.10.0 STLT and v0.11.0 SPrT shipped without their notebook subsections; this is the doc-only catch-up. Triggered by user noticing the gap. Task #98 captures the broader follow-on (a soft "docs probably need updating" warning on PRs that touch code without touching docs — would have caught this gap automatically). 171 active tests pass; identical to v0.11.0.
  • v0.11.0Sol Proper Time (SPrT) — --proper flag on every time-* subcommand applies gravitational + orbital-kinematic time dilation transparently. New bridge.get_proper_time_rate(body, ...) and bridge.compare_proper_times(a, b, ...) primitives; new time-proper standalone subcommand for the rate-only query. Same physics as Mercury's existing 43″/century PN diagonal correction, applied per-body to all 38 bodies in the roster — the user's framing was "gravitational time dilation fiber so users don't even need to know anything extra had to happen in the back end." Six published values (Earth GR, Sun GR, Mars GR, Pluto GR, Earth orbital kinematic, Mars-vs-Earth GR difference) reproduced to within 0.30%; the 0.0175 s/Earth-year Curiosity-rover Mars-Terra clock-rate figure verified inline. New surface_radius_km per body in bodies.py. 32+ new tests in test_sprt.py pin every component + the CLI surfaces. Phase A research: research/proper_time_rates.py + figures/proper_time_rates.md.
  • v0.10.0Sol Terra-Luna Time (STLT) — anchored Lunar time using the synodic month, with Meton's 432 BCE summer solstice as the default epoch. First Sol Time member with a non-J2000 default anchor; primary lunar-time entry per the moons-stuck-to-parent Sol <Parent>-<Body> Time naming convention. New bridge.jd_to_sol_terra_luna_time(jd_tdb, *, epoch="meton") + sol_terra_luna_time_to_jd(...); new CLI time-terra-luna with --epoch {meton, antikythera, hipparchus, mardokempad, j2000}. Synodic month is the natural unit; Saros (18.03 yr) and Metonic (19.00 yr) cycle counts come along for free. Anchor choice is empirically validated: the Hipparchus-Babylonian eclipse-archive midpoint (Mardokempad 721 BCE + Hipparchus 141 BCE) lands within +240 days of Meton's solstice — same year, eight months later — confirming Meton sits at the center of mass of Greek astronomical tradition (the "combo" candidate test from research/lunar_epoch_candidates.py). Also fixes the find_syzygies(backend="auto") latent bug class (same as v0.9.2's get_breathing_modulation fix). House-epoch design choice; not a claim to be NASA's eventual LCT.
  • v0.9.3PyPI-facing README staleness sweep + CI freshness check. Status section refreshed (8 versions of accumulated drift); Roadmap section pruned of items that have already shipped (Tier 2b, Sol Venusian/Mercurian Time, ITN pathway / find-tubes); leftover earth-body CLI examples corrected to terra; "Phase 9 'Breathing' Couplings" heading inverted to "Phase 9 Adaptive Couplings (a.k.a. 'breathing')" matching the v0.9.2 CLI rename. New tests/test_readme_freshness.py enforces three drift-prevention invariants: every CHANGELOG version must appear in this Status section; the banner under the H1 must equal __version__; every CLI body-name flag in an example must reference a name in SUPPORTED_BODIES. Same discipline as test_native_version_string_matches_package_version and test_parity_smoke.py::PARITY_TARGETS — enumerate the truth, fail on drift.
  • v0.9.2CLI: adaptive is the primary subcommand for state-dependent coupling modulation; breathing retained as a hidden synonym (help=argparse.SUPPRESS). Matches the adaptive-networks vocabulary (Gross & Blasius 2008; adaptive Kuramoto family). Both names work; new users discover adaptive via --help, visual-metaphor users keep typing breathing. Latent bug fixed in passing: bridge.get_breathing_modulation(backend="auto") was rejected by _validate_backend (sentinel not in SUPPORTED_BACKENDS); resolved before validation now, matching the docstring contract. The breathing CLI subcommand has been broken since v0.8.0 — now fixed.
  • v0.9.1Sol Time naming convention overhaul + Sol Terra Time + Sol Luna Time. Direct Latin proper noun (Mercury, Venus, Pluto, Terra, Luna, Sol) for rocky bodies + Sun + Luna; established adjective form (Jovian, Saturnian, Uranian, Neptunian) for gas/ice giants. Renames (BREAKING): jd_to_sol_mercurian_timejd_to_sol_mercury_time; same for venusian → venus, plutonian → pluto. New (additive): Sol Terra Time (STT, Terra's surface clock) + Sol Luna Time (SLT, Luna's tidally-locked surface clock; distinct from Sol Lunar Time which gives Luna's phase observed from Terra).
  • v0.9.0Body identity rename: moonluna, earthterra. BREAKING. Latin proper nouns for body identity strings; generic English moon (= any natural satellite) and earth (= soil/ground) return to their generic meanings. BODIES["luna"] / BODIES["terra"] replace the old keys. _data/initial_phases.json re-keyed (encoded phase residues unchanged at any JD). C-side es_bodies table re-emitted via codegen. JPL/skyfield kernel boundary handled via EphemerisBundle.lookup() translation map. Encoder hot path byte-identical to v0.8.1.
  • v0.8.1ITN pathway / Lagrange-tube query — find-tubes first cut. "Surfing the perturbations": closed-form Hohmann transfer-window enumeration mirroring v0.3.1's find-syzygies discipline. Earth → Mars sanity: 23 windows over J2000 + 50 yr at threshold 0.02; 258.87-d transfer time and 5.594 km/s Δv match textbook Hohmann to 0.01% / 0.1%.
  • v0.8.0Sol Symphony Times: 7 new planetary/stellar time systems. Venus, Mercury, Pluto, Sol (the Sun!), Jupiter, Saturn, Neptune join Mars / Lunar / Uranian. Special quirks honored: Mercury 3:2 spin-orbit resonance (solar day = 2 Mercury-years exactly); Venus retrograde with sidereal day longer than year; Sol differential rotation (Carrington Rotation Number); Saturn Cassini-revised rotation (Mankovich 2019).
  • v0.7.0C/Python parity Tier 2b — full HD pipeline in C (ABI v5). Three new C entry points: es_encode_state_hd, es_bind_observer, es_get_eclipse_probability. Bridge dispatches get_local_view and get_eclipse_probability on backend={"auto","bip","c","fpu-ref"}. Every encoder-touching bridge method now has a paired C path; the v0.6.0 parity discipline is fully realised.
  • v0.6.1Tier 2a foundation: portable channel-basis PRNG (ABI v4). Splitmix64 PRNG bit-identical between Python + C; es_channel_basis(seed, out, D) produces byte-identical complex64 hypervectors on both sides. Foundation for v0.7.0's HD encode pipeline.
  • v0.6.0C/Python parity Tier 1 + always-on parity smoke test (ABI v3). find_syzygies and get_breathing_modulation now have C twins; bridge dispatches on backend={"auto","bip","c"}. New tests/test_parity_smoke.py enumerates every encoder-touching bridge.* method in a PARITY_TARGETS table — adding a new bridge method without a parity classification fails CI.
  • v0.5.5Moon catalog patches (Phase C). Five LS-fit-vindicated moon entries join CATALOG_V2: dione (98.2%), tethys (93.8%), enceladus (98.9%), titan (95.5%), iapetus (98.6%). Methodology vindicated twice on independent body sets: planets at 96-99%, moons at 93-99%.
  • v0.5.4Sol Uranian Time (SUT) — third planetary time system alongside Mars / Lunar. CLI --help audit across all subcommands.
  • v0.5.3Moon residuals: 13 of 17 fixed. Period-truncation root cause confirmed via per-orbital-period diagnostic. Fix: 9+-decimal sidereal periods from JPL HORIZONS / NASA fact sheets. Galileans drop from 100°→<1° RMS.
  • v0.5.2 — Patch-shrinks-residual benchmark VINDICATED on planets via LS-fit catalog (Mars 99.2%, Mercury 99.9%, J–S 97.6/96.0%). CATALOG_V2 ships alongside v0.4.0. Moon-kernel infrastructure added.
  • v0.5.1 — Patch-shrinks-residual benchmark: PARTIAL vindication (J–S 77%, Mercury 40%, Mars stuck on FFT leakage); two v0.4.0 authoring bugs surfaced.
  • v0.5.0 — All major Jovian + Saturnian moons join the encoder (26 → 38 bodies). Three new resonances (Cassini Division, Enceladus tidal heating, Hyperion chaos). SPICE-free runtime via codegen-baked initial phases.
  • v0.4.1 — C-side runtime kernel patching (ABI v2). 237× speedup on patched encodes vs BIP.
  • v0.4.0 — Diagnosed-fiber runtime overlay (Python side). Patches as data, ksplice/kpatch-style.
  • v0.3.1 — C-in-wheel + spectral syzygy window search + DE441 error-spectrum FFT.
  • v0.3.0 — Mars Sol Date / Mars Coordinated Time, mean lunar primitives, LTE440 awareness, DE441 full-epoch sweep, natural-resonance gear group.
  • v0.2.0 — Phase 9 coverage extension to four resonance pairs (J–S 5:2, N–P 3:2, Io–Europa 2:1, Europa–Ganymede 2:1).
  • v0.1.0 — first PyPI release. 26-body Sol Star System Laplacian + Phase 9 adaptive ("breathing") couplings + ALU-native BIP encoder.

Roadmap

Items genuinely still ahead (everything previously listed under "in progress" v0.7.0, "Sol Venusian/Mercurian Time," "ITN pathway / Lagrange-tube query (first cut)," and "Sol Moon Times completion (IAU-major roster)" has shipped — see Status above for landing versions):

  • v0.16.0 — Tier-1 BODIES expansion (43 → 52) — Themed as "Lagrange-trojan + retrograde-irregular + Neptune sub-graph completion." Adds: 4 Saturnian Lagrange trojans (Helene at Dione L4, Polydeuces at Dione L5, Telesto at Tethys L4, Calypso at Tethys L5 — the roster's first L4/L5 entries), 2 Jovian retrograde irregulars (Pasiphae, Sinope — second retrograde marker beyond Triton), Jupiter's Himalia (largest prograde irregular), and Neptune's Proteus + Nereid (sub-graph completion). The Lagrange trojans are the spectral headliner: their period is identical to their parent moon's, giving the Laplacian a multiplicity-2 degeneracy at the L4/L5 frequency — the natural place where the Lagrange-highway research thread (below) intersects BODIES directly. Mirrors the v0.14.x ship pattern (BODIES additions + bridge wrappers + CLI subcommands + test modules + native rebuild + ABI v7 → v8). See ephemerides_spectral_research_notebook.md §11 for the full audit.
  • v0.16.x — Resonance-graph multi-leg find_itn_chains — the natural extension of the v0.8.1 Hohmann anchor. Searches the (body, epoch, heliocentric-energy-bucket) graph using Dijkstra/A* with Hohmann Δv as edge cost; each leg carries a per-leg integer (p, q) gear-ratio resonance signature. Stays in the integer-ALU + FPU pipeline discipline (no CR3BP integrator). API sketch: find_itn_chains(jd_lo, jd_hi, *, departure, target, dv_budget_kms=30.0, max_legs=4) -> List[ITNChainCandidate] with per-leg resonance_signature: Tuple[Tuple[int, int], ...]. Same minor adds L1/L2 gateway designation + Jacobi constant (closed-form Newton on the collinear quintic) + Richardson 1980 third-order halo-orbit amplitudes as supplementary fields on the existing ITNCandidate. See research notebook §12 for the full survey.
  • v0.17.x — Gateway-graph Laplacian + heteroclinic searchlargely unexplored in published literature. Build a graph whose nodes are (body, L_i, halo-family-index) tuples and whose edges are heteroclinic Δv-cost weighted connections, then ask whether its Fiedler partition agrees with empirical low-Δv accessibility classes. If yes, the spectral lens has earned its keep on ITN. Anderson & Lo 2009 and Topputo et al. treat the manifold network as a graph but do not analyse it spectrally. Likely a short paper's worth of work.
  • First-principles per-resonance α — replaces phenomenological α = 0.1 with values derived from a Hamilton/Delaunay-variable Lagrangian (Lie-series perturbation theory around each resonance). The DE441 sweep is the empirical motivation: bodies inside the resonance set phase-scramble at multi-millennium horizons because their α values are wrong-in-detail. The v0.5.5 LS-fit catalog patches are the empirical analog — Fourier-correction overlays that first-principles α should ultimately make redundant for bodies inside the resonance set.
  • Hyperion follow-up — multi-component patch or coupled titan-hyperion-4to3-coupled-v2. The single-sinusoid Hyperion patch hits 75% (chaos ceiling); a coupled / multi-component patch should clear the 80% gate.
  • Remaining 4 broken moons (metis / thebe / rhea / phoebe). Phoebe needs sign-aware retrograde encoder; Metis needs an authoritative period; Thebe + Rhea look perturbation-driven.
  • Tier-2 / Tier-3 thematic ships (deferred from the v0.16.0 audit): resonance-chain shepherd-cluster ship (4 Plutonian small moons in the Charon 3:4:5:6 chain; 5 Saturnian shepherds Pan/Daphnis/Atlas/Prometheus/Pandora); inner-Uranian + inner-Neptunian close-packed ring-system entry; outer-system dwarf-planet ship (Eris, Makemake, Haumea, Sedna, Quaoar with their moons); mission-visited asteroid ship (Eros, Itokawa, Bennu, Ryugu).
  • DE441 vs DE442 spectral error signature (experiment) — build two BIP instruments, one calibrated only from DE441, one only from DE442; encode the same JD on both; project the per-body residue deltas onto the encoder's eigenbasis. If the deltas have a coherent spectral signature, DE442's corrections to DE441 live in a specific eigenmode subspace — which means we could predict where ephemeris error correction is structurally needed without needing the corrected kernel.
  • LTC (Lunar Coordinated Time) — pending NASA + international space-agency standardisation (target ~2026–2028 per April 2024 White House directive). LTE440 (Lin et al. 2025) ships the underlying SPICE-format conversion ephemeris with 0.15 ns accuracy through 2050; the bridge gains an LTC namespace mirroring MarsTime once the LTC epoch + day-length convention are formalised.
  • Phase 10 resonance coverage — Jupiter–Uranus 7:1, Saturn–Uranus 3:1, Saros / Metonic / Terra–Luna precession entries. Each adds a row to the RESONANCES table; the integer-LUT machinery is shared.
  • Multi-millennium DE441 sweep with the v0.5+ resonance-corrected encoder. Re-derive Metonic and Saros anchors against the full 3.3 GB DE441 with adaptive ("breathing") couplings active.
  • Doxygen for ephemerides-spectral C public API — every entry point in c/include/ephemerides_spectral.h documented in the standard Doxygen style for downstream embedded / WASM consumers.
  • Bit-serial hardware port (Verilog/SystemC) — the cosine LUT becomes block RAM, the omega * step becomes a fixed-precision multiplier.

License

GPL-3.0-or-later.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ephemerides_spectral-0.21.0.tar.gz (443.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ephemerides_spectral-0.21.0-py3-none-any.whl (292.6 kB view details)

Uploaded Python 3

ephemerides_spectral-0.21.0-cp314-cp314-win_amd64.whl (311.8 kB view details)

Uploaded CPython 3.14Windows x86-64

ephemerides_spectral-0.21.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (304.8 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ephemerides_spectral-0.21.0-cp314-cp314-macosx_11_0_arm64.whl (304.8 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

ephemerides_spectral-0.21.0-cp313-cp313-win_amd64.whl (309.8 kB view details)

Uploaded CPython 3.13Windows x86-64

ephemerides_spectral-0.21.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (304.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ephemerides_spectral-0.21.0-cp313-cp313-macosx_11_0_arm64.whl (304.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

ephemerides_spectral-0.21.0-cp312-cp312-win_amd64.whl (309.8 kB view details)

Uploaded CPython 3.12Windows x86-64

ephemerides_spectral-0.21.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (304.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ephemerides_spectral-0.21.0-cp312-cp312-macosx_11_0_arm64.whl (304.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

ephemerides_spectral-0.21.0-cp311-cp311-win_amd64.whl (309.8 kB view details)

Uploaded CPython 3.11Windows x86-64

ephemerides_spectral-0.21.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (304.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ephemerides_spectral-0.21.0-cp311-cp311-macosx_11_0_arm64.whl (304.8 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

ephemerides_spectral-0.21.0-cp310-cp310-win_amd64.whl (309.8 kB view details)

Uploaded CPython 3.10Windows x86-64

ephemerides_spectral-0.21.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (304.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

ephemerides_spectral-0.21.0-cp310-cp310-macosx_11_0_arm64.whl (304.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file ephemerides_spectral-0.21.0.tar.gz.

File metadata

  • Download URL: ephemerides_spectral-0.21.0.tar.gz
  • Upload date:
  • Size: 443.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ephemerides_spectral-0.21.0.tar.gz
Algorithm Hash digest
SHA256 dee70487cace22bbc6427344f4e34881e1c4bcacfce6dcaa8545aefb982556ab
MD5 9a1922856fedc7f0f1d7afa84435f621
BLAKE2b-256 a005f45543e5a3c1858bc6e59bc264709eb0d095a419742fdb081db9ce71503b

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0.tar.gz:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-py3-none-any.whl
Algorithm Hash digest
SHA256 802163f29a22c70222ae7f778cf5163135fc73fabe12987a3de43d2cdf956402
MD5 f6edbdfe16df625fe84a6423ebd102fd
BLAKE2b-256 a1a341c875625a77b1915e053d88391e8982ae59440d7e6c6541330f786bd387

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-py3-none-any.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 c81b2cf02b4582c0bf54b41699af63e06c9ba2de8a070c311a7014c161f7d51b
MD5 d49e6ecbcb04406014e86f1b71c4f8dc
BLAKE2b-256 f95234b40edc22bf09120a7e0940772da7702c6ff165c507e3083cfbc370e431

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp314-cp314-win_amd64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d33d83c30fc0c7efa6310c7743446be7b4df975c0ba50c00a4244bfddeca790c
MD5 93a4f023539293fcd5779b6c82aff9db
BLAKE2b-256 3d4130bf34e6ef01b9da17bad7b5bc594571dee1b46789422681c7aa1ed4a492

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 535f27faa206b9445d9961d233412bfa0482ccf7b92c910c267f695d1fec3a26
MD5 bdd7bf7331e71d02c60174130c4b652f
BLAKE2b-256 639a1b81348f885c38251d21aa5a626ff8dec33db1978b16e7145e65621b274a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 73c21f54ee363438cf7aecf35787079159f12466d5c47b01257297e75e43e2c1
MD5 d897464cc46add129214421f64dca77c
BLAKE2b-256 6216d82561dcfa768e7a4ca93e706526acf81c9e22324cead145e5cf466d3b70

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp313-cp313-win_amd64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c64291ef5bc079fb87cf0d0dfd1042e4af6c1159e56d4e594a40e080116c0817
MD5 db7701c26722d0d62283d42e7faf00bf
BLAKE2b-256 c6039ddd64e2f0b8c46631a5675a6689f263d287eae50ff1babc3a1fc2dea631

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ecc2e350adab75583ede4dbf11f0c80a770a0b1adf63bfafa68eab045054d4e0
MD5 71e37c84c7a805849ebb115894fb475c
BLAKE2b-256 58bff8662678b7d2d1317a6342100cd46e6f53ed00f09ea2278aa3c3a546d56f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 9d09076528e330813fbf9351268d8b05762fb7ff2ac515c5918ed58984164f88
MD5 03e1a12590c09bfe6e36b94784cac050
BLAKE2b-256 abc9e3b623b76cc4a3480500b11086311b6af99bfe8ded62b8d5e5b099e5d717

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp312-cp312-win_amd64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5110c5a1c64381ec5f49ac4c4599eb8cd52ea1c0117ab426483779a68727ac34
MD5 fa6e649f7dabdc623433f6569c3039c9
BLAKE2b-256 f97dcd75a64151d638323a649201ea73676ce9243956d47aa954ec85c9abf320

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ca931501fb4beaccbda3c1fc087d0571157d269d03685b5b18f7df5f3e4fc222
MD5 bbd42ba6782efe66fed36307b7984e03
BLAKE2b-256 b347cdf742ec36d9b0695bb96778ab9dece2e87e2d9e10befbc87fa82f569038

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 1e2c014b3217547a6837aa5148678514e2d6c62ac1dcbbb11c333cc3fb59fdb9
MD5 68110a8a7ff8ce5d884e2524345391b4
BLAKE2b-256 a4dc8ab273dfb605a040d699a962dd473d2d5fe124b5200fb2af30c9e3fafa74

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp311-cp311-win_amd64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6aa1a6ce5bb1c831a5c5e8f39f2b2438a76b7acb4f91cb28e0996b7116a50880
MD5 f70b093acf8a4a7e551550e225503894
BLAKE2b-256 0511b0c1e5a143b98e0d54cd40cfabdcb8747562d73578c88dbea76e9b6ce887

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 eb89edeff130ccc019a0239470de93a4d4e1c7f25d352b0b13cc1439061030f9
MD5 2a9e37195c213374dee2f7ac9363ab3a
BLAKE2b-256 ed3ddb44dd9417858910ca7f02ec7f25ac4bf54d160151e39b1360aaa660e2f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 6523e163d820731302f31f16116b3741e312005e5bafd50e04539a755ae58e6b
MD5 5abb8120c1180da75f63857e33930f81
BLAKE2b-256 ff3cda74c647d270013fa32af2a47cf5c8e8910f2c83aa6abb0007fe267c17a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp310-cp310-win_amd64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 369c66b7e56637b7f48eb269da88a7e90ad158e2e30ce7ea6e8db6cead28724b
MD5 9f544c6d84d6c50c95e2abca14a25821
BLAKE2b-256 afaeb8b04b16d8e5b99a21e66daa5e6fa70f7964f737fb6df3353a52141eb9af

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ephemerides_spectral-0.21.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ephemerides_spectral-0.21.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6927e28b32fb2a91296042db98aebc4844205e284d207919fd18d547d8066384
MD5 e3f67c57aae16286a983bb901aed0d08
BLAKE2b-256 46df8b46b7f9a490cbbf7103265d6c2b6628504cd747e3f6946058c3721bd34c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ephemerides_spectral-0.21.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: ephemerides-spectral-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page