kshana 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +215 -64
  2. package/kshana_bg.wasm +0 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -14,7 +14,8 @@
14
14
  <a href="tests/sgp4_verification.rs"><img src="https://img.shields.io/badge/SGP4-666%2F666%20AIAA%20vectors%20%C2%B7%204.12mm-3fb950" alt="SGP4 validated against all 666 AIAA 2006-6753 vectors, worst 4.12 mm"></a>
15
15
  <a href="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml"><img src="https://img.shields.io/badge/coverage-~97%25%20line-3fb950" alt="~97% line coverage on src/ (cargo-tarpaulin LLVM engine), gated at 85% in CI"></a>
16
16
  <a href="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml"><img src="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
17
- <a href="https://github.com/ashfordeOU/kshana/releases"><img src="https://img.shields.io/github/v/release/ashfordeOU/kshana?sort=semver" alt="Release"></a>
17
+ <a href="https://github.com/ashfordeOU/kshana/releases"><img src="https://img.shields.io/badge/release-v0.16.0-c79e63" alt="Release v0.16.0"></a>
18
+ <a href="https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator"><img src="https://img.shields.io/badge/JetBrains-Marketplace-c79e63" alt="Kshana on the JetBrains Marketplace"></a>
18
19
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache-2.0"></a>
19
20
  <a href="Cargo.toml"><img src="https://img.shields.io/badge/rust-1.75%2B-orange.svg" alt="Rust 1.75+"></a>
20
21
  <a href="https://doi.org/10.5281/zenodo.20528627"><img src="https://img.shields.io/badge/DOI-10.5281%2Fzenodo.20528627-blue.svg" alt="DOI 10.5281/zenodo.20528627"></a>
@@ -43,7 +44,7 @@ citable table in [`docs/PROVENANCE.md`](docs/PROVENANCE.md).
43
44
  *Free and open source under Apache-2.0, professionally developed and maintained by
44
45
  Ashforde OÜ — commercial support, integration, and proprietary extensions available.*
45
46
 
46
- > **Status: v0.15.0 · a simulation substrate, not yet a product.** A validated,
47
+ > **Status: v0.16.0 · a simulation substrate, not yet a product.** A validated,
47
48
  > fully reproducible engine spanning the PNT stack — orbit geometry and constellation
48
49
  > design, a numerical (Cowell) propagator with a six-perturbation force model, maneuver
49
50
  > and trajectory design, time systems, inertial navigation (incl. map-aided and
@@ -104,7 +105,8 @@ geometry, inertial navigation, GNSS/INS fusion, integrity, clocks, and timing. I
104
105
  runs a scenario (often a GNSS outage), evolves calibrated sensor error models
105
106
  through the appropriate estimator, and scores the result against the operational
106
107
  figures of merit — emitting a reproducible JSON result and an SVG chart, from a
107
- Rust library, CLI, Python extension, or in-browser WebAssembly module.
108
+ Rust library, a CLI, a Python extension, an in-browser WebAssembly module, a
109
+ **Model Context Protocol (MCP) server** for AI agents, or a **JetBrains IDE plugin**.
108
110
 
109
111
  **It is not:** flight hardware, a quantum-payload design, a full GNSS signal
110
112
  receiver, or a certified avionics product. Quantum-hardware fidelity comes from
@@ -127,14 +129,16 @@ the P2 roadmap and [get in touch](#support--professional-services) to collaborat
127
129
  | Domain | Capability |
128
130
  |--------|------------|
129
131
  | **Orbit & geometry** | SGP4/SDP4 propagation (validated to 4.12 mm against all 666 AIAA 2006-6753 vectors); real two-line elements (a committed, date-stamped Celestrak `gps-ops` snapshot) or synthetic Walker-delta constellations whose mean elements realise the `i:T/P/F` formula to under 1 km over a 24 h propagation; multi-constellation visibility, dilution of precision, and GNSS availability; a gradient-free constellation-design optimiser, streets-of-coverage minimum-satellite sizing, a multi-constellation comparison tool, and a Walker **design sweep** that tabulates coverage / PDOP / revisit-time over a planes × satellites grid and reports the Pareto-optimal designs. |
130
- | **Numerical propagator** | A **Cowell** numerical propagator (`src/propagator.rs`) complementing the analytic SGP4/SDP4 path, with a hierarchical **six-perturbation** force model (`src/forces.rs`): two-body + the full **J2–J6 zonal** field (the exact analytic gradient of its disturbing potential), **epoch-driven Sun and Moon third-body** gravity (a built-in low-precision ephemeris, no DE/SPK kernel), **solar-radiation pressure** (cannonball model with a conical umbra+penumbra shadow), **atmospheric drag** (Vallado piecewise-exponential density, co-rotating atmosphere), and the **post-Newtonian Schwarzschild relativistic correction** — driven by a choice of two adaptive integrators (RK4 step-doubling or the **Dormand–Prince RK5(4)** embedded pair). Validated against analytic truth stronger than a cross-tool would give: the unperturbed orbit matches the exact universal-variable Kepler solution to **sub-metre over 24 h**, energy/angular-momentum conserve to ~1e-9, and each perturbation matches a hand-derived closed-form signature. |
132
+ | **Numerical propagator** | A **Cowell** numerical propagator (`src/propagator.rs`) complementing the analytic SGP4/SDP4 path, with a hierarchical **six-perturbation** force model (`src/forces.rs`): two-body + the full **J2–J6 zonal** field (the exact analytic gradient of its disturbing potential), an optional **EGM2008 tesseral spherical-harmonic geopotential to degree/order 70** (`src/gravity_sh.rs`; real NGA coefficients, Holmes–Featherstone normalized-Legendre recurrence, cross-checked against the closed-form Legendre functions and the analytic ∇V identity), **epoch-driven Sun and Moon third-body** gravity (a built-in low-precision ephemeris, no DE/SPK kernel), **solar-radiation pressure** (cannonball model with a conical umbra+penumbra shadow), **atmospheric drag** (Vallado piecewise-exponential density, co-rotating atmosphere), the **post-Newtonian Schwarzschild relativistic correction**, and the **Lense–Thirring frame-dragging** term (IERS 2010 §10, linear in Earth's angular momentum, ~1–2 orders below Schwarzschild) — driven by a choice of two adaptive integrators (RK4 step-doubling or the **Dormand–Prince RK5(4)** embedded pair). Validated against analytic truth stronger than a cross-tool would give: the unperturbed orbit matches the exact universal-variable Kepler solution to **sub-metre over 24 h**, energy/angular-momentum conserve to ~1e-9, and each perturbation matches a hand-derived closed-form signature. |
131
133
  | **Maneuvers & trajectory design** | Impulsive ΔV nodes with 6×6 covariance propagation (ECI / LVLH execution-error frames), finite-burn integration checked against the closed-form **Tsiolkovsky** rocket equation to < 0.01 %, an **Izzo-2015** single-revolution **Lambert** solver, an exact universal-variable **Kepler** propagator, and a **porkchop** (launch × arrival) C3 / arrival-V∞ sweep emitted as a JSON contour grid — the performance-simulation layer above GMAT/Orekit, with every Lambert output round-tripped against two-body truth and the porkchop minimum checked against the analytic Hohmann floor. |
132
134
  | **Time systems & reference frames** | IERS leap-second **UTC / TAI / TT / UT1** scales, a Julian-date API, the IAU-2000 **Earth Rotation Angle**, GMST-based **TEME ↔ ECEF** with WGS-84 geodetic frames, IAU 2006 precession (Fukushima–Williams), full **IAU 2000A/2000B nutation**, IERS **polar motion**, and the equinox-free **CIO-based IAU 2006/2000A GCRS↔ITRS** reduction — all validated **bit-for-bit** against the SOFA/ERFA vectors, and **independently cross-checked against ANISE** (the pure-Rust NAIF/SPICE reimplementation): kshana's GCRS→ITRS vs ANISE's ITRF93 from JPL's `earth_latest_high_prec.bpc`, the same IERS Earth-orientation parameters fed to both, agree to **≤ 0.86 m on the ground / ≤ 3.6 m at GNSS orbit** (max 0.028″) across eight epochs 2020–2023. |
133
135
  | **Inertial** | Three-axis strapdown INS — quaternion attitude, WGS-84 NED mechanization, coning/sculling compensation, and a deterministic IMU error model (scale-factor, misalignment, g-sensitivity, quantization, drift); a **first-principles cold-atom-interferometer accelerometer** (Mach–Zehnder phase, quantum projection noise, contrast decay, vibration coupling) that *derives* the velocity-random-walk coefficient; and a sequential-importance-resampling **particle filter** for map-aided (terrain-/gravity-referenced) GPS-denied navigation. |
134
- | **Gravity-map / alt-PNT** | A cold-atom **gravimeter measurement model** whose white-noise floor (`σ = ASD/√τ`) is derived from the CAI accelerometer physics; a low-degree, fully-normalised **spherical-harmonic gravity-anomaly field** (validated against the closed-form Legendre functions and a hand-derived single-term anomaly) plus synthetic mascons; and a **gravity-map-matching particle filter** that recovers a GPS-denied track from the anomaly sequence it flies through. A **60-minute GPS-denied benchmark** (a ~700 km / one-hour outage where the inertial solution drifts to ~70 km) is recovered to **~145 m (< 500 m)** by a hierarchical coarse-to-fine matcher — the ESA NAVISP *Quantum Wayfarer* target. |
136
+ | **Alt-PNT (GPS-denied)** | A cold-atom **gravimeter measurement model** whose white-noise floor (`σ = ASD/√τ`) is derived from the CAI accelerometer physics; a low-degree, fully-normalised **spherical-harmonic gravity-anomaly field** (validated against the closed-form Legendre functions and a hand-derived single-term anomaly) plus synthetic mascons; and a **gravity-map-matching particle filter** that recovers a GPS-denied track from the anomaly sequence it flies through. It extends to **terrain-referenced navigation** (TERCOM/SITAN against an SRTM `.hgt` DEM, `src/altpnt/terrain.rs`), an **IGRF-14 geomagnetic main field** to degree/order 13 (`src/igrf.rs`, validated against the tilted-dipole closed form and ∇V finite differences), and a **combined gravity + magnetic + terrain** navigator that fuses all three scalar channels through one particle filter (information is additive — no channel makes the fix worse). A **60-minute GPS-denied benchmark** (a ~700 km / one-hour outage where the inertial solution drifts to ~70 km) is recovered to **~145 m (< 500 m)** by a hierarchical coarse-to-fine matcher — the ESA NAVISP *Quantum Wayfarer* target. |
135
137
  | **Fusion** | Loosely-coupled 15-state GNSS/INS error-state EKF with closed-loop feedback (the `gnss-ins` pack); a **tightly-coupled** pseudorange update that keeps correcting with fewer than four satellites; a coupled **clock + position** filter; a general **unscented (sigma-point) Kalman** estimator for strongly nonlinear measurements; a tightly-coupled GNSS/INS **UKF navigator** (pseudorange + Doppler) whose force-model orbital coast is validated to **0.77 m RMS** over a 30-minute curving LEO pass that includes a 120-second GNSS outage; and a full **17-state tightly-coupled GNSS/INS UKF** (position, velocity, attitude error, accelerometer and gyro biases, clock bias and drift) whose **quantum-CAI dead-reckoning** coasts a 120-second outage on the cold-atom accelerometer's derived velocity-random-walk. |
136
138
  | **Orbit determination** | Recovery of an orbital state `[r, v]` from ground-station range tracking, composing the two-body + J2 force model and RK4 integrator with a **Gauss–Newton batch** corrector (`determine_orbit_batch`, sub-metre / mm·s⁻¹ from noiseless ranges, ~2 m at a 5 m noise floor) and a **sequential** unscented-filter variant (`determine_orbit_sequential`). |
137
- | **Integrity** | Snapshot and solution-separation (ARAIM-style) RAIM with horizontal/vertical protection levels (HPL/VPL), fault detection & exclusion, and Stanford integrity diagrams; an explicit integrity-risk-budget (**MHSS**) protection level, including the **dual-/multi-constellation constellation-wide fault mode** (EU ARAIM / DO-316). |
139
+ | **Lunar & cislunar** | An Earth–Moon **circular restricted three-body (CR3BP)** propagator in the rotating frame — conserved Jacobi constant and all five Lagrange points (`src/cr3bp.rs`) plus **LunaNet / LNIS** cislunar PNT geometry (MCI↔MCMF reduction, selenographic coordinates) with a **lunar south-pole ARAIM** pass that honestly surfaces the integrity gap: a ~30 m σ_URE drives the protection level well above a 50 m alert limit (`src/lunar.rs`, `scenarios/lunanet-araim.toml`). |
140
+ | **Integrity** | Snapshot and solution-separation (ARAIM-style) RAIM with horizontal/vertical protection levels (HPL/VPL), fault detection & exclusion, and Stanford integrity diagrams; an explicit integrity-risk-budget (**MHSS**) protection level, including the **dual-/multi-constellation constellation-wide fault mode** (EU ARAIM / DO-316), exercised on a real GPS + Galileo snapshot (`scenarios/araim-gps-galileo.toml`). |
141
+ | **Augmentation (SBAS)** | **SBAS / WAAS protection levels** in the DO-229E weighted-least-squares form (precision-approach and en-route K-factors) and the **L1/L5 dual-frequency ionosphere-free** combination (IS-GPS-705, γ₁₅ ≈ 1.793) that underpins DO-316 — `src/sbas.rs`, with the protection-level geometry cross-checked against a NumPy `inv(GᵀG)` reference. |
138
142
  | **Clock & timing** | Two-state Kalman holdover (Joseph-form covariance, NIS/NEES consistency health); Allan-family stability (ADEV / MDEV / TDEV / HDEV) with noise-type-specific confidence intervals and a full **IEEE-1139 five-coefficient power-law fit**; geometric corrections (Sagnac, GNSS common-view); and the operational transfer methods — **TWSTFT** with the BIPM Sagnac closed form, **GNSS common-view**, **PPP** ionosphere-free time transfer, a free-space **optical** link with turbulence scintillation, and an inverse-variance **clock-ensemble (paper) timescale** below the best contributing clock. |
139
143
  | **GNSS measurement domain** | Forward pseudorange / Doppler synthesis with **Klobuchar** (broadcast) and **IONEX / TEC-grid** (measured) ionosphere — including an IONEX file parser, time interpolation between maps, and the thin-shell slant-obliquity mapping — **Saastamoinen + Niell** troposphere, and snapshot RAIM (HPL/VPL). |
140
144
  | **Resilience** | Link-budget **jamming** (J/S → effective C/N₀ → loss of lock); a stochastic **time-spoof detector** (Neyman–Pearson / χ²₁ energy test with closed-form and Monte-Carlo P_fa/P_md and a Security FoM of 1 − P_md); and a **multi-layer spoof detector** fusing a RAIM-consistency parity test (with the common-mode blind spot modelled honestly), an RF AGC-power monitor, and a signal-quality (SQM early-minus-late) monitor. |
@@ -167,6 +171,13 @@ The capstone shows the fusion thesis: optical inter-satellite time-transfer keep
167
171
  a classical *clock* locked, isolating the *inertial* sensor as the classical suite's
168
172
  weak link — i.e. quantum inertial + optical timing together.
169
173
 
174
+ <p align="center">
175
+ <img src="docs/assets/clock-holdover.svg" alt="Clock holdover: phase error during a GNSS outage — the optical clock stays within the 20 ns spec for the whole outage while the chip-scale clock breaches it mid-outage" width="80%">
176
+ <br><em>Clock holdover through a GNSS outage: the optical clock (blue) stays inside the
177
+ 20 ns spec for the full coast; the chip-scale clock (red) breaches it part-way.
178
+ Generated by Kshana from <code>scenarios/clock-holdover.toml</code>.</em>
179
+ </p>
180
+
170
181
  A further scenario, `orbit-gnss-challenged.toml`, derives GNSS availability from
171
182
  **orbital geometry** rather than hand-authored windows: a spacecraft inside the GNSS
172
183
  shell is propagated against a GPS-like Walker constellation, and the visible-satellite
@@ -175,6 +186,14 @@ step. Over a day the user is in fix only ~59% of the time; the quantum clock hol
175
186
  5 ns timing solution through every gap (availability **1.0**), the chip-scale clock
176
187
  only **~0.83**.
177
188
 
189
+ <p align="center">
190
+ <img src="docs/assets/orbit-gnss-challenged.svg" alt="Orbit GNSS-challenged: visible-satellite count and fix state over a day for a spacecraft inside the GNSS shell" width="80%">
191
+ <br><em>GNSS availability derived from orbital geometry: the visible-satellite count
192
+ (line-of-sight, Earth-occultation, elevation mask) sets the fix state at each step,
193
+ so the clock must coast every gap. Generated by Kshana from
194
+ <code>scenarios/orbit-gnss-challenged.toml</code>.</em>
195
+ </p>
196
+
178
197
  The constellation can also be given as real two-line element sets. A *full* TLE
179
198
  (line 1 + line 2) is propagated with the full **SGP4/SDP4** model — including
180
199
  atmospheric drag and the deep-space lunar-solar and 12 h / 24 h resonance terms that
@@ -322,15 +341,17 @@ Then register `kshana-mcp` in your client's `mcpServers` config — see
322
341
  server is a standalone, workspace-excluded crate (the `rmcp` SDK is edition 2024), so it
323
342
  never affects the lean published `kshana` crate or its build.
324
343
 
325
- **In a JetBrains IDE** you can also install the **Kshana** plugin from the JetBrains
326
- Marketplace (Settings → Plugins → search "Kshana") to run scenarios from a right-click —
327
- see [`ide/jetbrains/`](ide/jetbrains/).
344
+ **In a JetBrains IDE** you can also install the
345
+ [**Kshana PNT simulator**](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator)
346
+ plugin from the JetBrains Marketplace (or *Settings → Plugins → Marketplace → search
347
+ "Kshana"*) to run scenarios from a right-click — see [`ide/jetbrains/`](ide/jetbrains/).
328
348
 
329
349
  ## Scenario format
330
350
 
331
- Scenarios are declarative TOML. A top-level `kind` selects the pack (`clock` is
332
- the default if omitted; `inertial`, `timetransfer`, `hybrid`, `fusion`,
333
- `gnss-ins`, `orbit`, `gnss-sim`, `integrity`, `spoof`, `jamming`, `sweep`, `sweep-nd`).
351
+ Scenarios are declarative TOML. A top-level `kind` selects the pack **seventeen** in
352
+ all (`clock` is the default if omitted): `inertial`, `timetransfer`, `hybrid`, `fusion`,
353
+ `gnss-ins`, `orbit`, `gnss-sim`, `integrity`, `lunar-integrity`, `spoof`, `jamming`,
354
+ `sweep`, `sweep-nd`, `gravity-map`, `terrain-nav`, and `combined-altpnt`.
334
355
  Common fields: `seed`, a `[time]` grid, a `[gnss]` availability timeline (the outage
335
356
  driver), and per-sensor blocks with `provenance` strings citing the source of every
336
357
  figure. Example (clock):
@@ -473,6 +494,20 @@ phasing_f = 1.0
473
494
  [clock_classical] # ... as above
474
495
  ```
475
496
 
497
+ The **GPS-denied alt-PNT** kinds navigate with no GNSS at all, matching a measured field
498
+ sequence against a map through a particle filter. A `gravity-map` scenario flies a track
499
+ through a spherical-harmonic gravity-anomaly field and recovers it from a cold-atom
500
+ gravimeter's reading (`scenarios/gps-denied-gravity-nav.toml`); a `terrain-nav` scenario
501
+ does the same against an SRTM elevation DEM (TERCOM/SITAN, `scenarios/terrain-nav.toml`);
502
+ and a `combined-altpnt` scenario fuses **gravity + IGRF magnetic + terrain** in one filter
503
+ (`scenarios/combined-altpnt.toml`).
504
+
505
+ A `lunar-integrity` scenario evaluates **cislunar** PNT: it runs a lunar south-pole
506
+ ARAIM protection-level pass against a LunaNet/LNIS relay set and honestly reports the
507
+ integrity gap — a ~30 m lunar σ_URE drives the protection level well above a 50 m alert
508
+ limit, so the service is *unavailable* under aviation-style integrity rules
509
+ (`scenarios/lunanet-araim.toml`).
510
+
476
511
  See `scenarios/` for one example of every kind.
477
512
 
478
513
  ## Output
@@ -515,11 +550,24 @@ New to these terms? Each is defined in plain language in the [glossary](docs/GLO
515
550
 
516
551
  ## Architecture
517
552
 
518
- One engine. The sensor packs plug in via a common error-model interface; alongside
519
- them sit an astrodynamics/numerical layer (analytic SGP4/SDP4 **and** a numerical
520
- Cowell propagator with its force model, maneuver design, and orbit determination) and a
521
- fusion / alt-PNT layer (the GNSS/INS estimators and the gravity-map matcher). See
522
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full set of diagrams.
553
+ **One engine, many front doors.** A single Rust core (`kshana`) runs every scenario,
554
+ reached through a CLI, a Python extension, an in-browser WebAssembly module, an **MCP
555
+ server** for AI agents, and a **JetBrains IDE plugin** all converging on one
556
+ `api::run_toml` dispatch. Inside, the sensor packs plug into a common error-model
557
+ interface; alongside them sit a **reference-frame layer** (IAU 2006/2000A
558
+ precession–nutation and the CIO-based GCRS↔ITRS reduction), an **astrodynamics/numerical
559
+ layer** (analytic SGP4/SDP4 **and** a numerical Cowell propagator with its
560
+ EGM2008/perturbation force model, maneuver design, and orbit determination), an
561
+ **integrity/GNSS layer** (RAIM/ARAIM, SBAS, the measurement domain, jamming, cislunar),
562
+ and a **fusion / alt-PNT layer** (the GNSS/INS estimators and the gravity/terrain/magnetic
563
+ map-matchers).
564
+
565
+ Two standalone, **workspace-excluded** crates sit beside the core — `mcp/kshana-mcp`
566
+ (the MCP server, built on the edition-2024 `rmcp` SDK) and `xval/anise-frames` (the
567
+ ANISE/SPICE frame cross-check, which pulls MPL-2.0 deps) — kept out of the published
568
+ crate's dependency graph, `Cargo.lock`, license gate, and MSRV build by the root
569
+ `Cargo.toml` `exclude` list. The JetBrains plugin (`ide/jetbrains`) is a separate Kotlin
570
+ project. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full set of diagrams.
523
571
 
524
572
  ```mermaid
525
573
  flowchart LR
@@ -534,85 +582,138 @@ flowchart LR
534
582
 
535
583
  ```mermaid
536
584
  flowchart TD
537
- cli["CLI · Python · WebAssembly"] --> api["api — run_toml / run_scenario: typed dispatch by kind"]
585
+ cli["CLI · Python · WebAssembly · MCP server · JetBrains plugin"] --> api["api — run_toml: typed dispatch over 17 kinds"]
538
586
  subgraph shared["Shared core"]
539
- types["types"]
540
- scenario["scenario · GNSS timeline"]
541
- allan["allan — Allan deviation"]
587
+ types["types · scenario · GNSS timeline"]
588
+ allan["allan ADEV/MDEV/TDEV/HDEV"]
589
+ end
590
+ subgraph frames["Time & reference frames"]
591
+ ts["timescales · jd2 — UTC/TAI/TT/UT1"]
592
+ pn["precession · nutation — IAU 2006/2000A"]
593
+ cio["cio — GCRS↔ITRS (CIO, SOFA-anchored)"]
542
594
  end
543
595
  subgraph packs["Sensor packs"]
544
- p1["Clock — models · estimator · kalman · security · fom"]
596
+ p1["clock — models · estimator · kalman · security"]
545
597
  p2["inertial — strapdown INS + quantum-CAI"]
546
- p3["timetransfer (+ _adv) — optical/RF link"]
598
+ p3["timetransfer — optical/RF/TWSTFT/PPP"]
547
599
  p4["hybrid — fused PNT suite"]
548
600
  end
549
601
  subgraph astro["Astrodynamics & numerical"]
550
- orbit["orbit — geometry → GNSS timeline + DOP"]
602
+ orbit["orbit · walker — geometry → GNSS + DOP"]
551
603
  sgp4["sgp4 · tle — SGP4/SDP4"]
552
604
  prop["propagator — Cowell"]
553
- forces["forces — J2–J6 · 3rd-body · SRP · drag · relativity"]
605
+ forces["forces — J2–J6 · 3rd-body · SRP · drag · GR"]
606
+ gsh["gravity_sh — EGM2008 d/o 70"]
554
607
  integ["integrator — RK4 · DOPRI"]
555
- ephem["ephem Sun/Moon"]
556
- man["maneuverburns · Lambert · porkchop"]
557
- od["orbit_determination — batch · sequential"]
608
+ man["maneuver · orbit_determination"]
609
+ cr["cr3bpEarth–Moon CR3BP"]
610
+ end
611
+ subgraph intg["Integrity & GNSS"]
612
+ raim["raim — RAIM/ARAIM · HPL/VPL"]
613
+ sbas["sbas — DO-229E PL · L1/L5"]
614
+ gsim["gnss_sim · ionex — measurement domain"]
615
+ jam["jamming — J/S → C/N₀"]
616
+ lun["lunar — cislunar ARAIM"]
558
617
  end
559
618
  subgraph fnav["Fusion & alt-PNT"]
560
619
  fus["fusion — EKF · UKF · 17-state · coupled"]
561
620
  grav["gravimeter · mapmatch · particle_filter"]
621
+ terr["altpnt/terrain · igrf — terrain + magnetic"]
622
+ end
623
+ subgraph io["Interop formats"]
624
+ iofmt["rinex · sp3 · oem · omm · glonass"]
562
625
  end
563
626
  api --> packs
564
627
  api --> astro
628
+ api --> intg
565
629
  api --> fnav
566
630
  packs --> shared
631
+ astro --> frames
567
632
  orbit --> sgp4
568
633
  prop --> forces
634
+ prop --> gsh
569
635
  prop --> integ
570
- forces --> ephem
571
- man --> integ
572
- od --> forces
573
- od --> integ
636
+ cr --> integ
574
637
  fus --> p2
575
638
  grav --> p2
639
+ terr --> grav
576
640
  orbit --> p1
641
+ orbit --> io
577
642
  p4 -. composes .-> p1
578
643
  p4 -. composes .-> p2
579
644
  p4 -. composes .-> p3
580
645
  ```
581
646
 
647
+ **Components & distribution.** The core crate ships through the Rust, Python, and
648
+ JavaScript ecosystems; the MCP server and IDE plugin reach AI agents and JetBrains IDEs.
649
+ Each `vX.Y.Z` tag republishes every channel automatically (see
650
+ [Versioning & releases](#versioning--releases)).
651
+
652
+ ```mermaid
653
+ flowchart LR
654
+ subgraph repo["One repository"]
655
+ core["kshana core<br/>library + CLI"]
656
+ mcp["mcp/kshana-mcp<br/>MCP server (excluded crate)"]
657
+ ide["ide/jetbrains<br/>Kotlin IDE plugin"]
658
+ xval["xval/anise-frames<br/>SPICE cross-check (excluded)"]
659
+ end
660
+ core --> crates["crates.io"]
661
+ core --> pypi["PyPI — wheels"]
662
+ core --> npm["npm — WebAssembly"]
663
+ core --> rel["GitHub Releases<br/>binaries · SBOM · SLSA · validation summary"]
664
+ core --> pages["kshana.dev<br/>GitHub Pages playground"]
665
+ core -. archived .-> zen["Zenodo DOI"]
666
+ mcp --> crates
667
+ mcp --> ghcr["ghcr.io — OCI image"]
668
+ mcp --> reg["official MCP registry"]
669
+ ide --> jb["JetBrains Marketplace"]
670
+ ```
671
+
582
672
  ## Repository layout
583
673
 
584
674
  ```
585
675
  kshana/
586
- ├── src/
587
- │ ├── types.rs · scenario.rs · allan.rs # shared core (time grid, GNSS timeline, Allan)
588
- │ ├── api.rs · main.rs # typed dispatch + CLI
589
- │ ├── python.rs · wasm.rs # optional PyO3 / wasm-bindgen bindings
676
+ ├── src/ # the kshana core crate (library + CLI)
677
+ │ ├── api.rs · main.rs · lib.rs # typed dispatch (17 kinds) + CLI + crate root
678
+ │ ├── python.rs · wasm.rs # optional PyO3 / wasm-bindgen bindings
679
+ │ ├── types.rs · scenario.rs · allan.rs # shared core (time grid, GNSS timeline, Allan)
590
680
  │ │
591
- │ ├── models.rs · estimator.rs · kalman.rs # Pack 1 — clock holdover + integrity
592
- │ ├── security.rs · detection.rs · spoof.rs · spoof_monitors.rs # spoof detection
681
+ │ ├── models.rs · estimator.rs · kalman.rs # Pack 1 — clock holdover + integrity
682
+ │ ├── security.rs · detection.rs · spoof.rs · spoof_monitors.rs # spoof detection
593
683
  │ ├── filter_health.rs · fom.rs · report.rs · chart.rs · run.rs # health · scoring · output
594
- │ ├── inertial/ # Pack 2 — strapdown INS (attitude, mechanization, imu_errors, quantum_imu)
595
- │ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs # Pack 3 — TWSTFT/CV/PPP/optical, Sagnac
596
- │ ├── hybrid.rs · ensemble.rs · sweep.rs # Pack 4 — fused PNT suite, Monte-Carlo, trade sweeps
684
+ │ ├── inertial/ # Pack 2 — strapdown INS (attitude · mechanization · imu_errors · quantum_imu)
685
+ │ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs # Pack 3 — TWSTFT/CV/PPP/optical, Sagnac
686
+ │ ├── hybrid.rs · ensemble.rs · sweep.rs # Pack 4 — fused PNT, Monte-Carlo, trade sweeps
687
+ │ │
688
+ │ ├── timescales.rs · jd2.rs · ephem.rs # time systems, two-part JD, Sun/Moon ephemeris
689
+ │ ├── precession.rs · nutation.rs · cio.rs # IAU 2006/2000A precession-nutation + CIO GCRS↔ITRS
690
+ │ ├── frames.rs · *_data.rs # TEME↔ECEF + generated nutation/CIO/EGM2008/IGRF tables
597
691
  │ │
598
692
  │ ├── orbit.rs · sgp4.rs · tle.rs · walker.rs # geometry, SGP4/SDP4, TLE, Walker design
599
- │ ├── propagator.rs · forces.rs · integrator.rs # numerical Cowell propagator + force model + RK4/DOPRI
600
- │ ├── ephem.rs · precession.rs · frames.rs · timescales.rs · jd2.rs # ephemerides, IAU precession, time/frames
601
- │ ├── maneuver.rs · batch_ls.rs · orbit_determination.rs # burns/Lambert/porkchop, Gauss-Newton, OD
693
+ │ ├── propagator.rs · forces.rs · gravity_sh.rs · integrator.rs # Cowell + perturbations (EGM2008 d/o70, GR) + RK4/DOPRI
694
+ │ ├── maneuver.rs · batch_ls.rs · orbit_determination.rs # burns/Lambert/porkchop, Gauss-Newton, OD
695
+ │ ├── cr3bp.rs · lunar.rs # Earth–Moon CR3BP, cislunar/LunaNet ARAIM
602
696
  │ │
603
- │ ├── fusion/ # GNSS/INS — EKF, UKF, tightly_coupled, tightly_coupled17, coupled
604
- │ ├── gravimeter.rs · mapmatch.rs · particle_filter.rs # gravity-map / alt-PNT navigation
605
- │ ├── raim.rs · lunar.rs # ARAIM HPL/VPL, cislunar integrity
606
- │ ├── gnss_sim.rs · ionex.rs · jamming.rs # measurement domain, ionosphere maps, jamming
607
- └── rinex.rs · rinex_obs.rs · glonass.rs · sp3.rs · oem.rs · omm.rs · permalink.rs # interop formats
608
- ├── scenarios/ # cited scenarios (one per kind + geometry-driven + GPS-denied)
609
- ├── scripts/ # reproducibility + repo-hygiene guards
610
- ├── docs/ # CONCEPTS, ARCHITECTURE, CAPABILITY, VALIDATION, PROVENANCE, GLOSSARY,
611
- ├── web/ # the WebAssembly playground + kshana.dev site
612
- ├── .github/workflows/ # CI gate, release, wheels, publish, and pages pipelines
613
- ├── pyproject.toml # Python packaging (maturin)
614
- ├── CHANGELOG.md # Keep a Changelog + SemVer
615
- └── CONTRIBUTING.md
697
+ │ ├── fusion/ # GNSS/INS — EKF · UKF · tightly_coupled(17) · coupled · closed_loop
698
+ │ ├── raim.rs · sbas.rs # RAIM/ARAIM HPL/VPL, SBAS DO-229E PLs + L1/L5 iono-free
699
+ │ ├── gnss_sim.rs · ionex.rs · jamming.rs # measurement domain, ionosphere maps, jamming
700
+ │ ├── gravimeter.rs · igrf.rs · mapmatch.rs · particle_filter.rs · altpnt/ # gravity/magnetic/terrain alt-PNT
701
+ ├── rinex.rs · rinex_obs.rs · glonass.rs · sp3.rs · oem.rs · omm.rs · permalink.rs # interop formats
702
+ │ └── bin/validation_report.rs # builds the release validation-summary HTML
703
+
704
+ ├── mcp/kshana-mcp/ # standalone, workspace-EXCLUDED crate the MCP server (+ Dockerfile, server.json)
705
+ ├── ide/jetbrains/ # standalone Kotlin/Gradle IntelliJ-Platform plugin
706
+ ├── xval/anise-frames/ # standalone, workspace-EXCLUDED crate ANISE/SPICE frame cross-check
707
+
708
+ ├── scenarios/ # one cited .toml per kind + geometry-driven + GPS-denied
709
+ ├── scripts/ # reproducibility + repo-hygiene + SBOM guards
710
+ ├── docs/ # CONCEPTS, ARCHITECTURE, CAPABILITY, VALIDATION, PROVENANCE, GLOSSARY, …
711
+ ├── web/ # the WebAssembly playground + kshana.dev site
712
+ ├── tools/ # table generators (EGM2008 · IGRF · nutation · CIO) + fetch_tles.sh
713
+ ├── .github/workflows/ # ci · release · publish · wheels · pages · mcp-publish · jetbrains-plugin · frame-xval
714
+ ├── pyproject.toml # Python packaging (maturin)
715
+ ├── CHANGELOG.md # Keep a Changelog + SemVer
716
+ └── CITATION.cff · ROADMAP.md · CONTRIBUTING.md · SECURITY.md
616
717
  ```
617
718
 
618
719
  ## Documentation
@@ -627,7 +728,15 @@ kshana/
627
728
  | [Provenance](docs/PROVENANCE.md) | reviewers / citers | every sensor parameter, model, and dataset traced to its published source, in one citable table |
628
729
  | [Reproducibility &amp; provenance](docs/REPRODUCIBILITY.md) | reviewers / packagers | determinism guarantees, golden-pinning, SBOM, build provenance |
629
730
  | [Positioning](docs/POSITIONING.md) | evaluators | where Kshana sits vs RTKLIB/gLAB (complementary), and the zero-install browser tier |
731
+ | [Technical report](paper/kshana-technical-report.md) · [JOSS paper](paper/paper.md) | reviewers / citers / evaluators | the full extended research paper — architecture, per-domain models, validation, case studies, and limitations — plus the concise JOSS submission |
630
732
  | [SGP4 validation](docs/SGP4-VALIDATION.md) | reviewers / citers | agreement with the AIAA 2006-6753 reference (666 states, ~4 mm) **and** a head-to-head against the independent `sgp4` crate (agree to sub-micron / 4.12 mm) |
733
+ | [Integrity FoM](docs/INTEGRITY.md) | evaluators | what the `integrity` / `security` figures mean — and what they are **not** vs aviation HPL/VPL |
734
+ | [Quantum models](docs/QUANTUM.md) · [details](docs/QUANTUM-MODELS.md) | reviewers | the cold-atom-interferometer physics layer, and where coefficients are still looked up |
735
+ | [Compliance](docs/COMPLIANCE.md) | evaluators | DO-229E / DO-316 algorithm scope, and what is **not** a conformance claim |
736
+ | [Result schema](docs/SCHEMA.md) | integrators | every field of the result JSON, with units and a source pointer |
737
+ | [Claims vs reality](docs/CLAIMS-VS-REALITY.md) | reviewers | the overclaim-closure ledger + the CI guard (`tests/no_overclaims.rs`) that keeps it resolved |
738
+ | [Roadmap](ROADMAP.md) | everyone | the phased roadmap — what has shipped and what is next |
739
+ | [MCP server](mcp/kshana-mcp/README.md) · [JetBrains plugin](ide/jetbrains/README.md) | agents / IDE users | run Kshana from an AI assistant or a JetBrains IDE |
631
740
  | [Changelog](CHANGELOG.md) | everyone | released history (Keep a Changelog + SemVer) |
632
741
  | [Contributing](CONTRIBUTING.md) | contributors | build, guards, test/citation discipline, DCO |
633
742
  | [Code of Conduct](CODE_OF_CONDUCT.md) | community | expected conduct (Contributor Covenant) |
@@ -646,6 +755,32 @@ kshana/
646
755
  - Maturity is stated honestly: optical-clock and optical-link figures are *targets /
647
756
  ground-demonstrator* results, not flown.
648
757
 
758
+ ### Validation at a glance
759
+
760
+ Every row is enforced by a named test in CI; the full evidence (and what is *not*
761
+ modelled) is in [`docs/VALIDATION.md`](docs/VALIDATION.md) and the per-release
762
+ [`kshana-validation-summary.html`](https://github.com/AshfordeOU/kshana/releases)
763
+ artifact (generated by `cargo run --bin validation_report`, SLSA-attested).
764
+
765
+ | Capability | Agreement | Reference / oracle |
766
+ |------------|-----------|--------------------|
767
+ | SGP4/SDP4 propagation | 666/666 vectors, worst **4.12 mm** | AIAA 2006-6753 (Vallado `tcppver.out`) + head-to-head vs the independent `sgp4` crate |
768
+ | Reference frames — IAU 2000A/B nutation, IAU 2006/2000A CIO chain, ERA | **bit-for-bit** (X,Y to 1e-14, s to 1e-18, ERA to 1e-12) | ERFA/SOFA `eraXys06a` · `eraC2ixys` · `eraEra00` · `eraNut00a/b` |
769
+ | GCRS→ITRS vs an independent SPICE engine | max **0.028″** → ≤ 0.86 m ground, ≤ 3.6 m GNSS orbit | ANISE (pure-Rust NAIF/SPICE), same IERS `finals2000A` EOP, 8 epochs 2020–2023 |
770
+ | EGM2008 geopotential (degree/order 70) | acceleration = ∇V to **< 1e-6**; zonal collapse to validated J2 | NGA EGM2008 coefficients + analytic ∇V identity |
771
+ | Allan estimators (ADEV/MDEV/TDEV/HDEV) + confidence bands | reproduce reference deviations; χ² bands match | NIST SP 1065 (Riley), 1000-point Table 31/32 |
772
+ | IMU error model — ARW / VRW / bias-instability | recovered to **< 5 %** (bias-instability < 15 %) | Analog Devices ADIS16465 datasheet; NaveGo reference profile |
773
+ | Numerical (Cowell) propagator, unperturbed | **sub-metre over 24 h**; energy/momentum conserve ~1e-9 | exact universal-variable Kepler |
774
+ | Lambert · Tsiolkovsky · porkchop | round-trip to two-body truth; ΔV **< 0.01 %** | Izzo 2015 · rocket equation · analytic Hohmann floor |
775
+ | Orbit determination (Gauss–Newton batch) | sub-m / mm·s⁻¹ noiseless; ~2 m at a 5 m noise floor | two-body + J2 over an RK4 arc |
776
+ | Tightly-coupled GNSS/INS UKF | **0.77 m RMS** over a 30-min LEO pass incl. a 120 s outage | force-model coast, hand-derived |
777
+ | GPS-denied gravity-map navigation | ~70 km INS drift → **~145 m** recovered | ESA NAVISP *Quantum Wayfarer* target |
778
+ | Terrain-referenced navigation (TERCOM/SITAN) | 70 km drift → **< 500 m** (grid-resolution floor ~140 m) | SRTM `.hgt` DEM; hand-injected drift (non-circular check) |
779
+ | IGRF-14 main field (degree/order 13) | pole ~80.7°N, dipole ~29.7 µT, physical 22–67 µT band | IAGA `igrf14coeffs.txt` (Schmidt semi-normalised) |
780
+ | ARAIM dual-constellation integrity | constellation-wide fault mode on real GPS + Galileo | EU ARAIM TR / DO-316; Celestrak `gps-ops` 2021-07-28 |
781
+ | Cross-platform reproducibility | bit-identical input + shape goldens on 3 OSes | Linux / macOS / Windows CI matrix, SHA-256 goldens |
782
+ | Test coverage | **~97 % line** on `src/`, gated ≥ 85 % | cargo-tarpaulin (LLVM engine) |
783
+
649
784
  ## FAQ
650
785
 
651
786
  **Do I need to understand quantum physics to use this?**
@@ -738,7 +873,7 @@ entry for every user-visible change. Participation is governed by our
738
873
 
739
874
  If you use Kshana in academic or technical work, please cite it. Machine-readable
740
875
  metadata is in [`CITATION.cff`](CITATION.cff) (GitHub renders a "Cite this repository"
741
- button from it); cite the version you used (e.g. `v0.15.0`) together with the
876
+ button from it); cite the version you used (e.g. `v0.16.0`) together with the
742
877
  scenario and seed for full reproducibility. Every release is archived on Zenodo with
743
878
  a citable DOI — the concept DOI [10.5281/zenodo.20528627](https://doi.org/10.5281/zenodo.20528627)
744
879
  always resolves to the latest version.
@@ -748,12 +883,28 @@ always resolves to the latest version.
748
883
  ## Versioning & releases
749
884
 
750
885
  Kshana follows [Semantic Versioning](https://semver.org). While pre-1.0 the public
751
- scenario/result schema may still change; breaking changes are called out explicitly
752
- in the [`CHANGELOG.md`](CHANGELOG.md). Tagged releases are published to
753
- [crates.io](https://crates.io/crates/kshana), [PyPI](https://pypi.org/project/kshana/),
754
- and [npm](https://www.npmjs.com/package/kshana), and listed under
755
- [GitHub Releases](https://github.com/AshfordeOU/kshana/releases). Every result is
756
- reproducible from `scenario + seed + engine version`.
886
+ scenario/result schema may still change; breaking changes are called out explicitly in
887
+ the [`CHANGELOG.md`](CHANGELOG.md). Every result is reproducible from
888
+ `scenario + seed + engine version`.
889
+
890
+ **Every `vX.Y.Z` tag publishes all channels automatically** — one CI pipeline fans out to:
891
+
892
+ | Channel | Install / get | Contents |
893
+ |---------|---------------|----------|
894
+ | [crates.io](https://crates.io/crates/kshana) | `cargo install kshana` · `kshana = "0.16"` | Rust library + CLI |
895
+ | [crates.io](https://crates.io/crates/kshana-mcp) | `cargo install kshana-mcp` | the MCP server |
896
+ | [PyPI](https://pypi.org/project/kshana/) | `pip install kshana` | abi3 wheels (Linux/macOS/Windows) + sdist |
897
+ | [npm](https://www.npmjs.com/package/kshana) | `npm install kshana` | WebAssembly module + JS wrapper |
898
+ | [ghcr.io](https://github.com/AshfordeOU/kshana/pkgs/container/kshana-mcp) | `docker run -i ghcr.io/ashfordeou/kshana-mcp` | multi-arch OCI image — no toolchain needed |
899
+ | official MCP registry | auto-discovered by MCP clients | `io.github.ashfordeOU/kshana-mcp` |
900
+ | [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator) | IDE → Plugins → search "Kshana" | the **Kshana — PNT simulator** IDE plugin |
901
+ | [GitHub Releases](https://github.com/AshfordeOU/kshana/releases) | download | `kshana` + `kshana-mcp` binaries, a CycloneDX **SBOM**, **SLSA** build provenance, and an HTML validation summary |
902
+ | [Zenodo](https://doi.org/10.5281/zenodo.20528627) | DOI | a citable archive of every release |
903
+ | [kshana.dev](https://kshana.dev) | open in a browser | the WebAssembly playground (redeployed from `main`) |
904
+
905
+ The MCP server's crate / image / registry version tracks the engine (it bundles the
906
+ library); the JetBrains plugin versions independently (it shells out to your installed
907
+ `kshana` binary).
757
908
 
758
909
  ## License
759
910
 
package/kshana_bg.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Chakshu Baweja <contact@ashforde.org>"
6
6
  ],
7
7
  "description": "Open, reproducible PNT-resilience simulator with quantum-sensor performance models",
8
- "version": "0.15.0",
8
+ "version": "0.16.0",
9
9
  "license": "Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",