<!-- SPDX-License-Identifier: Apache-2.0 -->
# Capability map — what Kshana does, partially does, and does not do
Kshana is a **PNT-performance-and-resilience simulator**, not a full space-systems
toolkit. This page is the honest scope map: for every capability area a procurement or
research reviewer might check, it states the status, what actually exists in the code,
what is missing, and where it sits on the roadmap. Status is one of:
- **yes** — implemented and validated to a stated level;
- **partial** — a real but limited model (scope explicitly bounded below);
- **none** — not modelled (out of scope today).
Nothing here is aspirational: "partial" never means "almost done", it means "this much
and no more". See also [`VALIDATION.md`](VALIDATION.md), [`INTEGRITY.md`](INTEGRITY.md),
[`QUANTUM-MODELS.md`](QUANTUM-MODELS.md), and the overclaim closure ledger
[`CLAIMS-VS-REALITY.md`](CLAIMS-VS-REALITY.md) (every historical overclaim, how it was
resolved, and a CI guard that keeps it resolved).
## Core PNT (where Kshana actually plays)
| Capability | Status | What exists | What is missing | Roadmap |
|------------|--------|-------------|-----------------|---------|
| **Orbit determination & propagation** | partial | Dependency-free **SGP4/SDP4**, validated to 4.12 mm vs all 666 AIAA 2006-6753 vectors (position **and** velocity, the latter to 1 mm/s); analytic Keplerian + J2-secular; inertial velocity exposed and surfaced **end-to-end** via the runnable **`ephemeris` scenario** (`src/ephemeris.rs`, reachable from CLI/Python/WASM/MCP) — per step it emits the TEME **and** GCRS state (position + velocity), the ITRF/ECEF position, the WGS-84 **sub-satellite ground track** (lat/lon/alt), and station azimuth/elevation/range + **range-rate/Doppler** (the radial range-rate matches the true position derivative JD-noise-free to 6e-9 m/s) — and via the CCSDS **OEM** velocity-carrying ephemeris export (`--export-oem`). A **numerical (Cowell) propagator** (`src/propagator.rs`) integrates a configurable **zonal-gravity** force model — the **full Earth zonal field through degree 6** (`forces::zonal_accel`, the published EGM-96 `J2..J6`) — with a choice of adaptive driver — RK4 **step doubling** or the **Dormand–Prince RK5(4)** embedded pair (`integrate_dopri` / `propagate_dopri`, a cheaper 7-eval embedded error estimate that clears the same Kepler gate and agrees with the RK4 path to <1 m on a J2..J6 orbit) — pinned against **analytic truth stronger than a numerical cross-tool**: the unperturbed orbit reproduces the **exact universal-variable Kepler solution to sub-metre over 24 h** (a tighter gate than the milestone's "vs reference < 10 m"), energy + angular momentum conserve to ~1e-9 relative, the J2 nodal regression matches the closed-form secular rate to first-order theory, the zonal acceleration is verified to be the **exact gradient of its own potential** (and to reduce to the 666-vector-validated J2 closed form), and `solve_kepler_checked` **returns `Err` rather than a wrong answer** when Newton fails to converge (e.g. near-perigee e = 0.999). **Epoch-driven third-body (Sun and Moon)** gravity is **wired into the time-varying integrator** (`ForceModel::third_body` / `accel_at`, with the `src/ephem.rs` Montenbruck & Gill low-precision Sun and Moon ephemerides — no DE/SPK kernel needed): each RHS evaluation samples the perturber positions at the advanced epoch `epoch_jd_tt + t/86400`, so the Sun/Moon move along their orbits during the integration. The perturbation is verified as the exact gradient of its disturbing potential, vanishes at the geocentre, and has the textbook LEO magnitudes (~5e-7 m/s² Sun, ~1.1e-6 m/s² Moon); the Sun ephemeris hits hand-derived J2000 anchors (perihelion distance, ~−23° solstice declination, ~1°/day motion) and the Moon ephemeris its perigee/apogee envelope, ~384 400 km mean distance, ≤ 5.3° inclination bound, and sidereal-month direction return; and the integration wiring is proven **bit-exact** (RHS term equals `third_body_accel` at the sampled position at t = 0 and t = 1 day) with a quarter-year epoch shift yielding a different trajectory. **Solar-radiation pressure** rides the same epoch-driven RHS (`forces::srp_accel` / `ForceModel::solar_radiation`): the cannonball model `ν·P☉·cᵣ·(A/m)·(AU/d)²·d̂` with a `forces::conical_shadow` umbra+penumbra eclipse factor (smooth ν ∈ [0,1], verified to taper through a monotonic penumbra that extends beyond the umbral cylinder), verified against the textbook 1-AU pressure (≈ 4.54e-6 N/m²), the ~1.36e-7 m/s² LEO magnitude pushing away from the Sun, the inverse-square fall-off (doubling Sun distance quarters it), an **exactly-zero** acceleration in the umbral cylinder, and a propagated displacement that scales ~linearly with A/m. **Atmospheric drag** is the first velocity-dependent term (`forces::drag_accel` / `ForceModel::drag` + the new `accel_rv` / velocity-passing RHS): quadratic drag `−½·ρ(h)·(C_D·A/m)·\|v_rel\|·v_rel` against the co-rotating atmosphere `v_rel = v − ωₑ ẑ × r`, with `ρ` the Vallado piecewise-exponential `forces::atmospheric_density` — verified by the 1.225 kg/m³ sea-level anchor, a strictly monotonic LEO decay with a physical ~58 km scale height, the ~2e-6 m/s² drag magnitude opposing the relative velocity, and the **dissipation signature** (a 300 km orbit loses specific energy monotonically and its semi-major axis decays a bounded ~km/day, where the vacuum orbit conserves energy). The **post-Newtonian (Schwarzschild) relativistic correction** is the second velocity-dependent term (`forces::relativistic_accel` / `ForceModel::relativity`): the IERS `β = γ = 1` form `a = (μ/c²r³)·{[4μ/r − v²]·r + 4(r·v)·v}`, the leading driver of the relativistic perigee advance — verified against its closed-form circular value `3μ²/(c²r³)·r̂` (radial, outward), its textbook `≈1.9e-9` LEO ratio to two-body, the hand-simplified radial-velocity form, and the **conservative signature** (it perturbs the orbit but holds the semi-major axis to under a metre/day, the structural opposite of drag). **Orbit determination** (`src/orbit_determination.rs`) closes the loop from observations back to a state: a **Gauss–Newton batch** corrector (`src/batch_ls.rs`) drives a candidate `[r, v]` onto the best fit of ground-station ranges propagated across the arc (sub-metre / mm·s⁻¹ from noiseless ranges; ~2 m with a post-fit residual at the 5 m noise floor — the signature of a consistent least-squares fit), with a **sequential** recursive variant on the unscented filter | No high-degree EGM **tesseral** field (200×200 + loader); drag density is the **static** Vallado piecewise-exponential (solar-activity-independent), **not** NRLMSISE-00 (the < 5 % thermospheric-density clause); SRP is the **cannonball** model with a geometric **conical umbra+penumbra** shadow (no solar limb darkening, no oblate-Earth shadow, no satellite shape/attitude); relativity is the **Schwarzschild** term only (no Lense–Thirring frame-dragging, no PPN-parameter tuning); **third-body/SRP use the low-precision ephemerides (~0.005° Sun, ~0.3° Moon), not DE/SPK-kernel accuracy**; no external GMAT/Orekit cross-validation of a high-fidelity orbit run; no orbit *determination* (fit from observations) | high-degree tesseral gravity + NRLMSISE-00 drag + solar limb darkening + Lense–Thirring + DE-grade ephemeris + GMAT cross-val + OD range-rate/angle measurements & analytic STM: P2+ |
| **Time systems** | partial | `src/timescales.rs`: Julian-date API (civil↔JD, MJD), UTC↔TAI via the full IERS leap-second table (10→37 s, 1972→2017), TAI→TT, UT1 via DUT1, and the IAU-2000 **Earth Rotation Angle** (ERA validated bit-for-bit against the SOFA `eraEra00` vector). The SGP4 path's **DUT1≈0 approximation is explicitly documented** at the `gstime` call site (a ≤ ~13″ GMST error, well inside SGP4's own model error), and the `ephemeris` scenario takes explicit `dut1_s`/`xp_arcsec`/`yp_arcsec` knobs so a caller can supply real IERS UT1 / polar motion | Single-`f64` JD (~50 µs resolution near 2020 — this, not the algorithm, is the floor on a finite-difference cross-check; two-part JD on the roadmap); pre-1972 rubber-seconds not modelled; DUT1 not predicted (must be supplied) | **done** (foundation); two-part JD: P2 |
| **Reference frames** | partial | `src/frames.rs`: GMST-based TEME↔ECEF, WGS-84 geodetic↔ECEF (exact + iterative inverse, machine-precision at all altitudes), and a geodetic ground-station observer (azimuth/elevation/range); **IAU 2006 precession** (`src/precession.rs`: the Fukushima–Williams angles `(γ̄, φ̄, ψ̄, ε̄_A)` + the GCRS↔mean-of-date bias-precession matrix); **IAU 2000A/2000B nutation + full TEME→GCRS chain** (`src/nutation.rs`: the **full IAU 2000A** series — 678 luni-solar + 687 planetary terms, `nutation_iau2000a` / `nutation_matrix_2000a`, table machine-generated from the ERFA `nut00a` reference by `tools/gen_nut00a.py` — alongside the 77-term 2000B series, Delaunay arguments, the SOFA `iauNumat` nutation matrix, the equation of the equinoxes, and `teme_to_gcrs(r, v, jd_tt)` via TEME→TOD→MOD→GCRS — both series validated **bit-for-bit** against the SOFA/ERFA `nut00a`/`nut00b` reference vectors, Δψ/Δε to 1e-13 rad); **IERS polar motion** PEF→ITRF (`teme_to_itrf` / `polar_motion_matrix`, SOFA `iauPom00`, caller-supplied `x_p`/`y_p` — a tens-of-metres effect at orbital radius); **CIO-based IAU 2006/2000A reduction** (`src/cio.rs`: the equinox-free GCRS↔CIRS↔ITRS chain — CIP `X,Y` from the 2006/2000A NPB matrix, the 66-term CIO-locator `s` series, `gcrs_to_cirs_matrix`, the Earth rotation angle, and the full `gcrs_to_itrs_matrix` — validated **bit-for-bit** against the SOFA `eraXys06a`/`eraC2ixys`/`eraEra00` vectors). The **end-to-end** transforms are now pinned to a published authoritative worked example, not just self-consistency: against the **Vallado** AIAA 2006-6753 state (2004-04-06, with its IERS EOP; `tests/frame_reference_vectors.rs`) TEME→PEF matches to **0.1 mm**, TEME→ITRF to **0.6 mm**, the full CIO GCRS→ITRS to **4 mm**, and ECEF→geodetic reproduces Vallado Example 3-3 lat/lon/alt to the last published digit. The whole chain is **user-reachable** via the `ephemeris` scenario (ITRF/ECEF position + WGS-84 sub-satellite ground track per step) | The default TEME→GCRS chain uses 2000B (~1 mas, below its own velocity-frame-rotation simplification); the < 0.1 mas full-2000A path is available via `nutation_matrix_2000a`, and the rigorous **CIO (X, Y, s)** reduction is available via `src/cio.rs`. The legacy TEME path uses IAU-1982 GMST (SGP4 convention); an ANISE/SPICE numerical cross-check (a second independent realisation) is a follow-on | TEME↔ECEF + geodetic: **done** (Vallado-verified); inertial TEME→GCRS: **done** (2000B + full 2000A); polar-motion ITRF: **done** (Vallado-verified); CIO GCRS→ITRS: **done** (Vallado-verified) |
| **Timing & frequency** | partial | Exact van-Loan-Q two-state Kalman clock (NIST SP 1065) with a **Joseph-stabilised covariance update** (positive-semidefinite under extreme Q/R ratios, Cholesky-checked in CI) and a **filter-consistency health monitor** (`src/filter_health.rs`): a Monte-Carlo NIS/NEES assessment against χ² confidence bands, surfaced as `filter_health` in the result JSON and a green/amber card in the playground, with a Q/R-mismatch sweep test proving the monitor flips to *inconsistent* when the tuning is off (Bar-Shalom §5.4); overlapping **ADEV, MDEV, TDEV, HDEV** estimators + χ²-based confidence intervals with **noise-type-specific effective degrees of freedom** (NIST SP 1065 Table 5 closed forms for WPM/FPM/WFM/FFM/RWFM, the set Stable32 uses; the exported ADEV curve identifies the record's power-law type from its MDEV slope and attaches a 95% band per τ — `src/allan.rs`), **numerically validated against the Stable32 reference deviations for the canonical NBS14 dataset to 1e-4** (`tests/allan_reference.rs`) and the edf cross-checked by a Monte-Carlo white-FM ensemble; honest grid-bounded holdover FoM; clock ensembles; **two-way time-transfer model** with reciprocal-delay cancellation + a non-reciprocal random-walk-FM differential-delay floor (`src/timetransfer.rs`, Allan signature reported) | full Greenhall-algorithm edf (the simple closed forms are bias-bounded but coarser than the exact BasicSum), and multi-noise-mixture identification | exact-edf + mixed-noise ID: P2 |
| **GNSS / PNT processing** | partial | A **measurement-domain pseudorange simulation** (`gnss-sim` kind, `src/gnss_sim.rs`): per visible satellite it synthesises `ρ = geometric range + c·δt_rx − c·δt_sv + I + T + noise + multipath` and the L1 Doppler, with the **Klobuchar single-frequency ionosphere** (IS-GPS-200 §20.3.3.5.2.5) and the **Saastamoinen zenith troposphere** (Davis 1985) projected by the **Niell (1996) mapping function** — each model unit-tested against hand computation — then feeds the residuals to **snapshot RAIM** for per-epoch HPL/VPL and emits a `gnss_measurements[]` array (pseudorange, Doppler, C/N₀, iono/tropo corrections per SV). Plus DOP/availability and solution-separation RAIM from orbits; **RINEX 3 multi-GNSS NAV ingestion** (GPS/Galileo/QZSS/BeiDou via IS-GPS-200, GLONASS state-vector) parsed → SV ECEF position & clock bias, usable as a first-class `Propagator` source AND as an inline constellation `rinex` block (`scenarios/orbit-rinex.toml`); **RINEX 3/4 OBSERVATION ingestion** and SP3 precise-orbit read/write | A **forward simulator, not a receiver/solver**: it generates pseudoranges from a known truth, it does not estimate a position from real measurements — no PPP/RTK, no carrier-phase ambiguity resolution, no dual-frequency iono-free combination; the observation parser reads real measurements but there is no *solution*; single-frequency iono only; BeiDou-GEO excluded | real-signal processing / PPP-RTK: use RTKLIB/gLAB |
| **Sensor fusion / INS dead-reckoning** | full | **3-axis strapdown library** (`src/inertial/{attitude,mechanization,imu_errors}.rs`): quaternion attitude with coning/sculling compensation, full NED mechanization (Earth-rate + transport-rate, WGS-84 Somigliana gravity), and a deterministic IMU error model (**scale-factor, misalignment, g-sensitivity, quantization, rate-ramp** modelled). The strapdown navigator is now **wired into a runnable loosely-coupled GNSS/INS pack** with a figure of merit (`src/fusion/pack.rs`, `kind = "gnss-ins"`): the three-axis mechanization is disciplined by the **15-state error-state EKF** (`src/fusion/{gnss_ins_ekf,closed_loop}.rs`, position/velocity/attitude/bias feedback) while GNSS is up, then coasts through the outage — replacing the truth-snap reset with genuine fusion, and reporting the fused horizontal error vs the open-loop free-INS coast. The separate legacy `inertial` pack still runs the **1-DOF scalar** budget with truth-snap reset. A **tightly-coupled pseudorange** update (`update_tightly_coupled` / `fuse_tightly_coupled`) is also implemented: it forms the innovation in the range domain (line-of-sight Jacobian on δp) and keeps correcting with **fewer than four satellites**, where a loosely-coupled PVT fix does not exist. A **full 17-state tightly-coupled GNSS/INS UKF** (`src/fusion/tightly_coupled17.rs`) carries position, velocity, attitude error, accelerometer and gyro biases, and the receiver clock (bias + drift), with **quantum-CAI dead-reckoning** — the velocity-random-walk process noise is the cold-atom accelerometer's derived `q_va` — coasting a 120-second outage bounded to a few hundred metres (vs the kilometres of a navigation-grade free INS). The deterministic IMU error model is **configurable per sensor from the `gnss-ins` TOML** (`[imu_*.error_model]`: scale-factor, misalignment, g-sensitivity, quantization, rate-ramp), defaulting to a pure constant-bias source when omitted | Tightly-coupled is **pseudorange-only** (carrier-phase and an explicit receiver-clock state are roadmap) and reachable via the navigator API but **not yet surfaced in a scenario pack**; a single deterministic driving trajectory; the loosely-coupled accel-bias/tilt pair is weakly separable so per-bias calibration is not claimed; IMU error model omits vibration rectification, temperature-gradient drift; the 17-state UKF and the tightly-coupled paths are **self-validated** (analytic CV integration, GNSS-aiding convergence, bias recovery, the CAI-limited 120-s outage bound) — an external **NaveGo / KF-GINS cross-validation** has not yet been run | carrier-phase tight coupling, tight-coupling pack surfacing, trajectory library, NaveGo/KF-GINS cross-validation: **P2** |
| **Integrity / RAIM / ARAIM** | partial | **Real snapshot RAIM** in `src/raim.rs`: least-squares solution + residual χ² fault detection (exact threshold from a dependency-free incomplete-gamma χ²) and **slope-based HPL/VPL** (pbias from a non-central χ² for the configured P_fa/P_md); **solution-separation (MHSS) RAIM** with fault detection/identification; **ARAIM integrity-risk (P_HMI) budget** (`araim_raim`) that solves the smallest HPL/VPL whose summed `P_HMI = Σ_k p_fault,k·Q((PL−T_k)/σ_k)` meets an explicit integrity-risk allocation, the **dual-/multi-constellation constellation-wide fault mode** (`araim_dual_raim`, EU ARAIM TN / DO-316; `P_const = 0` ⇒ bit-for-bit `araim_raim`), an explicit **integrity support message** (`IntegritySupportMessage`: σ_URA/σ_URE/b_nom/P_sat/P_const, with the WG-C GPS+Galileo reference values), plus a **Stanford(-ESA) integrity-diagram** (the `integrity` scenario kind, and a standalone `stanford_svg` renderer of the four zones + `PL=error` boundary). Documented end-to-end in [`ARAIM_REFERENCE.md`](ARAIM_REFERENCE.md). Plus the scenario FoM's filter self-consistency (k-σ bound) | RAIM is reachable via the `integrity` scenario kind but **not yet folded into the clock/holdover FoM** (those still report self-consistency); the ARAIM budget covers single-SV **and** constellation-wide faults but simultaneous multi-SV-subset faults and **FDE** beyond identification are not modelled, and `araim_dual_raim` is wired into the TOML scenario runner via the `araim_dual` flag (`scenarios/araim-gps-galileo.toml`), with a per-epoch availability path `araim_dual_constellation_availability`; the snapshot/MHSS/ARAIM cores are exercised on **real IGS precise-orbit (SP3) geometry** (`tests/igs_real_data.rs`) and on **real Celestrak GPS+Galileo TLEs** (`tests/araim_dual_real_data.rs`: pooling Galileo lifts availability 0.21→0.67 under a 12 m VAL; the constellation-fault-robust mode is limited with only two constellations); the exact EU-ARAIM-TN Table A-3 / 15–25 % figure against a single version-locked epoch + a Zenodo record remain external; not DO-229/ARAIM-certified | multi-fault ARAIM + receiver-domain gLAB parity + FoM wiring: **P2** (see [`INTEGRITY.md`](INTEGRITY.md)) |
| **Spoofing / jamming threat modelling** | partial | A **stochastic time-spoof detector** (`spoof` kind, `src/spoof.rs` + `src/detection.rs`): four injection shapes (linear ramp, step jump, meaconing, replay) against a clock-aided monitor with a two-sided **χ²₁ energy / Neyman–Pearson test**, the detection threshold set from a target false-alarm budget `P_fa`, and the **missed-detection probability `P_md` reported both closed-form and by Monte-Carlo** (the two agree to a few ×1/√N) — the Security figure of merit is `1 − P_md`. Plus a **link-budget jamming model** (`jamming` kind, `src/jamming.rs`): jammer-to-signal ratio from geometry (free-space path loss + per-direction receive-antenna gain), the standard **anti-jam effective-C/N₀ equation** (despreading processing gain + spectral-separation factor `Q`; Kaplan & Hegarty §9.4), per-satellite loss-of-lock at a configurable tracking threshold, and an `availability_under_jamming` figure of merit over a Walker constellation. Plus a **multi-layer RF/measurement spoof-monitor suite** (`src/spoof_monitors.rs`): a **multi-satellite RAIM-consistency** parity test (`parity_raim_test`, weighted residual SOS vs a χ²(m−4) threshold — and it correctly flags that a common-mode bias is RAIM-invisible), an **AGC monitor** (`AgcMonitor`, received-power excess over the expected floor), a **signal-quality / SQM monitor** (`SqmMonitor`, Early/Late correlator imbalance), and a layer-fusion combiner (`fuse_spoof_layers`). These compose into an **integrated `CombinedSpoofDetector`** whose `evaluate` ingests one epoch of observables (geometry + residuals, AGC power, Early/Late taps) and runs all three layers through the weighted fusion in a single call, returning the per-layer diagnostics; it is exposed as the runnable **`spoof-detect` scenario** (`src/spoof_detect.rs`, CLI / Python / playground reachable, JSON + SVG) and **characterised against the published TEXBAT scenario parameters** (Humphreys et al., ION GNSS 2012; `tests/spoof_texbat_validation.rs`) — reproducing the documented detectability pattern, including the negative results: overpowered ds2 caught by AGC + SQM, matched-power ds3 by SQM alone, position-push ds4 by RAIM, and the carrier-phase-aligned matched-power ds7 left (correctly) to the clock-aided detector | Jamming model is a **link budget** — no multipath, terrain shadowing of the jammer, near/far AGC dynamics, adaptive nulling, or acquisition-vs-tracking hysteresis; the spectral-separation `Q` values are representative, not per-PSD-derived. The clock-aided spoof detector is single-clock; the RF/measurement monitors are now integrated (`CombinedSpoofDetector`) and **characterised against the published TEXBAT scenario *parameters*** (Humphreys et al.); the residual is validation against the **raw** vectors — TEXBAT IQ (which needs an SDR acquisition/tracking front-end kshana does not have, being a simulator, not a receiver) or a licensed Spirent scenario — a documented follow-on | clock-aided + integrated multi-SV-RAIM-consistency + AGC + SQM **combined detector** + TEXBAT-parameter characterisation: **done**; raw-vector (TEXBAT IQ / licensed Spirent) validation: follow-on |
| **Quantum PNT sensor physics** | partial | Most sensors are **published Allan/noise-budget coefficients** (CSAC, optical), **plus a first-principles cold-atom-interferometer (CAI) accelerometer** in `src/inertial/quantum_imu.rs`: the three-pulse Mach–Zehnder phase `Φ = k_eff·a·T²`, quantum projection (shot) noise `σ_Φ = 1/(C√N)`, the derived velocity-random-walk PSD `q_va` the inertial stack consumes, contrast decay, the vibration transfer function `\|H(ω)\|` + white-PSD variance, and now the **Coriolis/rotation** (`coriolis_phase`, equivalent bias `2Ω×v`) and **AC-Stark light-shift** (`ac_stark_phase`, symmetric-cancellation) systematics + a cycle-time **drift sweep** (`cai_drift_sweep`). **Validated against a published device**: the modelled quantum floor lies below — and within ~2 orders of — the 96 nm/s²/√Hz of the Freier et al. 2016 mobile gravimeter (arXiv:1512.05660). Documented in [`QUANTUM.md`](QUANTUM.md) | Wavefront/beam-pointing systematics and Mach–Zehnder fringe-ambiguity resolution not modelled; the exact CARIOQA-PMP / Boeing-AOSense flight-test budgets (need published platform PSDs + per-shot SNR) and a JS playground preset are residual | wavefront systematics + flight-test repro: P2+ ([`QUANTUM-MODELS.md`](QUANTUM-MODELS.md)) |
| **Constellation design** | partial | Synthetic Walker (both analytic Keplerian **and SGP4 mean-element**, the latter propagated through the 4.12 mm-validated core — `src/walker.rs`) + real-TLE multi-constellation visibility & DOP (GPS+Galileo to 100%), validated against a **real Celestrak gps-ops snapshot** (`tests/igs_real_data.rs`); a **PDOP design sweep** over the `{planes × sats × inclination}` grid and **coverage-fraction / revisit-time** figures of merit; a **gradient-free design optimiser** (`optimize_walker_design`) that searches the grid for the best design under a chosen objective (`MinSatellitesForCoverage` / `MaxCoverage` / `MinWorstPdop`), validated to return the brute-force winner; and **analytical streets-of-coverage geometry** (`coverage_half_angle_rad`, `street_half_width_rad`; Rider/Beste closed forms, hand-verified — GPS at a 5° mask: λ ≈ 71.2°, 4-sat street half-width ≈ 62.8°) | The full Rider **minimum-satellite global-coverage solver** (the seam-sensitive plane count) is not yet implemented; no 3-D playground globe view; multi-constellation DOP is not yet cross-checked against an external reference tool (gnss-rtk); geodetic vs geocentric "up" in the DOP frame | streets-of-coverage min-sat solver + 3-D globe + gnss-rtk DOP cross-check: P2 |
| **Verification & validation** | partial | One world-class island (SGP4 vs 666 AIAA vectors); deterministic Allan checks | Golden tests pin few exact numbers; calibration on single seeds (see V&V roadmap) | golden numerics + calibration ensembles: P1 (M17/M18) |
## Broader space-systems domains (out of scope today)
These are **none** — listed so the scope is unambiguous, not implied by silence. Each is
a deliberate non-goal for now; Kshana is a PNT simulator, not GMAT/STK/Orekit.
| Capability | Status | Note / roadmap |
|------------|--------|----------------|
| Mission design / trajectory optimization | partial | `src/maneuver.rs`: impulsive ΔV nodes with 6×6 covariance propagation (ECI/LVLH execution-error frames), finite-burn integration checked against the closed-form **Tsiolkovsky** equation to < 0.01 %, an **Izzo-2015 single-revolution Lambert** solver + an exact universal-variable **Kepler propagator** (Lambert outputs round-tripped against two-body truth), and a **porkchop** (launch × arrival) C3 / arrival-V∞ sweep emitted as a JSON contour grid whose minimum is checked against the analytic Hohmann floor. **No trajectory optimizer, no multi-revolution Lambert, no planetary ephemeris** (the porkchop uses a synthetic coplanar-circular heliocentric model; a GMAT Earth–Mars C3 cross-check needs a shared DE-ephemeris and has not been run) — the performance-simulation layer above GMAT/Orekit, not a replacement. P3 |
| AOCS / GNC / attitude | none | no attitude representation; the IMU "gyro" is a scalar tilt channel |
| Reference frames → Earth-fixed | none | **P1** brings TEME→ECEF/ITRF (listed above under frames) |
| Comms & link budgets | none | no RF/optical link, EIRP/G-T, access scheduling |
| Ground segment & operations | none | no ground-station entity, pass scheduling, or ops timeline |
| Telemetry / TT&C / CCSDS | partial | bespoke TOML-in/JSON-out; **CCSDS OEM (Orbit Ephemeris Message) export** (502.0-B KVN, for GMAT/Orekit/STK); other CCSDS message types (ODM/AEM/TDM) and SPICE interop remain a roadmap item (P2) |
| Interoperability & standards (RINEX/SP3/SPICE/CCSDS) | partial | RINEX 3 **multi-GNSS NAV** — GPS, Galileo, QZSS, BeiDou MEO/IGSO (IS-GPS-200) **and GLONASS** (PZ-90 state-vector RK4) — ingested + propagated + runnable as one mixed constellation; **RINEX 3/4 OBSERVATION parser** (pseudorange/carrier/Doppler/SNR by observation code, with LLI/SSI flags); SP3-c/d precise-ephemeris **read ↔ write round trip** (parse + export for Ginan/RTKLIB/gLAB) **and a 9th-order Lagrange propagator** (`Propagator::Sp3Precise`); SP3 export is **CLI-exposed** (`kshana <orbit.toml> --export-sp3 out.sp3`, or `export_sp3 = true`) and **round-trip-validated** against the real GPS constellation to <0.5 m over 24 h (`tests/sp3_export_roundtrip.rs`); **CCSDS OEM 2.0 ephemeris writer** — the velocity-carrying TEME state export for flight-dynamics tools — now **CLI-exposed** (`kshana <orbit.toml> --export-oem out.oem`, or `export_oem = true`) and round-trip-checked against the propagator state (`tests/sp3_export_roundtrip.rs`). No BeiDou-GEO, no SP3 clock interpolation, no OEM reader, no observation *solution* (parse only), no SPICE/other-CCSDS yet — **P2** "annex adjacent domains via standard formats" |
| Space weather / environment (iono/atmo/radiation) | none | iono/TEC is a known GNSS error source omitted even in the PNT niche; P2+ |
| Gravity-map / alt-PNT navigation | partial | `src/gravimeter.rs`: a cold-atom **gravimeter measurement model** whose white-noise floor is derived from the CAI accelerometer ASD (`σ = ASD/√τ`), a low-degree **fully-normalised spherical-harmonic gravity-anomaly field** (validated against the closed-form Legendre functions and a hand-derived single-term anomaly) plus synthetic **mascons**, and a **gravity-map-matching particle filter** (composing `mapmatch` + `particle_filter`) that recovers a GPS-denied track from the anomaly sequence it flies through. The **60-minute GPS-denied benchmark** (`run_gps_denied_gravity_nav`, `scenarios/gps-denied-gravity-nav.toml`) flies a ~700 km / one-hour outage where the inertial solution drifts to **≈ 70 km**, and a **hierarchical coarse-to-fine** matcher with the gravimeter's deterministic seeded white noise recovers it to **≈ 145 m (< 500 m)** — stable across noise realisations, and provably refinement-limited (a single coarse grid stalls at ~2 km). Plus a **full IGRF-14 geomagnetic main-field model** (`src/igrf.rs`: the IAGA Schmidt-normalised spherical-harmonic field to degree/order 13, 2025.0 + secular variation, coefficients machine-generated from the official `igrf14coeffs.txt`; validated against the closed-form tilted dipole, a finite-difference of the scalar potential, and the known geomagnetic pole/strength) — the magnetic field a platform can map-match for magnetic-anomaly navigation. Plus **terrain-referenced navigation (TERCOM/SITAN)** and the **combined gravity+magnetic+terrain navigator** (`src/altpnt/terrain.rs`): a hand-rolled SRTM `.hgt` digital-elevation-model parser (16-bit signed big-endian, row-major, north-row-first, void -32768; validated against the GDAL SRTMHGT driver spec and a closed-form bilinear-midpoint oracle), a radar/baro **altimeter** model and `run_terrain_nav` matcher that recovers a GPS-denied track from the ground-elevation profile against the DEM, and `run_combined_altpnt` which fuses **three scalar field channels** per waypoint (Δg mGal · |B| nT crustal-anomaly · elevation m) so the joint posterior is sharper (lower CRLB) than any single field — bounded < 500 m over the 60-min outage and, in expectation, no worse than the best single channel. All three are now **scenario-engine `kind=` wired** (`gravity-map`, `terrain-nav`, `combined-altpnt`) with an SVG drift chart (`scenarios/terrain-nav.toml`, `scenarios/combined-altpnt.toml`). **Still missing: the full EGM2008/EIGEN coefficient set and its loader** (the gravity field is low-degree + mascons, not a real high-resolution map), a Monte-Carlo over map-representation-error realisations, and a real high-frequency **crustal** magnetic-anomaly map (the magnetic channel rides on the smooth IGRF main field plus synthetic crustal mascons; the CI terrain field is the self-contained synthetic DEM, with `#[ignore]`-gated real-SRTM-tile checks against published Whitney/Badwater spot-heights via `tools/fetch_srtm_tile.py`). P3 |
| Re-entry / EDL, Launch analysis, EO/payload | none | out of scope |
| Lunar / cislunar PNT (LunaNet) | partial | `src/lunar.rs`: a **lunar ARAIM** engine reusing the Earth-side MHSS core with LunaNet LNIS parameters (σ_URE ≈ 30 m, P_sat ≈ 1e-4), the **MCI↔MCMF cislunar frame reduction** (`mci_to_mcmf` / `mcmf_to_mci`, a simplified mean-rotation model at the sidereal rate) and **selenographic** lat/lon/alt (`mcmf_to_selenographic`), and a **south-pole protection-level pass** (`south_pole_hpl_pass`) that quantifies the integrity gap — with 30 m ranging the HPL is finite but exceeds a 50 m surface-ops alert limit. `src/cr3bp.rs` adds the Earth–Moon **CR3BP** (rotating-frame dynamics + RK4 propagator + Jacobi constant + the five Lagrange points, validated against the published L1/L2/L3 values and the exact L4/L5) — the three-body core a real NRHO needs | The relay geometry is still representative, **not** a differential-corrected 9:2 LANS NRHO (the CR3BP core exists but periodic-NRHO ICs + the de-normalised selenocentric transform are not yet wired in); the MCMF model omits physical libration / the precessing lunar pole (no DE421/SPICE); a runnable `lunar-integrity` scenario kind (`scenarios/lunanet-araim.toml`) exposes the south-pole pass from the CLI | NRHO ICs + SPICE/LunaNet interface: **P3** |
## Ecosystem & readiness (tracked honestly, not a code capability)
| Area | Status | Note |
|------|--------|------|
| Language bindings & packaging | partial | Rust + Python (abi3) + WASM on three registries; string-in/string-out bindings |
| Education / onboarding UX | partial | Browser playground (a real structural white-space); guided mode is roadmap |
| Community / governance | none | single-founder; no Zenodo DOI/JOSS/citations yet (founder-gated outreach) |
| Funding & procurement readiness | none | TRL ~3; no agency citations/contracts yet (see strategy notes) |
_Last aligned with the 2026-06-02 grand audit's 27-row capability matrix._