kshana 0.10.0 → 0.11.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
@@ -6,7 +6,7 @@
6
6
 
7
7
  <p align="center">
8
8
  <strong>क्षण</strong> — Sanskrit for <em>the precise instant</em>, the smallest measure of time.<br>
9
- Open, reproducible hybrid quantum / classical PNT performance simulation.
9
+ Open, reproducible PNT-resilience simulation with published quantum-sensor performance models.
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -22,25 +22,33 @@
22
22
  <p align="center">
23
23
  <strong>Kshana</strong> (क्षण, Sanskrit: <em>"the precise instant"</em>) is an open, reproducible
24
24
  <strong>PNT-resilience simulator with quantum-sensor performance models</strong> —
25
- positioning, navigation, and timing. It compares quantum and classical sensors using
26
- published Allan/noise-budget coefficients; it is not a first-principles quantum-physics
27
- simulator (see <a href="docs/QUANTUM-MODELS.md">docs/QUANTUM-MODELS.md</a>).
25
+ positioning, navigation, and timing. It compares quantum and classical sensors mostly
26
+ from published Allan/noise-budget coefficients, with a first-principles cold-atom-
27
+ interferometer accelerometer layer (Mach–Zehnder phase, quantum projection noise,
28
+ contrast decay, and vibration coupling) that <em>derives</em> the noise coefficient
29
+ rather than looking it up; it is not yet a full quantum-physics simulator (Coriolis and
30
+ light-shift systematics remain coefficient-level — see
31
+ <a href="docs/QUANTUM.md">docs/QUANTUM.md</a> and
32
+ <a href="docs/QUANTUM-MODELS.md">docs/QUANTUM-MODELS.md</a>).
28
33
  </p>
29
34
 
30
35
  It quantifies, in hard and reproducible numbers, what quantum clocks, quantum
31
36
  inertial sensors, and optical time-transfer buy a navigation system over classical
32
37
  PNT — scored against the operational figures of merit that matter for resilient
33
38
  navigation. Every result is reproducible from `scenario + seed + engine version`,
34
- and every sensor parameter is traceable to a published source.
39
+ and every sensor parameter is traceable to a published source — consolidated in one
40
+ citable table in [`docs/PROVENANCE.md`](docs/PROVENANCE.md).
35
41
 
36
42
  *Free and open source under Apache-2.0, professionally developed and maintained by
37
43
  Ashforde OÜ — commercial support, integration, and proprietary extensions available.*
38
44
 
39
- > **Status: v0.10.0 · a simulation substrate, not yet a product.** A validated,
40
- > fully reproducible engine spanning the PNT stack — orbit geometry, inertial
41
- > navigation, GNSS/INS fusion, integrity, clocks, and timing. Honest by design:
42
- > every figure of merit is labelled *validated* or *not-modeled*, and optical-clock
43
- > figures are space goals on ground hardware (no strontium optical clock has flown).
45
+ > **Status: v0.11.0 · a simulation substrate, not yet a product.** A validated,
46
+ > fully reproducible engine spanning the PNT stack — orbit geometry and constellation
47
+ > design, time systems, inertial navigation (incl. map-aided), GNSS/INS fusion (loose,
48
+ > tight, UKF, coupled clock+position), ARAIM integrity, clocks, advanced time-and-frequency
49
+ > transfer, the GNSS measurement domain, and resilience (jamming + multi-layer spoofing).
50
+ > Honest by design: every figure of merit is labelled *validated* or *not-modeled*, and
51
+ > optical-clock figures are space goals on ground hardware (no strontium optical clock has flown).
44
52
  > See **[Capabilities](#capabilities)** for what it does, **[What it is / is not](#what-it-is--is-not)**
45
53
  > for scope, and [`docs/CAPABILITY.md`](docs/CAPABILITY.md) / [`docs/VALIDATION.md`](docs/VALIDATION.md)
46
54
  > for per-capability maturity and the claims table.
@@ -97,17 +105,30 @@ receiver, or a certified avionics product. Quantum-hardware fidelity comes from
97
105
  published error models, not from this tool. The granular maturity of each
98
106
  capability is documented in [`docs/CAPABILITY.md`](docs/CAPABILITY.md).
99
107
 
108
+ **It is not (yet):** a *full* atom-interferometry physics engine (most quantum sensors
109
+ consume published Allan/noise-budget coefficients; the CAI accelerometer has a
110
+ first-principles layer — Mach–Zehnder phase, projection noise, contrast decay, and
111
+ vibration coupling — but Coriolis and light-shift systematics remain a **P2** roadmap
112
+ layer, see [`ROADMAP.md`](ROADMAP.md) and [`docs/QUANTUM-MODELS.md`](docs/QUANTUM-MODELS.md));
113
+ a GNSS receiver or PVT solver (it models the measurement domain and resilience, not
114
+ signal acquisition or a least-squares fix); or a mission-design / orbit-determination
115
+ tool. Owning this scope is deliberate. If you need first-principles cold-atom
116
+ interferometer error budgets (e.g. CARIOQA-PMP-grade or X-37B-style validation), see
117
+ the P2 roadmap and [get in touch](#support--professional-services) to collaborate.
118
+
100
119
  ## Capabilities
101
120
 
102
121
  | Domain | Capability |
103
122
  |--------|------------|
104
- | **Orbit & geometry** | SGP4/SDP4 propagation (validated to 4.12 mm against all 666 AIAA 2006-6753 vectors), real-TLE or synthetic Walker constellations, multi-constellation visibility, dilution of precision, and GNSS availability. |
105
- | **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). |
106
- | **Fusion** | Loosely-coupled GNSS/INS error-state EKF (15-state) with closed-loop feedback that coasts through GNSS outages on a calibrated inertial solution. |
107
- | **Integrity** | Snapshot and solution-separation (ARAIM-style) RAIM with horizontal/vertical protection levels (HPL/VPL) including levels solved from an explicit ARAIM integrity-risk (P_HMI) budget fault detection and identification, and Stanford integrity diagrams. |
108
- | **Clock & timing** | Two-state Kalman holdover, Allan-family stability (ADEV/MDEV/TDEV/HDEV) with confidence intervals, and optical/RF two-way time transfer. |
109
- | **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 propagation), usable as a constellation source that drives a scenario directly (RINEX in, PNT geometry out); RINEX-3/4 observation-file parser (pseudorange, carrier phase, Doppler, and signal strength by observation code); SP3-c/d precise-ephemeris reader/writer for IGS/analysis-centre orbit products, with 9th-order Lagrange interpolation that turns a precise-orbit file into a propagation source; CCSDS OEM 2.0 (Orbit Ephemeris Message) writer that exports a propagated constellation in the standard format flight-dynamics tools (GMAT, Orekit, STK) ingest. |
110
- | **Resilience** | Clock-aided spoof-detectability analysis against a configurable time-spoof attack. |
123
+ | **Orbit & geometry** | SGP4/SDP4 propagation (validated to 4.12 mm against all 666 AIAA 2006-6753 vectors); real two-line elements (a committed, date-stamped Celestrak `gps-ops` snapshot) or synthetic Walker-delta constellations whose mean elements realise the `i:T/P/F` formula to under 1 km over a 24 h propagation; multi-constellation visibility, dilution of precision, and GNSS availability; a gradient-free constellation-design optimiser, streets-of-coverage minimum-satellite sizing, a multi-constellation comparison tool, and a Walker **design sweep** that tabulates coverage / PDOP / revisit-time over a planes × satellites grid and reports the Pareto-optimal designs. |
124
+ | **Time systems** | IERS leap-second **UTC / TAI / TT / UT1** scales, a Julian-date API, the IAU-2000 **Earth Rotation Angle**, and GMST-based **TEME ↔ ECEF** with WGS-84 geodetic frames — plus IAU 2006 precession (Fukushima–Williams) toward an ITRF-precise reduction. |
125
+ | **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. |
126
+ | **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; and 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. |
127
+ | **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). |
128
+ | **Clock & timing** | Two-state Kalman holdover (Joseph-form covariance, NIS/NEES consistency health); Allan-family stability (ADEV / MDEV / TDEV / HDEV) with noise-type-specific confidence intervals and a full **IEEE-1139 five-coefficient power-law fit**; geometric corrections (Sagnac, GNSS common-view); and the operational transfer methods **TWSTFT** with the BIPM Sagnac closed form, **GNSS common-view**, **PPP** ionosphere-free time transfer, a free-space **optical** link with turbulence scintillation, and an inverse-variance **clock-ensemble (paper) timescale** below the best contributing clock. |
129
+ | **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). |
130
+ | **Resilience** | Link-budget **jamming** (J/S → effective C/N₀ → loss of lock); a stochastic **time-spoof detector** (Neyman–Pearson / χ²₁ energy test with closed-form and Monte-Carlo P_fa/P_md and a Security FoM of 1 − P_md); and a **multi-layer spoof detector** fusing a RAIM-consistency parity test (with the common-mode blind spot modelled honestly), an RF AGC-power monitor, and a signal-quality (SQM early-minus-late) monitor. |
131
+ | **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); 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). |
111
132
 
112
133
  Each capability is reachable as a Rust API, a runnable scenario `kind`, or both.
113
134
  Maturity per capability — *validated*, *runnable*, or *library* — is tracked in
@@ -148,7 +169,12 @@ The constellation can also be given as real two-line element sets. A *full* TLE
148
169
  (line 1 + line 2) is propagated with the full **SGP4/SDP4** model — including
149
170
  atmospheric drag and the deep-space lunar-solar and 12 h / 24 h resonance terms that
150
171
  matter for ~12 h GNSS orbits — validated against the official AIAA 2006-6753 vectors
151
- to a worst-case ≈ 4 mm (`scenarios/orbit-sgp4-gps.toml`). A line-2-only block keeps
172
+ to a worst-case ≈ 4 mm. `scenarios/orbit-sgp4-gps.toml` ships a **real Celestrak
173
+ `gps-ops` snapshot** of the operational GPS constellation (2021-07-28, 30 satellites)
174
+ and requires valid TLE checksums — two-line element sets are open data from the US
175
+ Space Force / 18th Space Defense Squadron catalogue, redistributed by Celestrak
176
+ (Dr T. S. Kelso, [celestrak.org](https://celestrak.org)); refresh with
177
+ `scripts/fetch_tles.sh`. A line-2-only block keeps
152
178
  the analytic two-body propagation (`scenarios/orbit-real-tle.toml`); the two forms can
153
179
  be mixed in one constellation. A constellation can equally be built from a block of
154
180
  **RINEX-3 GPS broadcast-ephemeris** records — the format a receiver decodes —
@@ -180,8 +206,19 @@ cargo run -- scenarios/orbit-gnss-challenged.toml
180
206
  cargo run -- scenarios/orbit-sgp4-gps.toml
181
207
  cargo run -- scenarios/orbit-rinex.toml
182
208
  cargo run -- scenarios/integrity-raim.toml
209
+
210
+ # Export a propagated constellation to an SP3-c precise-ephemeris file:
211
+ cargo run -- scenarios/orbit-sgp4-gps.toml --export-sp3 gps.sp3
183
212
  ```
184
213
 
214
+ **Interoperability role.** Kshana is the *performance-simulation* layer that sits
215
+ alongside the post-processing toolchain, not a replacement for it: feed its **RINEX**
216
+ output into RTKLIB or gLAB for a position solution, and use its **SP3** output as a
217
+ precise-orbit product for tools like Ginan — Kshana answers *what resilience a given
218
+ PNT architecture buys* before you have real signals, in formats those tools already
219
+ ingest (`--export-sp3`, or `export_sp3 = true` in an `orbit` scenario, writes
220
+ `<scenario>.sp3`).
221
+
185
222
  Example output (clock holdover — note the Integrity and Security figures of merit):
186
223
 
187
224
  ```
@@ -250,8 +287,9 @@ console.log(version(), result.classical.fom.timing_p95_ns);
250
287
 
251
288
  ## Scenario format
252
289
 
253
- Scenarios are declarative TOML. A top-level `kind` selects the pack
254
- (`clock` is the default if omitted; `inertial`, `timetransfer`, `hybrid`, `orbit`).
290
+ Scenarios are declarative TOML. A top-level `kind` selects the pack (`clock` is
291
+ the default if omitted; `inertial`, `timetransfer`, `hybrid`, `fusion`,
292
+ `gnss-ins`, `orbit`, `gnss-sim`, `integrity`, `spoof`, `jamming`, `sweep`, `sweep-nd`).
255
293
  Common fields: `seed`, a `[time]` grid, a `[gnss]` availability timeline (the outage
256
294
  driver), and per-sensor blocks with `provenance` strings citing the source of every
257
295
  figure. Example (clock):
@@ -294,9 +332,13 @@ quaternion attitude with coning/sculling compensation, a full NED mechanization
294
332
  (Earth-rate and transport-rate terms, WGS-84 Somigliana gravity), and a
295
333
  deterministic IMU error model in which **scale-factor, misalignment,
296
334
  g-sensitivity, quantization, and rate-ramp are modelled** (IEEE Std 952-1997
297
- §A.2; Groves 2013 §4.3). That 3-axis path is **not yet wired into the scenario
298
- pack/FoM** switching the pack over, with a loosely-coupled GNSS/INS filter, is
299
- the next inertial milestone. A
335
+ §A.2; Groves 2013 §4.3). That 3-axis path is now **wired into a runnable
336
+ loosely-coupled GNSS/INS pack** (`kind = "gnss-ins"`): a 15-state error-state EKF
337
+ disciplines the strapdown solution against noisy fixes while GNSS is up, then
338
+ coasts through the outage, reporting the fused horizontal error against the
339
+ open-loop free-INS coast. A **tightly-coupled pseudorange** update is also
340
+ available (it forms the innovation in the range domain, so it keeps correcting
341
+ with fewer than four satellites). A
300
342
  clock-holdover scenario may add `runs` (> 1) to run a **Monte Carlo ensemble** — each
301
343
  figure of merit is then reported as a mean with a 5th–95th-percentile spread and the
302
344
  chart shades the error confidence band (see `scenarios/clock-ensemble.toml`).
@@ -308,10 +350,39 @@ cross-covariance: this is a stacked pair of error budgets, **not** a true couple
308
350
  clock+position joint filter (cross-block covariance is a roadmap item). See
309
351
  `scenarios/fusion-pnt.toml`.
310
352
 
311
- A `spoof` scenario injects a ramping false-time spoof (an `[attack]` block with
312
- `start_s` and `rate_ns_per_s`) and runs each clock's integrity monitor, reporting
313
- whether and when the spoof is detected and whether it reaches the spec undetected a
314
- concrete demonstration of the Security figure of merit (see `scenarios/spoof-attack.toml`).
353
+ A `spoof` scenario injects a time-spoof one of four `[attack.shape]` kinds
354
+ (`linear_ramp`, `step_jump`, `meaconing`, `replay`; a bare `rate_ns_per_s` is still
355
+ accepted as a linear ramp) and runs each clock's spoof detector. The detector is a
356
+ two-sided **χ²₁ energy / Neyman–Pearson test** on the clock-aided monitor statistic:
357
+ the threshold is set from a target false-alarm budget `target_pfa`, and the
358
+ **missed-detection probability `P_md`** is reported both closed-form and by
359
+ Monte-Carlo (`mc_runs` trials per hypothesis — the two agree to a few ×1/√N). The
360
+ **Security figure of merit is `1 − P_md`** at the operationally-harmful (spec)
361
+ magnitude, so a quiet clock that catches a spec-sized spoof scores ≈ 1 and a noisy
362
+ one that often misses it scores lower (see `scenarios/spoof-attack.toml`,
363
+ `scenarios/spoof-meaconing.toml`).
364
+
365
+ A `gnss-sim` scenario is a **measurement-domain** simulation: for each visible
366
+ satellite it synthesises the pseudorange `ρ = geometric range + c·δt_rx − c·δt_sv +
367
+ I + T + noise + multipath` and the L1 Doppler, with the **Klobuchar** single-frequency
368
+ ionosphere (`[iono]`, IS-GPS-200 §20.3.3.5.2.5) and the **Saastamoinen** zenith
369
+ troposphere projected by the **Niell (1996)** mapping function (`[tropo]`). The
370
+ residuals feed **snapshot RAIM** for per-epoch HPL/VPL, and every satellite's
371
+ pseudorange, Doppler, C/N₀, and iono/tropo corrections are emitted in the JSON
372
+ `gnss_measurements` array. It is a forward simulator (it generates measurements from
373
+ a known truth), not a receiver/solver — a zero-noise run reproduces geometry plus the
374
+ corrections to sub-millimetre (see `scenarios/gnss-sim-raim.toml`).
375
+
376
+ A `jamming` scenario models RF interference as a **link budget**: a `[jammer]`
377
+ (ECEF position, transmit `power_dbw`, type) raises the jammer-to-signal ratio at a
378
+ `[receiver]` watching a Walker `[constellation]`. From the geometry (free-space
379
+ path loss and the per-direction receive-antenna gain) it computes each satellite's
380
+ `J/S`, the **effective C/N₀** via the standard anti-jam equation (despreading
381
+ processing gain × the spectral-separation factor `Q`; Kaplan & Hegarty §9.4), and
382
+ flags loss of lock below a configurable tracking threshold — reporting an
383
+ `availability_under_jamming` figure of merit. A 10 W broadband jammer at 1 km
384
+ denies the receiver entirely (J/S ≈ 72 dB); the same jammer at 100 km only
385
+ degrades the links (see `scenarios/jamming-demo.toml`).
315
386
 
316
387
  A `sweep` scenario runs a **trade study**: it varies one `parameter` (`threshold_ns`,
317
388
  `duration_s`, `quantum_q_wf`, or `classical_q_wf`) from `start` to `stop` over `steps`
@@ -319,6 +390,14 @@ points on a `lin` or `log` `scale`, records a `metric` (e.g. `holdover_s`) for b
319
390
  clocks, and charts the two curves. The base scenario goes under `[base]` (see
320
391
  `scenarios/sweep-clock-stability.toml`).
321
392
 
393
+ A `sweep-nd` scenario generalises this to **any pack and any number of axes**: it
394
+ varies dotted TOML keys of a `[base]` scenario (of any `kind`) over the Cartesian
395
+ product of `[[axes]]`, re-runs each grid node, and records `metrics` given as
396
+ dotted JSON paths into the result (e.g. `classical.fom.holdover_s`). It works for
397
+ every pack because it operates at the TOML/result boundary; native runs evaluate
398
+ the grid in parallel (no extra dependency, wasm falls back to sequential) and the
399
+ output is deterministic and row-major (see `scenarios/sweep-nd-inertial.toml`).
400
+
322
401
  An `orbit` scenario derives the `[gnss]` timeline from geometry instead of authoring
323
402
  it — give a `[user]` orbit, a `[constellation]`, an elevation `mask_deg`, and the two
324
403
  clock blocks. It also reports position accuracy from the satellite geometry; the
@@ -360,10 +439,13 @@ See `scenarios/` for one example of every kind.
360
439
  The result artifact is versioned, self-describing JSON: per-step time series, the
361
440
  scored figures of merit, the active model specs (with provenance), the seed, a
362
441
  **scenario hash** — so any chart can be reproduced from the file — and, for each clock,
363
- an `adev_curve` (`[{tau_s, adev, n_samples}]`): the overlapping Allan deviation across
364
- octave-spaced averaging times, the standard way to read a clock's stability. The
365
- browser playground renders it as a log-log "Clock stability (ADEV)" chart. (MDEV/TDEV/HDEV
366
- and confidence intervals are not yet computed roadmap.) Every field, with units and a
442
+ an `adev_curve` (`[{tau_s, adev, n_samples, noise, edf, ci_lo, ci_hi}]`): the overlapping
443
+ Allan deviation across octave-spaced averaging times the standard way to read a clock's
444
+ stability now with a **noise-type-specific 95% confidence band** per point (the record's
445
+ power-law type is identified from its modified-Allan slope, and the χ² interval uses the
446
+ matching NIST SP 1065 effective degrees of freedom). The browser playground renders it as a
447
+ log-log "Clock stability (ADEV)" chart. (MDEV, TDEV, and HDEV are available as library
448
+ estimators; the exported result curve is the overlapping ADEV.) Every field, with units and a
367
449
  source pointer, is documented in [`docs/SCHEMA.md`](docs/SCHEMA.md). The figures of
368
450
  merit follow the standard operational PNT figures of merit:
369
451
 
@@ -467,6 +549,7 @@ kshana/
467
549
  | [Glossary](docs/GLOSSARY.md) | everyone | plain-language definitions of every term |
468
550
  | [Architecture](docs/ARCHITECTURE.md) | developers / reviewers | module map, engine pipeline, dispatch, and diagrams |
469
551
  | [Validation status](docs/VALIDATION.md) | reviewers / citers | what is `validated` vs `not modeled`, with evidence |
552
+ | [Provenance](docs/PROVENANCE.md) | reviewers / citers | every sensor parameter, model, and dataset traced to its published source, in one citable table |
470
553
  | [Reproducibility &amp; provenance](docs/REPRODUCIBILITY.md) | reviewers / packagers | determinism guarantees, golden-pinning, SBOM, build provenance |
471
554
  | [Positioning](docs/POSITIONING.md) | evaluators | where Kshana sits vs RTKLIB/gLAB (complementary), and the zero-install browser tier |
472
555
  | [SGP4 validation](docs/SGP4-VALIDATION.md) | reviewers / citers | agreement with the AIAA 2006-6753 reference (666 states, ~4 mm) |
@@ -542,15 +625,25 @@ CPython versions).
542
625
 
543
626
  ## Roadmap
544
627
 
545
- See [`CHANGELOG.md`](CHANGELOG.md) for released history and the `[Unreleased]`
546
- section for what's next (Earth-fixed frame reduction — TEME&rarr;ECEF/ITRF and
547
- explicit time systems: UTC/UT1/TAI/TT with leap seconds). SGP4/SDP4 orbit
548
- propagation has **shipped** (v0.7.0, validated against the AIAA 2006-6753 vectors),
549
- and its inertial velocity is now exposed downstream. An active
550
- spoofing-attack demonstrator, multi-constellation availability, a single-axis (1-DOF)
628
+ See [`ROADMAP.md`](ROADMAP.md) for the phased roadmap, [`CHANGELOG.md`](CHANGELOG.md)
629
+ for released history, and [`docs/CAPABILITY.md`](docs/CAPABILITY.md) for the
630
+ per-capability roadmap. Near-term items include **ITRF-precise frame reduction**
631
+ (polar motion and sub-arcsecond nutation on top of the shipped GMST-based
632
+ TEME&harr;ECEF), two-part Julian dates, tightly-coupled carrier-phase fusion, and
633
+ surfacing the loosely-/tightly-coupled GNSS/INS navigator across more packs. The
634
+ **quantum physics layer** is a **P2** item: the CAI accelerometer is now simulated from
635
+ first principles (Mach–Zehnder phase, projection noise, contrast decay, vibration
636
+ coupling), while the clock/time-transfer sensors are still driven by published
637
+ Allan/noise-budget coefficients. GMST-based TEME&harr;ECEF, the IERS
638
+ leap-second time systems (UTC/TAI/TT/UT1), SGP4/SDP4 orbit propagation (v0.7.0,
639
+ validated against the AIAA 2006-6753 vectors), and the runnable `gnss-ins` fusion
640
+ pack have all **shipped**, and the inertial velocity is exposed downstream. An active
641
+ stochastic time-spoof detector (Neyman–Pearson / χ²₁ energy test with Monte-Carlo
642
+ P_fa/P_md and a Security FoM of 1−P_md), a link-budget jamming model (J/S → effective
643
+ C/N₀ → loss of lock), multi-constellation availability, a single-axis (1-DOF)
551
644
  IMU error budget, two independent (clock + position) Kalman estimators reported as a
552
- combined FoM, real constellation geometry from TLEs, an HTML scorecard report, a
553
- clock-stability-based spoof-detectability bound, geometry-derived GNSS availability
645
+ combined FoM, real constellation geometry from TLEs, an HTML scorecard report,
646
+ geometry-derived GNSS availability
554
647
  *and* dilution of precision from Keplerian orbits with eccentricity and J2 drift,
555
648
  Monte Carlo confidence bands, trade-study parameter sweeps, an in-browser WebAssembly
556
649
  playground, and optional Python (PyO3) and WebAssembly (wasm-bindgen) bindings have
@@ -568,12 +661,12 @@ entry for every user-visible change. Participation is governed by our
568
661
 
569
662
  If you use Kshana in academic or technical work, please cite it. Machine-readable
570
663
  metadata is in [`CITATION.cff`](CITATION.cff) (GitHub renders a "Cite this repository"
571
- button from it); cite the version you used (e.g. `v0.10.0`) together with the
664
+ button from it); cite the version you used (e.g. `v0.11.0`) together with the
572
665
  scenario and seed for full reproducibility. Every release is archived on Zenodo with
573
666
  a citable DOI — the concept DOI [10.5281/zenodo.20528627](https://doi.org/10.5281/zenodo.20528627)
574
667
  always resolves to the latest version.
575
668
 
576
- > Baweja, C. (2026). *Kshana — hybrid quantum/classical PNT performance simulator*. Ashforde OÜ. https://doi.org/10.5281/zenodo.20528627
669
+ > Baweja, C. (2026). *Kshana — a PNT-resilience simulator with quantum-sensor performance models*. Ashforde OÜ. https://doi.org/10.5281/zenodo.20528627
577
670
 
578
671
  ## Versioning & releases
579
672
 
package/kshana.d.ts CHANGED
@@ -6,6 +6,30 @@
6
6
  */
7
7
  export function chart_svg(toml: string): string;
8
8
 
9
+ /**
10
+ * Decode a permalink token back into the scenario TOML; returns an empty string if the
11
+ * token is not valid Base64 or not valid UTF-8.
12
+ */
13
+ export function decode_permalink(token: string): string;
14
+
15
+ /**
16
+ * Encode a scenario TOML into a URL-safe permalink token for a `?s=` query parameter.
17
+ */
18
+ export function encode_permalink(toml: string): string;
19
+
20
+ /**
21
+ * Run a scenario; on failure return the structured error *kind* tag
22
+ * (`invalid_input`, `unsupported`, …) so the caller can branch on the failure
23
+ * category rather than parse the message. Returns an empty string on success.
24
+ */
25
+ export function error_kind(toml: string): string;
26
+
27
+ /**
28
+ * List the available scenario kinds and their metadata as a JSON array (name,
29
+ * description, required and optional fields), for programmatic introspection.
30
+ */
31
+ export function list_kinds(): string;
32
+
9
33
  /**
10
34
  * Run a scenario given as a TOML string; returns the result document as a JSON
11
35
  * string. Throws a JS error if the scenario is invalid.
@@ -27,6 +51,10 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
27
51
  export interface InitOutput {
28
52
  readonly memory: WebAssembly.Memory;
29
53
  readonly chart_svg: (a: number, b: number) => [number, number, number, number];
54
+ readonly decode_permalink: (a: number, b: number) => [number, number];
55
+ readonly encode_permalink: (a: number, b: number) => [number, number];
56
+ readonly error_kind: (a: number, b: number) => [number, number];
57
+ readonly list_kinds: () => [number, number];
30
58
  readonly run: (a: number, b: number) => [number, number, number, number];
31
59
  readonly summary: (a: number, b: number) => [number, number, number, number];
32
60
  readonly version: () => [number, number];
package/kshana.js CHANGED
@@ -26,6 +26,87 @@ export function chart_svg(toml) {
26
26
  }
27
27
  }
28
28
 
29
+ /**
30
+ * Decode a permalink token back into the scenario TOML; returns an empty string if the
31
+ * token is not valid Base64 or not valid UTF-8.
32
+ * @param {string} token
33
+ * @returns {string}
34
+ */
35
+ export function decode_permalink(token) {
36
+ let deferred2_0;
37
+ let deferred2_1;
38
+ try {
39
+ const ptr0 = passStringToWasm0(token, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
40
+ const len0 = WASM_VECTOR_LEN;
41
+ const ret = wasm.decode_permalink(ptr0, len0);
42
+ deferred2_0 = ret[0];
43
+ deferred2_1 = ret[1];
44
+ return getStringFromWasm0(ret[0], ret[1]);
45
+ } finally {
46
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Encode a scenario TOML into a URL-safe permalink token for a `?s=` query parameter.
52
+ * @param {string} toml
53
+ * @returns {string}
54
+ */
55
+ export function encode_permalink(toml) {
56
+ let deferred2_0;
57
+ let deferred2_1;
58
+ try {
59
+ const ptr0 = passStringToWasm0(toml, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
60
+ const len0 = WASM_VECTOR_LEN;
61
+ const ret = wasm.encode_permalink(ptr0, len0);
62
+ deferred2_0 = ret[0];
63
+ deferred2_1 = ret[1];
64
+ return getStringFromWasm0(ret[0], ret[1]);
65
+ } finally {
66
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Run a scenario; on failure return the structured error *kind* tag
72
+ * (`invalid_input`, `unsupported`, …) so the caller can branch on the failure
73
+ * category rather than parse the message. Returns an empty string on success.
74
+ * @param {string} toml
75
+ * @returns {string}
76
+ */
77
+ export function error_kind(toml) {
78
+ let deferred2_0;
79
+ let deferred2_1;
80
+ try {
81
+ const ptr0 = passStringToWasm0(toml, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
82
+ const len0 = WASM_VECTOR_LEN;
83
+ const ret = wasm.error_kind(ptr0, len0);
84
+ deferred2_0 = ret[0];
85
+ deferred2_1 = ret[1];
86
+ return getStringFromWasm0(ret[0], ret[1]);
87
+ } finally {
88
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
89
+ }
90
+ }
91
+
92
+ /**
93
+ * List the available scenario kinds and their metadata as a JSON array (name,
94
+ * description, required and optional fields), for programmatic introspection.
95
+ * @returns {string}
96
+ */
97
+ export function list_kinds() {
98
+ let deferred1_0;
99
+ let deferred1_1;
100
+ try {
101
+ const ret = wasm.list_kinds();
102
+ deferred1_0 = ret[0];
103
+ deferred1_1 = ret[1];
104
+ return getStringFromWasm0(ret[0], ret[1]);
105
+ } finally {
106
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
107
+ }
108
+ }
109
+
29
110
  /**
30
111
  * Run a scenario given as a TOML string; returns the result document as a JSON
31
112
  * string. Throws a JS error if the scenario is invalid.
package/kshana_bg.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -4,8 +4,8 @@
4
4
  "collaborators": [
5
5
  "Chakshu Baweja <contact@ashforde.org>"
6
6
  ],
7
- "description": "Open hybrid quantum/classical PNT performance simulator",
8
- "version": "0.10.0",
7
+ "description": "Open, reproducible PNT-resilience simulator with quantum-sensor performance models",
8
+ "version": "0.11.0",
9
9
  "license": "Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",