kshana 0.21.0 → 0.24.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.
package/README.md CHANGED
@@ -1,1196 +1,105 @@
1
- <p align="center">
2
- <img src="docs/assets/kshana-mark.svg" alt="Kshana mark a compass reticle marking the precise instant" width="96" height="96">
3
- </p>
1
+ <!-- Surface README for the npm WebAssembly package. Copied into web/pkg/README.md by
2
+ web/build.sh after wasm-pack runs (web/pkg is gitignored/generated). Images/links are
3
+ ABSOLUTE (pinned to /main) because npm does not rewrite relative paths or render Mermaid.
4
+ The canonical, full README lives at README.md on GitHub. To re-pin images to an immutable
5
+ release tag at publish time, replace `/main/` with `/vX.Y.Z/` across this file. -->
4
6
 
5
7
  <p align="center">
6
- <img src="docs/assets/kshana-wordmark.png" alt="Kshana" width="300">
8
+ <img src="https://raw.githubusercontent.com/AshfordeOU/kshana/main/docs/assets/kshana-wordmark.png" alt="Kshana" width="300">
7
9
  </p>
8
10
 
9
11
  <p align="center">
10
12
  <strong>क्षण</strong> — Sanskrit for <em>the precise instant</em>, the smallest measure of time.<br>
11
- Open, reproducible PNT-resilience simulation with published quantum-sensor performance models.
13
+ Open, reproducible PNT-resilience simulation, compiled to WebAssembly the whole engine, in the browser.
12
14
  </p>
13
15
 
14
16
  <p align="center">
15
- <a href="https://ashfordeou.github.io/kshana/"><img src="https://img.shields.io/badge/playground-try%20in%20browser-c79e63" alt="Live playground run in your browser, no install"></a>
16
- <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>
17
- <a href="#validation-at-a-glance"><img src="https://img.shields.io/badge/validated-15%20external%20oracles-3fb950" alt="15 capabilities validated against independent external oracles (real data, independent libraries, or published reference vectors); 42 more are honestly labelled MODELLED and 4 are PARTNER-owned — see Validation at a glance"></a>
18
- <a href="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml"><img src="https://img.shields.io/badge/coverage-~96%25%20line-3fb950" alt="~96% line coverage on src/ (cargo-tarpaulin LLVM engine), gated at 85% in CI"></a>
19
- <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>
20
- <a href="https://github.com/ashfordeOU/kshana/releases"><img src="https://img.shields.io/badge/release-v0.21.0-c79e63" alt="Release v0.21.0"></a>
21
- <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>
22
- <a href="https://glama.ai/mcp/servers/ashfordeOU/kshana"><img src="https://glama.ai/mcp/servers/ashfordeOU/kshana/badges/score.svg" alt="kshana-mcp on Glama — MCP server quality score"></a>
23
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-AGPL_v3-blue.svg" alt="License: AGPL-3.0-only"></a>
24
- <a href="LICENSING.md"><img src="https://img.shields.io/badge/commercial_licence-available-2ea043" alt="Commercial licence available from Ashforde OÜ"></a>
25
- <a href="Cargo.toml"><img src="https://img.shields.io/badge/rust-1.75%2B-orange.svg" alt="Rust 1.75+"></a>
17
+ <a href="https://github.com/AshfordeOU/kshana/blob/main/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>
18
+ <a href="https://github.com/AshfordeOU/kshana#validation-at-a-glance"><img src="https://img.shields.io/badge/validated-51%20external%20oracles-3fb950" alt="51 of 102 capabilities validated against independent external oracles"></a>
19
+ <a href="https://github.com/AshfordeOU/kshana/releases"><img src="https://img.shields.io/badge/release-v0.24.0-c79e63" alt="Release v0.24.0"></a>
20
+ <a href="https://ashforde.org"><img src="https://img.shields.io/badge/playground-try%20in%20browser-c79e63" alt="Live playground run in your browser, no install"></a>
21
+ <a href="https://github.com/AshfordeOU/kshana/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-AGPL_v3-blue.svg" alt="License: AGPL-3.0-only"></a>
26
22
  <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>
27
23
  </p>
28
24
 
29
- <p align="center">
30
- <strong>Kshana</strong> (क्षण, Sanskrit: <em>"the precise instant"</em>) is an open, reproducible
31
- <strong>PNT-resilience simulator with quantum-sensor performance models</strong>
32
- positioning, navigation, and timing. It compares quantum and classical sensors mostly
33
- from published Allan/noise-budget coefficients, with a first-principles cold-atom-
34
- interferometer accelerometer layer (Mach–Zehnder phase, quantum projection noise,
35
- contrast decay, and vibration coupling) that <em>derives</em> the noise coefficient
36
- rather than looking it up; it is not yet a full quantum-physics simulator (Coriolis and
37
- light-shift systematics remain coefficient-level — see
38
- <a href="docs/QUANTUM.md">docs/QUANTUM.md</a> and
39
- <a href="docs/QUANTUM-MODELS.md">docs/QUANTUM-MODELS.md</a>).
40
- </p>
41
-
42
- It quantifies, in hard and reproducible numbers, what quantum clocks, quantum
43
- inertial sensors, and optical time-transfer buy a navigation system over classical
44
- PNT — scored against the operational figures of merit that matter for resilient
45
- navigation. Every result is reproducible from `scenario + seed + engine version`,
46
- and every sensor parameter is traceable to a published source — consolidated in one
47
- citable table in [`docs/PROVENANCE.md`](docs/PROVENANCE.md).
48
-
49
- *Free and open source under the GNU AGPL-3.0 — with a commercial licence available
50
- from Ashforde OÜ for proprietary/closed integration (see [`LICENSING.md`](LICENSING.md)).
51
- Professionally developed and maintained by [Ashforde OÜ](https://ashforde.org); commercial
52
- support, integration, and proprietary extensions available.*
53
-
54
- > **Status: v0.21.0 · a simulation substrate, not yet a product.** A validated,
55
- > fully reproducible engine spanning the PNT stack — orbit geometry and constellation
56
- > design, a numerical (Cowell) propagator with a six-perturbation force model, maneuver
57
- > and trajectory design, time systems, inertial navigation (incl. map-aided and
58
- > gravity-map-matching alt-PNT), GNSS/INS fusion (loose, tight, UKF, coupled
59
- > clock+position, 17-state), orbit determination, ARAIM integrity, clocks, advanced
60
- > time-and-frequency transfer, the GNSS measurement domain, resilience (jamming +
61
- > multi-layer spoofing), and an open **deep-space / Mars radiometric navigation**
62
- > engine (light-time + Shapiro, CCSDS-TDM, reduced-dynamic SRIF, one-/two-way fusion);
63
- > plus first-order **mission-analysis** budgets (launch / re-entry / EO-coverage / pointing /
64
- > ground-station passes / link), a **space-weather** environment model, an **AI/ML
65
- > RF-impairment** evaluation testbed, and the versioned **Kshana Interchange Format (KIF)**.
66
- > Honest by design: every figure of merit is labelled *validated* or *modelled*, and
67
- > optical-clock figures are space goals on ground hardware (no strontium optical clock has flown).
68
- >
69
- > **Validation ladder** (maturity is *not* uniform across domains — and saying so is the point):
70
- > | Domain | Tier |
71
- > |---|---|
72
- > | Earth PNT (orbit, frames, time, clocks, IMU, integrity) | **Real-data validated** — ESA SP3 (Galileo 0.13 m, Swarm-A 0.10 m), NIST SP1065, SOFA/ERFA, heritage vectors |
73
- > | Deep-space / Mars navigation | **Simulation-validated** — synthetic closed-loop OD + analytic self-consistency; Sun-central dynamics cross-checked vs JPL **DE440** (137 m @ 1-day arc) |
74
- > | Real-mission deep-space OD | **Roadmap** — pending real DSN/ESTRACK tracking-data validation |
75
- >
76
- > Deep-space figures (Mars-LMO OD ≈ 0.2 m; relay-PNT orbiter 0.4 m / rover 5.1 m) are **simulation / covariance figures of merit**, not real-mission results.
77
- > See **[Capabilities](#capabilities)** for what it does, **[What it is / is not](#what-it-is--is-not)**
78
- > for scope, and [`docs/CAPABILITY.md`](docs/CAPABILITY.md) / [`docs/VALIDATION.md`](docs/VALIDATION.md)
79
- > for per-capability maturity. The overclaim closure ledger
80
- > [`docs/CLAIMS-VS-REALITY.md`](docs/CLAIMS-VS-REALITY.md) tracks every historical overclaim,
81
- > how it was resolved, and a CI guard (`tests/no_overclaims.rs`) that keeps it resolved.
82
-
83
- > **Try it in your browser:** the [playground](web/) runs the engine client-side as
84
- > WebAssembly — pick a scenario, edit the parameters, and see the result, with nothing
85
- > uploaded. Build it locally with `./web/build.sh` (see [`web/README.md`](web/README.md)),
86
- > or publish it to GitHub Pages via the `pages` workflow.
87
-
88
- > **New to this?** In plain terms: GPS-style satellite signals tell things *where they
89
- > are* and *what time it is*. When those signals are lost (jammed, blocked, or out of
90
- > view in space), a system has to keep going on its own onboard clock and motion
91
- > sensors — and they slowly drift. "Quantum" clocks and sensors drift far more slowly.
92
- > Kshana measures, in honest numbers, **how much longer a quantum-equipped system can
93
- > coast** before it exceeds its accuracy limits. New readers should start with the
94
- > [plain-language primer](docs/CONCEPTS.md) and the [glossary](docs/GLOSSARY.md).
95
-
96
- ---
97
-
98
- ## Contents
99
-
100
- - [Why](#why) · [What it is / is not](#what-it-is--is-not) · [Capabilities](#capabilities) · [Results](#results)
101
- - [Install & build](#install--build) · [Usage](#usage) ([Python](#python), [WebAssembly](#webassembly))
102
- - [Scenario format](#scenario-format) · [Output](#output) · [Architecture](#architecture)
103
- - [Repository layout](#repository-layout) · [Validation & honesty](#validation-reproducibility--honesty)
104
- - [Documentation](#documentation) · [FAQ](#faq) · [Troubleshooting](#troubleshooting)
105
- - [Roadmap](#roadmap) · [Contributing](#contributing) · [Citing](#citing) · [Versioning & releases](#versioning--releases) · [License](#license)
106
- - [Support & professional services](#support--professional-services) · [References](#key-references)
107
-
108
- ## Why
109
-
110
- Resilient PNT depends on holding position and time when GNSS is denied or jammed.
111
- Quantum sensors promise far slower drift during those outages. There is no good
112
- **open** tool to quantify that advantage honestly and reproducibly — so primes,
113
- agencies, and labs each rebuild private one-offs. Kshana aims to be the neutral,
114
- citable reference for exactly this question.
115
-
116
- The engine knows nothing about "quantum" vs "classical": each sensor is an
117
- **error model** plugged into a common pipeline, so a quantum and a classical
118
- device are compared *apples-to-apples* on the same scenario, with independent
119
- noise realizations.
120
-
121
- ## What it is / is not
122
-
123
- **It is:** a deterministic, dependency-light engine spanning the PNT stack — orbit
124
- geometry, inertial navigation, GNSS/INS fusion, integrity, clocks, and timing. It
125
- runs a scenario (often a GNSS outage), evolves calibrated sensor error models
126
- through the appropriate estimator, and scores the result against the operational
127
- figures of merit — emitting a reproducible JSON result and an SVG chart, from a
128
- Rust library, a CLI, a Python extension, an in-browser WebAssembly module, a
129
- **Model Context Protocol (MCP) server** for AI agents, or a **JetBrains IDE plugin**.
130
-
131
- **It is not:** flight hardware, a quantum-payload design, a full GNSS signal
132
- receiver, or a certified avionics product. Quantum-hardware fidelity comes from
133
- published error models, not from this tool. The granular maturity of each
134
- capability is documented in [`docs/CAPABILITY.md`](docs/CAPABILITY.md).
135
-
136
- **It is not (yet):** a *full* atom-interferometry physics engine (most quantum sensors
137
- consume published Allan/noise-budget coefficients; the CAI accelerometer has a
138
- first-principles layer — Mach–Zehnder phase, projection noise, contrast decay, and
139
- vibration coupling — but Coriolis and light-shift systematics remain a **P2** roadmap
140
- layer, see [`ROADMAP.md`](ROADMAP.md) and [`docs/QUANTUM-MODELS.md`](docs/QUANTUM-MODELS.md));
141
- a full GNSS *signal-acquisition* receiver (it now solves a single-point **PVT** position
142
- fix from real RINEX code observations — validated on real IGS data — but does **not**
143
- acquire or track raw signal); or a full mission-design suite (it has Lambert / porkchop /
144
- maneuver / orbit-determination building blocks, but is the performance-simulation layer
145
- *above* GMAT/Orekit, not a replacement). Owning this scope is deliberate. If you need first-principles cold-atom
146
- interferometer error budgets (e.g. CARIOQA-PMP-grade or X-37B-style validation), see
147
- the P2 roadmap and [get in touch](#support--professional-services) to collaborate.
148
-
149
- ## Capabilities
150
-
151
- | Domain | Capability |
152
- |--------|------------|
153
- | **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 (GDOP/PDOP/HDOP/VDOP/TDOP, validated to 1e-6 against gnss_lib_py 1.0.4, Stanford NAV Lab)**, 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. |
154
- | **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. |
155
- | **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. |
156
- | **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. |
157
- | **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. |
158
- | **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; the **gravity-functional synthesis kernel** (`gravity_sh::gravity_magnitude` / `gravity_disturbance_mgal`) — the "map reader" a gravity-aided navigator matches against — is validated against the **GRS80 normal-gravity standard**, reproducing the closed-form Somigliana normal gravity and the published γ_e / γ_p to **3.5e-12** and producing a physically-bounded disturbance map from the real ICGEM **EGM2008** field (RMS ≈ 26 mGal, max ≈ 89 mGal at d/o 70; `tests/icgem_gravity_reference.rs`); 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. |
159
- | **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. |
160
- | **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`). |
161
- | **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`) — now with a **6×6 state-transition matrix and a single-shooting differential corrector** (`cr3bp_jacobian`, `propagate_state_stm`, `differential_correct_halo`) that produces genuinely periodic **halo / NRHO** orbits: the STM is validated against finite differences, corrected orbits close to machine precision, and seeding the published apolune state reproduces the **L2 southern 9:2 NRHO** (the Gateway orbit) at period ≈ 6.57 d / perilune ≈ 3,250 km, consistent with the published ≈ 6.56 d / ≈ 3,370 km (a CR3BP — circular, Sun-free — solution, **not** validated against a real LANS/Gateway ephemeris; the selenocentric MCI/MCMF transform of the corrected orbit is a follow-on); 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`). |
162
- | **Lunar PNT suite** | A modelled lunar/cislunar navigation suite layered on the CR3BP core, each a runnable `kind`: **Lunar Coordinate Time** (`lunar-time-offset`, `src/lunar_time.rs` — the secular LTC/TCL − TT rate from the self-potential difference + kinetic term, reported with the published 56–59 µs/day band); a geodetic **lunar VLBI** delay observable (`lunar-vlbi`, `src/lunar_vlbi.rs` — an Earth-baseline near-field two-range-difference delay + rate, cross-checked against the same-codebase plane-wave Δ-DOR in the far-field limit, partials finite-difference-verified); a **joint multi-technique OD + clock** batch estimator (`lunar-joint-od-clock`, `src/lunar_combination.rs` — a Gauss–Newton fit fusing VLBI + lunar-local ranges + inter-satellite ranges that makes a surface station's full 3-D position observable where local ranging alone leaves a weak direction); **reference-frame realisation** (`lunar-frame-realisation`, `src/lunar_frame_realise.rs` — a 7-parameter Helmert datum fit + IAU 2015 WGCCRE orientation tie); a **Moonlight/LCNS-class service-volume** analysis (`moonlight-service-volume`, `src/lunar_service.rs` — DOP / coverage / availability + a generalised lunar ARAIM HPL/VPL envelope, reusing the gnss_lib_py-validated DOP kernel and the LunaNet σ_URE≈30 m machinery); **lunar differential PNT** (`lunar-differential-pnt`, `src/lunar_dpnt.rs` — a lunar DGNSS/SBAS analogue: exact common-mode clock cancellation + first-order spatial decorrelation vs baseline, reusing the DO-229E SBAS protection level); and a **LunaNet/IOAG-aligned interoperability export** (`lunar-interop-export`, `src/lunar_interop.rs` — CCSDS-OEM + lunar-time-scale round-trip in the IAU 2015 lunar body frame, wrapped in the KIF envelope). All **MODELLED** against internal consistency / reference implementations from **illustrative public-source parameters** — **not** validated against real VLBI/Gateway tracking, **not** affiliated with or endorsed by any agency, no TRL / heritage claim. |
163
- | **Deep-space & Mars PNT** | An open **radiometric navigation engine**: iterative light-time + **Shapiro** relativistic delay, two-/one-/three-way **Doppler & range** (Moyer two-leg), coherent transponder turnaround ratios, regenerative/PN ranging (CCSDS 414), and **Δ-DOR** plane-of-sky (CCSDS 506), with solar-plasma/tropo/iono media; **CCSDS-TDM (503)** tracking-data-message parse + emit; a **reduced-dynamic Square-Root Information Filter** (RTN empirical accelerations + a 3-state onboard clock + Mars atmospheric drag) that does **Mars-LMO orbit determination to ≈ 0.2 m** in a synthetic closed loop; a joint **one-way + two-way fusion** estimator; a multi-body dynamics core (`Body{μ, re, zonals, gravity, IAU-pole}`, Mars GMM-3 gravity, an IAU body-fixed Mars frame, a pluggable `EphemerisProvider` seam, two-part Julian dates + TT↔TDB); and the **`mars-pnt`** relay-PNT scenario (a MARCONI areostationary relay constellation) with an end-to-end **GSE performance simulator** (geometry → link budget → observables → SRIF → covariance). **Simulation-validated** (covariance / closed-loop figures of merit); the Sun-central Mars dynamics are cross-checked against JPL **DE440** (137 m @ 1-day arc, `xval/anise-mars-od`). Real DSN/ESTRACK tracking-data validation is on the roadmap. |
164
- | **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`). The protection level applies the one-sided **nominal-bias** projection `b_k = Σ_i|s_i|·b_nom` per fault mode and the **integrity** sigma σ_URA (distinct from the accuracy σ_URE) from the Integrity Support Message — see [`docs/ARAIM_REFERENCE.md`](docs/ARAIM_REFERENCE.md). The detection kernel (the χ²/non-central-χ²/normal thresholds and K-multipliers) is **externally validated against SciPy** across 171 cases (`tests/raim_reference.rs`); the geometry reuses the gnss_lib_py-validated DOP kernel. The ARAIM MHSS integrity-risk *budget allocation* itself has no published numeric oracle and stays honestly Modelled. |
165
- | **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`. The protection-level algorithm is **externally validated against the RTKLIB SBAS-PL fork** (`zsiki/rtklib_ws` `waasprotlevels()`, Siki & Takács 2017, DO-229D App. J) run on **real EGNOS data**, reproducing its HPL to < 2e-3 m (`tests/sbas_reference.rs`); gLAB v6.0.0 confirmed the identical convention. |
166
- | **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** — the estimators are validated on real hardware against **Stable32**: a **real 5071A caesium primary standard vs a hydrogen maser** (556,990 phase samples, 16 averaging factors, OADEV/OHDEV to 1e-3; `tests/cs5071a_reference.rs`) and the **canonical Stable32 PHASE.DAT** regression series (139 averaging factors, OADEV/MDEV/TDEV to 1e-3; `tests/phasedat_reference.rs`); 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. A **GNSS-denied clock-holdover calculator** (`src/holdover.rs`) exposes the closed-form van-Loan coast-error growth as a *holdover-to-threshold* inversion — how long a clock free-runs before its timing error exceeds budget — across representative classical and quantum-clock classes; **modelled** (cross-checked against the multi-step `clock_state` covariance recursion), and honest that for a very stable clock the holdover to a tight threshold is set by the *assumed* long-tau noise floor, not the cited ADEV. A **conditional Timing Protection Level** (`src/tpl.rs`) extends holdover to spoofing: a bound on the *undetected* time error, given an independent cross-check, that composes a k-sigma monitor floor, the van-Loan coast variance over the detection latency, and a CUSUM time-to-alarm. Calibrated on a real recorded spoof (JammerTest 2024) and reproducible via `cargo run --example tpl_jammertest`; **MODELLED** composition (no integrity-risk-per-hour budget), conditional on detection — there is no finite *unconditional* bound. |
167
- | **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). |
168
- | **Resilience** | Link-budget **jamming** (J/S → effective C/N₀ → loss of lock, with the anti-jam spectral-separation factor `Q` now **derived from the actual signal and jammer power spectra** via `src/navsignal.rs` — `Q = 1/(R_c·κ)`, cross-checked in CI against the previous representative constant); 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; and a **quantum-inertial dead-reckoning error budget** (`QuantumNavBudget`, `src/inertial/quantum_imu.rs`) composing the cold-atom-interferometer white-noise velocity-random-walk with residual bias (cross-checked against the independent `AccelModel` integrator) and scale-factor error into a position-drift-over-holdover figure — the inertial twin of the clock holdover. A **framework-aligned resilience-scoring engine** (`src/resilience/`) maps an architecture's simulated behaviour to per-dimension sub-scores across the DHS RPCF categories, then studies the **decision-stability** of any single composite score or maturity Level under a Dirichlet weighting simplex and a five-threat ensemble — Kendall-τ rank instability, top-1 winner flip rate, and common-mode **diversity collapse** (Hill-N2), with an integrity-hashed assurance report (35 hand-derived oracle tests). Reproducible via `cargo run --example resilience_report`; **MODELLED** synthetic architectures, a self-assessment aligned to RPCF v2.0, **not** a certification. See [`docs/RESILIENCE-CROSSWALK.md`](docs/RESILIENCE-CROSSWALK.md). |
169
- | **Nav-signal & code tracking** | The **signal level** between the link budget and the measurement domain (`src/navsignal.rs`): unit-area **power spectral densities** for **BPSK-R(n)** and **sine-BOC(m,n)**; the **spectral-separation coefficient** κ = ∫ G_s·G_i df, which **derives the anti-jam `Q`** the jamming model uses (`Q = 1/(R_c·κ)`) from the actual signal/jammer spectra instead of a representative constant; the **RMS (Gabor) bandwidth** (BOC > BPSK — the ranging-information / Cramér–Rao measure); the **coherent early–late DLL code-tracking thermal-noise jitter** (Kaplan & Hegarty; ~sub-metre for C/A at 45 dB-Hz); and the **multipath error envelope** (coherent EML — narrow-correlator suppression). Validated against closed-form anchors (BPSK self-SSC = 2/(3·R_c), unit-area PSDs, sub-metre C/A jitter). This is signal-**performance** analysis, **not** antenna / RF-payload hardware design (a payload partner's role). |
170
- | **Interoperability** | **RINEX-3** multi-GNSS broadcast-ephemeris ingestion (GPS, Galileo, QZSS, BeiDou MEO/IGSO via IS-GPS-200; GLONASS via PZ-90 state-vector RK4) usable as a constellation source (RINEX in, PNT geometry out); a **RINEX-3/4** observation parser (pseudorange, carrier phase, Doppler, signal strength) that now **feeds a single-point-positioning solver** (`pvt`) — real code observations in, a real **receiver position** out, validated on IGS data; an **SP3-c/d** precise-ephemeris reader/writer with 9th-order Lagrange interpolation; and **CCSDS OEM 2.0 + OMM** (mean-elements) export for flight-dynamics tools (GMAT, Orekit, STK); and **CCSDS-TDM (503)** tracking-data-message parse + emit for deep-space radiometric tracking. |
171
- | **Mission analysis (systems engineering)** | First-order mission-design budgets, each a runnable kind: two-body **launch & ascent geometry** (`launch-window` — launch azimuth `sin Az = cos i/cos lat`, minimum inclination, Earth-rotation bonus, dogleg plane-change Δv, daily opportunities; `src/launch.rs`); an **Allen–Eggers ballistic re-entry corridor** (`reentry` — peak deceleration, peak-g velocity/altitude, peak-heating velocity; `src/reentry.rs`); **Earth-observation coverage geometry** (`eo-coverage` — swath / nadir GSD / off-nadir access / revisit via the SMAD space triangle; `src/eo_payload.rs`); a **3-DOF attitude & pointing error budget** (`attitude-budget` — worst-case gravity-gradient torque + RSS pointing budget; `src/attitude_budget.rs`); **ground-station pass prediction** (`passes` — AOS/TCA/LOS, max elevation, access time; `src/passes.rs`); and a **one-way link budget** over the CCSDS 401 / DSN 810-005 link equation (`link-budget` — FSPL, C/N₀, Eb/N₀, margin, closure; `src/linkbudget.rs`). **MODELLED** first-order analytic budgets — the pre-hardware layer below STK/GMAT/Basilisk, not a 6-DoF or radiometric replacement. |
172
- | **Space environment** | A **space-weather environment model** (`space-weather`, `src/space_weather.rs`): solar (F10.7 / centred-81-day F10.7a) and geomagnetic (Kp, with the definitional Kp↔ap table) activity indices, the **Jacchia-1971** exospheric temperature they drive (validated vs published solar min/mean/max), and the activity-corrected vs static thermospheric neutral density at altitude — the solar-cycle density dependence the static USSA76 atmosphere omits. **MODELLED**: a calibrated first-order scale-height coupling, **not** a data-validated (NRLMSISE) atmosphere. |
173
- | **AI/ML evaluation & trade** | An **RF-impairment detection evaluation testbed** (`impairment-eval`, `src/impairment_eval.rs`): a labelled, parameter-grounded **synthetic** corpus (nominal / jamming / spoof-time / spoof-position / multipath), a detector-agnostic **ROC/AUC** harness scoring any detector (energy \| agc \| sqm \| parity \| fused) with per-class Pd at a target Pfa, and the in- vs out-of-distribution **optimism gap** (distribution-shift mode). Plus a **quantum-vs-classical PNT trade** (`quantum-trade`, `src/quantum_trade.rs`) quantifying a candidate clock's timing/inertial holdover benefit from a **measured-ADEV** curve vs a classical baseline, with the long-τ floor caveat carried on the artifact and a GNSS-denied resilience-vs-time envelope. The evaluation **metrics** (AUC / confusion / Pd-Pmd) are **validated to an exact match against scikit-learn 1.9.0** — including on **real ESA OPS-SAT telemetry** (the OPSSAT-AD dataset, Ruszczak et al. 2025, CC BY 4.0), where Kshana's Mann–Whitney ROC AUC reproduces scikit-learn's `roc_auc_score` to < 1e-9 on the held-out test split and a transparent peak-count detector separates the labelled anomalies at AUC ≈ 0.85 (`tests/opssat_ad_reference.rs`) — and the trade engine's numerical **kernels** (ADEV NNLS fit, χ² consistency bands, van-Loan clock Q) **against scipy 1.17.1**; the device-benefit numbers built on top stay **MODELLED** operating characteristics — never field/IQ data, no good/bad verdict. Building on the testbed, a deeper **optimism-gap study** (`src/impairment_study.rs`, `impairment_ml.rs`, `eval_stats.rs`) scores a **13-detector** panel (energy/AGC/SQM/parity plus seeded logistic-regression and one-hidden-layer-MLP detectors), fits in- vs out-of-distribution **scaling laws** with a permutation null, and learns a **leave-one-out predictor** of out-of-distribution degradation from in-distribution statistics (`cargo run --example optimism_study`). A **software-defined-receiver front end** (`src/sdr.rs` — raw IQ/IF → correlator early/prompt/late taps → SQM) and **real-data ingest adapters** (`src/realdata/` — RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid) let the same detectors run over recordings supplied locally (no datasets are committed). The **quantum-vs-classical resilience crossover map** under parameter uncertainty (`src/crossover.rs`; `cargo run --bin crossover_study`) regenerates the inertial and clock crossover studies behind the Results figures. |
174
- | **Quantum-Enabled PNT demonstrator** | Three runnable, **MODELLED** application areas behind the open engine, each emitting honest `TradeEvidence` + a representativeness / gaps-to-flight record (`src/representativeness.rs`): **trusted quantum time transfer** (`quantum-time-transfer`, `src/timetransfer_chain.rs` — an end-to-end optical-lattice-clock + photonic-link vs CSAC + RF two-way budget, with a reused timing protection level, a delay/replay-attack security FoM (1 − P_md), and clock-anomaly detection + CUSUM latency); **GNSS-free quantum navigation** (`quantum-gnss-free-nav`, `src/quantum_nav_od.rs` — a cold-atom-interferometer inertial coast vs a navigation-grade INS over a GNSS outage, honest that with no external fix the accelerometer bias is unobservable so the error still grows); and quantum-system **fault/anomaly detection** (`quantum-anomaly-detect`, `src/quantum_faults.rs` — a labelled fault catalogue with a bootstrap-CI ROC AUC from the externally-validated `eval_stats` and a minimum-detectable-fault at a fixed false-alarm rate). A shared **quantum device error-model library** (`src/quantum_devices.rs`) and a unified **quantum-vs-classical trade harness** (`src/qtrade.rs`) underpin them. The validated kernels they ride (eval-metrics vs scikit-learn, trade kernels vs scipy) are reused; the device-benefit numbers built on top stay **MODELLED** — **illustrative public-source** device/link parameters, models the *class*, no TRL / flight heritage / certification, no agency endorsement. |
175
- | **Frugal engineering & integrity impact** | A **cost-per-coverage ROI** lens (`src/frugal.rs`) — cost per unit of delivered coverage for an architecture trade — and a **detection-miss → integrity-impact** mapping (`src/integrity_impact.rs`) that turns a monitor's missed-detection rate into its integrity-risk contribution. **MODELLED** decision-support budgets, additive. |
176
- | **Artifact interchange** | The **Kshana Interchange Format (KIF)** (`src/interchange.rs`) — a versioned, self-describing envelope wrapping a scenario result with its kind, schema version, and MODELLED/VALIDATED labels, so a stored artifact stays self-documenting and older envelopes remain forward-compatibly readable. |
25
+ **Kshana** is an open, reproducible **PNT-resilience simulator with quantum-sensor
26
+ performance models** positioning, navigation, and timing. This package is the Rust
27
+ engine compiled to **WebAssembly**: it runs entirely client-side pass a scenario TOML
28
+ string in, get a reproducible JSON result and an SVG chart back, with nothing uploaded.
29
+ Every result is reproducible from `scenario + seed + engine version`, and every sensor
30
+ parameter is traceable to a published source.
177
31
 
178
- Each capability is reachable as a Rust API, a runnable scenario `kind`, or both.
179
- Maturity per capability *validated*, *runnable*, or *library* is tracked in
180
- [`docs/CAPABILITY.md`](docs/CAPABILITY.md). A **machine-checked verification matrix**
181
- (`src/verification.rs`) renders the requirement module test oracle status
182
- cross-reference, with unit-tested honesty invariants that permit a *validated* label
183
- only where an independent **external** oracle backs it — and that record the
184
- hardware/PA capabilities Kshana deliberately does **not** provide.
185
-
186
- ## Results
187
-
188
- Each scenario compares a quantum sensor against its classical counterpart through a
189
- ~1.8 h GNSS outage. Numbers are reproducible (`scenario + seed + version`).
32
+ > ***Validated, not asserted.*** 666/666 AIAA SGP4 vectors to **4.12 mm** · Cowell
33
+ > force model **0.08 m** vs Orekit 12.2 · Galileo **0.61 m** / Swarm-A **0.10 m** vs
34
+ > real ESA precise ephemerides · GCRS→ITRS bit-for-bit vs SOFA/ERFA · ML metrics exact
35
+ > vs scikit-learn · **51 of 102** capabilities validated against independent external
36
+ > oracles; 47 honestly labelled Modelled, 4 partner-owned.
190
37
 
191
38
  <p align="center">
192
- <img src="docs/assets/inertial-deadreckoning.svg" alt="Inertial dead-reckoning: position error during a GNSS outage the quantum (cold-atom) sensor stays near the spec line while the navigation-grade sensor diverges to tens of kilometres" width="80%">
193
- <br><em>Dead-reckoning position error during a GNSS outage: the quantum sensor (blue)
194
- stays flat near the spec; the classical sensor (red) diverges to tens of kilometres.
195
- Generated by Kshana from <code>scenarios/imu-deadreckoning.toml</code>.</em>
39
+ <img src="https://raw.githubusercontent.com/AshfordeOU/kshana/main/docs/assets/diagrams/system-overview.png" alt="Kshana system overview: five front doors (CLI, Python wheel, WebAssembly playground, MCP server, JetBrains plugin) converge on a single api::run_toml dispatch, through the engine, to a reproducible result.json + chart.svg" width="840">
196
40
  </p>
197
41
 
198
- | Pack | Scenario | Quantum | Classical |
199
- |------|----------|---------|-----------|
200
- | **1 — Clock holdover** | `clock-holdover.toml` (20 ns spec) | optical clock holds the full outage | CSAC breaches the spec mid-outage |
201
- | **2 — Inertial dead-reckoning** | `imu-deadreckoning.toml` (100 m spec) | cold-atom: **~41 m**, holds full outage | nav-grade: breaches in **~350 s** → tens of km |
202
- | **3 — Time transfer** (optical inter-satellite link) | `timetransfer.toml` | optical: **~0.3 mm** ranging | RF (TWSTFT): **~150 mm** ranging |
203
- | **4 — Hybrid fusion** (capstone) | `hybrid-pnt.toml` | full position+timing for the whole outage | **position-limited at ~350 s** |
204
-
205
- The capstone shows the fusion thesis: optical inter-satellite time-transfer keeps even
206
- a classical *clock* locked, isolating the *inertial* sensor as the classical suite's
207
- weak link — i.e. quantum inertial + optical timing together.
208
-
209
- <p align="center">
210
- <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%">
211
- <br><em>Clock holdover through a GNSS outage: the optical clock (blue) stays inside the
212
- 20 ns spec for the full coast; the chip-scale clock (red) breaches it part-way.
213
- Generated by Kshana from <code>scenarios/clock-holdover.toml</code>.</em>
214
- </p>
42
+ ### Validated against external oracles every row CI-gated
215
43
 
216
- A further scenario, `orbit-gnss-challenged.toml`, derives GNSS availability from
217
- **orbital geometry** rather than hand-authored windows: a spacecraft inside the GNSS
218
- shell is propagated against a GPS-like Walker constellation, and the visible-satellite
219
- count (line-of-sight, Earth-occultation, elevation mask) sets the fix state at each
220
- step. Over a day the user is in fix only ~59% of the time; the quantum clock holds a
221
- 5 ns timing solution through every gap (availability **1.0**), the chip-scale clock
222
- only **~0.83**.
44
+ | | Capability | Result | External oracle |
45
+ |---|---|---|---|
46
+ | | SGP4/SDP4 propagation | 666/666 vectors, worst **4.12 mm** | AIAA 2006-6753 (Vallado) + independent `sgp4` crate |
47
+ | | Numerical Cowell force model | **0.08 m** / 24 h, 275 epochs | Orekit 12.2 `DormandPrince853` (CS GROUP) |
48
+ | | Orbit fit vs precise ephemeris | Galileo **0.61 m** · Swarm-A **0.10 m** | ESA/ESOC SP3 precise orbits |
49
+ | | GCRS→ITRS frame chain | bit-for-bit vs SOFA; ≤ 0.86 m vs SPICE | ERFA/SOFA + ANISE (pure-Rust SPICE) |
50
+ | ✅ | Allan deviations | reproduce reference deviations | NIST SP 1065 + Stable32 on a real Cs clock |
51
+ | ✅ | GNSS DOP · ML detector metrics | to **1e-6** · to **1e-9** | gnss_lib_py · scikit-learn |
223
52
 
224
53
  <p align="center">
225
- <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%">
226
- <br><em>GNSS availability derived from orbital geometry: the visible-satellite count
227
- (line-of-sight, Earth-occultation, elevation mask) sets the fix state at each step,
228
- so the clock must coast every gap. Generated by Kshana from
229
- <code>scenarios/orbit-gnss-challenged.toml</code>.</em>
54
+ <img src="https://raw.githubusercontent.com/AshfordeOU/kshana/main/docs/assets/figures/validation-breakdown.png" alt="Verification status across all 102 capabilities: 51 Validated, 47 Modelled, 4 Partner-owned" width="780">
230
55
  </p>
231
56
 
232
- The constellation can also be given as real two-line element sets. A *full* TLE
233
- (line 1 + line 2) is propagated with the full **SGP4/SDP4** model — including
234
- atmospheric drag and the deep-space lunar-solar and 12 h / 24 h resonance terms that
235
- matter for ~12 h GNSS orbits — validated against the official AIAA 2006-6753 vectors
236
- to a worst-case ≈ 4 mm. `scenarios/orbit-sgp4-gps.toml` ships a **real Celestrak
237
- `gps-ops` snapshot** of the operational GPS constellation (2021-07-28, 30 satellites)
238
- and requires valid TLE checksums — two-line element sets are open data from the US
239
- Space Force / 18th Space Defense Squadron catalogue, redistributed by Celestrak
240
- (Dr T. S. Kelso, [celestrak.org](https://celestrak.org)); refresh with
241
- `scripts/fetch_tles.sh`. A line-2-only block keeps
242
- the analytic two-body propagation (`scenarios/orbit-real-tle.toml`); the two forms can
243
- be mixed in one constellation. A constellation can equally be built from a block of
244
- **RINEX-3 GPS broadcast-ephemeris** records — the format a receiver decodes —
245
- propagated by the IS-GPS-200 user algorithm and fed through the same geometry
246
- (`scenarios/orbit-rinex.toml`).
247
-
248
- ## Install & build
249
-
250
- Requires a Rust toolchain (≥ 1.75; developed on 1.93).
57
+ ## Install
251
58
 
252
59
  ```bash
253
- git clone https://github.com/AshfordeOU/kshana
254
- cd kshana
255
- cargo build --release
256
- cargo test # all tests pass
60
+ npm install kshana
257
61
  ```
258
62
 
259
63
  ## Usage
260
64
 
261
- Run any scenario; the CLI dispatches on the scenario's `kind` field and writes a
262
- `<scenario>.result.json` and a `<scenario>.chart.svg` next to it:
263
-
264
- ```bash
265
- cargo run -- scenarios/clock-holdover.toml
266
- cargo run -- scenarios/imu-deadreckoning.toml
267
- cargo run -- scenarios/timetransfer.toml
268
- cargo run -- scenarios/hybrid-pnt.toml
269
- cargo run -- scenarios/orbit-gnss-challenged.toml
270
- cargo run -- scenarios/orbit-sgp4-gps.toml
271
- cargo run -- scenarios/orbit-rinex.toml
272
- cargo run -- scenarios/integrity-raim.toml
273
-
274
- # Export a propagated constellation to an SP3-c precise-ephemeris file:
275
- cargo run -- scenarios/orbit-sgp4-gps.toml --export-sp3 gps.sp3
276
-
277
- # Export the constellation's mean elements to a CCSDS OMM catalogue (one OMM
278
- # message per TLE-defined satellite, with its real NORAD id / COSPAR designator):
279
- cargo run -- scenarios/orbit-sgp4-gps.toml --export-omm gps.omm
280
-
281
- # Export the velocity-carrying state to a CCSDS OEM 2.0 ephemeris (GMAT/Orekit/STK):
282
- cargo run -- scenarios/orbit-sgp4-gps.toml --export-oem gps.oem
283
- ```
284
-
285
- **Other CLI modes** — lint a scenario, feed real Earth-orientation data, or run a whole suite:
286
-
287
- ```bash
288
- # Lint a scenario without running it (checks the kind + required fields):
289
- cargo run -- --validate scenarios/integrity-raim.toml
290
-
291
- # Feed a real IERS Earth-orientation file (finals2000A) for frame precision:
292
- cargo run -- scenarios/orbit-sgp4-gps.toml --eop tests/fixtures/agency/eop/finals2000A_2022001.txt
293
-
294
- # Run a SUITE of scenarios into one aggregated, stamped study artifact
295
- # (writes <suite>.study.json + <suite>.study.html next to the manifest):
296
- cargo run -- --study scenarios/quantum-pnt-demonstrator.suite.toml --study-name "Quantum-Enabled PNT demonstrator"
297
- ```
298
-
299
- A **suite** manifest is a small TOML — a `title` and a `scenarios = [ … ]` array of
300
- scenario paths — that the engine runs in turn, folding every result (with its
301
- MODELLED / VALIDATED labels) into one self-describing study artifact. See
302
- [`scenarios/quantum-pnt-demonstrator.suite.toml`](scenarios/quantum-pnt-demonstrator.suite.toml).
303
-
304
- **Interoperability role.** Kshana is the *performance-simulation* layer that sits
305
- alongside the post-processing toolchain, not a replacement for it: feed its **RINEX**
306
- output into RTKLIB or gLAB for a position solution, and use its **SP3** output as a
307
- precise-orbit product for tools like Ginan — Kshana answers *what resilience a given
308
- PNT architecture buys* before you have real signals, in formats those tools already
309
- ingest (`--export-sp3`, or `export_sp3 = true` in an `orbit` scenario, writes
310
- `<scenario>.sp3`). The same orbit can be published as standards-track **CCSDS OMM**
311
- mean elements (`--export-omm`, or `export_omm = true`, writes `<scenario>.omm`) —
312
- one OMM 502.0 KVN message per TLE-defined satellite, carrying each object's real
313
- NORAD catalogue number, COSPAR international designator, and epoch, for any
314
- OMM-aware consumer instead of a bespoke two-line element set.
315
-
316
- Example output (clock holdover — note the Integrity and Security figures of merit):
317
-
318
- ```
319
- scenario c827e5d40d25 | quantum holdover 6600s p95 0.0ns integrity 1.000 security 0.997 | classical holdover 2610s p95 19.7ns integrity 1.000 security 0.000
320
- wrote scenarios/clock-holdover.result.json and scenarios/clock-holdover.chart.svg
321
- ```
322
-
323
- The optical clock's tight detection floor keeps `security 0.997`; the chip-scale
324
- clock's own noise over the monitoring window exceeds the 20 ns spec, so it has no
325
- spoof-detection margin (`security 0.000`). The orbit scenario additionally reports a
326
- geometry block — fraction of samples with a fix, and best/median PDOP and position
327
- accuracy — alongside the clock result.
328
-
329
- > **Read these two numbers carefully.** `security` is an *analytic spoof-detectability
330
- > bound* derived from each clock's stability — it is meaningful only against a
331
- > configured spoofing scenario and is **not** a multi-satellite RAIM detector. `integrity`
332
- > here is the filter's *self-consistency* (fraction of outage samples inside its own k-sigma
333
- > bound), **not** an aviation HPL/VPL integrity figure. See
334
- > [`docs/INTEGRITY.md`](docs/INTEGRITY.md).
335
- >
336
- > For genuine receiver-autonomous integrity, the **`integrity` scenario kind**
337
- > (`scenarios/integrity-raim.toml`) runs real snapshot and solution-separation
338
- > (ARAIM-style) RAIM over the propagated constellation geometry: it computes
339
- > horizontal/vertical **protection levels (HPL/VPL)** per epoch and reports the
340
- > fraction of epochs that meet the configured alert limits, with a Stanford
341
- > integrity diagram for error-vs-PL classification.
342
-
343
- ### Reproducible study artifacts
344
-
345
- Four open studies each regenerate a byte-deterministic artifact (fixed seed) from one
346
- command — the numbers behind the quantum-vs-classical crossover, RF-impairment
347
- optimism-gap, PNT-resilience-scoring, and timing-protection-level studies:
348
-
349
- ```bash
350
- # Quantum-vs-classical resilience crossover map (writes paper/crossover/*.json):
351
- cargo run --release --bin crossover_study -- paper/crossover
352
-
353
- # RF-impairment optimism-gap study (13-detector panel, scaling laws, LOO predictor):
354
- cargo run --release --example optimism_study -- paper-artifacts/optimism-study.json
355
-
356
- # Framework-aligned PNT-resilience scoring + decision-instability study:
357
- cargo run --release --example resilience_report -- paper-artifacts/resilience-study.json
358
-
359
- # Conditional Timing Protection Level, calibrated on a real recorded spoof:
360
- cargo run --release --example tpl_jammertest
361
- ```
362
-
363
- Each artifact records its engine version, seeds, and a config hash and carries an honest
364
- MODELLED/VALIDATED label. The real-data probes (`*_probe`) run the same pipeline over
365
- recordings you supply locally; no datasets are shipped in the repo. The RF-impairment
366
- optimism-gap study is written up in the preprint
367
- [arXiv:2606.22054](https://arxiv.org/abs/2606.22054), and the conditional timing
368
- protection level (`tpl_jammertest` above) in the preprint
369
- [arXiv:2606.24210](https://arxiv.org/abs/2606.24210) (see [Citing](#citing)).
370
-
371
- ### Python
372
-
373
- An optional Python extension (PyO3, abi3) wraps the same engine. Build and install
374
- it with [maturin](https://www.maturin.rs/):
375
-
376
- ```bash
377
- pip install maturin
378
- maturin develop --features python # or: maturin build --features python
379
- ```
380
-
381
- ```python
382
- import json, kshana
383
-
384
- result = json.loads(kshana.run(open("scenarios/clock-holdover.toml").read()))
385
- print(result["quantum"]["fom"]["integrity"])
386
-
387
- # json, svg, and a one-line summary at once:
388
- result_json, chart_svg, summary = kshana.run_full(open("scenarios/orbit-gnss-challenged.toml").read())
389
- print(kshana.version(), summary)
390
- ```
391
-
392
- Beyond `run` / `run_full` / `version`, the module exposes `run_typed` (a structured
393
- result object), `validate_toml` (lint → list of error strings), `list_kinds` /
394
- `scenario_kinds` (the dispatchable kinds), and `error_kind` (the `KshanaError` tag for
395
- a rejected scenario) — see [`docs/PYTHON_API.md`](docs/PYTHON_API.md).
396
-
397
- Wheels are built for Linux, macOS, and Windows by the `wheels` workflow on each
398
- release tag.
399
-
400
- ### WebAssembly
401
-
402
- The engine also runs in the browser via [wasm-pack](https://rustwasm.github.io/wasm-pack/):
403
-
404
- ```bash
405
- wasm-pack build --target web -- --features wasm
406
- ```
65
+ The package is an ES module with a WebAssembly payload. Initialise it once, then call
66
+ the engine synchronously:
407
67
 
408
68
  ```js
409
- import init, { run, chart_svg, version } from "./pkg/kshana.js";
410
- await init();
411
- const result = JSON.parse(run(tomlText));
412
- console.log(version(), result.classical.fom.timing_p95_ns);
413
- ```
414
-
415
- The module also exports `summary` (the one-line result string), `list_kinds` /
416
- `error_kind` (introspection), and `encode_permalink` / `decode_permalink` — the
417
- shareable-URL codec the playground uses to round-trip a whole scenario through the
418
- address-bar fragment.
419
-
420
- ### AI agents (MCP)
421
-
422
- [![kshana MCP server](https://glama.ai/mcp/servers/ashfordeOU/kshana/badges/card.svg)](https://glama.ai/mcp/servers/ashfordeOU/kshana)
423
-
424
- Kshana ships an [MCP](https://modelcontextprotocol.io) server, [`kshana-mcp`](mcp/kshana-mcp/),
425
- so AI assistants and agents can run the **validated** engine instead of guessing the
426
- math — usable from **Cursor, JetBrains AI Assistant / Junie, and any MCP-compatible
427
- assistant or agent**. It exposes `run_scenario`, `list_scenario_kinds`,
428
- `validate_scenario`, `export_sp3`, and `export_omm` (each a thin wrapper over
429
- `kshana::api`).
430
-
431
- ```bash
432
- cargo install kshana-mcp # crates.io
433
- docker run --rm -i ghcr.io/ashfordeou/kshana-mcp # or OCI, no Rust toolchain
434
- ```
69
+ import init, { run, run_full, chart_svg, version } from "kshana";
435
70
 
436
- Then register `kshana-mcp` in your client's `mcpServers` config — see
437
- [`mcp/kshana-mcp/README.md`](mcp/kshana-mcp/README.md) for per-client snippets. The
438
- server is a standalone, workspace-excluded crate (the `rmcp` SDK is edition 2024), so it
439
- never affects the lean published `kshana` crate or its build.
71
+ await init(); // load the wasm
440
72
 
441
- **In a JetBrains IDE** you can also install the
442
- [**Kshana PNT simulator**](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator)
443
- plugin from the JetBrains Marketplace (or *Settings → Plugins → Marketplace → search
444
- "Kshana"*) to run scenarios from a right-click — see [`ide/jetbrains/`](ide/jetbrains/).
445
-
446
- ## Scenario format
447
-
448
- Scenarios are declarative TOML. A top-level `kind` selects the pack — **forty-four** in
449
- all (`clock` is the default if omitted): `inertial`, `timetransfer`, `hybrid`, `hybrid-ukf`, `fusion`,
450
- `gnss-ins`, `orbit`, `ephemeris`, `gnss-sim`, `integrity`, `lunar-integrity`, `lunar-time-offset`, `spoof`,
451
- `spoof-detect`, `jamming`, `sweep`, `sweep-nd`, `gravity-map`, `terrain-nav`, `terrain-slam`,
452
- `combined-altpnt`, `pvt`, `mars-pnt`, `impairment-eval` (AI/ML RF-impairment detection
453
- evaluation testbed — labelled synthetic corpus + detector-agnostic ROC/AUC harness +
454
- in/out-of-distribution optimism gap), `quantum-trade` (quantum-vs-classical PNT
455
- trade with measured-ADEV ingestion + GNSS-denied resilience envelope; MODELLED),
456
- `space-weather` (solar/geomagnetic indices + Jacchia-71 exospheric temperature +
457
- activity-driven thermospheric density over the static atmosphere; MODELLED),
458
- `oem-interop` (CCSDS OEM import/round-trip bridge for GMAT/Orekit/STK ephemerides;
459
- MODELLED), the mission-analysis trio `launch-window` (two-body launch azimuth /
460
- plane-change / opportunities), `reentry` (Allen-Eggers ballistic re-entry corridor),
461
- `eo-coverage` (EO swath / GSD / access / revisit geometry), `space-packet` (CCSDS
462
- 133.0 TM/TC Space Packet framing — exact bit layout, round-trip verified), and
463
- `attitude-budget` (3-DOF gravity-gradient torque + RSS pointing error budget),
464
- `passes` (ground-station rise/set pass prediction — AOS/TCA/LOS, max elevation,
465
- access), and `link-budget` (one-way CCSDS/DSN link equation — FSPL / Eb·N₀ /
466
- margin / closure); the **lunar-PNT suite** `lunar-vlbi`, `lunar-joint-od-clock`,
467
- `lunar-frame-realisation`, `moonlight-service-volume`, `lunar-differential-pnt`,
468
- `lunar-interop-export`; and the **Quantum-Enabled PNT demonstrator**
469
- `quantum-time-transfer`, `quantum-gnss-free-nav`, `quantum-anomaly-detect` — the
470
- mission-analysis trio and these later kinds all MODELLED.
471
- Common fields: `seed`, a `[time]` grid, a `[gnss]` availability timeline (the outage
472
- driver), and per-sensor blocks with `provenance` strings citing the source of every
473
- figure. Example (clock):
474
-
475
- ```toml
476
- seed = 42
477
- threshold_ns = 20.0
478
- [time]
479
- step_s = 10.0
480
- duration_s = 7200.0
481
- [gnss]
482
- windows = [
483
- { t0 = 0.0, t1 = 600.0, state = "nominal" }, # 10 min GNSS sync
484
- { t0 = 600.0, t1 = 7200.0, state = "denied" }, # ~1.8 h outage
485
- ]
486
- [clock_quantum]
487
- id = "optical-sr-lattice"
488
- provenance = "Strontium optical lattice clock, space-oriented goal sigma_y(1s)=1e-15 (arXiv:1503.08457)"
489
- y0 = 5.0e-17
490
- q_wf = 1.0e-30 # white FM: q_wf = sigma_y(1s)^2
491
- q_rw = 0.0 # random-walk FM
492
- drift = 0.0 # linear aging (per second)
493
- [clock_classical]
494
- id = "csac-sa45s"
495
- provenance = "Microchip SA65 / SA.45s CSAC datasheet sigma_y(1s)=3e-10"
496
- y0 = 5.0e-10
497
- q_wf = 9.0e-20
498
- q_rw = 0.0
499
- drift = 0.0
500
- ```
501
-
502
- Optional fields (off when absent): a clock may add `flicker_floor` (1/f FM Allan
503
- floor); an inertial sensor may add `gyro_bias` and `q_arw` (gyro bias and angular
504
- random walk), and `bias_instability` and `q_aa` (the Allan bias-instability floor and
505
- acceleration random walk) — together a **single-axis (1-DOF) accelerometer error
506
- budget** (VRW/ARW and bias-instability). This is the error budget the shipped
507
- `inertial` scenario *pack* runs. Separately, the library now carries a verified
508
- **3-axis strapdown navigator** (`src/inertial/{attitude,mechanization,imu_errors}.rs`):
509
- quaternion attitude with coning/sculling compensation, a full NED mechanization
510
- (Earth-rate and transport-rate terms, WGS-84 Somigliana gravity), and a
511
- deterministic IMU error model in which **scale-factor, misalignment,
512
- g-sensitivity, quantization, and rate-ramp are modelled** (IEEE Std 952-1997
513
- §A.2; Groves 2013 §4.3). That 3-axis path is now **wired into a runnable
514
- loosely-coupled GNSS/INS pack** (`kind = "gnss-ins"`): a 15-state error-state EKF
515
- disciplines the strapdown solution against noisy fixes while GNSS is up, then
516
- coasts through the outage, reporting the fused horizontal error against the
517
- open-loop free-INS coast. A **tightly-coupled pseudorange** update is also
518
- available (it forms the innovation in the range domain, so it keeps correcting
519
- with fewer than four satellites). A
520
- clock-holdover scenario may add `runs` (> 1) to run a **Monte Carlo ensemble** — each
521
- figure of merit is then reported as a mean with a 5th–95th-percentile spread and the
522
- chart shades the error confidence band (see `scenarios/clock-ensemble.toml`).
523
-
524
- A `fusion` scenario (same blocks as `hybrid`) runs **two independent Kalman estimators**
525
- — one for the clock state, one for the position state — disciplined by GNSS and aided by
526
- optical time transfer, and reports a combined holdover FoM. The two blocks share no
527
- cross-covariance: this is a stacked pair of error budgets, **not** a true coupled
528
- clock+position joint filter (cross-block covariance is a roadmap item). See
529
- `scenarios/fusion-pnt.toml`.
530
-
531
- A `spoof` scenario injects a time-spoof — one of four `[attack.shape]` kinds
532
- (`linear_ramp`, `step_jump`, `meaconing`, `replay`; a bare `rate_ns_per_s` is still
533
- accepted as a linear ramp) — and runs each clock's spoof detector. The detector is a
534
- two-sided **χ²₁ energy / Neyman–Pearson test** on the clock-aided monitor statistic:
535
- the threshold is set from a target false-alarm budget `target_pfa`, and the
536
- **missed-detection probability `P_md`** is reported both closed-form and by
537
- Monte-Carlo (`mc_runs` trials per hypothesis — the two agree to a few ×1/√N). The
538
- **Security figure of merit is `1 − P_md`** at the operationally-harmful (spec)
539
- magnitude, so a quiet clock that catches a spec-sized spoof scores ≈ 1 and a noisy
540
- one that often misses it scores lower (see `scenarios/spoof-attack.toml`,
541
- `scenarios/spoof-meaconing.toml`).
542
-
543
- A `gnss-sim` scenario is a **measurement-domain** simulation: for each visible
544
- satellite it synthesises the pseudorange `ρ = geometric range + c·δt_rx − c·δt_sv +
545
- I + T + noise + multipath` and the L1 Doppler, with the **Klobuchar** single-frequency
546
- ionosphere (`[iono]`, IS-GPS-200 §20.3.3.5.2.5) and the **Saastamoinen** zenith
547
- troposphere projected by the **Niell (1996)** mapping function (`[tropo]`). The
548
- residuals feed **snapshot RAIM** for per-epoch HPL/VPL, and every satellite's
549
- pseudorange, Doppler, C/N₀, and iono/tropo corrections are emitted in the JSON
550
- `gnss_measurements` array. It is a forward simulator (it generates measurements from
551
- a known truth), not a receiver/solver — a zero-noise run reproduces geometry plus the
552
- corrections to sub-millimetre (see `scenarios/gnss-sim-raim.toml`).
553
-
554
- A `jamming` scenario models RF interference as a **link budget**: a `[jammer]`
555
- (ECEF position, transmit `power_dbw`, type) raises the jammer-to-signal ratio at a
556
- `[receiver]` watching a Walker `[constellation]`. From the geometry (free-space
557
- path loss and the per-direction receive-antenna gain) it computes each satellite's
558
- `J/S`, the **effective C/N₀** via the standard anti-jam equation (despreading
559
- processing gain × the spectral-separation factor `Q`; Kaplan & Hegarty §9.4), and
560
- flags loss of lock below a configurable tracking threshold — reporting an
561
- `availability_under_jamming` figure of merit. A 10 W broadband jammer at 1 km
562
- denies the receiver entirely (J/S ≈ 72 dB); the same jammer at 100 km only
563
- degrades the links (see `scenarios/jamming-demo.toml`).
564
-
565
- A `sweep` scenario runs a **trade study**: it varies one `parameter` (`threshold_ns`,
566
- `duration_s`, `quantum_q_wf`, or `classical_q_wf`) from `start` to `stop` over `steps`
567
- points on a `lin` or `log` `scale`, records a `metric` (e.g. `holdover_s`) for both
568
- clocks, and charts the two curves. The base scenario goes under `[base]` (see
569
- `scenarios/sweep-clock-stability.toml`).
570
-
571
- A `sweep-nd` scenario generalises this to **any pack and any number of axes**: it
572
- varies dotted TOML keys of a `[base]` scenario (of any `kind`) over the Cartesian
573
- product of `[[axes]]`, re-runs each grid node, and records `metrics` given as
574
- dotted JSON paths into the result (e.g. `classical.fom.holdover_s`). It works for
575
- every pack because it operates at the TOML/result boundary; native runs evaluate
576
- the grid in parallel (no extra dependency, wasm falls back to sequential) and the
577
- output is deterministic and row-major (see `scenarios/sweep-nd-inertial.toml`).
578
-
579
- An `orbit` scenario derives the `[gnss]` timeline from geometry instead of authoring
580
- it — give a `[user]` orbit, a `[constellation]`, an elevation `mask_deg`, and the two
581
- clock blocks. It also reports position accuracy from the satellite geometry; the
582
- optional `sigma_uere_m` (1-sigma user-equivalent range error, default 1 m) scales the
583
- position dilution of precision into a position sigma. The user orbit may be made
584
- **eccentric** with `eccentricity` and `argp_deg`, and `j2 = true` adds Earth-oblateness
585
- secular drift (see `scenarios/orbit-molniya.toml`). The constellation can instead be a
586
- **real one**: give `[constellation]` a `tle` block of two-line element sets and the
587
- satellites are parsed from it (see `scenarios/orbit-real-tle.toml`). Add one or more
588
- `[[constellations]]` blocks for **multi-GNSS** (e.g. GPS + Galileo; see
589
- `scenarios/orbit-multignss.toml`):
590
-
591
- ```toml
592
- kind = "orbit"
593
- seed = 7
594
- threshold_ns = 5.0
595
- mask_deg = 10.0
596
- sigma_uere_m = 1.0 # optional; position sigma = position-DOP * this
597
- [time]
598
- step_s = 60.0
599
- duration_s = 86400.0
600
- [user] # spacecraft (altitude in km, angles in deg)
601
- altitude_km = 8000.0
602
- inclination_deg = 0.0
603
- [constellation] # Walker-delta GNSS (GPS-like)
604
- altitude_km = 20180.0
605
- inclination_deg = 55.0
606
- planes = 6
607
- sats_per_plane = 4
608
- phasing_f = 1.0
609
- [clock_quantum] # ... as above
610
- [clock_classical] # ... as above
611
- ```
612
-
613
- The **GPS-denied alt-PNT** kinds navigate with no GNSS at all, matching a measured field
614
- sequence against a map through a particle filter. A `gravity-map` scenario flies a track
615
- through a spherical-harmonic gravity-anomaly field and recovers it from a cold-atom
616
- gravimeter's reading (`scenarios/gps-denied-gravity-nav.toml`); a `terrain-nav` scenario
617
- does the same against an SRTM elevation DEM (TERCOM/SITAN, `scenarios/terrain-nav.toml`);
618
- and a `combined-altpnt` scenario fuses **gravity + IGRF magnetic + terrain** in one filter
619
- (`scenarios/combined-altpnt.toml`).
620
-
621
- A `lunar-integrity` scenario evaluates **cislunar** PNT: it runs a lunar south-pole
622
- ARAIM protection-level pass against a LunaNet/LNIS relay set and honestly reports the
623
- integrity gap — a ~30 m lunar σ_URE drives the protection level well above a 50 m alert
624
- limit, so the service is *unavailable* under aviation-style integrity rules
625
- (`scenarios/lunanet-araim.toml`).
626
-
627
- A `lunar-time-offset` scenario reports the **relativistic Earth–Moon clock rate** — the
628
- basis of a Lunar Coordinate Time scale (LTC/TCL). A first-principles post-Newtonian
629
- identity sums the self-potential difference (IAU `L_G` geoid potential minus the Moon's
630
- surface self-potential) and the Moon's kinetic (second-order Doppler) term to a secular
631
- rate of ≈ 57 µs/day, reported with the published 56–59 µs/day band; it also gives the
632
- accumulated LTC−TT offset over a horizon and an inverse-variance ensemble (a lunar
633
- paper-clock). **MODELLED** — the headline figure is *reference-dependent* (Earth geoid
634
- vs lunar selenoid, averaging window), which is why a band, not a single certified
635
- number, is reported (`scenarios/lunar-time-offset.toml`).
636
-
637
- See `scenarios/` for at least one worked example of every kind (44 kinds, 57 `.toml`
638
- files — several kinds ship more than one example). A few kinds have an example file
639
- whose name differs from the kind: `lunar-integrity` → `scenarios/lunanet-araim.toml`,
640
- `gravity-map` → `scenarios/gps-denied-gravity-nav.toml`. List the dispatchable kinds at
641
- any time with `cargo run -- --validate <file>` errors, the Python `list_kinds()`, or the
642
- MCP `list_scenario_kinds` tool.
643
-
644
- ## Output
645
-
646
- The result artifact is versioned, self-describing JSON: per-step time series, the
647
- scored figures of merit, the active model specs (with provenance), the seed, a
648
- **scenario hash** — so any chart can be reproduced from the file — and, for each clock,
649
- an `adev_curve` (`[{tau_s, adev, n_samples, noise, edf, ci_lo, ci_hi}]`): the overlapping
650
- Allan deviation across octave-spaced averaging times — the standard way to read a clock's
651
- stability — now with a **noise-type-specific 95% confidence band** per point (the record's
652
- power-law type is identified from its modified-Allan slope, and the χ² interval uses the
653
- matching NIST SP 1065 effective degrees of freedom). The browser playground renders it as a
654
- log-log "Clock stability (ADEV)" chart. (MDEV, TDEV, and HDEV are available as library
655
- estimators; the exported result curve is the overlapping ADEV.) Every field, with units and a
656
- source pointer, is documented in [`docs/SCHEMA.md`](docs/SCHEMA.md).
657
-
658
- **Every chart is self-describing.** The browser playground, the CLI's `*.chart.svg`
659
- export, and the HTML scorecard all stamp each chart image with a footer reading
660
- `Kshana v<version> · scenario <hash> · kshana.dev`. The `scenario <hash>` is the first
661
- 12 hex characters of the run's **scenario hash** — a SHA-256 over the canonical scenario
662
- definition (seed, thresholds, model parameters, GNSS windows, …); the integrity and lunar
663
- reports, which carry no hash of their own, fall back to a SHA-256 of the scenario source.
664
- It is the **same fingerprint** shown in the one-line summary and the result JSON, so a
665
- saved or pasted chart always carries its version, the exact scenario that produced it (for
666
- bit-for-bit reproduction), and the source — change any input and the hash changes.
667
-
668
- The figures of merit follow the standard operational PNT figures of merit:
669
-
670
- | Figure of merit | How Kshana computes it |
671
- |-----------------|------------------------|
672
- | Timing Performance (clock/orbit packs) | clock-phase error RMS + 95th-percentile over the outage, in **nanoseconds** (`timing_rms_ns`) — a timing metric, not position |
673
- | Positioning Performance (inertial/hybrid packs) | 1-DOF position-error RMS + 95th-percentile over the outage, in **metres** (`pos_rms_m`); single-axis. A single run is flagged `monte_carlo: false`; set `runs = N` for a Monte Carlo ensemble that reports each metric's mean, spread, and bootstrap 95% CI. Still **not** a 2-D CEP/2DRMS or DOP-weighted accuracy (those need the 3-axis model — roadmap) |
674
- | Autonomy | holdover duration — time in-spec after GNSS loss (grid-quantised: a lower bound) |
675
- | Resilience | error-growth slope during the outage |
676
- | Availability | fraction of the run with an in-spec solution |
677
- | Integrity | filter **self-consistency** — fraction of outage samples whose error stays inside the Kalman filter's own k-sigma bound. **Not** an aviation HPL/VPL/RAIM integrity figure (see [`docs/INTEGRITY.md`](docs/INTEGRITY.md)) |
678
- | Security | **analytic spoof-*detectability* bound** from clock stability — how small/slow a time-spoof a single-clock consistency monitor could flag. Meaningful only with a configured attack; **not** a multi-satellite RAIM detector |
679
-
680
- New to these terms? Each is defined in plain language in the [glossary](docs/GLOSSARY.md).
681
-
682
- ## Architecture
683
-
684
- **One engine, many front doors.** A single Rust core (`kshana`) runs every scenario,
685
- reached through a CLI, a Python extension, an in-browser WebAssembly module, an **MCP
686
- server** for AI agents, and a **JetBrains IDE plugin** — all converging on one
687
- `api::run_toml` dispatch. Inside, the sensor packs plug into a common error-model
688
- interface; alongside them sit a **reference-frame layer** (IAU 2006/2000A
689
- precession–nutation and the CIO-based GCRS↔ITRS reduction), an **astrodynamics/numerical
690
- layer** (analytic SGP4/SDP4 **and** a numerical Cowell propagator with its
691
- EGM2008/perturbation force model, maneuver design, and orbit determination), an
692
- **integrity/GNSS layer** (RAIM/ARAIM, SBAS, the measurement domain, jamming, cislunar),
693
- a **fusion / alt-PNT layer** (the GNSS/INS estimators and the gravity/terrain/magnetic
694
- map-matchers), a **deep-space & lunar layer** (radiometric Mars-PNT and the MODELLED
695
- lunar PNT suite — LTC time, VLBI, joint OD+clock, frame realisation, service-volume,
696
- differential PNT, interop), a **mission-analysis layer** (launch / re-entry / coverage /
697
- pointing / pass / link budgets and the space-weather environment), and the open
698
- **resilience & AI/ML study layer** (RPCF resilience scoring, the RF-impairment optimism
699
- gap, and the quantum-enabled PNT demonstrator) whose reproducible artifacts ride the
700
- validated kernels.
701
-
702
- Two standalone, **workspace-excluded** crates sit beside the core — `mcp/kshana-mcp`
703
- (the MCP server, built on the edition-2024 `rmcp` SDK) and `xval/anise-frames` (the
704
- ANISE/SPICE frame cross-check, which pulls MPL-2.0 deps) — kept out of the published
705
- crate's dependency graph, `Cargo.lock`, license gate, and MSRV build by the root
706
- `Cargo.toml` `exclude` list. The JetBrains plugin (`ide/jetbrains`) is a separate Kotlin
707
- project. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full set of diagrams.
708
-
709
- ```mermaid
710
- flowchart LR
711
- SCN["Scenario (.toml)<br/>seed · GNSS timeline · sensor params"] --> ENG
712
- subgraph ENG["Engine (per step)"]
713
- direction TB
714
- M["Error model<br/>step(): evolve noise state"] --> E["Estimator<br/>GNSS-disciplined holdover"]
715
- E --> F["FoM scoring<br/>vs the 6 figures of merit"]
716
- end
717
- ENG --> OUT["result.json + chart.svg<br/>(reproducible: scenario+seed+version)"]
718
- ```
719
-
720
- ```mermaid
721
- flowchart TD
722
- cli["CLI · Python · WebAssembly · MCP server · JetBrains plugin"] --> api["api — run_toml: typed dispatch over 44 kinds"]
723
- subgraph shared["Shared core"]
724
- types["types · scenario · GNSS timeline"]
725
- allan["allan — ADEV/MDEV/TDEV/HDEV"]
726
- end
727
- subgraph frames["Time & reference frames"]
728
- ts["timescales · jd2 — UTC/TAI/TT/UT1"]
729
- pn["precession · nutation — IAU 2006/2000A"]
730
- cio["cio — GCRS↔ITRS (CIO, SOFA-anchored)"]
731
- end
732
- subgraph packs["Sensor packs"]
733
- p1["clock — models · estimator · kalman · security"]
734
- p2["inertial — strapdown INS + quantum-CAI"]
735
- p3["timetransfer — optical/RF/TWSTFT/PPP"]
736
- p4["hybrid — fused PNT suite"]
737
- end
738
- subgraph astro["Astrodynamics & numerical"]
739
- orbit["orbit · walker — geometry → GNSS + DOP"]
740
- sgp4["sgp4 · tle — SGP4/SDP4"]
741
- prop["propagator — Cowell"]
742
- forces["forces — J2–J6 · 3rd-body · SRP · drag · GR"]
743
- gsh["gravity_sh — EGM2008 d/o 70"]
744
- integ["integrator — RK4 · DOPRI"]
745
- man["maneuver · orbit_determination"]
746
- cr["cr3bp — Earth–Moon CR3BP + halo/NRHO corrector"]
747
- end
748
- subgraph intg["Integrity & GNSS"]
749
- raim["raim — RAIM/ARAIM · HPL/VPL"]
750
- sbas["sbas — DO-229E PL · L1/L5"]
751
- gsim["gnss_sim · ionex — measurement domain"]
752
- jam["jamming — J/S → C/N₀"]
753
- nsig["navsignal — PSD · SSC → anti-jam Q · DLL jitter"]
754
- lun["lunar — cislunar ARAIM"]
755
- end
756
- subgraph fnav["Fusion & alt-PNT"]
757
- fus["fusion — EKF · UKF · 17-state · coupled"]
758
- grav["gravimeter · mapmatch · particle_filter"]
759
- terr["altpnt/terrain · igrf — terrain + magnetic"]
760
- end
761
- subgraph ds["Deep-space & Mars"]
762
- dsr["radiometric · ccsds_tdm — light-time · Δ-DOR · TDM"]
763
- dso["deepspace_od — reduced-dynamic SRIF"]
764
- dsm["mars_pnt · gse_sim — relay-PNT + GSE sim"]
765
- end
766
- subgraph lunx["Lunar PNT suite (MODELLED)"]
767
- lsx["lunar_time · lunar_vlbi · lunar_combination — LTC time · geodetic VLBI · joint OD+clock"]
768
- lsy["lunar_frame_realise · lunar_service · lunar_dpnt · lunar_interop — frame realisation · Moonlight service-volume · differential PNT · LunaNet/IOAG interop"]
769
- end
770
- subgraph mission["Mission analysis & environment"]
771
- ma["launch · reentry · eo_payload · attitude_budget · passes · linkbudget — first-order budgets"]
772
- sw["space_weather — Jacchia-71 thermospheric density"]
773
- end
774
- subgraph io["Interop formats"]
775
- iofmt["rinex · sp3 · oem · omm · glonass · ccsds_tdm"]
776
- end
777
- subgraph resil["Resilience studies & AI/ML — open, reproducible artifacts"]
778
- tpl["tpl — conditional Timing Protection Level"]
779
- resc["resilience — RPCF scoring + decision-instability"]
780
- opt["impairment_eval · impairment_study · impairment_ml · eval_stats — optimism gap"]
781
- sdrr["sdr · realdata — IQ/IF front end + ingest adapters"]
782
- cross["crossover · quantum_trade — quantum-vs-classical map + trade"]
783
- qd["quantum_devices · quantum_faults · quantum_nav_od · qtrade · timetransfer_chain · representativeness — Quantum-Enabled PNT demonstrator"]
784
- end
785
- gen["study generators<br/>cargo run --example/--bin"] --> resil
786
- api --> packs
787
- api --> astro
788
- api --> intg
789
- api --> fnav
790
- api --> ds
791
- api --> lunx
792
- api --> mission
793
- packs --> shared
794
- astro --> frames
795
- orbit --> sgp4
796
- prop --> forces
797
- prop --> gsh
798
- prop --> integ
799
- cr --> integ
800
- nsig --> jam
801
- fus --> p2
802
- grav --> p2
803
- terr --> grav
804
- orbit --> p1
805
- orbit --> io
806
- p4 -. composes .-> p1
807
- p4 -. composes .-> p2
808
- p4 -. composes .-> p3
809
- tpl -. uses .-> allan
810
- resc -. uses .-> intg
811
- opt -. uses .-> sdrr
812
- cross -. uses .-> packs
813
- ```
814
-
815
- **Components & distribution.** The core crate ships through the Rust, Python, and
816
- JavaScript ecosystems; the MCP server and IDE plugin reach AI agents and JetBrains IDEs.
817
- Each `vX.Y.Z` tag republishes every channel automatically (see
818
- [Versioning & releases](#versioning--releases)).
819
-
820
- ```mermaid
821
- flowchart LR
822
- subgraph repo["One repository"]
823
- core["kshana core<br/>library + CLI"]
824
- mcp["mcp/kshana-mcp<br/>MCP server (excluded crate)"]
825
- ide["ide/jetbrains<br/>Kotlin IDE plugin"]
826
- xval["xval/anise-{frames,lunar-od,mars-od}<br/>SPICE/DE440 cross-checks (excluded)"]
827
- end
828
- core --> crates["crates.io"]
829
- core --> pypi["PyPI — wheels"]
830
- core --> npm["npm — WebAssembly"]
831
- core --> rel["GitHub Releases<br/>binaries · SBOM · SLSA · validation summary"]
832
- core --> pages["kshana.dev<br/>GitHub Pages playground"]
833
- core -. archived .-> zen["Zenodo DOI"]
834
- mcp --> crates
835
- mcp --> ghcr["ghcr.io — OCI image"]
836
- mcp --> reg["official MCP registry"]
837
- ide --> jb["JetBrains Marketplace"]
838
- ```
839
-
840
- ## Repository layout
73
+ const toml = `kind = "clock_holdover"\n# ... scenario fields ...`;
74
+ const result = JSON.parse(run(toml));
75
+ console.log(version(), result.classical.fom.timing_p95_ns);
841
76
 
77
+ // JSON result + SVG chart in one call:
78
+ const { json, svg } = run_full(toml);
842
79
  ```
843
- kshana/
844
- ├── src/ # the kshana core crate (library + CLI)
845
- │ ├── api.rs · main.rs · lib.rs # typed dispatch (44 kinds) + CLI + crate root
846
- │ ├── python.rs · wasm.rs # optional PyO3 / wasm-bindgen bindings
847
- │ ├── types.rs · scenario.rs · allan.rs # shared core (time grid, GNSS timeline, Allan)
848
- │ │
849
- │ ├── models.rs · estimator.rs · kalman.rs # Pack 1 — clock holdover + integrity
850
- │ ├── security.rs · detection.rs · spoof.rs · spoof_monitors.rs # spoof detection
851
- │ ├── filter_health.rs · fom.rs · fom_label.rs · report.rs · chart.rs · run.rs # health · FoM scoring + labelling · output
852
- │ ├── suite.rs · study.rs # scenario suites + aggregated multi-scenario study artifacts (`--study`)
853
- │ ├── inertial/ # Pack 2 — strapdown INS (attitude · mechanization · imu_errors · quantum_imu)
854
- │ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs # Pack 3 — TWSTFT/CV/PPP/optical, Sagnac
855
- │ ├── hybrid.rs · ensemble.rs · sweep.rs # Pack 4 — fused PNT, Monte-Carlo, trade sweeps
856
- │ │
857
- │ ├── timescales.rs · jd2.rs · ephem.rs # time systems, two-part JD, Sun/Moon ephemeris
858
- │ ├── precession.rs · nutation.rs · cio.rs # IAU 2006/2000A precession-nutation + CIO GCRS↔ITRS
859
- │ ├── frames.rs · *_data.rs # TEME↔ECEF + generated nutation/CIO/EGM2008/IGRF tables
860
- │ │
861
- │ ├── orbit.rs · sgp4.rs · tle.rs · walker.rs # geometry, SGP4/SDP4, TLE, Walker design
862
- │ ├── propagator.rs · forces.rs · gravity_sh.rs · integrator.rs # Cowell + perturbations (EGM2008 d/o70, GR) + RK4/DOPRI
863
- │ ├── maneuver.rs · batch_ls.rs · orbit_determination.rs # burns/Lambert/porkchop, Gauss-Newton, OD
864
- │ ├── cr3bp.rs · lunar.rs · lunar_frame.rs · lunar_od.rs # Earth–Moon CR3BP + halo/NRHO STM corrector, cislunar/LunaNet ARAIM, MCI↔MCMF, lunar OD
865
- │ ├── lunar_time.rs · lunar_vlbi.rs · lunar_combination.rs · lunar_frame_realise.rs · lunar_service.rs · lunar_dpnt.rs · lunar_interop.rs # MODELLED lunar PNT suite — LTC time · geodetic VLBI · joint OD+clock · frame realisation · Moonlight service-volume · differential PNT · LunaNet/IOAG interop export
866
- │ ├── body.rs · mars_frame.rs · ephem_provider.rs · radiometric.rs · ccsds_tdm.rs # deep-space: multi-body · Mars frame · ephemeris seam · radiometric obs + CCSDS-TDM
867
- │ ├── deepspace_od.rs · clock_state.rs · mars_atmos.rs · mars_pnt.rs · linkbudget.rs · gse_sim.rs # SRIF OD · onboard clock · Mars drag · relay-PNT · link budget · GSE sim
868
- │ │
869
- │ ├── fusion/ # GNSS/INS — EKF · UKF · tightly_coupled(17) · coupled · closed_loop
870
- │ ├── raim.rs · sbas.rs # RAIM/ARAIM HPL/VPL, SBAS DO-229E PLs + L1/L5 iono-free
871
- │ ├── gnss_sim.rs · ionex.rs · pvt.rs · jamming.rs # measurement domain · ionosphere maps · single-point positioning · jamming
872
- │ ├── navsignal.rs # nav-signal PSD (BPSK-R/BOC) · spectral-separation → anti-jam Q · DLL code-tracking jitter · multipath envelope
873
- │ ├── gravimeter.rs · igrf.rs · mapmatch.rs · particle_filter.rs · altpnt/ # gravity/magnetic/terrain alt-PNT
874
- │ ├── rinex.rs · rinex_obs.rs · glonass.rs · sp3.rs · oem.rs · omm.rs · permalink.rs # interop formats
875
- │ ├── launch.rs · reentry.rs · eo_payload.rs · attitude_budget.rs · passes.rs · space_packet.rs # mission-analysis budgets + CCSDS Space Packet
876
- │ ├── space_weather.rs · holdover.rs · tpl.rs # space-weather environment · GNSS-denied clock-holdover calculator · conditional Timing Protection Level (under spoofing)
877
- │ ├── resilience/ # framework-aligned PNT-resilience scoring + decision-instability study (RPCF · Dirichlet · Kendall-τ · diversity collapse · assurance report)
878
- │ ├── impairment_eval.rs · impairment_study.rs · impairment_ml.rs · eval_stats.rs # AI/ML RF-impairment eval testbed · optimism-gap study · LR/MLP detectors · bootstrap/DeLong/Spearman stats
879
- │ ├── sdr.rs · realdata/ # software-defined-receiver front end (IQ/IF → E/P/L taps → SQM) + real-data ingest adapters (RINEX · UBX · GnssLogger · JammerTest · Yunnan · SatGrid)
880
- │ ├── crossover.rs · quantum_trade.rs · frugal.rs · integrity_impact.rs # quantum-vs-classical crossover map · PNT trade · cost-per-coverage ROI · integrity impact
881
- │ ├── quantum_devices.rs · quantum_faults.rs · quantum_nav_od.rs · qtrade.rs · timetransfer_chain.rs · representativeness.rs # Quantum-Enabled PNT demonstrator — device error models · fault catalogue · GNSS-free quantum OD · unified trade harness · quantum time-transfer chain · representativeness / gaps-to-flight ledger
882
- │ ├── interchange.rs · verification.rs # KIF artifact envelope · machine-checked verification matrix
883
- │ └── bin/crossover_study.rs · bin/validation_report.rs # crossover-study artifact generator · release validation-summary HTML
884
-
885
- ├── mcp/kshana-mcp/ # standalone, workspace-EXCLUDED crate — the MCP server (+ Dockerfile, server.json)
886
- ├── ide/jetbrains/ # standalone Kotlin/Gradle IntelliJ-Platform plugin
887
- ├── xval/anise-{frames,lunar-od,mars-od}/ # standalone, workspace-EXCLUDED ANISE/SPICE cross-checks (frames · lunar DE440 · Mars DE440)
888
-
889
- ├── examples/ # reproducible study generators: tpl_jammertest · resilience_report · optimism_study + real-data probes (jammertest_probe · yunnan_probe · satgrid_probe · texbat_probe · ingest_realdata)
890
- ├── paper-artifacts/ # byte-deterministic study artifacts, regenerable from examples/ (optimism-study.json · resilience-study.json); raw datasets stay out
891
- ├── scenarios/ # one cited .toml per kind + geometry-driven + GPS-denied
892
- ├── scripts/ # reproducibility + repo-hygiene + SBOM guards
893
- ├── docs/ # CONCEPTS, ARCHITECTURE, CAPABILITY, VALIDATION, PROVENANCE, GLOSSARY, …
894
- ├── web/ # the WebAssembly playground + kshana.dev site
895
- ├── tools/ # table generators (EGM2008 · IGRF · nutation · CIO) + fetch_tles.sh
896
- ├── .github/workflows/ # ci · release · publish · wheels · pages · mcp-publish · jetbrains-plugin · frame-xval
897
- ├── pyproject.toml # Python packaging (maturin)
898
- ├── CHANGELOG.md # Keep a Changelog + SemVer
899
- └── CITATION.cff · ROADMAP.md · CONTRIBUTING.md · SECURITY.md
900
- ```
901
-
902
- ## Documentation
903
-
904
- | Document | For whom | What's in it |
905
- |----------|----------|--------------|
906
- | [Concepts primer](docs/CONCEPTS.md) | everyone, start here | what Kshana does and why, from zero to the physics |
907
- | [Playground](web/README.md) | everyone | run the engine in your browser (WebAssembly); build &amp; deploy notes |
908
- | [Glossary](docs/GLOSSARY.md) | everyone | plain-language definitions of every term |
909
- | [Architecture](docs/ARCHITECTURE.md) | developers / reviewers | module map, engine pipeline, dispatch, and diagrams |
910
- | [Validation status](docs/VALIDATION.md) | reviewers / citers | what is `validated` vs `not modeled`, with evidence |
911
- | [Provenance](docs/PROVENANCE.md) | reviewers / citers | every sensor parameter, model, and dataset traced to its published source, in one citable table |
912
- | [Reproducibility &amp; provenance](docs/REPRODUCIBILITY.md) | reviewers / packagers | determinism guarantees, golden-pinning, SBOM, build provenance |
913
- | [Wheel platform tags](docs/WHEEL_TAGS.md) | packagers | the abi3 Python wheel matrix — which platform tag `pip install kshana` resolves |
914
- | [Positioning](docs/POSITIONING.md) | evaluators | where Kshana sits vs RTKLIB/gLAB (complementary), and the zero-install browser tier |
915
- | [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 |
916
- | [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) |
917
- | [Force-model validation](docs/AGENCY-ORBIT-VALIDATION.md) | reviewers / citers | the full-force engine (`src/precise_od.rs`) fit to agency ephemerides — methodology and validated residuals |
918
- | [Real TLE guide](docs/REAL_TLE_GUIDE.md) | users | driving scenarios from real Celestrak / Space-Track constellation TLEs (vs the bundled synthetic Walker set) |
919
- | [Integrity FoM](docs/INTEGRITY.md) | evaluators | what the `integrity` / `security` figures mean — and what they are **not** vs aviation HPL/VPL |
920
- | [ARAIM reference](docs/ARAIM_REFERENCE.md) | reviewers / integrators | the open MHSS ARAIM protection-level implementation — the `b_k` nominal-bias projection, σ_URA vs σ_URE, and the fault-mode priors |
921
- | [Quantum models](docs/QUANTUM.md) · [details](docs/QUANTUM-MODELS.md) | reviewers | the cold-atom-interferometer physics layer, and where coefficients are still looked up |
922
- | [Compliance](docs/COMPLIANCE.md) | evaluators | DO-229E / DO-316 algorithm scope, and what is **not** a conformance claim |
923
- | [Standards &amp; interoperability](docs/STANDARDS.md) | integrators | the GNSS / flight-dynamics / agency interchange formats Kshana reads and writes (RINEX, SP3, CCSDS OEM/OMM/TDM/Space-Packet, …) |
924
- | [Result schema](docs/SCHEMA.md) | integrators | every field of the result JSON, with units and a source pointer |
925
- | [Python API](docs/PYTHON_API.md) | Python users | the PyO3 binding surface — calling the engine, the scenario/result types, and examples |
926
- | [Claims vs reality](docs/CLAIMS-VS-REALITY.md) | reviewers | the overclaim-closure ledger + the CI guard (`tests/no_overclaims.rs`) that keeps it resolved |
927
- | [Roadmap](ROADMAP.md) | everyone | the phased roadmap — what has shipped and what is next |
928
- | [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 |
929
- | [Changelog](CHANGELOG.md) | everyone | released history (Keep a Changelog + SemVer) |
930
- | [Contributing](CONTRIBUTING.md) | contributors | build, guards, test/citation discipline, DCO |
931
- | [Governance](GOVERNANCE.md) | contributors / community | how Kshana is governed — who decides, how, and the open/closed boundary |
932
- | [Code of Conduct](CODE_OF_CONDUCT.md) | community | expected conduct (Contributor Covenant) |
933
- | [Security policy](SECURITY.md) | reporters | how to report a vulnerability; dual-use note |
934
-
935
- ## Validation, reproducibility & honesty
936
-
937
- - Every noise term is calibrated to a **published, cited** figure and validated
938
- against the standard relation (Allan deviation for clocks; Groves' dead-reckoning
939
- error growth for inertial; the timing→ranging conversion for time transfer). Status
940
- per term is tracked in [`docs/VALIDATION.md`](docs/VALIDATION.md) as `validated` or
941
- `not modeled` — nothing is presented as validated that is not.
942
- - **Reproducible by construction:** `scenario + seed + engine version → identical
943
- bits`. `scripts/check-reproducible.sh` enforces it; quantum and classical runs use
944
- independent seeds so their noise is uncorrelated.
945
- - Maturity is stated honestly: optical-clock and optical-link figures are *targets /
946
- ground-demonstrator* results, not flown.
947
-
948
- ### Validation at a glance
949
80
 
950
- Every row is enforced by a named test in CI. This table is a **curated highlight**;
951
- the full machine-checked matrix is **61 rows — 15 VALIDATED, 42 MODELLED, 4 PARTNER**
952
- (`src/verification.rs`), with the complete evidence (and what is honestly *not* yet
953
- validated) in [`docs/VALIDATION.md`](docs/VALIDATION.md) and the per-release
954
- [`kshana-validation-summary.html`](https://github.com/AshfordeOU/kshana/releases)
955
- artifact (generated by `cargo run --bin validation_report`, SLSA-attested).
956
-
957
- The **Status** column states the *kind* of evidence, matching the validation ladder above: **VALIDATED** = checked against an independent external oracle (real data, an independent library, or published reference vectors); **MODELLED** = checked against analytic truth or simulation self-consistency (no independent external dataset). VALIDATED describes the *method* of checking, not a pass/fail — an honest miss against real data (the LRO row) is still VALIDATED. `CI` rows are process guards, not figures of merit. A few real-data islands (the measured caesium clock, Stable32 PHASE.DAT, and the OPS-SAT/ICGEM checks where the raw inputs carry no redistribution licence) are **data-gated**: the test prints a skip notice and stays green when the input is absent, and the public reference numbers are committed under `tests/fixtures/`. Reproduce the raw inputs with the matching `scripts/fetch_*.sh`.
958
-
959
- | Status | Capability | Agreement | Reference / oracle |
960
- |--------|------------|-----------|--------------------|
961
- | **VALIDATED** | SGP4/SDP4 propagation | 666/666 vectors, worst **4.12 mm** | AIAA 2006-6753 (Vallado `tcppver.out`) + head-to-head vs the independent `sgp4` crate |
962
- | **VALIDATED** | 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` |
963
- | **VALIDATED** | 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 |
964
- | **MODELLED** | EGM2008 geopotential (degree/order 70) | acceleration = ∇V to **< 1e-6**; zonal collapse to validated J2 | NGA EGM2008 coefficients + analytic ∇V identity |
965
- | **VALIDATED** | Gravity-functional synthesis (gravity-aided / GNSS-free nav map) | GRS80 Somigliana + γ_e/γ_p to **3.5e-12**; real EGM2008 disturbance map physical (RMS ≈ 26 mGal, d/o 70) | GRS80 (Moritz 1980, IAG) Somigliana normal gravity + real ICGEM EGM2008 (`tests/icgem_gravity_reference.rs`) |
966
- | **VALIDATED** | Allan estimators (ADEV/MDEV/TDEV/HDEV) + confidence bands | reproduce reference deviations; χ² bands match | NIST SP 1065 (Riley), 1000-point Table 31/32 |
967
- | **VALIDATED** | Allan estimators on a **real measured caesium clock** | OADEV/OHDEV to **1e-3** (observed ≤ 3e-5), 16 averaging factors | Stable32 on a real 5071A Cs vs H-maser, 556,990 pts (`tests/cs5071a_reference.rs`, data-gated) |
968
- | **VALIDATED** | Allan estimators on the **canonical Stable32 PHASE.DAT** | OADEV/MDEV/TDEV to **1e-3** (observed ≤ 5e-5), 139 averaging factors | Stable32 reference deviations for PHASE.DAT (`tests/phasedat_reference.rs`, data-gated) |
969
- | **MODELLED** | IMU error model — ARW / VRW / bias-instability | recovered to **< 5 %** (bias-instability < 15 %) | Analog Devices ADIS16465 datasheet; NaveGo reference profile |
970
- | **MODELLED** | Numerical (Cowell) propagator, unperturbed | **sub-metre over 24 h**; energy/momentum conserve ~1e-9 | exact universal-variable Kepler |
971
- | **MODELLED** | Lambert · Tsiolkovsky · porkchop | round-trip to two-body truth; ΔV **< 0.01 %** | Izzo 2015 · rocket equation · analytic Hohmann floor |
972
- | **MODELLED** | 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 |
973
- | **VALIDATED** | Force-model fit vs Galileo precise ephemeris (full-arc) | **0.61 m** 3-D RMS, 24 h, d/o-70, force-only | ESA/ESOC `ESA0MGNFIN` final orbit (E11), real `finals2000A` EOP |
974
- | **VALIDATED** | Force-model fit vs Swarm-A precise ephemeris (reduced-dynamic) | **0.10 m** 3-D RMS (empirical-tier bound, not a measure) | ESA `SW_OPER_SP3ACOM_2_` precise orbit |
975
- | **VALIDATED** | Force-model fit vs LRO lunar (honest miss) | **6.6 m** reduced-dynamic, *above* the 5 m target | JPL Horizons LRO (NAIF −85) + GRAIL `GRGM660PRIM` |
976
- | **MODELLED** | Deep-space Mars OD (reduced-dynamic SRIF) | **≈ 0.2 m** Mars-LMO (simulation FoM, *not* real-mission) | synthetic closed-loop OD — estimator-machinery validation |
977
- | **VALIDATED** | Sun-central Mars dynamics vs JPL DE440 | **137 m @ 1-day arc** (grows with arc = unmodelled n-body) | JPL DE440 via ANISE (`xval/anise-mars-od`, kernel-gated) |
978
- | **VALIDATED** | Single-point positioning vs a surveyed IGS coordinate (real observations) | **5.7 m** 3-D RMS / **1.1 m** horizontal, dual-frequency iono-free code SPP | IGS station ABMF survey + GPS broadcast ephemeris, 2018-05-13 (`tests/pvt_abmf.rs`) |
979
- | **MODELLED** | 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 |
980
- | **MODELLED** | GPS-denied gravity-map navigation | ~70 km INS drift → **~145 m** recovered | ESA NAVISP *Quantum Wayfarer* target |
981
- | **MODELLED** | Terrain-referenced navigation (TERCOM/SITAN) | 70 km drift → **< 500 m** (grid-resolution floor ~140 m) | SRTM `.hgt` DEM; hand-injected drift (non-circular check) |
982
- | **MODELLED** | 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) |
983
- | **MODELLED** | Nav-signal modulation & code tracking | BPSK self-SSC = **2/(3·R_c)**; unit-area PSDs; **sub-metre** C/A DLL jitter @ 45 dB-Hz | Closed-form SSC/PSD anchors + Kaplan & Hegarty DLL thermal-noise formula |
984
- | **MODELLED** | CR3BP halo/NRHO differential corrector | STM = finite differences; orbit closes to **machine precision**; L2 9:2 NRHO **≈ 6.57 d / perilune ≈ 3,250 km** | finite-difference STM check + published L2 southern 9:2 NRHO (≈ 6.56 d / ≈ 3,370 km) — CR3BP, not a real Gateway ephemeris |
985
- | **VALIDATED** | ARAIM dual-constellation integrity | constellation-wide fault mode on real GPS + Galileo | EU ARAIM TR / DO-316; Celestrak `gps-ops` 2021-07-28 |
986
- | **VALIDATED** | GNSS geometry / DOP (GDOP/PDOP/HDOP/VDOP/TDOP) | match to **1e-6 relative** across 8 geometries (well-conditioned → near-singular) | gnss_lib_py 1.0.4 (Stanford NAV Lab) — independent library (`tests/dop_reference.rs`) |
987
- | **VALIDATED** | ML detector-evaluation metrics (AUC/ROC/confusion/Pd-Pmd/precision/F1) | **exact counts + < 1e-9** over 5 datasets × 24 thresholds | scikit-learn 1.9.0 (Pedregosa et al., JMLR 2011) — independent library (`tests/eval_metrics_reference.rs`) |
988
- | **VALIDATED** | Anomaly-detection ROC AUC on **real ESA OPS-SAT telemetry** | AUC reproduces scikit-learn to **< 1e-9**; peak-count detector AUC **≈ 0.85** on the labelled test split | scikit-learn `roc_auc_score` on the OPSSAT-AD test split (Ruszczak et al. 2025, CC BY 4.0) — real OPS-SAT telemetry (`tests/opssat_ad_reference.rs`) |
989
- | **VALIDATED** | Quantum-trade numerical kernels (ADEV NNLS fit · χ² consistency bands · van-Loan clock Q) | NNLS + Q **exact**; χ² **< 5e-4** at operating dof ≥ 48 | scipy 1.17.1 — `optimize.nnls` / `stats.chi2.ppf` / `linalg.expm` (`tests/scipy_reference.rs`) |
990
- | **MODELLED** | Conditional Timing Protection Level (holdover-limited undetected time error under spoofing) | composition reproduces the multi-step `clock_state` covariance recursion; calibrated on a real recorded spoof | JammerTest 2024 (Zenodo 15911589) scalars + van-Loan / CUSUM closed forms (`examples/tpl_jammertest`) |
991
- | **MODELLED** | PNT-resilience scoring + decision-instability | 35 hand-derived oracle tests; byte-deterministic study artifact (fixed seed) | DHS RPCF v2.0 mapping + Dirichlet / Kendall-τ / Hill-N2 closed forms — synthetic architectures, not a certification |
992
- | **MODELLED** | RF-impairment optimism-gap study (scaling laws + leave-one-out predictor) | permutation-null significance; byte-deterministic artifact (5 seeds) | synthetic parameter-grounded corpus — the eval *metrics* are VALIDATED vs scikit-learn (above); the study is MODELLED |
993
- | CI | Cross-platform reproducibility | bit-identical input + shape goldens on 3 OSes | Linux / macOS / Windows CI matrix, SHA-256 goldens |
994
- | CI | Test coverage | **~96 % line** on `src/`, gated ≥ 85 % | cargo-tarpaulin (LLVM engine) |
995
-
996
- ## FAQ
997
-
998
- **Do I need to understand quantum physics to use this?**
999
- No. If you can run a command line you can run Kshana. Start with the
1000
- [plain-language primer](docs/CONCEPTS.md); look terms up in the [glossary](docs/GLOSSARY.md).
1001
-
1002
- **Is this a quantum-hardware design or flight software?**
1003
- No. It is a performance *simulator*. Quantum-hardware fidelity comes from published
1004
- error models, not from this tool. See [What it is / is not](#what-it-is--is-not).
1005
-
1006
- **Are the quantum results realistic, or marketing?**
1007
- Every parameter is cited to a datasheet or paper, every model is validated against a
1008
- textbook relation, and maturity is labelled honestly in
1009
- [VALIDATION.md](docs/VALIDATION.md) — including that no strontium optical clock has
1010
- flown. The engine is neutral: quantum and classical are the same code with different
1011
- published numbers.
1012
-
1013
- **Can I trust two runs to agree?**
1014
- Yes — runs are deterministic: `scenario + seed + engine version → bit-identical output`,
1015
- enforced by `scripts/check-reproducible.sh`.
1016
-
1017
- **Can I use it from Python or in a browser?**
1018
- Yes — see [Python](#python) and [WebAssembly](#webassembly). Both call the same engine.
1019
-
1020
- **How do I model my own sensor?**
1021
- Write a scenario `.toml` with your sensor's published figures in the `provenance`
1022
- fields. See [Scenario format](#scenario-format) and the examples in `scenarios/`.
1023
-
1024
- **Is it free for commercial use?**
1025
- Yes — under the AGPL-3.0, including in commercial settings, as long as you honour the
1026
- AGPL's copyleft (notably: if you modify Kshana and offer it over a network, you must
1027
- offer those users your modified source). If that does not suit you — e.g. you need to
1028
- embed Kshana in a proprietary product or run a closed network service — a commercial
1029
- licence is available from Ashforde OÜ; see [`LICENSING.md`](LICENSING.md) and
1030
- [Support](#support--professional-services).
1031
-
1032
- ## Troubleshooting
1033
-
1034
- **`cargo build` fails on an old toolchain.** Kshana needs Rust ≥ 1.75. Update with
1035
- `rustup update`.
1036
-
1037
- **Building the Python extension fails to link on macOS** (`Undefined symbols … _Py…`).
1038
- A Python extension resolves its symbols at load time. `maturin` sets the right linker
1039
- flag automatically — use `maturin develop --features python` rather than a bare
1040
- `cargo build`.
1041
-
1042
- **The Python build complains the interpreter is newer than PyO3 knows.** Set
1043
- `PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` (abi3 wheels are forward-compatible across
1044
- CPython versions).
1045
-
1046
- **WebAssembly build can't find the target.** Install it once with
1047
- `rustup target add wasm32-unknown-unknown`, then `wasm-pack build --target web -- --features wasm`.
1048
-
1049
- **Where did my output go?** Each run writes `<scenario>.result.json` and
1050
- `<scenario>.chart.svg` next to the input `.toml`. These are git-ignored by design.
1051
-
1052
- ## Roadmap
1053
-
1054
- See [`ROADMAP.md`](ROADMAP.md) for the phased roadmap, [`CHANGELOG.md`](CHANGELOG.md)
1055
- for released history, and [`docs/CAPABILITY.md`](docs/CAPABILITY.md) for the
1056
- per-capability roadmap. The **ITRF-precise frame reduction** is now delivered — the
1057
- full CIO-based IAU 2006/2000A GCRS↔ITRS chain (polar motion + sub-arcsecond nutation),
1058
- validated bit-for-bit against SOFA/ERFA and independently cross-checked against ANISE
1059
- (pure-Rust SPICE) to ≤ 3.6 m at GNSS orbit. Near-term items include tightly-coupled carrier-phase fusion and surfacing the
1060
- loosely-/tightly-coupled GNSS/INS navigator across more packs; the **deep-space / Mars
1061
- radiometric-navigation** engine landed in v0.17.0 (simulation-validated). The
1062
- **quantum physics layer** is a **P2** item: the CAI accelerometer is now simulated from
1063
- first principles (Mach–Zehnder phase, projection noise, contrast decay, vibration
1064
- coupling), while the clock/time-transfer sensors are still driven by published
1065
- Allan/noise-budget coefficients. GMST-based TEME&harr;ECEF, the IERS
1066
- leap-second time systems (UTC/TAI/TT/UT1), SGP4/SDP4 orbit propagation (v0.7.0,
1067
- validated against the AIAA 2006-6753 vectors), and the runnable `gnss-ins` fusion
1068
- pack have all **shipped**, and the inertial velocity is exposed downstream. An active
1069
- stochastic time-spoof detector (Neyman–Pearson / χ²₁ energy test with Monte-Carlo
1070
- P_fa/P_md and a Security FoM of 1−P_md), a link-budget jamming model (J/S → effective
1071
- C/N₀ → loss of lock), multi-constellation availability, a single-axis (1-DOF)
1072
- IMU error budget, two independent (clock + position) Kalman estimators reported as a
1073
- combined FoM, real constellation geometry from TLEs, an HTML scorecard report,
1074
- geometry-derived GNSS availability
1075
- *and* dilution of precision from Keplerian orbits with eccentricity and J2 drift,
1076
- Monte Carlo confidence bands, trade-study parameter sweeps, an in-browser WebAssembly
1077
- playground, and optional Python (PyO3) and WebAssembly (wasm-bindgen) bindings have
1078
- landed on `main`.
1079
-
1080
- ## Contributing
1081
-
1082
- See [`CONTRIBUTING.md`](CONTRIBUTING.md). In short: tests pass (`cargo test`), the
1083
- two guard scripts pass, Conventional Commits, and a `CHANGELOG.md` `[Unreleased]`
1084
- entry for every user-visible change. Participation is governed by our
1085
- [Code of Conduct](CODE_OF_CONDUCT.md). To report a security issue, see the
1086
- [Security policy](SECURITY.md) — please do not open a public issue for vulnerabilities.
1087
-
1088
- ## Citing
1089
-
1090
- If you use Kshana in academic or technical work, please cite it. Machine-readable
1091
- metadata is in [`CITATION.cff`](CITATION.cff) (GitHub renders a "Cite this repository"
1092
- button from it); cite the version you used (e.g. `v0.21.0`) together with the
1093
- scenario and seed for full reproducibility. Every release is archived on Zenodo with
1094
- a citable DOI — the concept DOI [10.5281/zenodo.20528627](https://doi.org/10.5281/zenodo.20528627)
1095
- always resolves to the latest version.
1096
-
1097
- > Baweja, C. (2026). *Kshana — a PNT-resilience simulator with quantum-sensor performance models*. [Ashforde OÜ](https://ashforde.org). https://doi.org/10.5281/zenodo.20528627
1098
-
1099
- **Related publications.** Studies built on the open engine are written up separately; their
1100
- numbers regenerate from the [reproducible study artifacts](#reproducible-study-artifacts) above.
1101
-
1102
- > Baweja, C. (2026). *Anticipating the Optimism Gap: Predicting Distribution-Shift Degradation of RF-Impairment Detectors from In-Distribution Statistics*. arXiv:2606.22054. https://doi.org/10.48550/arXiv.2606.22054
1103
- >
1104
- > Baweja, C. (2026). *A Conditional Timing Protection Level: Holdover-Limited Undetected Time Error Under GNSS Spoofing*. arXiv:2606.24210. https://doi.org/10.48550/arXiv.2606.24210
1105
-
1106
- ## Versioning & releases
1107
-
1108
- Kshana follows [Semantic Versioning](https://semver.org). While pre-1.0 the public
1109
- scenario/result schema may still change; breaking changes are called out explicitly in
1110
- the [`CHANGELOG.md`](CHANGELOG.md). Every result is reproducible from
1111
- `scenario + seed + engine version`.
1112
-
1113
- **Every `vX.Y.Z` tag publishes all channels automatically** — one CI pipeline fans out to:
1114
-
1115
- | Channel | Install / get | Contents |
1116
- |---------|---------------|----------|
1117
- | [crates.io](https://crates.io/crates/kshana) | `cargo install kshana` · `kshana = "0.20"` | Rust library + CLI |
1118
- | [crates.io](https://crates.io/crates/kshana-mcp) | `cargo install kshana-mcp` | the MCP server |
1119
- | [PyPI](https://pypi.org/project/kshana/) | `pip install kshana` | abi3 wheels (Linux/macOS/Windows) + sdist |
1120
- | [npm](https://www.npmjs.com/package/kshana) | `npm install kshana` | WebAssembly module + JS wrapper |
1121
- | [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 |
1122
- | official MCP registry | auto-discovered by MCP clients | `io.github.ashfordeOU/kshana-mcp` |
1123
- | [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator) | IDE → Plugins → search "Kshana" | the **Kshana — PNT simulator** IDE plugin |
1124
- | [GitHub Releases](https://github.com/AshfordeOU/kshana/releases) | download | `kshana` + `kshana-mcp` binaries, a CycloneDX **SBOM**, **SLSA** build provenance, and an HTML validation summary |
1125
- | [Zenodo](https://doi.org/10.5281/zenodo.20528627) | DOI | a citable archive of every release |
1126
- | [kshana.dev](https://kshana.dev) | open in a browser | the WebAssembly playground (redeployed from `main`) |
1127
-
1128
- The MCP server's crate / image / registry version tracks the engine (it bundles the
1129
- library); the JetBrains plugin versions independently (it shells out to your installed
1130
- `kshana` binary).
1131
-
1132
- ## License
1133
-
1134
- **Dual-licensed.** Use Kshana under **either** the GNU **AGPL-3.0-only** (see
1135
- [`LICENSE`](LICENSE)) **or** a **commercial licence** from Ashforde OÜ for
1136
- proprietary/closed integration that the AGPL does not suit. Which one applies, and
1137
- why it is set up this way, is explained in [`LICENSING.md`](LICENSING.md).
1138
-
1139
- Contributions are licensed inbound under the AGPL **and** grant Ashforde OÜ the right
1140
- to include them in the commercially-licensed edition (so the dual-licence keeps
1141
- working) — see [`CONTRIBUTING.md`](CONTRIBUTING.md). Sign off each commit per the
1142
- Developer Certificate of Origin with `git commit -s`.
1143
-
1144
- **Trademark.** "Kshana" and its marks are trademarks of Ashforde OÜ. The licence
1145
- covers the code, not the name — please rename forks and derivative distributions.
1146
-
1147
- ## Support & professional services
1148
-
1149
- Kshana is free and open source under the AGPL-3.0 and **professionally developed and
1150
- maintained by Ashforde OÜ** (Estonia). The open engine is complete and usable on its
1151
- own. For organisations that need more, Ashforde OÜ offers:
1152
-
1153
- - **Commercial support & integration** — embedding Kshana in your toolchain, custom
1154
- scenarios, and priority fixes.
1155
- - **Custom sensor models** — calibrated to your hardware, including export-sensitive
1156
- resilience models maintained in a private overlay.
1157
- - **Kshana Pro** — proprietary model-based systems-engineering and programme tooling
1158
- that plugs into the open engine to complete the workflow.
1159
- - **Training & consulting** on quantum/classical PNT performance analysis.
1160
-
1161
- This is the open-core model: the engine is, and stays, openly licensed; the sustaining
1162
- business is expertise, support, and the proprietary extensions — not license fees.
1163
- Contact **contact@ashforde.org** · [ashforde.org](https://ashforde.org).
1164
-
1165
- ## Key references
1166
-
1167
- **Validation oracles & standards** — the external authorities Kshana's checks are anchored to:
81
+ Beyond `run` / `run_full` / `version`, the module also exports `summary` (the one-line
82
+ result string), `list_kinds` / `error_kind` (introspection), and
83
+ `encode_permalink` / `decode_permalink` the shareable-URL codec the
84
+ [playground](https://ashforde.org) uses to round-trip a whole scenario through the
85
+ address-bar fragment.
1168
86
 
1169
- - Vallado, Crawford, Hujsak & Kelso *Revisiting Spacetrack Report #3* ([AIAA 2006-6753](https://doi.org/10.2514/6.2006-6753); [test data](https://celestrak.org/publications/AIAA/2006-6753/)): the SGP4/SDP4 verification set Kshana matches to 4.12 mm, and the worked frame examples the TEME→ITRF chain is checked against.
1170
- - IAU [SOFA](https://www.iausofa.org/) / [ERFA](https://github.com/liberfa/erfa) the reference time and frame routines the IAU 2000A nutation and the CIO GCRS↔ITRS reduction are validated bit-for-bit against.
1171
- - Petit & Luzum (eds.) *IERS Conventions (2010)*, [IERS TN 36](https://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html) (Earth-orientation, polar motion, and frame standards).
1172
- - Riley *Handbook of Frequency Stability Analysis*, [NIST SP 1065](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication1065.pdf) (Allan-deviation relations and the NBS14 reference series).
1173
- - Pedregosa et al. — *scikit-learn: Machine Learning in Python*, [JMLR 12 (2011)](https://jmlr.org/papers/v12/pedregosa11a.html): the reference ROC/AUC, confusion-matrix and precision/recall/F1 implementations the RF-impairment evaluation testbed is matched to exactly (`tests/eval_metrics_reference.rs`).
1174
- - Virtanen et al. — *SciPy 1.0*, [Nature Methods 17 (2020)](https://doi.org/10.1038/s41592-019-0686-2): `optimize.nnls`, `stats.chi2` and `linalg.expm` — the reference routines the quantum-trade measured-ADEV NNLS fit, the χ² consistency bands, and the van-Loan clock process-noise covariance are validated against (`tests/scipy_reference.rs`).
1175
- - Knowles, Kanhere, Neamati & Gao — *gnss_lib_py*, [SoftwareX 27 (2024)](https://doi.org/10.1016/j.softx.2024.101811): used both as open prior art (see *Comparison & open prior art* below) and as the **independent DOP oracle** the GDOP/PDOP/HDOP/VDOP/TDOP computation is matched to 1e-6 (`tests/dop_reference.rs`).
1176
- - Montenbruck & Gill — *Satellite Orbits: Models, Methods and Applications* ([Springer](https://doi.org/10.1007/978-3-642-58351-3)): the force models behind the force-model fit to agency precise ephemerides.
1177
- - Howell — *Three-dimensional, periodic, halo orbits*, Celestial Mechanics 32(1) (1984), [doi:10.1007/BF01358403](https://doi.org/10.1007/BF01358403); Zimovan-Spreen, Howell & Davis — *Near rectilinear halo orbits and nearby higher-period dynamical structures*, Astrodynamics 6 (2022), [doi:10.1007/s42064-021-0125-x](https://doi.org/10.1007/s42064-021-0125-x) (the halo/NRHO families the CR3BP differential corrector reproduces).
87
+ Every figure of merit is labelled **validated** or **modelled**; optical-clock figures
88
+ are space goals on ground hardware (no strontium optical clock has flown). Maturity is
89
+ *not* uniform across domainsEarth PNT is real-data validated; deep-space / Mars
90
+ navigation is simulation-validated; real-mission deep-space OD is on the roadmap.
1178
91
 
1179
- **Device & method physics** — the cited sources behind the sensor models:
92
+ ## Learn more
1180
93
 
1181
- - Origlia, Schiller, Bongs et al. [arXiv:1503.08457](https://arxiv.org/abs/1503.08457) (strontium optical lattice clock, space-oriented goal).
1182
- - Oelker et al., *Nature Photonics* (2019) — [doi:10.1038/s41566-019-0493-4](https://doi.org/10.1038/s41566-019-0493-4) (laboratory Sr clock, 4.8×10⁻¹⁷).
1183
- - Templier et al., *Science Advances* (2022) — [arXiv:2209.13209](https://arxiv.org/abs/2209.13209) (hybrid quantum accelerometer triad).
1184
- - Groves, *Principles of GNSS, Inertial, and Multisensor Integrated Navigation* — [IEEE AESS tutorial (UCL Discovery)](https://discovery.ucl.ac.uk/id/eprint/1470141/) (dead-reckoning error growth).
1185
- - Giorgetta et al., *Nature Photonics* 7, 434 (2013) — [arXiv:1211.4902](https://arxiv.org/abs/1211.4902); Deschênes et al., *Phys. Rev. X* 6, 021016 (2016) — [APS](https://journals.aps.org/prx/abstract/10.1103/PhysRevX.6.021016) (optical two-way time-frequency transfer; the optical inter-satellite link models its non-reciprocity budget after these).
1186
- - Betz — *Binary Offset Carrier Modulations for Radionavigation*, NAVIGATION 48(4) (2001), [doi:10.1002/j.2161-4296.2001.tb00247.x](https://doi.org/10.1002/j.2161-4296.2001.tb00247.x) (the BOC modulation and spectral-separation theory behind `src/navsignal.rs`).
1187
- - Kaplan & Hegarty (eds.) — *Understanding GPS/GNSS: Principles and Applications* (3rd ed., Artech House, 2017): the anti-jam effective-C/N₀ equation and the early–late DLL code-tracking thermal-noise jitter the nav-signal and jamming models use.
94
+ - **Full README & validation matrix** <https://github.com/AshfordeOU/kshana>
95
+ - **Live playground** <https://ashforde.org>
96
+ - **Capabilities** [docs/CAPABILITY.md](https://github.com/AshfordeOU/kshana/blob/main/docs/CAPABILITY.md)
97
+ - **Validation & provenance** [docs/VALIDATION.md](https://github.com/AshfordeOU/kshana/blob/main/docs/VALIDATION.md) · [docs/PROVENANCE.md](https://github.com/AshfordeOU/kshana/blob/main/docs/PROVENANCE.md)
1188
98
 
1189
- **Comparison & open prior art** — the tools and surveys Kshana is positioned against:
99
+ ## Licence
1190
100
 
1191
- - Humphreys et al. [*TEXBAT*](https://radionavlab.ae.utexas.edu/texbat/) (ION GNSS 2012): the spoofing test-battery parameters the multi-layer detector is characterised against.
1192
- - González et al. — [NaveGo](https://github.com/rodralez/NaveGo) (2017): the open, validated inertial-navigation error profiles used as the classical baseline.
1193
- - Iiyama, Casadesús Vila & Gao — [*LuPNT*](https://github.com/Stanford-NavLab/LuPNT) (ION GNSS+ 2023, Stanford NavLab): open lunar-PNT simulator.
1194
- - Knowles, Kanhere, Neamati & Gao *gnss\_lib\_py*, SoftwareX 27 (2024), [doi:10.1016/j.softx.2024.101811](https://doi.org/10.1016/j.softx.2024.101811): open GNSS data analysis.
1195
- - Li, Zaminpardaz, Kealy & Greentree — *Quantum sensors for enhanced positioning and navigation: a comprehensive review*, GPS Solutions 30(1):62 (2026), [doi:10.1007/s10291-026-02030-y](https://doi.org/10.1007/s10291-026-02030-y).
1196
- - Bertone et al. — *Earth and Space Science* 8(6) (2021), [doi:10.1029/2020EA001454](https://doi.org/10.1029/2020EA001454): GRAIL reduced-dynamic OD, the empirical-acceleration floor the LRO fit reproduces.
101
+ Free and open source under the **GNU AGPL-3.0-only**. A **commercial licence** is
102
+ available from [Ashforde ](https://ashforde.org) for proprietary/closed integration
103
+ see [LICENSING.md](https://github.com/AshfordeOU/kshana/blob/main/LICENSING.md).
104
+ Professionally developed and maintained by Ashforde OÜ; commercial support, integration,
105
+ and proprietary extensions available.