Runtime kernel patching (v0.4.0) — diagnosed-fiber overlay¶
The v0.4.0 release introduces a runtime overlay for diagnosed-fiber patches. Patches sit beside the published spectral kernel as data — not code edits — and contribute per-body residue deltas at encode time. The kernel's published bytes never change.
Why "overlay, not bones"?¶
The spectral kernel — the static RESONANCES table, the Laplacian
construction, the integer Q-format frequencies — is the kernel's
truth as we know it. We want to ship that truth with byte-pinned
reproducibility: a wheel with SHA-256 X always encodes JD Y to
phase residue Z. Forever.
But the v0.3.1 DE441 error-spectrum FFT makes it visible that the kernel is incomplete. Specific FFT residual peaks scream "missing coupling": Mars at 7.96 yr (3.45°), Mercury at 10.69 yr (9.19°), Jupiter–Saturn jointly at 9.56 yr (±45° each, the smoking-gun J–S 5:2 libration depth).
If we fixed the kernel by adding those couplings to RESONANCES /
L_static and re-shipping, three things would happen:
- The published bytes would change. Existing tests / hash-pins / reproducibility claims tied to v0.3.1 would all need to be re-floored against v0.4.0.
- First-principles vs empirical lines would blur. The current
RESONANCEStable reflects derivable mean-motion physics. An empirical Fourier correction read off an FFT is not the same kind of object — it should be marked as such. - Iteration on diagnosed corrections becomes a hard fork. Every tweak demands a new release; can't compose; can't disable.
The runtime overlay solves all three:
- Patches are data, applied at encode time. The kernel bytes stay pinned to a release SHA. Bricked patches are unloadable.
- Patches are explicitly empirical. Each carries
notespointing to the FFT peak it targets and the suspected missing physics — they're hypotheses, not first-principles. - Patches compose. Multiple sinusoidal overlays sum order-independently. Disable, swap, A/B test as data, not as code edits + redeploys.
This is the same architectural choice Linux made with ksplice / kpatch: ship the immutable kernel, patch at runtime via an overlay, keep the bones unchanged.
What ships in v0.4.0¶
| Component | Status |
|---|---|
DiagnosedPatch dataclass + module-level registry (apply_patch, clear_patches, list_patches, snapshot, evaluate_active_patches) |
✅ v0.4.0 |
Bridge surface (bridge.apply_patch / apply_custom_patch / list_active_patches / list_catalog_patches / clear_patches) |
✅ v0.4.0 |
CLI (patches catalog / patches active / patches apply --name / patches clear) |
✅ v0.4.0 |
| BIP encoder runtime-overlay integration (overlay summed AFTER base encode, BEFORE final cyclic-group reduction) | ✅ v0.4.0 |
Catalog of three patches authored from the v0.3.1 FFT analysis (Mars 7.96 yr diagonal; Mercury 10.69 yr diagonal; Jupiter–Saturn 9.56 yr coupled with correlation=-1) |
✅ v0.4.0 |
| Tests pinning the structural properties (clear-restores-byte-identical; diagonal-patches-don't-leak; coupled-anti-correlated; composition-independent) | ✅ v0.4.0 |
C-side overlay (es_apply_patch / es_clear_patches / es_n_active_patches / es_get_patch_at, ABI v2) |
✅ v0.4.1 |
| Cross-backend byte-exact parity test (BIP and C identical phases under overlay) | ✅ v0.4.1 |
| Sync layer (Python registry mirrors into C; rollback on rejection) | ✅ v0.4.1 |
In v0.4.0 the C backend transparently fell back to BIP when patches
were active. In v0.4.1 the native binary carries its own patch
registry, mirrored into via the bridge sync layer; backend="c"
applies the overlay natively at ~46 μs / encode with 3 patches
active (vs ~10.8 ms on BIP — a 237× speedup). With no native
loaded — sdist install without C toolchain, Pyodide, the pure-Python
fallback wheel — the overlay still runs Python-side and the BIP
backend handles everything.
Patch-contribution shape — at a JD ladder¶
The reproducible shape of each catalog patch's contribution, encoded
at five JDs across the ±20 yr horizon. Each cell is
patched_phase[body] − baseline_phase[body] mapped to degrees on
the cyclic group. With no patches active, the encoder is byte-
identical to v0.3.1.
Full demo output — generated by
python -m research.demo_runtime_patches.
mars-7.96yr-diagonal (kind = sinusoid)¶
- amplitude: 3.45° (read off the v0.3.1 FFT peak rank #1)
- period: 2907.3 d (7.96 yr)
- target: Mars only
| Δt (yr) | Δmars (deg) |
|---|---|
| -20.0 | +0.2737 |
| -5.0 | +2.4875 |
| 0.0 | 0.0000 |
| +5.0 | -2.4875 |
| +20.0 | -0.2737 |
A single sinusoid. Zero at REFERENCE_JD by construction (no phase_rad
offset wired into this catalog entry; users authoring custom patches
can bake in any anchor phase). All other 24 bodies are unchanged at
every JD.
mercury-10.69yr-diagonal (kind = sinusoid)¶
- amplitude: 9.19° (FFT peak rank #1 for Mercury)
- period: 3905.1 d (10.69 yr)
- target: Mercury only
| Δt (yr) | Δmercury (deg) |
|---|---|
| -20.0 | +6.6742 |
| -5.0 | -1.8547 |
| 0.0 | 0.0000 |
| +5.0 | +1.8547 |
| +20.0 | -6.6742 |
Same sinusoidal form, different period; only Mercury affected.
jupiter-saturn-9.56yr-coupled (kind = coupled-sinusoid)¶
- amplitude: 45.0° (the smoking-gun J–S 5:2 libration depth)
- period: 3490.9 d (9.56 yr)
- correlation: −1 (anti-correlated libration around the conjunction)
- targets: Jupiter and Saturn together
| Δt (yr) | Δjupiter (deg) | Δsaturn (deg) |
|---|---|---|
| -20.0 | -24.7258 | +24.7258 |
| -5.0 | +6.5213 | -6.5213 |
| 0.0 | 0.0000 | 0.0000 |
| +5.0 | -6.5213 | +6.5213 |
| +20.0 | +24.7258 | -24.7258 |
Anti-correlated to within the cyclic-group ULP — the libration signature. The two columns sum to zero exactly (in residues) because the coupled-sinusoid evaluates one delta and applies +1× to body_a, −1× to body_b. This is the "missing coupling" structural fix wearing its empirical-correction clothing.
Composition¶
Two patches on disjoint bodies compose order-independently. Property
verified by tests/test_runtime_patches.py::test_compose_two_disjoint_patches_independence:
- apply Mars patch → encode → Mars delta is M
- apply Mercury patch → encode → Mars delta is still M (Mercury patch doesn't perturb Mars), Mercury delta is N
- clear, apply Mercury alone → encode → Mercury delta is still N
For two patches both targeting the same body, the deltas sum
linearly (sin sums commute on the cyclic group via uint64 wrapping
addition; the final reduction & (MODULO - 1) collapses cleanly).
What this DOESN'T claim¶
The patches in the v0.4.0 catalog are empirical Fourier
corrections, not first-principles physics. They paper over a
missing entry in the static RESONANCES table or a missing PN term.
Each patch is a hypothesis — "this peak is a sin at this period,
of this amplitude" — that the v0.5.x first-principles α derivation
(Hamilton/Delaunay-variable Lagrangian around each resonance) should
ultimately replace.
Whether a patch helps is then a measurable property: re-run the
FFT-residual analysis with patches active, check the targeted peak
shrunk. That experiment is one-line (apply_catalog_patch(...) then
re-run de441_error_spectrum); the demonstration cost is bounded by
the encoder-cycles of one full sweep (~6 s on the C native path,
~5 min in pure Python at 1024 samples × 30-d cadence).
How to use¶
from ephemerides_spectral import bridge
# Inspect the catalog
print(bridge.list_catalog_patches())
# Apply a bundled patch
bridge.apply_patch("jupiter-saturn-9.56yr-coupled")
# Check what's active
print(bridge.list_active_patches())
# Encode (the patch contributes to the result)
state = bridge.get_system_state(2451545.0 + 20 * 365.25, backend="bip")
# Author your own from FFT-diagnosed peaks
bridge.apply_custom_patch(
name="my-earth-correction",
kind="sinusoid",
body="earth",
amplitude_deg=0.93,
period_days=1940.2, # the v0.3.1 Earth peak at 5.31 yr
notes="hypothesis: Earth aliased peak from a sub-Nyquist signal",
)
# Wipe back to v0.3.1 byte-exact baseline
bridge.clear_patches()
CLI parity is 1:1:
ephemerides-spectral patches catalog
ephemerides-spectral patches apply --name mars-7.96yr-diagonal
ephemerides-spectral patches active
ephemerides-spectral patches clear
What's next¶
v0.4.x phase F: C-side overlay— shipped in v0.4.1. The ABI v2 surface (es_apply_patch/es_clear_patches/es_n_active_patches/es_get_patch_at) is live; cross-backend byte-exact parity verified.- v0.4.x first-principles α: replaces the empirical sinusoidal
patches with derived modulation depths from Lie-series perturbation
theory around each resonance. The patches in this catalog are
expected to shrink in amplitude once the underlying physics is
in
RESONANCES. - Patch-shrinks-residual benchmark: an automated regression that
re-runs
de441_error_spectrumwith the catalog patches active and asserts the targeted peaks shrunk by>= 80 %of the patch amplitude. This pins the catalog as useful, not just applicable.