
Connects Claude to the Kshana PNT-resilience simulator, a validated engine for positioning, navigation, and timing scenarios. You get orbital propagation (SGP4 passing all 666 AIAA test vectors), inertial navigation, GNSS/INS fusion (loose, tight, UKF), and clock models including quantum sensor performance from published Allan coefficients. Run GNSS-outage scenarios from a prompt, compare quantum versus classical sensor drift, get reproducible JSON results scored against operational figures of merit. Useful when you're prototyping resilient-nav concepts, exploring alternate-PNT architectures, or need a conversational interface to orbit geometry and sensor fusion without writing scenario boilerplate. The underlying engine is Apache 2.0, professionally maintained, with ~97% test coverage and a brutally honest claims-versus-reality ledger.
Sponsors
Kshana · क्षण · the precise instant
An open-source simulator for PNT (positioning, navigation and timing) resilience.
Open Kshana Studio · Install · Capabilities · Evidence · Research · Documentation · Cite
Languages: English ·
Nederlands ·
Polski ·
Português (Brasil) ·
Português (Portugal) ·
Suomi ·
Svenska ·
Dansk ·
Norsk bokmål ·
Čeština ·
Українська ·
Русский ·
Deutsch ·
Français ·
Español ·
Eesti ·
日本語 ·
简体中文
The command line, run summaries, charts and reports speak each language with --lang <tag>
(for example kshana scenarios/holdover-test-example.toml --lang de), and so do the Python, WebAssembly and MCP surfaces.
Each name opens this README in that language, and the website is translated too (for example kshana.dev/de/).
These are machine translations that no native speaker has reviewed yet; English is the reference.
See Localisation.
Kshana replays jamming, spoofing and clock holdover when GNSS (Global Navigation Satellite System) signals fail, and tells you how long a system keeps time and position inside its budget, and which clock or sensor buys the most margin. It is one Rust engine. It runs in a terminal, a notebook, an IDE (integrated development environment), an AI (artificial intelligence) assistant, or in your browser.
Every run is reproducible bit for bit from the scenario, the seed and the engine version. Every capability carries one of three labels in a machine-checked ledger: VALIDATED (an independent external oracle agrees), MODELLED (internally consistent, and said out loud) or PARTNER (a hardware partner owns it).
Status: v0.40.0. A validated, reproducible simulation substrate for PNT resilience. Timing and holdover come first, because that domain is the best validated. Kshana is a study and trade-off instrument: not radio-frequency (RF) signal-generator hardware (it drives no radio and transmits nothing; its signal-level output is baseband IQ sample files for software receivers), not a hardware or certified GNSS receiver (its software receiver is an analysis tool) and not a flight product. New to the field? Start with the plain-language primer and the glossary.
0.40 adds a mission-level error budget, labels every figure and table with its evidence tier, reads measured clock logs, checks data-partner submissions, estimates where an interference emitter can be, and speaks seventeen languages beside English. The ledger is now 401 rows: 176 VALIDATED, 221 MODELLED, 4 PARTNER. No row was promoted to VALIDATED, and every miss below is pinned by a test.
mission-thread kind chains phases from launch to entry (launch-ascent, leo-rendezvous,
tli-and-cruise, entry and four lunar kinds) with stated handover rules, a margin against stated requirements and the weakest
link; an end-to-end Artemis-class example over 11 phases (Earth and lunar segments), 92 scenario kinds in all. Every number is MODELLED. The cislunar propagation against the public Artemis I trajectory
misses its pre-registered bar (45.3 km and 0.25 m/s against 5 km and 0.05 m/s; the cause is small manoeuvres the model does not include), and the lunar propagator against the CAPSTONE
orbit misses (136.8 km against 25 km at the end of one revolution); the LRO comparison is met. The rows stay MODELLED
(Mission thread, lunar segment). In the Studio the thread is read at /studio/mission-thread/.docs/CLOCK-LOG-FORMATS.md) and a fitted
series can drive the holdover. Against pre-registered bars the fit misses F1(a) on five of six records and F2 on one; both
stay MODELLED (Changelog).kshana partner check checks the format of a submission and scores nothing (docs/PARTNER-DATA.md).kshana interference-map locate gives a region and an ellipse, never a bare point, from ADS-B or AIS
reports. Compared once with the Jammertest 2025 transmitter sites, the result is NOT ASSESSABLE for both sources (too few
scheduled sessions in the open data), so the row stays MODELLED (Interference map).docs/i18n.md).0.39 adds no feature and changes no result; the engine's output is the 0.38 output. It fixes one thing on the command line, updates dependencies of the cross-validation tooling, and states the benchmark verdicts in full.
kshana kinds | head (any closed standard output) no longer panics: the program exits
quietly with status 141, as other tools do for a closed pipe. Other write errors still report themselves.memmap2 0.9.11 in the two ANISE cross-check locks and pillow 13.0.0 and
certifi 2026.10.19 in the oracle environment pins, all under xval/: nothing that ships changed.agc_k_sigma AUC 0.766 against at least 0.80), D1 (largest gap 0.0301) and task (b) R1 (carried,
not re-run). No bar was loosened (Bench).0.38 makes the neutral referee measurable: it scores receiver logs against a published test schedule, reads more receivers and sensors, tests timing systems, and ships a benchmark and an interference observatory. It stays advisory: nothing here is certified, no result is a type approval, and nothing transmits. Each row states what the ledger holds for it (how a label is earned); a status names only what was checked, and the ledger row and the linked page say what was not.
| New in 0.38 | What it does, and why | Ledger status | Read |
|---|---|---|---|
| Jammertest scoring | kshana jammertest import reads the published NPRA test catalogue and transmission plan as scheduled truth; jammertest score scores a receiver log per test (detection latency, missed alarms, false alarms, time to recover), as a signed evidence pack if you give a key | MODELLED: one ledger row. The bars were pre-registered before any scored run; on the JammerTest 2024 data the minimum-data rule failed in both runs (4 and 7 scorable windows against 10 required), so no bar is assessable and nothing is claimed | Jammertest |
| The receiver's own flags | UBX-NAV-STATUS spoofDetState, UBX-SEC-SIG and NovAtel RXSTATUS read into a per-epoch self_report and compared with Kshana's alarms (both, receiver only, Kshana only, neither); a Septentrio SBF reader and read-only --serial input | MODELLED; agreement between a receiver's detector and Kshana's is not validation | Receiver trust |
| More receivers and sensors | RTKLIB .pos, NovAtel OEM7, RTCM 3 MSM4/MSM7 C/N0 (from the BSD-licensed pyrtcm tables, not the RTCM text), GNSS-SDR monitor streams, an IMU log as a second sensor, a ROS 2 package, a gnss_lib_py bridge, and imu-fit for hybrid sensor parameters | MODELLED: six ledger rows; self-written fixtures only, no capture from a real receiver, IMU, GNSS-SDR run or ROS graph was read | Machine inputs |
| Timing and holdover tests | the holdover-test kind scores a holdover test (GNSS removed by the operator, holdover, recovery) from a measured time-error record against ITU-T masks, "measured against the mask"; linuxptp and chrony log readers; the hardware stages and the lab-attestation field | MODELLED: two ledger rows; the times are the operator's statement, not verified | Timing HIL, Hardware safety |
| Standards packs, LunaNet AFS, lab round trip | scored packs for DHS RPCF, IMO MSC.1/Circ.1575 and ICAO Doc 9849 Appendix F against bars stated before the run, "supports evidence for"; a NIST IR 8323r1 crosswalk; a LunaNet AFS code generator and checker; a signed pack that links a lab run's scenario, test conditions, receiver log and score | MODELLED for the packs and the round trip; the AFS code check is VALIDATED against its printed check columns (see the ledger rows) | Standards, LunaNet AFS |
| kshana-bench and the observatory | fixed tasks, splits and metrics for interference detection, IQ detection, holdover prediction and the optimism gap, with a sealed holdout and a static leaderboard; a reproducible daily interference product with a 24 h delay, coarse cells and no attribution | no ledger row of its own: it scores submissions, and its baselines are labelled MODELLED in the result files; against the pre-registered bars the scorer, C1 to C3 and D2 are met and three bars are NOT MET (pinned by tests): A2 (agc_k_sigma AUC 0.766 against at least 0.80 on the test split), D1 (largest gap 0.0301) and task (b) R1 (carried, not re-run); see xval/bench/RESULTS-v2.md | Bench, Observatory |
| Exporters | trust telemetry as Home Assistant MQTT discovery and state messages (publish only, no credentials) beside Prometheus, CEF, LEEF and OTLP | MODELLED: one ledger row | Trust telemetry |
| Optical link margin against time | the optical-atmosphere kind can write one seeded realisation of a site's weather as a link-margin series | MODELLED: one ledger row; one draw from the model, not the climate | Optical atmosphere |
0.37's highlights: changelog. The full 0.38 list is in the changelog.
Each capability from the table above, in a few lines: what it does, one command to run it, one
picture drawn from a real run of the engine, and what the ledger holds for it. The pictures
are written by tools/gen_figures_038.py into
docs/figures/0.38/ (never drawn by hand): python3 tools/gen_figures_038.py
rewrites them from a built engine, and --check fails if one is stale or its caption here differs.
Where an input is a log, it is a made-up one the script writes, because the real third-party logs
are never vendored, and the caption says so. Everything below is advisory: not certified, not a
type approval, and nothing transmits. A status names what was checked and nothing more;
how a label is earned.
kshana jammertest import turns the published NPRA test catalogue and transmission plan into
scheduled truth, and kshana jammertest score scores a receiver log against it: for each
scheduled test, whether it was detected, how late, and how long the receiver took to recover, plus
false alarms outside every slot. The catalogue is fetched, never vendored.
xval/jammertest-plan/fetch.sh ../jammertest-plan
kshana jammertest score session.toml --catalog ../jammertest-plan/testcatalog2025.json \
--plan ../jammertest-plan/plan-tuesday-2025-09-16.json --location 1 --json
Ledger status: MODELLED. The bars were fixed before any scored run; on the JammerTest 2024 data the minimum-data rule failed in both runs, so no bar is assessable and nothing is claimed. Jammertest.
UBX-NAV-STATUS spoofDetState, UBX-SEC-SIG and NovAtel RXSTATUS are read into a per-epoch
self_report and set beside Kshana's alarms: both, receiver only, Kshana only, or neither. A
Septentrio SBF reader and a read-only --serial input feed the same comparison. Neither side is
ground truth.
kshana receiver-trust session.toml # [log] format = "ubx", path = "receiver.ubx"
Ledger status: MODELLED. Agreement between a receiver's detector and Kshana's is not validation. Receiver trust.
RTKLIB .pos, NovAtel OEM7, RTCM 3 MSM4/MSM7 C/N0, GNSS-SDR monitor streams, an IMU log as a second
sensor, a ROS 2 package and a gnss_lib_py bridge all end in the same receiver-trust timeline.
imu-fit reads the sensor parameters the hybrid and fusion scenarios need off a stationary IMU
log, so a scenario can be run with the sensor you actually have.
kshana imu-fit still.csv --format csv --axis x --expected-mean 0 --id bench-imu
Ledger status: MODELLED. Self-written fixtures only; no capture from a real receiver, IMU, GNSS-SDR run or ROS graph was read. Machine inputs.
The holdover-test kind scores a holdover test (GNSS removed by the operator, holdover, recovery)
from a measured time-error record against ITU-T masks, and says so in those words: measured
against the mask. linuxptp and chrony log readers feed it; the hardware stages and the
lab-attestation field say who stated what.
kshana scenarios/holdover-test-example.toml
Ledger status: MODELLED. The times GNSS was removed and restored are the operator's statement, not verified. Timing HIL, Hardware safety.
Scored packs for the DHS Resilient PNT test profiles, IMO MSC.1/Circ.1575 and ICAO Doc 9849
Appendix F, plus a NIST IR 8323r1 crosswalk in compliance-report. Each test runs a bundled
scenario and compares a result field with a bar stated before the run; a test that needs a receiver
log is listed as needing an input, not scored. The wording is "supports evidence for".
kshana standards-pack list
kshana standards-pack run imo-circ-1575
Ledger status: MODELLED. A met bar says a modelled scenario met a stated bar, nothing about a product; every miss is kept and pinned by a test. Standards.
The LunaNet Augmented Forward Signal code generator (Gold, Weil and tertiary codes, the message frame and its error coding) and a checker for a recorded or generated symbol stream, pinned to one edition of the specification.
kshana lunanet-afs-check spec
kshana lunanet-afs-check generate --frames 2 --out afs.sym
kshana lunanet-afs-check symbols afs.sym
Ledger status: VALIDATED for the code and synchronisation checks, against the values the specification prints (which it marks TBC); one check is NOT MET, kept and pinned (one printed tertiary-code column differs: the document prints the same value for two PRNs). The LDPC and CRC words of subframes 2 to 4 are not checked. The ledger rows say exactly which. LunaNet AFS.
kshana.test-conditions/1 is a published description of what a laboratory did (events, times,
powers). kshana evidence round-trip links the scenario hash, the conditions hash, the receiver log
hash and the score into one signed pack, and refuses a pack whose conditions and scoring scenario
disagree about the events. Kshana never produces or replays a signal: how a scenario reached a
receiver is the operator's responsibility.
kshana evidence --help
The picture is the layout of a pack. Ledger status: MODELLED. Test conditions, Test bench.
Fixed tasks, splits and metrics for interference detection, IQ detection, holdover prediction and the optimism gap, with a sealed holdout and a static leaderboard. It scores submissions; it is not a ranking of receivers.
kshana bench baseline --task d --split test --out results/
Ledger status: no ledger row of its own; the baselines are labelled MODELLED in the result files.
Against the pre-registered bars the scorer, C1 to C3 and D2 are met and three bars are NOT MET, each
pinned by a test: A2 (agc_k_sigma AUC 0.766 against at least 0.80 on the test split), D1 (largest gap
0.0301) and task (b) R1 (carried from the earlier campaign, not re-run). The figures are in
xval/bench/RESULTS-v2.md. Bench.
One product per UTC day and region from an open aircraft-position archive, on a fixed coarse grid: each cell is degraded, not degraded, or not observed (which is not "clear"). Released no earlier than 24 h after the day ends, with small cells suppressed and no attribution of cause.
kshana interference-map daily /path/to/extracted/2026-09-15 \
--dataset adsb-lol --day 2026-09-15 --bbox 53.5,9.0,66.0,31.0 --out products/
The picture is the committed sample days, not an observatory product. Ledger status: MODELLED: no external oracle, no ground truth and no cause attribution; a cell that is not observed was not assessed, which is not the same as clear. Observatory method.
Trust telemetry as Prometheus text, CEF, LEEF, OTLP and Home Assistant MQTT discovery and state messages. The command publishes only to a destination you give it and holds no credentials.
kshana trust-telemetry --result session.result.json --print-metrics
kshana trust-telemetry --result session.result.json --print-syslog --format cef
Ledger status: MODELLED. Trust telemetry.
The optical-atmosphere kind can write one seeded realisation of a site's weather as a link-margin
series: cloud episodes, a liquid-water column for each, one scintillation sample per step. The
Studio's Optical PNT page opens the optical-atmosphere scenarios.
kshana scenarios/optical-atmosphere-network.toml
Ledger status: MODELLED. One draw from the model, not the climate. Optical atmosphere.
kshana.dev/studio gains a Bridge replay (two runs side by side on one
mission clock, at /studio/replay/), an Optical PNT page
(/studio/optical/), a Holdover test page (/studio/holdover/) and an observatory viewer
(/studio/observatory/). They run the same engine in the browser, nothing is uploaded, and they carry
the same advisory statement. The pictures above are drawn from the engine's own output by a script;
they are not screenshots of these pages.
gnss-ssv)For a spacecraft above, around or far past the GNSS orbits: how many GNSS signals it can use, how strong they are, how good the geometry is, and what an onboard filter can do with them. One kind, four modes, chosen by the scenario's tables: a shell of users (the share of time with one and four signals, per constellation), a trajectory (signals, C/N0, dilution of precision and the limb-ray medium along an orbit), a navigation run (a nine-state filter on pseudoranges, to the Moon) and a formation (relative navigation of deputies about a chief). The public source for the availability comparison is the interoperable GNSS Space Service Volume booklet (UN OOSA ST/SPACE/75, from the International Committee on GNSS), which is itself a simulation; it is fetched, never vendored. Full page: docs/SSV.md.
kshana scenarios/gnss-ssv-shell.toml # shell: the upper space service volume, reduced size
kshana scenarios/gnss-ssv-heo.toml # trajectory: a high Earth orbit, limb medium
kshana scenarios/gnss-ssv-nav-lunar.toml # navigation: an onboard filter toward the Moon
kshana scenarios/gnss-ssv-formation-heo.toml # formation: relative navigation
Ledger status: MODELLED, and the comparison with the booklet mostly misses. The bars were fixed before the run. Of eight, only S0 (the inverse link budget, 13 of 13 values) and S6 (the lunar mission) are met. S1 to S5 and S7 are NOT MET: the upper and lower service volume geometry (43 of 52 and 48 of 52 cells), the 15/20/25 dB-Hz upper service volume, the six GEO missions, the HEO mission, and the parametric sidelobe pattern against measured GPS panel patterns. Almost every miss in S1 to S5 involves GLONASS, and the booklet prints two different reference angles for it; a diagnostic variant that uses the other pair brings S1, S2 and S4 to every cell, but it does not replace the run of record and no row is VALIDATED. The formation run's absolute filter is also overconfident (mean normalised error squared well above the value of about 3 that a consistent filter gives).
Space-user navigation, what the comparison shows.
lunar-infrastructure)The Moon's orbit and surface as navigation and geodetic infrastructure, in five studies chosen by
study: od-consistency (an onboard Earth-GNSS orbit determination in a halo orbit against an
independent ground one), carrier-phase (integer ambiguity fixing between surface stations and an
orbiter), frame-coestimation (the lunar datum from Earth-station ranging with and without orbiter
links), space-tie (laser, VLBI and GNSS offsets on one spacecraft against the local-tie error) and
geodesy-sensitivity (which observable family sees the Love numbers h2, k2 and l2). The model is a
restricted three-body one with stated simplifications and illustrative inputs. Full page:
docs/LUNAR-INFRASTRUCTURE.md.
kshana scenarios/lunar-infrastructure-od-consistency.toml
kshana scenarios/lunar-infrastructure-carrier-phase.toml # quick; the scored run takes about eight minutes
kshana scenarios/lunar-infrastructure-frame-coestimation.toml
kshana scenarios/lunar-infrastructure-space-tie.toml
kshana scenarios/lunar-infrastructure-geodesy-sensitivity.toml
Ledger status: MODELLED, and three bars are NOT MET. The numerics are checked against independent numpy and scipy programs; nothing is compared with a measurement of a lunar quantity, and nothing is VALIDATED. Met: the two orbit solutions are consistent (mean q 5.81 against 6 expected), and orbiter links raise the smallest datum eigenvalue about 111-fold, assuming a known orbit. Not met: the injected 3e-10 m/s2 model error is not detected (C3: the onboard solution is known to about 350 m, so about ten metres hides in its covariance); integer fixing is not achieved (1 to 3 % success at 25 dBi, and at the registered 12 dBi the problem cannot be formed); and the trace half of G3 for adding an observable family (the trace rose in 12 of 28 additions, each time because the family raised the rank). Each miss is pinned by a test. Lunar infrastructure.
Open kshana.dev/studio and the whole engine runs in your browser, compiled to WebAssembly. Nothing to install, and nothing is uploaded. The Studio has two views of the same engine, and a switch in the header moves between them, keeping the scenario, the view and any settings you changed.
The Simple view is where the Studio opens. It starts from questions (how many satellites can I see, can I trust my position fix, how long can a clock keep time, what does a jammer do to my receiver) and from a map of everything the engine can do, each area with its share of validated methods. Open a scenario and the answer comes first: one plain sentence, written for what that scenario measures, then its key figures and a chart. At most five settings are on show, the ones that change the answer most; the rest wait under Advanced settings. How this is computed explains the method, and For researchers gives the engine's own figures, the scenario file, the code to run it from Python and the citation.
The Advanced view is the full dashboard: the scenario library, five numbered steps (Choose, Set, Run, Read results, Share or export), the key figures with PASS and FAIL chips where the run states a threshold, and every panel: overview, charts, maps, replay, the engine's report and exports. One search box reaches scenarios, domains and the fields inside them, and you can pin up to four runs and compare them side by side.
The Studio's source and its build notes are in web/README.md.
The rest of kshana.dev is built from this repository's own files and engine runs: missions, capabilities, the evidence ledger, the published research and the editions.
One engine covers the whole failure chain, from the first jammed satellite to the last
nanosecond of clock holdover. The engine has 92 scenario kinds; kshana kinds lists
them and docs/SCENARIOS.md documents every field.
ghcr.io/ashfordeou/kshana-mcp:0.15.1