Maskinoversettelse, ikke gjennomgått av en morsmålsbruker. Engelsk er referansen.

API-er og integrasjonerRediger på GitHubKilde: docs/ARCHITECTURE.md

Kshana — Arkitektur

Kshana er én motor organisert i lag over en felles kjerne: sensorpakkene (klokke, treghet, tidsoverføring, hybrid); et astrodynamikk-/numerisk lag (analytisk SGP4/SDP4 (SGP4: Simplified General Perturbations 4; SDP4: Simplified Deep-space Perturbations 4), en numerisk Cowell-propagator med sin kraftmodell med sju forstyrrelser, manøverutforming, banebestemmelse fra avstandsmålinger fra bakkestasjoner, og tilpasning av kraftmodellen mot presise efemerider fra romorganisasjoner); et lag for tid og referansesystem (IERS (International Earth Rotation and Reference Systems Service) tidsskalaer, IAU (International Astronomical Union) 2006/2000A presesjon–nutasjon, og CIO-reduksjonen (Celestial Intermediate Origin) GCRS↔ITRS (GCRS: Geocentric Celestial Reference System; ITRS: International Terrestrial Reference System)); et fusjonslag (GNSS/INS-estimatorene (GNSS: global navigation satellite system; INS: inertial navigation system)); og lagene for integritet, resiliens, alt-PNT (PNT: positioning, navigation and timing) og måne (RAIM/ARAIM/SBAS (RAIM: receiver autonomous integrity monitoring; ARAIM: advanced receiver autonomous integrity monitoring; SBAS: satellite-based augmentation system), jamming og spoofdeteksjon i flere lag, kartmatching av gravitasjon/terreng/magnetfelt, og cislunar PNT); og de nyere lagene LEO-PNT (PNT i lav jordbane), spektrum, solsystem og konstellasjonsutforming, nettverkstidssynkronisering og kampanje, med rapport-, animasjons- og interoperabilitetsskriverne som hver kjøring kan bruke (§1d). På tvers av alle disse vet ikke motoren noe om «kvante» mot «klassisk»: den driver sensorers feilmodeller gjennom et GNSS-avbruddsscenario, kjører en estimator og gir poengsum til utfallet. En kvante- og en klassisk enhet sammenlignes derfor på det samme scenarioet, og skiller seg bare i sine (publiserte, siterte) feilparametere og sine uavhengige støyseed.

Dette dokumentet samler de strukturelle og atferdsmessige diagrammene. §1 er kjernen med sensorpakker; §1a kartlegger lagene for astrodynamikk, fusjon og alt-PNT som er lagt til siden; §1b–§1d lagene for studier, domener og utdata. For bruk, se README; for hva som er og ikke er validert, se VALIDATION; for modenhetstabellen per funksjon, se CAPABILITY.

Forkortelser brukt i diagrammene og ikke skrevet ut der de står: ADEV, Allan-deviasjon; BW, båndbredde; CAI, kaldatom-interferometer; CZML, Cesium Language; Δ-DOR, delta differential one-way ranging; DO-229E, RTCAs mottakerstandard for SBAS (Radio Technical Commission for Aeronautics); EKF, utvidet Kalman-filter; FM, frekvensmodulasjon; GSE, bakkestøtteutstyr; HPL/VPL, horisontalt/vertikalt beskyttelsesnivå; IMU, treghetsmåleenhet; IOAG, Interagency Operations Advisory Group; IQ, samplene in-phase/quadrature; ISL, lenke mellom satellitter; ITU-T, telekommunikasjonssektoren i International Telecommunication Union; J2–J6, Jordens sonale gravitasjonsharmoniske av grad 2 til 6; KIF, Kshana Interchange Format; KML, Keyhole Markup Language; KPI, nøkkelindikator for ytelse; L1/L5, GNSS-bærebølgebånd (L2 i CR3BP-halobanene er derimot Lagrange-punktet 2 i systemet Jorden–Månen); LEO, lav jordbane; LOO, utelatelse av én om gangen; LTC, Coordinated Lunar Time; MEO, middels jordbane; MTIE, maksimal tidsintervallfeil; N2, Hill-diversitetstallet av orden 2; NED, nord-øst-ned; NTN, ikke-terrestrisk nettverk; OD, banebestemmelse; OPS-SAT, den europeiske romorganisasjon ESAs satellitt-laboratorium for programvare i bane; PPP, presis punktposisjonering; PSD, effekttetthetsspekter; PVT, posisjon, hastighet og tid; RINEX, Receiver Independent Exchange Format; RK4 / RK5(4), Runge–Kutta-integratorer av fjerde orden og innebygd femte(fjerde) orden; SH, sfærisk harmonisk; SigMF, Signal Metadata Format; SIR, sampling importance resampling; SRIF, kvadratrotinformasjonsfilter; SRP, solstrålingstrykk; SSC, spektral separasjonskoeffisient; STK, Systems Tool Kit; SVG, Scalable Vector Graphics; TDEV, tidsdeviasjon; TDM, Tracking Data Message fra CCSDS (Consultative Committee for Space Data Systems); TLE, two-line element-sett; TPL, Timing Protection Level; UBX, u-blox' binære protokoll; UHF, ultrahøy frekvens; VLBI, interferometri med svært lang grunnlinje; VRW / ARW, tilfeldig vandring i hastighet / vinkel; WASM, WebAssembly.


1. Modulstruktur#

flowchart TD
    main["main.rs<br/>CLI (thin wrapper)"]
    py["python.rs<br/>PyO3 (feature)"]
    wasm["wasm.rs<br/>wasm-bindgen (feature)"]
    api["api.rs<br/>run_toml: parse · dispatch by kind · json+svg+summary"]

    subgraph shared["Shared core"]
      types["types.rs<br/>Seconds · TimeGrid · ModelSpec"]
      scenario["scenario.rs<br/>GnssState · GnssTimeline · ClockCfg · Scenario"]
      allan["allan.rs<br/>overlapping Allan deviation"]
    end

    subgraph pack1["Pack 1 · Clock holdover"]
      models["models.rs<br/>ErrorModel · ClockModel (incl. flicker FM)"]
      estimator["estimator.rs<br/>HoldoverEstimator"]
      kalman["kalman.rs<br/>KalmanClock → Integrity bound"]
      security["security.rs<br/>clock-aided spoof detection → Security"]
      fom["fom.rs<br/>Sample · FoMScores · score · worst_case_holdover"]
      report["report.rs<br/>RunResult · hash · to_svg"]
      run["run.rs<br/>run / run_clock / run_orbit_clock"]
    end

    inertial["inertial/<br/>Pack 2 · AccelModel (accel + gyro + bias instability/RW) · run_inertial · quantum_imu CAI + QuantumNavBudget dead-reckoning-over-holdover"]
    timetransfer["timetransfer.rs<br/>Pack 3 · TimeTransferLink · run_timetransfer"]
    hybrid["hybrid.rs<br/>Pack 4 · run_suite · score_hybrid · run_hybrid (+ integrity/security)"]
    fusion["fusion/<br/>joint Kalman PNT estimator · run_fusion"]
    orbit["orbit.rs<br/>Propagator (Kepler | SGP4) · Walker / TLE / multi-constellation · visibility · DOP"]
    tle["tle.rs<br/>two-line element parsing (line 2 → Kepler, full TLE → SGP4)"]
    sgp4mod["sgp4.rs<br/>SGP4 / SDP4 propagator (deep-space + resonance)"]
    ensemble["ensemble.rs<br/>Monte Carlo confidence bands"]
    sweep["sweep.rs<br/>trade-study parameter sweeps"]
    spoof["spoof.rs<br/>active spoofing-attack demonstrator"]
    jamming["jamming.rs<br/>link-budget anti-jam C/N₀ (J/S · processing gain · Q)"]
    navsignal["navsignal.rs<br/>signal level: BPSK-R / BOC PSD · SSC κ · Gabor BW · DLL jitter · multipath · ranging-code (m-seq/Gold) design-trade"]
    holdover["holdover.rs<br/>GNSS-denied clock holdover: van-Loan coast → holdover-to-threshold · quantum-clock classes"]
    verification["verification.rs<br/>machine-checked requirement→module→test→oracle→status matrix"]

    main --> api
    py --> api
    wasm --> api
    api --> run
    api --> inertial
    api --> timetransfer
    api --> hybrid
    api --> ensemble
    api --> sweep
    api --> fusion
    api --> spoof
    spoof --> security
    api --> jamming
    api --> holdover
    api --> verification
    navsignal -. derives anti-jam Q (κ → Q=1/(R_c·κ)) .-> jamming
    jamming -. uses PSD / SSC .-> navsignal
    holdover -. coast-variance vs van-Loan recursion .-> kalman
    ensemble --> run
    sweep --> run
    orbit --> tle
    tle --> sgp4mod
    orbit -. SGP4 propagator .-> sgp4mod
    fusion -. composes .-> models
    fusion -. composes .-> inertial
    fusion --> kalman

    run --> models
    run --> estimator
    run --> kalman
    run --> security
    run --> fom
    run --> report
    run --> orbit
    models --> types
    scenario --> types
    inertial --> scenario
    timetransfer --> types
    orbit --> scenario
    hybrid -. composes .-> models
    hybrid -. composes .-> estimator
    hybrid -. composes .-> inertial
    hybrid -. composes .-> timetransfer
    pack1 --> shared
    inertial --> allan

CLI-en (kommandolinjegrensesnittet) og begge bindingene går gjennom ett inngangspunkt api::run_toml, så de driver aldri fra hverandre. Pakkene gjenbruker den felles kjernen (types, scenario, allan); pakke 4 (hybrid) setter sammen modellene og estimatorene fra pakke 1–3 i stedet for å implementere dem på nytt; orbit utleder en GNSS-tidslinje fra geometri som deretter mater kjøringen av pakke 1. Modulen navsignal ligger på signalnivå mellom lenkebudsjettet og måledomenet: den utleder den spektrale separasjonskoeffisienten κ fra de faktiske effektspektrene til signalet og jammeren, og ut fra den beregner jamming nå sin anti-jam-Q = 1/(R_c·κ) i stedet for å ta en representativ konstant (krysskontrollert i CI (kontinuerlig integrasjon)); den bærer også avveiningene i utformingen av avstandskoder (m-sekvens/Gold).

Tre ytterligere moduler danner ryggraden i resiliens uten GNSS. holdover svarer direkte på det operative spørsmålet — hvor lenge kan denne klokken gå fritt før tidsfeilen overskrider budsjettet? — ved å eksponere van-Loan-formen for feil under frigang som en inversjon fra holdover til terskel, krysskontrollert mot den flertrinns kovariansrekursjonen clock_state. Dens treghetstvilling ligger i inertial::quantum_imu (QuantumNavBudget), som setter sammen hvitt støy-driften fra kaldatom-interferometeret med bias- og skalafaktorfeil til et budsjett for posisjonsdrift over holdover (biasleddet krysskontrollert mot den uavhengige AccelModel-integratoren). verification gjengir hele motorens matrise fra krav til modul til test til uavhengig referanse til status, med enhetstestede invarianter som forbyr en validert-merking uten en uavhengig ekstern referanse — slik at påstanden om sikring ikke kan drive fra koden.

1a. Lag for astrodynamikk, fusjon og alt-PNT#

Utover kjernen med sensorpakker deler tre delsystemer den samme felles kjernen og mater (eller mates av) orbit. Laget for astrodynamikk / numerikk legger til en ikke-analytisk Cowell-propagator ved siden av den analytiske SGP4/SDP4-veien; fusjonslaget bærer GNSS/INS-estimatorene; og alt-PNT-laget er GPS-fri (GPS: Global Positioning System) gravitasjonskartmatching. Dette er bibliotek-/scenariofunksjoner (se CAPABILITY for hvilke som er koblet til en scenario-kind mot nåbare som et Rust-API (application programming interface)).

flowchart TD
    subgraph astro["Astrodynamics & numerical"]
      orbit2["orbit · sgp4 · tle · walker<br/>analytic SGP4/SDP4 · Walker design"]
      prop["propagator<br/>Cowell driver (accel_at / accel_rv)"]
      forces["forces<br/>two-body · J2–J6 · EGM2008 d/o-70 · 3rd-body · SRP · drag · Schwarzschild + Lense–Thirring · tides"]
      integ["integrator<br/>RK4 step-doubling · Dormand–Prince RK5(4)"]
      ephem["ephem<br/>low-precision Sun & Moon"]
      man["maneuver<br/>impulsive/finite burns · Izzo Lambert · porkchop"]
      od["orbit_determination<br/>Gauss–Newton batch (batch_ls) · sequential UKF"]
    end
    subgraph fusion["Fusion (GNSS/INS)"]
      ekf["fusion/gnss_ins_ekf · closed_loop · pack<br/>15-state loosely-coupled EKF"]
      tc["fusion/tightly_coupled (8-state)<br/>fusion/tightly_coupled17 (17-state, quantum-CAI)"]
      ukf["fusion/ukf — sigma-point core"]
      coup["fusion/coupled — clock+position cross-covariance"]
    end
    subgraph alt["Alt-PNT (GPS-denied)"]
      grav["gravimeter<br/>cold-atom model + SH anomaly field + mascons"]
      pf["particle_filter — SIR"]
      mm["mapmatch — field-match likelihood"]
    end
    prop --> forces
    prop --> integ
    forces --> ephem
    man --> integ
    od --> forces
    od --> integ
    od --> ukf
    tc --> ukf
    tc -. coasts on .-> forces
    grav --> pf
    mm --> pf
    grav --> mm
    ekf -. drives .-> strap["inertial/ strapdown (quaternion · NED · IMU errors)"]
    tc -. drives .-> strap
    grav -. CAI floor .-> strap

Den numeriske propagatorens kraftledd er av som standard, så å slå dem på forstyrrer aldri de utgitte gullfilene. Det tettkoblede UKF-et (unscented Kalman filter) med 17 tilstander holder en GNSS-pause ut på den utledede hastighetens tilfeldige vandring fra kvante-CAI-akselerometeret; banebestemmelse gjenbruker den samme forces/integrator for å propagere en kandidattilstand over sporingsbuen.

Den samme felles kjernen bærer også fire ytterligere delsystemer som ikke er tegnet ovenfor (pakkene deres står i fordelingen i §4): et lag for tid og referansesystem (timescales, jd2, precession, nutation, cio, frames, eop) som reduserer TEME↔GCRS↔ITRS (TEME: true equator, mean equinox) og mater pakken ephemeris/bakkespor; et integritetslag (raim, sbas) for RAIM/ARAIM/SBAS; et resilienslag (jamming, spoof, spoof_detect, spoof_monitors, detection) for jamming og spoofdeteksjon i flere lag, med et navigasjonssignallag (navsignal) på signalnivå — effekttetthetsspektre for BPSK-R (BPSK: binary phase-shift keying) / sinus-BOC (BOC: binary offset carrier), den spektrale separasjonskoeffisienten κ som nå utleder jammings anti-jam-Q, RMS-båndbredden (Gabor) for avstandsmåling, koherent early–late-DLL (delay-locked loop) jitter ved kodesporing og feilomhyllingen for flerveisutbredelse (analyse av signalytelse, ikke utforming av RF-nyttelast (RF: radiofrekvens) / antennemaskinvare — en nyttelastpartners rolle); og et måne-/cislunarlag (lunar, lunar_frame, lunar_od, cr3bp) for CR3BP-dynamikk (circular restricted three-body problem) — inkludert tilstandsovergangsmatrisen på 6×6 og en differensialkorrektor med enkeltskyting (cr3bp_jacobian, propagate_state_stm, differential_correct_halo) som gir genuint periodiske halo-/NRHO-baner (NRHO: near-rectilinear halo orbit), og gjengir den publiserte sørlige L2 9:2 NRHO (Gateway-banen) med periode ≈ 6,57 d / perilune ≈ 3 250 km (publisert ≈ 6,56 d / ≈ 3 370 km); den selenosentriske MCI/MCMF-transformasjonen (MCI: Moon-centred inertial; MCMF: Moon-centred, Moon-fixed) av en korrigert bane og familiefortsettelse gjenstår som oppfølginger, og NRHO er en CR3BP-løsning (sirkulær, uten Sol), ikke validert mot en ekte LANS/Gateway-efemeride (LANS: Lunar Augmented Navigation Service) — og LunaNet-integritet. Tilpasningen av kraftmodellen mot efemerider fra romorganisasjoner (precise_od, lunar_od, tides, gravity_sh) og det fulle settet av alt-PNT-felt (igrf, altpnt/terrain, gravimeter) runder av modullisten; se CAPABILITY for modenhet per modul.

1b. Resiliensstudier, evaluering av maskinlæring og reproduserbare artefakter#

Fem ytterligere modulgrupper danner laget for åpne, reproduserbare studier bak prosjektets forskningsartikler. I motsetning til scenario-kind-ene nås disse som generatorer med cargo run --example / --bin som skriver byte-deterministiske artefakter (faste seed, registrert motorversjon + konfigurasjonshash). Alle er MODELLED (syntetisk eller kalibrert mot offentlige datasett) og bærer ærlige valideringsmerker — ingen av dem er en sertifisering.

flowchart TD
    gen["study generators<br/>examples/ · bin/ (cargo run) → byte-deterministic artifacts"]

    subgraph timing["Timing integrity"]
      tplm["tpl<br/>conditional Timing Protection Level: k-σ floor · van-Loan coast · CUSUM"]
    end
    subgraph resilm["Resilience scoring & decision-instability"]
      arch["resilience/arch · score<br/>architecture model + RPCF-aligned scoring"]
      stats["resilience/stats<br/>Dirichlet · Kendall-τ · flip-rate · bootstrap"]
      div["resilience/diversity · timeline<br/>Hill-N2 common-mode collapse · KPIs"]
      study["resilience/study · report · panel<br/>instability study + integrity-hashed assurance report"]
    end
    subgraph aiml["RF-impairment optimism-gap (Machine learning)"]
      ie["impairment_eval<br/>labelled synthetic corpus · ROC/AUC harness"]
      is["impairment_study<br/>13-detector panel · scaling laws · LOO predictor"]
      ml["impairment_ml<br/>logistic-regression + one-hidden-layer MLP"]
      es["eval_stats<br/>bootstrap CI · DeLong · Spearman · ridge"]
      sdrm["sdr · realdata<br/>IQ/IF → E/P/L taps → SQM + ingest adapters"]
    end
    subgraph trade["Quantum-vs-classical"]
      cross["crossover<br/>resilience crossover map under parameter uncertainty"]
      qt["quantum_trade<br/>measured-ADEV holdover benefit vs classical"]
    end

    gen --> timing
    gen --> resilm
    gen --> aiml
    gen --> trade
    tplm -. cross-checked vs .-> recursion["holdover · clock_state · allan"]
    is --> ie
    is --> ml
    is --> es
    ie -. real recordings via .-> sdrm
    cross -. composes .-> packs2["clock · inertial packs"]
  • tpl — det betingede Timing Protection Level: en holdover-begrenset grense for den uoppdagede tidsfeilen under spoofing, som setter sammen et k-σ-monitorgulv, van-Loan-kovariansen for frigang over deteksjonsforsinkelsen og en CUSUM-tid til alarm (cumulative sum); kalibrert på en ekte registrert spoof (JammerTest 2024). Det finnes ingen endelig ubetinget grense — TPL er betinget av at en uavhengig krysskontroll oppdager angrepet.
  • resilience/ — en motor for poengsetting av PNT-resiliens i tråd med rammeverk (kategorier i DHS (Department of Homeland Security) RPCF (Resilient PNT Conformance Framework)) pluss en studie av beslutningsustabilitet: et Dirichlet-vektingssimpleks, Kendall-τ-rangustabilitet, hyppighet av skifte av vinner på topp 1 og diversitetskollaps i felles modus (Hill-N2), med en integritetshashet sikringsrapport og 35 håndavledede tester mot uavhengig referanse. Se RESILIENCE-CROSSWALK. Syntetiske arkitekturer tilpasset RPCF v2.0 — en egenvurdering, ikke en sertifisering.
  • impairment_eval / impairment_study / impairment_ml / eval_stats — studien av optimismegapet for RF-svekkelser: et merket syntetisk korpus og en detektoragnostisk ROC/AUC-løype (ROC: receiver operating characteristic; AUC: area under the curve), et panel med 13 detektorer (energi/AGC/SQM/paritet (AGC: automatic gain control; SQM: signal-quality monitoring) pluss seedede detektorer med logistisk regresjon og MLP med ett skjult lag (MLP: multi-layer perceptron)), skaleringslover innenfor og utenfor fordelingen med en permutasjonsnull, og en leave-one-out-prediktor for degradering utenfor fordelingen. Evalueringsmetrikkene er validert bit for bit mot scikit-learn.
  • sdr / realdata — en front end for programvaredefinert mottaker (rå IQ/IF (IQ: in-phase/quadrature; IF: intermediate frequency) → korrelatorens early/prompt/late-uttak → SQM) og innlesingsadaptere (RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid) som lar de samme detektorene kjøre over opptak levert lokalt; ingen datasett er sjekket inn i depotet.
  • crossover / quantum_trade — kartet over resiliensovergangen mellom kvante og klassisk under parameterusikkerhet, og avveiningen av holdover-gevinst med målt ADEV; de numeriske kjernene i avveiningen er validert mot scipy.

1c. Lag for integritet, GNSS, dyp rom, måne og oppdrag#

De gjenværende domenene kobles til den samme api-fordelingen og gjenbruker den felles kjernen, referansesystemene og geometrien. Alt her er MODELLED med mindre en rad i verification-matrisen viser til en ekstern uavhengig referanse (RAIM-kjernen mot SciPy, SBAS mot RTKLIB-forken (et åpen kildekode-bibliotek for sanntids kinematisk posisjonering), DOP-kjernen (dilution of precision) i gnss_lib_py, OPS-SAT-evalueringen, kjernen for beskyttelsesnivå i lunar ARAIM, konsistensen mellom leverandørene av månens efemerider) — resten av månesuiten og kvantedemonstratoren er modellert, illustrerende, fra offentlige kilder, og bærer ingen påstand om TRL (technology readiness level) / arv / støtte fra romorganisasjoner.

flowchart TD
    api["api.rs — run_toml / run_scenario · 92 kinds"]

    subgraph gnss["Integrity & GNSS measurement"]
      raim["raim — RAIM/ARAIM · HPL/VPL (kernel vs SciPy)"]
      sbas["sbas — DO-229E PL · L1/L5 (vs RTKLIB fork)"]
      meas["gnss_sim · ionex · pvt · glonass — pseudorange · iono maps · single-point PVT"]
      imp["integrity_impact · frugal — miss→integrity · cost-per-coverage"]
    end

    subgraph deep["Deep-space & Mars"]
      core2["body · ephem_provider · clock_state — multi-body · ephemeris seam · onboard clock"]
      radio["radiometric · ccsds_tdm — light-time · Doppler/range · Δ-DOR · TDM"]
      mars["deepspace_od · mars_frame · mars_atmos · mars_pnt · linkbudget · gse_sim — SRIF OD · Mars frame · relay-PNT · GSE sim"]
    end

    subgraph lunar["Lunar PNT suite (evidence tier per piece in the matrix · illustrative public-source)"]
      cis["cr3bp · lunar · lunar_frame · lunar_od — CR3BP · halo/NRHO · cislunar ARAIM · MCI↔MCMF"]
      suite["lunar_time · lunar_vlbi · lunar_combination · lunar_frame_realise — LTC time · VLBI · joint OD+clock · frame realisation"]
      suite2["lunar_service · lunar_dpnt · lunar_interop — Moonlight service-volume · differential PNT · LunaNet/IOAG interop"]
    end

    subgraph quantum["Quantum-Enabled PNT demonstrator (MODELLED)"]
      qd["quantum_devices · quantum_faults · quantum_nav_od — device error models · fault catalogue · GNSS-free OD"]
      qt["qtrade · timetransfer_chain · representativeness — unified trade · time-transfer chain · gaps-to-flight ledger"]
    end

    subgraph mission["Mission analysis, environment & interop"]
      ma["launch · reentry · eo_payload · attitude_budget · passes · linkbudget — first-order budgets"]
      env["space_weather — Jacchia-71 density"]
      iop["rinex · rinex_obs · sp3 · oem · omm · ccsds_tdm · space_packet · interchange · permalink — interop formats + KIF"]
      ver["verification — requirement→module→test→oracle→status matrix"]
    end

    api --> gnss & deep & lunar & quantum & mission
    raim -. reuses .-> meas
    suite -. reuses validated DOP / SBAS kernels .-> gnss
    qt -. rides validated kernels (scipy / sklearn) .-> quantum

1d. LEO-PNT, spektrum, solsystem, nettverkstidssynkronisering, kampanjer og utdata#

De nyeste lagene følger det samme mønsteret: hvert er én eller flere scenario-kind-er sendt fra api, bygget på den felles kjernen, og MODELLED med mindre en matriserad navngir en ekstern uavhengig referanse.

flowchart TD
    api["api.rs — run_toml / run_scenario"]

    subgraph leo["LEO PNT (low Earth orbit positioning, navigation and timing)"]
      lsig["leo_signal — signal design: acquisition, code tracking, GNSS compatibility, band trade"]
      lpass["leo_pass · leo_link (geometry · antenna · itu · iono · energy · spoof · presets) — pass and per-band link budget"]
      lnav["leo_navmsg (elements · fit · codec · sisre · services · text) — broadcast ephemeris and clock message"]
      lfus["leo_fusion (doppler · joint_pvt · ppp · ntn · timing · polar · presets) — fused MEO+LEO PVT · PPP · 5G NTN"]
      lchain["leo_pnt_chain — one system end to end, each stage handing its output to the next"]
    end

    subgraph rf["Spectrum"]
      spec["spectrum · navsignal — L-band (and UHF/S/C) PSD waterfall under a jammer timeline"]
      sig["sigmf — SigMF recording read/write · Welch PSD of complex IQ"]
    end

    subgraph sky["Solar system & constellations"]
      ss["solar_system · body · ephem · ephem_provider — bodies, constants, light time at one epoch"]
      bp["body_pnt — positioning around any body with a local constellation"]
      cd["constellation · walker — Walker delta/star, multi-shell, published GNSS slots, coverage/DOP maps"]
    end

    subgraph net["Network timing"]
      tel["telecom_timing — time error, MTIE, TDEV vs ITU-T masks"]
      slot["slot_timing — seconds until a free-running clock leaves a slot guard"]
    end

    subgraph comp["Composition & outputs"]
      camp["campaign · study · suite — chained phases, sweeps, Monte Carlo, shared conditions"]
      rep["advanced_report — report.html + report.json with a reproducibility record"]
      anim["animation — SVG / HTML / frame animations"]
      iop["interop (czml · kml · geojson · stk) · sigmf — exchange files for --export"]
    end

    api --> leo & rf & sky & net & comp
    lchain -. composes .-> lsig & lpass & lnav & lfus
    lsig -. SSC chain .-> spec
    lfus -. GNSS presets .-> cd
    bp -. reuses .-> ss
    camp -. runs other kinds through .-> api

Detaljene per type står i LEO-PNT, LEO-SIGNAL, LEO-PASS, LEO-NAVMSG, LEO-PNT-FUSION, SPECTRUM, CONSTELLATION-DESIGN, TELECOM-TIMING, SLOT-TIMING, CAMPAIGNS, REPORTS, ANIMATION og INTEROP.

1e. Lag for mottakertillit, evidens, telemetri, trening og compliance (0,35)#

Disse lagene leser en mottakers egen logg eller skriver filer for andre verktøy; ingen av dem syntetiserer eller sender et radiofrekvenssignal. De ligger ved siden av api i stedet for under scenariotypene, bortsett fra receiver-trust selv, som er en scenariotype. Alle er MODELLED med mindre en matriserad navngir en ekstern uavhengig referanse, og de maritime utdataene er veiledende, ikke typegodkjent navigasjonsutstyr.

Modul Hva den gjør Dokumentert i
receiver_trust gir poengsum til en mottakerlogg epoke for epoke med tillitsmonitorene; en fartøyplattform legger til de maritime monitorene og scoren 0–100 med årsaker RECEIVER-TRUST, MARITIME-TRUST
receiver_trust::live den samme poengsettingen på en strøm etter hvert som den kommer (stdin, en fil som utvides, TCP eller UDP), setningen $PKSHT og den valgfrie gaten; LiveEngine er hele motoren uten inn- eller utdata MARITIME-TRUST
evidence en signert pakke med hashkjede av et loggvindu, dets konfigurasjon og motorens resultat, som kan verifiseres frakoblet; valgfritt RFC 3161 tidsstempeltoken EVIDENCE-PACKS
telemetry tillitsstrømmen som Prometheus-metrikker, syslog-hendelser (CEF eller LEEF) og valgfri OpenTelemetry (funksjonen otlp, av som standard) TRUST-TELEMETRY
nmea_synth syntetisk bro-NMEA 0183 med skriptede hendelser for jamming, drag-off, tidsspoofing og replay samt en instruktørlogg, for mannskapstrening (kun tekst) NMEA-TRAINING
interference_map aggregerte kart over redusert navigasjon fra åpent lisensierte fly- og skipsrapporter, og en rutes eksponering for dem; kun lokale filer INTERFERENCE-MAP
osnma en verifikator på mottakersiden for Galileo OSNMA: leser I/NAV-sider (rene sider, vektor-CSV, en UBX-strøm), kontrollerer den signerte nøkkelen, TESLA-kjeden og MAC-ene, og rapporterer per satellitt om navigasjonsdataene er autentisert; osnma::cli::verify_report er den ene banen som kommandolinjen, Python og WebAssembly deler; kun autentiseringsstatus, ikke en integritetstjeneste OSNMA
compliance kobler utdata fra Kshana til offentlige robusthetsrammeverk og fyller ut koblingen fra resultatdokumenter; run_from_text og assess_texts tar tekster, ikke stier compliance/
interop::testbench et scenarios kjøretøybevegelse og hendelser som bevegelses-CSV, NMEA, veipunkttekst og hendelsesfiler for en GNSS-simulator i laboratoriet; ingen signaler skrives TEST-BENCH

Integrasjoner for båter (Signal K-programtillegget, OpenCPN i gate-modus og referansebygget) kaller kommandolinjeverktøyet; se MARINE-INTEGRATIONS.

2. Motorens pipeline (per kjøring)#

Hver kjøring stepper én enkelt sensormodell gjennom tidsrutenettet. Modellen styres så lenge GNSS er nominelt, og får gå fritt (holdover / dødregning) under avbruddet.

flowchart TD
    A["for each time step t"] --> B{"i &gt; 0 ?"}
    B -- yes --> C["model.step(dt, rng)<br/>evolve noise state"]
    B -- no --> D
    C --> D{"GNSS state at t ?"}
    D -- "Nominal" --> E["discipline to truth<br/>(estimator sync / dead-reckoning reset)<br/>error = 0"]
    D -- "Denied/Degraded" --> F["estimator predicts;<br/>error = truth − prediction"]
    E --> G["record Sample(t, error, gnss)"]
    F --> G
    G --> A
    A -. after loop .-> H["score(series, spec)<br/>→ figures of merit"]
    H --> I["assemble Result<br/>(specs · series · FoM · scenario hash)"]

Et scenario kjører denne pipelinen to ganger, én gang for kvantesensoren og én gang for den klassiske sensoren, med uavhengige seed (classical_seed = seed + 0x9e3779b97f4a7c15), slik at de to støyrealiseringene er ukorrelerte.

3. Grensesnittet for feilmodeller (utvidelsespunktet)#

Hver sensor implementerer den samme ideen: et objekt med tilstand der step() fører den interne stokastiske feilen videre, og der den akkumulerte tilstanden leses ut ved hvert tikk. Klokker eksponerer akkumulert fase, akselerometre eksponerer dobbeltintegrert posisjon, og lenker eksponerer jitter per måling.

classDiagram
    class ErrorModel {
      <<trait>>
      +step(dt, rng)
      +spec() ModelSpec
    }
    class ClockModel {
      +y0, q_wf, q_rw, drift, flicker
      +phase() s
      +det_freq()  +drift_rate()
    }
    class AccelModel {
      +bias, q_va, gyro_bias, q_arw
      +pos() m  +theta() rad
      +reset()
    }
    class TimeTransferLink {
      +sigma_j
      +sample(rng) s
    }
    ErrorModel <|.. ClockModel
    ClockModel : white FM + random-walk FM + flicker FM + aging
    AccelModel : accel bias + VRW + gyro bias + ARW (gravity-tilt)
    TimeTransferLink : white timing jitter

ModelSpec { id, kind, provenance, params } følger med inn i resultatet, slik at hvert tall i utdataene kan spores til den publiserte kilden som er oppgitt i provenance.

Ved siden av den analytiske HoldoverEstimator kjører klokkepakken et Kalman-filter med to tilstander (fase, frekvens) (KalmanClock) hvis prosessstøy tilsvarer referansemodellen. Når det går på tomgang gjennom et avbrudd, vokser faseavvikets varians nøyaktig til q_wf·T + q_rw·T³/3, den analytiske holdover-relasjonen, og filterets løpende 1-σ-grense brukes til å fylle ut kvalitetsmålet Integritet (andelen av avbruddets sampler der feilen holder seg innenfor k-σ-grensen).

4. Utsendelse (CLI og bindinger)#

api::run_toml(src) er det eneste inngangspunktet: den titter på kind på øverste nivå, deserialiserer det samsvarende scenarioet, kjører pakken og returnerer { json, svg, summary, csv } (csv finnes bare for de typene som publiserer en reproduserbarhetstabell). CLI-en skriver disse til filer, sammen med rapporten (report.html, report.json) og eventuelle utdata fra --export / --animate; bindingene for Python og WebAssembly returnerer dem til verten. Én utsendelse, ingen avdrift.

flowchart TD
    F["api::run_toml(src) · run_scenario(src)"] --> K{"ScenarioKind::classify<br/>typed · exhaustive · 92 kinds<br/>(absent kind → clock; unknown kind → InvalidInput)"}
    K --> G1["Timing<br/>clock · timetransfer · quantum-time-transfer · telecom-timing · slot-timing"]
    K --> G2["Inertial & fusion<br/>inertial · hybrid · hybrid-ukf · fusion · gnss-ins · quantum-gnss-free-nav · ins-trn-coast · hybrid-optical-rf"]
    K --> G3["Orbit, geometry & positioning<br/>orbit · ephemeris · constellation-design · gnss-sim · pvt"]
    K --> G4["Integrity<br/>integrity · lunar-integrity · araim-reference-check"]
    K --> G5["Resilience & spectrum<br/>jamming · spoof · spoof-detect · quantum-anomaly-detect · tracking-loop · spectrum · conflict-resilience"]
    K --> G6["Alt-PNT (GPS-denied)<br/>gravity-map · terrain-nav · terrain-slam · combined-altpnt"]
    K --> G7["LEO PNT<br/>leo-signal · leo-pass · leo-navmsg · leo-pvt · leo-ppp · ntn-positioning · leo-pnt-chain"]
    K --> G8["Lunar / cislunar suite (MODELLED)<br/>lunar-time-offset · lunar-time-budget · lunar-vlbi · lunar-vlbi-fim · lunar-joint-od-clock<br/>lunar-frame-realisation · lunar-frame-campaign · lunar-llr-datum · realtime-frame-eop<br/>moonlight-service-volume · lunar-differential-pnt · lunar-interop-export · lunar-beacon<br/>lunar-jamming · lunar-attack-surface · earth-gnss-lunar · cislunar-observability · cislunar-arc-recovery"]
    K --> G9["Deep space & solar system<br/>mars-pnt · solar-system · body-pnt"]
    K --> G10["Machine learning & trade<br/>impairment-eval · quantum-trade"]
    K --> G11["Mission analysis & environment<br/>launch-window · reentry · eo-coverage · attitude-budget · aperture-duty-cycle<br/>passes · link-budget · space-packet · space-weather"]
    K --> G12["Trade studies, campaigns & interop<br/>sweep · sweep-nd · campaign · oem-interop"]
    G1 & G2 & G3 & G4 & G5 & G6 & G7 & G8 & G9 & G10 & G11 & G12 --> W["RunOutput { json, svg, summary, csv }<br/>+ SHA-256 scenario_hash"]

Utsendelsen skjer på en typet enum ScenarioKind som matches uttømmende (se neste delavsnitt), så å legge til en pakke er en endring som kompilatoren kontrollerer. Et manglende kind faller tilbake på pakken clock, slik at eksisterende scenarioer med én type deserialiseres uendret (serde ignorerer feltet kind på hver scenariostruktur). En ukjent kind avvises med KshanaError::InvalidInput, som nevner den nærmeste innebygde typen når navnet ser ut som en skrivefeil.

Typet utsendelse og det strukturerte API-et#

Utsendelsen skjer på en typet enum ScenarioKind, ikke på en rå strengmatch: ScenarioKind::classify(src) løser feltet kind opp til en variant, og utsenderen matcher den uttømmende. Å legge til en pakke er en endring som kompilatoren kontrollerer, ikke en skrivefeil i en streng. To typede flater ligger ved siden av run_toml, som returnerer en streng (beholdt for CLI-en og eksisterende bindinger):

  • run_scenario(src) -> Result<RunOutput, KshanaError>: det typede inngangspunktet, med et strukturert feiltaksonomi (InvalidInput, NonConvergence, Unsupported, IoError). Hver feil har en stabil kind_tag(), slik at en kaller kan forgrene seg på feilkategorien i stedet for å tolke meldingen. Bindingene eksponerer dette som error_kind(toml).
  • list_scenario_kinds() -> Vec<ScenarioMeta> (og list_scenario_kinds_json(), eksponert i bindingene som list_kinds()): programmatisk introspeksjon. Den gir hver types navn, beskrivelse og obligatoriske og valgfrie felt, til automatisk utfylling i brukergrensesnitt (UI) og notatbøker.

Å utvide Kshana med en ekstern pakke#

En tredjepartspakke implementerer to små, semver-stabile traits fra api:

use kshana::api::{ExternalPack, KshanaError, RunOutput, Scenario, ScenarioMeta};

struct MyPack {
    threshold: f64, // the deserialized scenario fields
}

impl Scenario for MyPack {
    fn run(&self) -> Result<RunOutput, KshanaError> {
        // Run the model, then build the unified output envelope.
        Ok(RunOutput {
            json: format!("{{\"threshold\": {}}}", self.threshold),
            svg: String::from("<svg xmlns=\"http://www.w3.org/2000/svg\"/>"),
            summary: format!("my-pack | threshold {}", self.threshold),
            csv: None,
        })
    }
}

impl ExternalPack for MyPack {
    fn kind_name(&self) -> &'static str {
        "my-pack"
    }
    fn meta(&self) -> ScenarioMeta {
        ScenarioMeta {
            name: "my-pack",
            description: "An out-of-tree example pack.",
            required_fields: &["threshold"],
            optional_fields: &[],
        }
    }
}

ExternalPack har også en standardmetode register_into(&mut PackRegistry), som ikke gjør noe med mindre en pakke velger å bruke registerets utsendelsessøm i src/registry.rs. Den innebygde pakken jamming er koblet inn via Scenario som det gjennomgåtte eksempelet. Pakker utenfor kodetreet følger den samme kontrakten uten å forke kjernen (på samme måte som utvidelsespunktet ErrorModel i §3, som det private robusthetslaget bruker).

Kshana har derfor to stabile utvidelsessømmer: du kan legge til en sensor ved å implementere ErrorModel (§3), eller en hel scenariotype ved å implementere Scenario + ExternalPack. Begge er semver-stabile, og ingen av dem krever en fork av kjernen:

classDiagram
    class ErrorModel {
      <<trait — sensor seam>>
      +step(dt, rng)
      +spec() ModelSpec
    }
    class Scenario {
      <<trait — pack seam>>
      +run() RunOutput
    }
    class ExternalPack {
      <<trait : Scenario>>
      +kind_name() str
      +meta() ScenarioMeta
    }
    ErrorModel <|.. ClockModel
    ErrorModel <|.. AccelModel
    ErrorModel <|.. TimeTransferLink
    Scenario <|.. ExternalPack
    Scenario <|.. JammingPack : worked example
    ExternalPack <|.. ThirdPartyPack : out-of-tree, no core fork

5. Den hybride avslutningen#

Hybridpakken kjører en suite (én klokke og én inertisensor) og krever at både tidssynkronisering og posisjon holder seg innenfor spesifikasjonen. pnt_holdover er tiden til én av dem overskrides. Eventuelt resynkroniserer en optisk intersatellittlenke klokken under avbruddet, og dette gjelder bare tidsstøtte. Posisjonen resynkroniseres ikke, fordi tidsoverføring gir tid, ikke posisjon. Dette er det som gjør inertisensoren til den begrensende faktoren.

flowchart LR
    subgraph suite["PNT suite (per technology)"]
      clk["clock → timing error"]
      acc["inertial sensor → position error"]
      isl["optical ISL<br/>re-sync clock at interval"] -. aids .-> clk
    end
    clk --> J["both within spec ?"]
    acc --> J
    J --> P["pnt_holdover = first breach<br/>(timing OR position)"]

6. GNSS-tilgjengelighet utledet av geometri#

orbit.rs er et deterministisk geometrilag uten avhengigheter. En Propagator er enten den analytiske keplerske Orbit (tolegemeproblem, eventuelt med sekulær J2) eller en full Sgp4-propagator bygd fra et komplett to-linjers elementsett. En Walker-delta-generator lager syntetiske konstellasjoner, og siktlinjesynlighet = jordokkultasjon + elevasjonsmaske. Antallet synlige satellitter gir en GNSS-tilstand (≥4 = nominell, 1–3 = redusert, 0 = nektet), og build_timeline gjør dette om til tilgjengelighetstidslinjen som driver den vanlige klokke-holdover-kjøringen. Tilgjengeligheten er altså utledet av geometri i stedet for å være skrevet for hånd, mens kjøringen, estimatoren og skåringen er uendret.

En konstellasjon som er oppgitt som fulle TLE-er, propageres med SGP4/SDP4-modellen i sgp4.rs (validert mot AIAA (American Institute of Aeronautics and Astronautics) 2006-6753-vektorene). Elementer med bare linje 2 beholder den analytiske tolegemebanen. De to kan blandes i én konstellasjonsblokk.

flowchart LR
    U["user orbit"] --> V
    C["Walker constellation"] --> V["visible_count(t)<br/>occultation + mask"]
    V --> S["gnss_state: ≥4 / 1–3 / 0"]
    S --> T["build_timeline → GnssTimeline"]
    T --> R["run_orbit_clock → clock holdover"]

7. Bindinger#

Kjernen kompileres uendret til native kode, til en Python-utvidelse og til WebAssembly. Modulene for Python (python.rs, PyO3 abi3) og WebAssembly (wasm.rs, wasm-bindgen) er valgfrie avhengigheter som styres av funksjonsflagg (--features python / --features wasm): standardbygget og testsuiten kompilerer dem aldri, mens avhengighetsrevisjonen (cargo deny --all-features) inspiserer avhengighetstrærne deres, fordi disse crate-ene leveres inne i wheel-pakken og npm-pakken. Begge kaller api::run_toml, så alle flater returnerer identiske resultater. WebAssembly-modulen driver nettleserens lekeplass i web/ og eksporterer tretten funksjoner: run, run_all (én motorkjøring som returnerer resultat, diagram, oppsummering og tabell samlet), chart_svg, summary, table_csv, list_kinds, error_kind, version, kodeken encode_permalink / decode_permalink for delbare URL-er (URL: nettadresse) og de tre eksportørene export_sp3 / export_omm / export_oem som ligger bak lekeplassens eksportmeny. To døråpninger til gir tilgang til samme api: MCP-serveren (Model Context Protocol) (mcp/kshana-mcp, en rmcp-crate utenfor arbeidsområdet som eksponerer femten verktøy: run_scenario, list_scenario_kinds, validate_scenario, list_example_scenarios, get_example_scenario, report_scenario, animate_scenario, list_export_formats, export_interop, import_route, export_sp3, export_omm, export_oem, export_table_csv, assess_receiver_log; de to eksempelverktøyene leser de medfølgende scenarioene gjennom bibliotekets funksjon bundled-scenarios, som er av som standard og som bare denne serveren slår på) og JetBrains-IDE-programtillegget (integrated development environment) (ide/jetbrains, et Kotlin-prosjekt som kaller CLI-en kshana i stedet for å lenke mot biblioteket).

flowchart LR
    cli["CLI · main.rs<br/>native binary"] --> api
    py["Python · python.rs (PyO3 abi3)<br/>RunOutput class + run · run_full · run_typed · scenario_kinds · list_kinds · validate_toml · error_kind · version"] --> api
    wasm["WebAssembly · wasm.rs (wasm-bindgen)<br/>run · run_all · chart_svg · summary · table_csv · list_kinds · error_kind · version · encode/decode_permalink<br/>export_sp3 · export_omm · export_oem"] --> api
    mcp["MCP server · mcp/kshana-mcp (rmcp)<br/>tools: run_scenario · list_scenario_kinds · validate_scenario<br/>list_example_scenarios · get_example_scenario<br/>report_scenario · animate_scenario<br/>list_export_formats · export_interop · import_route<br/>export_sp3 · export_omm · export_oem · export_table_csv"] --> api
    ide["JetBrains plugin · ide/jetbrains (Kotlin)"] -- spawns process --> cli
    api["api::run_toml / run_scenario / list_scenario_kinds"] --> out["identical { json, svg, summary } on every surface"]

Funksjonsstyring: Python og WASM er --features python / --features wasm. Tabellen over medfølgende scenarioer er --features bundled-scenarios (MCP-serverens eneste bruk av den). MCP-serveren og kryssjekkene i xval/* er crate-er som er UTELATT fra arbeidsområdet. IDE-programtillegget lenker ikke mot noe, det kjører CLI-en.

8. Determinisme og reproduserbarhet#

  • All tilfeldighet går gjennom én enkelt seedet ChaCha8Rng per kjøring. Rekkefølgen på stegene er fast, så (scenario, seed, engine version) → identical bits.
  • Resultatet har en SHA-256 (SHA: Secure Hash Algorithm) scenario_hash. scripts/check-reproducible.sh kjører et referansescenario to ganger og kontrollerer at utdataene er byte-identiske.
  • Den samme motoren kompileres til native kode, til en Python-utvidelse og til wasm32-unknown-unknown for kjøring i nettleseren med de samme tallene.

9. Utsatt / framtidig struktur#

Astrodynamikk-, fusjons- og alt-PNT-lagene i §1a er alle ferdige: den fulle SGP4/SDP4-propagatoren, den numeriske Cowell-propagatoren med sin kraftmodell med sju perturbasjoner og to adaptive integratorer, manøver- og banedesign, banebestemmelse, GNSS/INS-estimatorene med 15, 8 og 17 tilstander, det koblede klokke+posisjon-filteret og tyngdekartmatching. Det samme gjelder Sikkerhet-kvalitetsmålet med en aktiv spoof-demonstrator, ekte TLE-er og geometri for flere konstellasjoner, Monte Carlo-bånd, avveiningsstudier med sveip, den utskrivbare HTML-rapporten (HyperText Markup Language) med sin maskinlesbare tvilling, og arbeidsflytene for utgivelse, publisering, wheels og pages.

Flere funksjoner som tidligere sto her som framtidig arbeid, er siden ferdigstilt og dekkes ovenfor eller i VALIDATION: den fulle IAU 2000A-nutasjonen og den ekvinoksfrie CIO-reduksjonen GCRS↔ITRS / ITRF (International Terrestrial Reference Frame) (validert bit for bit mot SOFA/ERFA (SOFA: Standards of Fundamental Astronomy; ERFA: Essential Routines for Fundamental Astronomy)), geopotensialet EGM2008 (Earth Gravitational Model 2008) til grad/orden 70, leddet for Lense–Thirring-rammedragning, tidevann i fast jord, hav og atmosfære, en kryssvalidering av efemeride på DE-nivå (DE440/ANISE (DE440: Development Ephemeris 440; ANISE: Attitude, Navigation, Instrument, Spacecraft, Ephemeris, et rent Rust-verktøysett for planetgeometri)), den eksterne kryssvalideringen mot Orekit 12,2 av den numeriske Cowell-propagatoren (0,08 m over 24 h) og av batch- og sekvensiell banebestemmelse, og den tett koblede navigatoren med 17 tilstander som er gjort tilgjengelig som scenariotypen hybrid-ukf.

De gjenstående oppfølgingene spores i CHANGELOG [Unreleased] og i veikartet per funksjon i CAPABILITY: en ekstern referanseverdi for EGM-evaluatoren (Earth Gravitational Model) for høy grad nøyaktig på polaksen og en pyshtools-ren sammenligning nær polen (evaluatoren til grad 2190 og lasteren .gfc for kjøretid er levert, MODELLED, se xval/high-degree-gravity/), en tidsvarierende romværsdriver for det valgfrie nivået for luftmotstandstetthet etter NRLMSISE-00 (NRLMSISE: Naval Research Laboratory Mass Spectrometer and Incoherent Scatter Radar Extended atmosphere model) (standard luftmotstandstetthet er den statiske eksponentialmodellen, og Jacchia-71-tettheten i typen space-weather er karakterisert mot NRLMSISE-00, men ikke erstattet av den), en ekstern kontroll av den valgfrie skyggemodellen med solskivens randdemping, tett kobling av GNSS/INS med bærebølgefase og et ekte EGM2008/EIGEN-tyngdekart (EIGEN: European Improved Gravity model of the Earth by New techniques) for alt-PNT-matcheren.

Et privat overlegg-repo rommer robusthetsdybde som er eksportfølsom. Det kobles inn via det samme grensesnittet ErrorModel (og kontrakten ExternalPack i §4) uten å endre den offentlige motoren.