kshana 0.14.1 → 0.15.1

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 +234 -61
  2. package/kshana_bg.wasm +0 -0
  3. package/package.json +2 -2
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.15.1-c79e63" alt="Release v0.15.1"></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.14.1 · a simulation substrate, not yet a product.** A validated,
47
+ > **Status: v0.15.1 · 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
@@ -303,11 +322,36 @@ const result = JSON.parse(run(tomlText));
303
322
  console.log(version(), result.classical.fom.timing_p95_ns);
304
323
  ```
305
324
 
325
+ ### AI agents (MCP)
326
+
327
+ Kshana ships an [MCP](https://modelcontextprotocol.io) server, [`kshana-mcp`](mcp/kshana-mcp/),
328
+ so AI assistants and agents can run the **validated** engine instead of guessing the
329
+ math — usable from **Cursor, JetBrains AI Assistant / Junie, and any MCP-compatible
330
+ assistant or agent**. It exposes `run_scenario`, `list_scenario_kinds`,
331
+ `validate_scenario`, `export_sp3`, and `export_omm` (each a thin wrapper over
332
+ `kshana::api`).
333
+
334
+ ```bash
335
+ cargo install kshana-mcp # crates.io
336
+ docker run --rm -i ghcr.io/ashfordeou/kshana-mcp # or OCI, no Rust toolchain
337
+ ```
338
+
339
+ Then register `kshana-mcp` in your client's `mcpServers` config — see
340
+ [`mcp/kshana-mcp/README.md`](mcp/kshana-mcp/README.md) for per-client snippets. The
341
+ server is a standalone, workspace-excluded crate (the `rmcp` SDK is edition 2024), so it
342
+ never affects the lean published `kshana` crate or its build.
343
+
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/).
348
+
306
349
  ## Scenario format
307
350
 
308
- Scenarios are declarative TOML. A top-level `kind` selects the pack (`clock` is
309
- the default if omitted; `inertial`, `timetransfer`, `hybrid`, `fusion`,
310
- `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`.
311
355
  Common fields: `seed`, a `[time]` grid, a `[gnss]` availability timeline (the outage
312
356
  driver), and per-sensor blocks with `provenance` strings citing the source of every
313
357
  figure. Example (clock):
@@ -450,6 +494,20 @@ phasing_f = 1.0
450
494
  [clock_classical] # ... as above
451
495
  ```
452
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
+
453
511
  See `scenarios/` for one example of every kind.
454
512
 
455
513
  ## Output
@@ -492,11 +550,24 @@ New to these terms? Each is defined in plain language in the [glossary](docs/GLO
492
550
 
493
551
  ## Architecture
494
552
 
495
- One engine. The sensor packs plug in via a common error-model interface; alongside
496
- them sit an astrodynamics/numerical layer (analytic SGP4/SDP4 **and** a numerical
497
- Cowell propagator with its force model, maneuver design, and orbit determination) and a
498
- fusion / alt-PNT layer (the GNSS/INS estimators and the gravity-map matcher). See
499
- [`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.
500
571
 
501
572
  ```mermaid
502
573
  flowchart LR
@@ -511,85 +582,138 @@ flowchart LR
511
582
 
512
583
  ```mermaid
513
584
  flowchart TD
514
- 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"]
515
586
  subgraph shared["Shared core"]
516
- types["types"]
517
- scenario["scenario · GNSS timeline"]
518
- 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)"]
519
594
  end
520
595
  subgraph packs["Sensor packs"]
521
- p1["Clock — models · estimator · kalman · security · fom"]
596
+ p1["clock — models · estimator · kalman · security"]
522
597
  p2["inertial — strapdown INS + quantum-CAI"]
523
- p3["timetransfer (+ _adv) — optical/RF link"]
598
+ p3["timetransfer — optical/RF/TWSTFT/PPP"]
524
599
  p4["hybrid — fused PNT suite"]
525
600
  end
526
601
  subgraph astro["Astrodynamics & numerical"]
527
- orbit["orbit — geometry → GNSS timeline + DOP"]
602
+ orbit["orbit · walker — geometry → GNSS + DOP"]
528
603
  sgp4["sgp4 · tle — SGP4/SDP4"]
529
604
  prop["propagator — Cowell"]
530
- 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"]
531
607
  integ["integrator — RK4 · DOPRI"]
532
- ephem["ephem Sun/Moon"]
533
- man["maneuverburns · Lambert · porkchop"]
534
- 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"]
535
617
  end
536
618
  subgraph fnav["Fusion & alt-PNT"]
537
619
  fus["fusion — EKF · UKF · 17-state · coupled"]
538
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"]
539
625
  end
540
626
  api --> packs
541
627
  api --> astro
628
+ api --> intg
542
629
  api --> fnav
543
630
  packs --> shared
631
+ astro --> frames
544
632
  orbit --> sgp4
545
633
  prop --> forces
634
+ prop --> gsh
546
635
  prop --> integ
547
- forces --> ephem
548
- man --> integ
549
- od --> forces
550
- od --> integ
636
+ cr --> integ
551
637
  fus --> p2
552
638
  grav --> p2
639
+ terr --> grav
553
640
  orbit --> p1
641
+ orbit --> io
554
642
  p4 -. composes .-> p1
555
643
  p4 -. composes .-> p2
556
644
  p4 -. composes .-> p3
557
645
  ```
558
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
+
559
672
  ## Repository layout
560
673
 
561
674
  ```
562
675
  kshana/
563
- ├── src/
564
- │ ├── types.rs · scenario.rs · allan.rs # shared core (time grid, GNSS timeline, Allan)
565
- │ ├── api.rs · main.rs # typed dispatch + CLI
566
- │ ├── 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)
567
680
  │ │
568
- │ ├── models.rs · estimator.rs · kalman.rs # Pack 1 — clock holdover + integrity
569
- │ ├── 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
570
683
  │ ├── filter_health.rs · fom.rs · report.rs · chart.rs · run.rs # health · scoring · output
571
- │ ├── inertial/ # Pack 2 — strapdown INS (attitude, mechanization, imu_errors, quantum_imu)
572
- │ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs # Pack 3 — TWSTFT/CV/PPP/optical, Sagnac
573
- │ ├── 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
574
691
  │ │
575
692
  │ ├── orbit.rs · sgp4.rs · tle.rs · walker.rs # geometry, SGP4/SDP4, TLE, Walker design
576
- │ ├── propagator.rs · forces.rs · integrator.rs # numerical Cowell propagator + force model + RK4/DOPRI
577
- │ ├── ephem.rs · precession.rs · frames.rs · timescales.rs · jd2.rs # ephemerides, IAU precession, time/frames
578
- │ ├── 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
579
696
  │ │
580
- │ ├── fusion/ # GNSS/INS — EKF, UKF, tightly_coupled, tightly_coupled17, coupled
581
- │ ├── gravimeter.rs · mapmatch.rs · particle_filter.rs # gravity-map / alt-PNT navigation
582
- │ ├── raim.rs · lunar.rs # ARAIM HPL/VPL, cislunar integrity
583
- │ ├── gnss_sim.rs · ionex.rs · jamming.rs # measurement domain, ionosphere maps, jamming
584
- └── rinex.rs · rinex_obs.rs · glonass.rs · sp3.rs · oem.rs · omm.rs · permalink.rs # interop formats
585
- ├── scenarios/ # cited scenarios (one per kind + geometry-driven + GPS-denied)
586
- ├── scripts/ # reproducibility + repo-hygiene guards
587
- ├── docs/ # CONCEPTS, ARCHITECTURE, CAPABILITY, VALIDATION, PROVENANCE, GLOSSARY,
588
- ├── web/ # the WebAssembly playground + kshana.dev site
589
- ├── .github/workflows/ # CI gate, release, wheels, publish, and pages pipelines
590
- ├── pyproject.toml # Python packaging (maturin)
591
- ├── CHANGELOG.md # Keep a Changelog + SemVer
592
- └── 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
593
717
  ```
594
718
 
595
719
  ## Documentation
@@ -605,6 +729,13 @@ kshana/
605
729
  | [Reproducibility &amp; provenance](docs/REPRODUCIBILITY.md) | reviewers / packagers | determinism guarantees, golden-pinning, SBOM, build provenance |
606
730
  | [Positioning](docs/POSITIONING.md) | evaluators | where Kshana sits vs RTKLIB/gLAB (complementary), and the zero-install browser tier |
607
731
  | [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) |
732
+ | [Integrity FoM](docs/INTEGRITY.md) | evaluators | what the `integrity` / `security` figures mean — and what they are **not** vs aviation HPL/VPL |
733
+ | [Quantum models](docs/QUANTUM.md) · [details](docs/QUANTUM-MODELS.md) | reviewers | the cold-atom-interferometer physics layer, and where coefficients are still looked up |
734
+ | [Compliance](docs/COMPLIANCE.md) | evaluators | DO-229E / DO-316 algorithm scope, and what is **not** a conformance claim |
735
+ | [Result schema](docs/SCHEMA.md) | integrators | every field of the result JSON, with units and a source pointer |
736
+ | [Claims vs reality](docs/CLAIMS-VS-REALITY.md) | reviewers | the overclaim-closure ledger + the CI guard (`tests/no_overclaims.rs`) that keeps it resolved |
737
+ | [Roadmap](ROADMAP.md) | everyone | the phased roadmap — what has shipped and what is next |
738
+ | [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 |
608
739
  | [Changelog](CHANGELOG.md) | everyone | released history (Keep a Changelog + SemVer) |
609
740
  | [Contributing](CONTRIBUTING.md) | contributors | build, guards, test/citation discipline, DCO |
610
741
  | [Code of Conduct](CODE_OF_CONDUCT.md) | community | expected conduct (Contributor Covenant) |
@@ -623,6 +754,32 @@ kshana/
623
754
  - Maturity is stated honestly: optical-clock and optical-link figures are *targets /
624
755
  ground-demonstrator* results, not flown.
625
756
 
757
+ ### Validation at a glance
758
+
759
+ Every row is enforced by a named test in CI; the full evidence (and what is *not*
760
+ modelled) is in [`docs/VALIDATION.md`](docs/VALIDATION.md) and the per-release
761
+ [`kshana-validation-summary.html`](https://github.com/AshfordeOU/kshana/releases)
762
+ artifact (generated by `cargo run --bin validation_report`, SLSA-attested).
763
+
764
+ | Capability | Agreement | Reference / oracle |
765
+ |------------|-----------|--------------------|
766
+ | SGP4/SDP4 propagation | 666/666 vectors, worst **4.12 mm** | AIAA 2006-6753 (Vallado `tcppver.out`) + head-to-head vs the independent `sgp4` crate |
767
+ | 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` |
768
+ | 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 |
769
+ | EGM2008 geopotential (degree/order 70) | acceleration = ∇V to **< 1e-6**; zonal collapse to validated J2 | NGA EGM2008 coefficients + analytic ∇V identity |
770
+ | Allan estimators (ADEV/MDEV/TDEV/HDEV) + confidence bands | reproduce reference deviations; χ² bands match | NIST SP 1065 (Riley), 1000-point Table 31/32 |
771
+ | IMU error model — ARW / VRW / bias-instability | recovered to **< 5 %** (bias-instability < 15 %) | Analog Devices ADIS16465 datasheet; NaveGo reference profile |
772
+ | Numerical (Cowell) propagator, unperturbed | **sub-metre over 24 h**; energy/momentum conserve ~1e-9 | exact universal-variable Kepler |
773
+ | Lambert · Tsiolkovsky · porkchop | round-trip to two-body truth; ΔV **< 0.01 %** | Izzo 2015 · rocket equation · analytic Hohmann floor |
774
+ | 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 |
775
+ | 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 |
776
+ | GPS-denied gravity-map navigation | ~70 km INS drift → **~145 m** recovered | ESA NAVISP *Quantum Wayfarer* target |
777
+ | Terrain-referenced navigation (TERCOM/SITAN) | 70 km drift → **< 500 m** (grid-resolution floor ~140 m) | SRTM `.hgt` DEM; hand-injected drift (non-circular check) |
778
+ | 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) |
779
+ | ARAIM dual-constellation integrity | constellation-wide fault mode on real GPS + Galileo | EU ARAIM TR / DO-316; Celestrak `gps-ops` 2021-07-28 |
780
+ | Cross-platform reproducibility | bit-identical input + shape goldens on 3 OSes | Linux / macOS / Windows CI matrix, SHA-256 goldens |
781
+ | Test coverage | **~97 % line** on `src/`, gated ≥ 85 % | cargo-tarpaulin (LLVM engine) |
782
+
626
783
  ## FAQ
627
784
 
628
785
  **Do I need to understand quantum physics to use this?**
@@ -715,7 +872,7 @@ entry for every user-visible change. Participation is governed by our
715
872
 
716
873
  If you use Kshana in academic or technical work, please cite it. Machine-readable
717
874
  metadata is in [`CITATION.cff`](CITATION.cff) (GitHub renders a "Cite this repository"
718
- button from it); cite the version you used (e.g. `v0.14.1`) together with the
875
+ button from it); cite the version you used (e.g. `v0.15.1`) together with the
719
876
  scenario and seed for full reproducibility. Every release is archived on Zenodo with
720
877
  a citable DOI — the concept DOI [10.5281/zenodo.20528627](https://doi.org/10.5281/zenodo.20528627)
721
878
  always resolves to the latest version.
@@ -725,12 +882,28 @@ always resolves to the latest version.
725
882
  ## Versioning & releases
726
883
 
727
884
  Kshana follows [Semantic Versioning](https://semver.org). While pre-1.0 the public
728
- scenario/result schema may still change; breaking changes are called out explicitly
729
- in the [`CHANGELOG.md`](CHANGELOG.md). Tagged releases are published to
730
- [crates.io](https://crates.io/crates/kshana), [PyPI](https://pypi.org/project/kshana/),
731
- and [npm](https://www.npmjs.com/package/kshana), and listed under
732
- [GitHub Releases](https://github.com/AshfordeOU/kshana/releases). Every result is
733
- reproducible from `scenario + seed + engine version`.
885
+ scenario/result schema may still change; breaking changes are called out explicitly in
886
+ the [`CHANGELOG.md`](CHANGELOG.md). Every result is reproducible from
887
+ `scenario + seed + engine version`.
888
+
889
+ **Every `vX.Y.Z` tag publishes all channels automatically** — one CI pipeline fans out to:
890
+
891
+ | Channel | Install / get | Contents |
892
+ |---------|---------------|----------|
893
+ | [crates.io](https://crates.io/crates/kshana) | `cargo install kshana` · `kshana = "0.15"` | Rust library + CLI |
894
+ | [crates.io](https://crates.io/crates/kshana-mcp) | `cargo install kshana-mcp` | the MCP server |
895
+ | [PyPI](https://pypi.org/project/kshana/) | `pip install kshana` | abi3 wheels (Linux/macOS/Windows) + sdist |
896
+ | [npm](https://www.npmjs.com/package/kshana) | `npm install kshana` | WebAssembly module + JS wrapper |
897
+ | [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 |
898
+ | official MCP registry | auto-discovered by MCP clients | `io.github.ashfordeOU/kshana-mcp` |
899
+ | [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator) | IDE → Plugins → search "Kshana" | the **Kshana — PNT simulator** IDE plugin |
900
+ | [GitHub Releases](https://github.com/AshfordeOU/kshana/releases) | download | `kshana` + `kshana-mcp` binaries, a CycloneDX **SBOM**, **SLSA** build provenance, and an HTML validation summary |
901
+ | [Zenodo](https://doi.org/10.5281/zenodo.20528627) | DOI | a citable archive of every release |
902
+ | [kshana.dev](https://kshana.dev) | open in a browser | the WebAssembly playground (redeployed from `main`) |
903
+
904
+ The MCP server's crate / image / registry version tracks the engine (it bundles the
905
+ library); the JetBrains plugin versions independently (it shells out to your installed
906
+ `kshana` binary).
734
907
 
735
908
  ## License
736
909
 
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.14.1",
8
+ "version": "0.15.1",
9
9
  "license": "Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "kshana.d.ts"
18
18
  ],
19
19
  "main": "kshana.js",
20
- "homepage": "https://github.com/AshfordeOU/kshana",
20
+ "homepage": "https://kshana.dev",
21
21
  "types": "kshana.d.ts",
22
22
  "sideEffects": [
23
23
  "./snippets/*"