Kshana run report

L-band jamming from the spectrum, clock holdover and a Galileo-only fallback

Kind campaign · engine 0.29.0 · scenario campaign-spectrum-holdover-integrity.toml (file digest 88f7d33f660c94af…)

1. Executive summary

Campaign: existing scenario kinds composed into one run, with every number read from a real run of the named kind.

campaign 1ce2687e8ded | L-band jamming from the spectrum, clock holdover and a Galileo-only fallback | chain: 3 phases over 910 s, 0 events, alarm raised on 600 s of the grid | 8 member runs (MODELLED)

reproducibility.runs_total
8 count
seed
20260928
timeline.duration_s
910 s
timeline.step_s
1 s
reproducibility.runs_total
8 count

Honesty label (result `label`): MODELLED composition of existing scenario kinds. Every number is read from a real run of the named kind; the chaining (additive carry of a channel across a phase boundary, zero-order hold onto the timeline grid, a phase ended at a computed time) is a modelling choice, and each phase carries the label of the kind that produced it.

Capabilities used: 5 VALIDATED, 7 MODELLED, 1 PARTNER (relied on, not provided); see section 5.

Member runs: 8, aggregated in section 3a.

2. Inputs

Every field the scenario file sets, flattened to its path. Units come from the result's units block (the field-units schema, docs/field-units-schema.json) where it describes the field, otherwise from the field-name suffix; a unit neither states is shown as not stated.

ParameterValueUnitUnit source
kindcampaigntexta text input carries no unit
phases[0].duration_s60sfield-name suffix
phases[0].end_attimeline.bands[0].first_loss_t_stexta text input carries no unit
phases[0].end_at_run1not statedno units entry and no unit suffix
phases[0].nameonsettexta text input carries no unit
phases[0].runs[0].scenario.clock_classical.idcsac-sa45stexta text input carries no unit
phases[0].runs[0].scenario.clock_classical.provenanceMicrochip SA65 / SA.45s CSAC datasheet sigma_y(1s)=3e-10; q_wf=sigma_y(1s)^2.texta text input carries no unit
phases[0].runs[0].scenario.clock_classical.q_rw0not statedno units entry and no unit suffix
phases[0].runs[0].scenario.clock_classical.q_wf9.0000e-20not statedno units entry and no unit suffix
phases[0].runs[0].scenario.clock_classical.y05.0000e-10not statedno units entry and no unit suffix
phases[0].runs[0].scenario.clock_quantum.idoptical-sr-latticetexta text input carries no unit
phases[0].runs[0].scenario.clock_quantum.provenanceStrontium optical lattice clock, space-oriented goal sigma_y(1s)=1e-15 (arXiv:1503.08457); not flown.texta text input carries no unit
phases[0].runs[0].scenario.clock_quantum.q_rw0not statedno units entry and no unit suffix
phases[0].runs[0].scenario.clock_quantum.q_wf1.0000e-30not statedno units entry and no unit suffix
phases[0].runs[0].scenario.clock_quantum.y05.0000e-17not statedno units entry and no unit suffix
phases[0].runs[0].scenario.gnss.windows[0].statenominaltexta text input carries no unit
phases[0].runs[0].scenario.gnss.windows[0].t00not statedno units entry and no unit suffix
phases[0].runs[0].scenario.gnss.windows[0].t160not statedno units entry and no unit suffix
phases[0].runs[0].scenario.seed421field-units schema: input entry `seed`, matched by field name
phases[0].runs[0].scenario.threshold_ns50nsfield-name suffix
phases[0].runs[0].scenario.time.duration_s60sfield-name suffix
phases[0].runs[0].scenario.time.step_s1sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[0].runs[1].scenario.duration_s60sfield-name suffix
phases[0].runs[1].scenario.grid.f_max_mhz1590MHzfield-name suffix
phases[0].runs[1].scenario.grid.f_min_mhz1160MHzfield-name suffix
phases[0].runs[1].scenario.grid.n_freq430not statedno units entry and no unit suffix
phases[0].runs[1].scenario.jammers[0].bandwidth_mhz16MHzfield-name suffix
phases[0].runs[1].scenario.jammers[0].centre_mhz1575.42MHzfield-name suffix
phases[0].runs[1].scenario.jammers[0].eirp_dbw-13dBWfield-name suffix
phases[0].runs[1].scenario.jammers[0].namechirp privacy devicetexta text input carries no unit
phases[0].runs[1].scenario.jammers[0].on_s10sfield-name suffix
phases[0].runs[1].scenario.jammers[0].range_m100mfield-name suffix
phases[0].runs[1].scenario.jammers[0].sweep_period_us9usfield-name suffix
phases[0].runs[1].scenario.jammers[0].waveformchirptexta text input carries no unit
phases[0].runs[1].scenario.kindspectrumtexta text input carries no unit
phases[0].runs[1].scenario.receiver.antenna_temp_k290Kfield-name suffix
phases[0].runs[1].scenario.receiver.noise_figure_db2dBfield-name suffix
phases[0].runs[1].scenario.receiver.tracking_threshold_dbhz25dB-Hzfield-name suffix
phases[0].runs[1].scenario.seed71field-units schema: input entry `seed`, matched by field name
phases[0].runs[1].scenario.step_s1sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[0].runs[1].series[0].channelcn0_l1ca_dbhztexta text input carries no unit
phases[0].runs[1].series[0].ttimeline.t_s[]texta text input carries no unit
phases[0].runs[1].series[0].unitdB-Hztexta text input carries no unit
phases[0].runs[1].series[0].ytimeline.bands[0].cn0_effective_dbhz[]texta text input carries no unit
phases[0].runs[1].series[1].channelcn0_e1_dbhztexta text input carries no unit
phases[0].runs[1].series[1].ttimeline.t_s[]texta text input carries no unit
phases[0].runs[1].series[1].unitdB-Hztexta text input carries no unit
phases[0].runs[1].series[1].ytimeline.bands[1].cn0_effective_dbhz[]texta text input carries no unit
phases[0].runs[1].series[2].channelcn0_floor_dbhztexta text input carries no unit
phases[0].runs[1].series[2].ttimeline.t_s[]texta text input carries no unit
phases[0].runs[1].series[2].yreceiver.tracking_threshold_dbhztexta text input carries no unit
phases[0].runs[1].series[3].channelalarmtexta text input carries no unit
phases[0].runs[1].series[3].comparebelowtexta text input carries no unit
phases[0].runs[1].series[3].ttimeline.t_s[]texta text input carries no unit
phases[0].runs[1].series[3].threshold25not statedno units entry and no unit suffix
phases[0].runs[1].series[3].ytimeline.bands[0].cn0_effective_dbhz[]texta text input carries no unit
phases[0].runs[2].scenario.al_h_m40mfield-name suffix
phases[0].runs[2].scenario.al_v_m50mfield-name suffix
phases[0].runs[2].scenario.constellation.altitude_km20200kmfield-name suffix
phases[0].runs[2].scenario.constellation.inclination_deg55degfield-name suffix
phases[0].runs[2].scenario.constellation.phasing_f1not statedno units entry and no unit suffix
phases[0].runs[2].scenario.constellation.planes6not statedno units entry and no unit suffix
phases[0].runs[2].scenario.constellation.sats_per_plane4not statedno units entry and no unit suffix
phases[0].runs[2].scenario.kindintegritytexta text input carries no unit
phases[0].runs[2].scenario.mask_deg5degfield-name suffix
phases[0].runs[2].scenario.p_fa1.0000e-5not statedno units entry and no unit suffix
phases[0].runs[2].scenario.p_md0.001not statedno units entry and no unit suffix
phases[0].runs[2].scenario.seed71field-units schema: input entry `seed`, matched by field name
phases[0].runs[2].scenario.sigma_uere_m1mfield-name suffix
phases[0].runs[2].scenario.time.duration_s60sfield-name suffix
phases[0].runs[2].scenario.time.step_s10sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[0].runs[2].scenario.user.altitude_km0.4kmfield-name suffix
phases[0].runs[2].scenario.user.inclination_deg45degfield-name suffix
phases[0].runs[2].scenario.user.raan_deg10degfield-name suffix
phases[0].runs[2].scenario.user.u0_deg0degfield-name suffix
phases[1].carry[time_error_ns]not statedno units entry and no unit suffix
phases[1].duration_s600sfield-name suffix
phases[1].nameholdovertexta text input carries no unit
phases[1].runs[0].scenario.clock_classical.idcsac-sa45stexta text input carries no unit
phases[1].runs[0].scenario.clock_classical.provenanceMicrochip SA65 / SA.45s CSAC datasheet sigma_y(1s)=3e-10; q_wf=sigma_y(1s)^2.texta text input carries no unit
phases[1].runs[0].scenario.clock_classical.q_rw0not statedno units entry and no unit suffix
phases[1].runs[0].scenario.clock_classical.q_wf9.0000e-20not statedno units entry and no unit suffix
phases[1].runs[0].scenario.clock_classical.y05.0000e-10not statedno units entry and no unit suffix
phases[1].runs[0].scenario.clock_quantum.idoptical-sr-latticetexta text input carries no unit
phases[1].runs[0].scenario.clock_quantum.provenanceStrontium optical lattice clock, space-oriented goal sigma_y(1s)=1e-15 (arXiv:1503.08457); not flown.texta text input carries no unit
phases[1].runs[0].scenario.clock_quantum.q_rw0not statedno units entry and no unit suffix
phases[1].runs[0].scenario.clock_quantum.q_wf1.0000e-30not statedno units entry and no unit suffix
phases[1].runs[0].scenario.clock_quantum.y05.0000e-17not statedno units entry and no unit suffix
phases[1].runs[0].scenario.gnss.windows[0].statenominaltexta text input carries no unit
phases[1].runs[0].scenario.gnss.windows[0].t00not statedno units entry and no unit suffix
phases[1].runs[0].scenario.gnss.windows[0].t11not statedno units entry and no unit suffix
phases[1].runs[0].scenario.gnss.windows[1].statedeniedtexta text input carries no unit
phases[1].runs[0].scenario.gnss.windows[1].t01not statedno units entry and no unit suffix
phases[1].runs[0].scenario.gnss.windows[1].t1600not statedno units entry and no unit suffix
phases[1].runs[0].scenario.seed431field-units schema: input entry `seed`, matched by field name
phases[1].runs[0].scenario.threshold_ns50nsfield-name suffix
phases[1].runs[0].scenario.time.duration_s600sfield-name suffix
phases[1].runs[0].scenario.time.step_s10sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[1].runs[1].scenario.duration_s600sfield-name suffix
phases[1].runs[1].scenario.grid.f_max_mhz1590MHzfield-name suffix
phases[1].runs[1].scenario.grid.f_min_mhz1160MHzfield-name suffix
phases[1].runs[1].scenario.grid.n_freq430not statedno units entry and no unit suffix
phases[1].runs[1].scenario.jammers[0].bandwidth_mhz16MHzfield-name suffix
phases[1].runs[1].scenario.jammers[0].centre_mhz1575.42MHzfield-name suffix
phases[1].runs[1].scenario.jammers[0].eirp_dbw-13dBWfield-name suffix
phases[1].runs[1].scenario.jammers[0].namechirp privacy devicetexta text input carries no unit
phases[1].runs[1].scenario.jammers[0].on_s0sfield-name suffix
phases[1].runs[1].scenario.jammers[0].range_m100mfield-name suffix
phases[1].runs[1].scenario.jammers[0].sweep_period_us9usfield-name suffix
phases[1].runs[1].scenario.jammers[0].waveformchirptexta text input carries no unit
phases[1].runs[1].scenario.kindspectrumtexta text input carries no unit
phases[1].runs[1].scenario.receiver.antenna_temp_k290Kfield-name suffix
phases[1].runs[1].scenario.receiver.noise_figure_db2dBfield-name suffix
phases[1].runs[1].scenario.receiver.tracking_threshold_dbhz25dB-Hzfield-name suffix
phases[1].runs[1].scenario.seed71field-units schema: input entry `seed`, matched by field name
phases[1].runs[1].scenario.step_s10sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[1].runs[1].series[0].channelcn0_l1ca_dbhztexta text input carries no unit
phases[1].runs[1].series[0].ttimeline.t_s[]texta text input carries no unit
phases[1].runs[1].series[0].unitdB-Hztexta text input carries no unit
phases[1].runs[1].series[0].ytimeline.bands[0].cn0_effective_dbhz[]texta text input carries no unit
phases[1].runs[1].series[1].channelcn0_e1_dbhztexta text input carries no unit
phases[1].runs[1].series[1].ttimeline.t_s[]texta text input carries no unit
phases[1].runs[1].series[1].unitdB-Hztexta text input carries no unit
phases[1].runs[1].series[1].ytimeline.bands[1].cn0_effective_dbhz[]texta text input carries no unit
phases[1].runs[1].series[2].channelcn0_floor_dbhztexta text input carries no unit
phases[1].runs[1].series[2].ttimeline.t_s[]texta text input carries no unit
phases[1].runs[1].series[2].yreceiver.tracking_threshold_dbhztexta text input carries no unit
phases[1].runs[1].series[3].channelalarmtexta text input carries no unit
phases[1].runs[1].series[3].comparebelowtexta text input carries no unit
phases[1].runs[1].series[3].ttimeline.t_s[]texta text input carries no unit
phases[1].runs[1].series[3].threshold25not statedno units entry and no unit suffix
phases[1].runs[1].series[3].ytimeline.bands[1].cn0_effective_dbhz[]texta text input carries no unit
phases[2].duration_s300sfield-name suffix
phases[2].namegalileo-fallbacktexta text input carries no unit
phases[2].runs[0].scenario.clock_classical.idcsac-sa45stexta text input carries no unit
phases[2].runs[0].scenario.clock_classical.provenanceMicrochip SA65 / SA.45s CSAC datasheet sigma_y(1s)=3e-10; q_wf=sigma_y(1s)^2.texta text input carries no unit
phases[2].runs[0].scenario.clock_classical.q_rw0not statedno units entry and no unit suffix
phases[2].runs[0].scenario.clock_classical.q_wf9.0000e-20not statedno units entry and no unit suffix
phases[2].runs[0].scenario.clock_classical.y05.0000e-10not statedno units entry and no unit suffix
phases[2].runs[0].scenario.clock_quantum.idoptical-sr-latticetexta text input carries no unit
phases[2].runs[0].scenario.clock_quantum.provenanceStrontium optical lattice clock, space-oriented goal sigma_y(1s)=1e-15 (arXiv:1503.08457); not flown.texta text input carries no unit
phases[2].runs[0].scenario.clock_quantum.q_rw0not statedno units entry and no unit suffix
phases[2].runs[0].scenario.clock_quantum.q_wf1.0000e-30not statedno units entry and no unit suffix
phases[2].runs[0].scenario.clock_quantum.y05.0000e-17not statedno units entry and no unit suffix
phases[2].runs[0].scenario.gnss.windows[0].statenominaltexta text input carries no unit
phases[2].runs[0].scenario.gnss.windows[0].t00not statedno units entry and no unit suffix
phases[2].runs[0].scenario.gnss.windows[0].t1300not statedno units entry and no unit suffix
phases[2].runs[0].scenario.seed441field-units schema: input entry `seed`, matched by field name
phases[2].runs[0].scenario.threshold_ns50nsfield-name suffix
phases[2].runs[0].scenario.time.duration_s300sfield-name suffix
phases[2].runs[0].scenario.time.step_s10sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[2].runs[1].scenario.duration_s300sfield-name suffix
phases[2].runs[1].scenario.grid.f_max_mhz1590MHzfield-name suffix
phases[2].runs[1].scenario.grid.f_min_mhz1160MHzfield-name suffix
phases[2].runs[1].scenario.grid.n_freq430not statedno units entry and no unit suffix
phases[2].runs[1].scenario.jammers[0].centre_mhz1575.42MHzfield-name suffix
phases[2].runs[1].scenario.jammers[0].eirp_dbw-20dBWfield-name suffix
phases[2].runs[1].scenario.jammers[0].nameCW tone on L1texta text input carries no unit
phases[2].runs[1].scenario.jammers[0].on_s0sfield-name suffix
phases[2].runs[1].scenario.jammers[0].range_m1000mfield-name suffix
phases[2].runs[1].scenario.jammers[0].waveformcwtexta text input carries no unit
phases[2].runs[1].scenario.kindspectrumtexta text input carries no unit
phases[2].runs[1].scenario.receiver.antenna_temp_k290Kfield-name suffix
phases[2].runs[1].scenario.receiver.noise_figure_db2dBfield-name suffix
phases[2].runs[1].scenario.receiver.tracking_threshold_dbhz25dB-Hzfield-name suffix
phases[2].runs[1].scenario.seed71field-units schema: input entry `seed`, matched by field name
phases[2].runs[1].scenario.step_s10sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[2].runs[1].series[0].channelcn0_l1ca_dbhztexta text input carries no unit
phases[2].runs[1].series[0].ttimeline.t_s[]texta text input carries no unit
phases[2].runs[1].series[0].unitdB-Hztexta text input carries no unit
phases[2].runs[1].series[0].ytimeline.bands[0].cn0_effective_dbhz[]texta text input carries no unit
phases[2].runs[1].series[1].channelcn0_e1_dbhztexta text input carries no unit
phases[2].runs[1].series[1].ttimeline.t_s[]texta text input carries no unit
phases[2].runs[1].series[1].unitdB-Hztexta text input carries no unit
phases[2].runs[1].series[1].ytimeline.bands[1].cn0_effective_dbhz[]texta text input carries no unit
phases[2].runs[1].series[2].channelcn0_floor_dbhztexta text input carries no unit
phases[2].runs[1].series[2].ttimeline.t_s[]texta text input carries no unit
phases[2].runs[1].series[2].yreceiver.tracking_threshold_dbhztexta text input carries no unit
phases[2].runs[1].series[3].channelalarmtexta text input carries no unit
phases[2].runs[1].series[3].comparebelowtexta text input carries no unit
phases[2].runs[1].series[3].ttimeline.t_s[]texta text input carries no unit
phases[2].runs[1].series[3].threshold25not statedno units entry and no unit suffix
phases[2].runs[1].series[3].ytimeline.bands[1].cn0_effective_dbhz[]texta text input carries no unit
phases[2].runs[2].scenario.al_h_m40mfield-name suffix
phases[2].runs[2].scenario.al_v_m50mfield-name suffix
phases[2].runs[2].scenario.constellation.altitude_km23221.664kmfield-name suffix
phases[2].runs[2].scenario.constellation.inclination_deg56degfield-name suffix
phases[2].runs[2].scenario.constellation.phasing_f1not statedno units entry and no unit suffix
phases[2].runs[2].scenario.constellation.planes3not statedno units entry and no unit suffix
phases[2].runs[2].scenario.constellation.sats_per_plane8not statedno units entry and no unit suffix
phases[2].runs[2].scenario.kindintegritytexta text input carries no unit
phases[2].runs[2].scenario.mask_deg5degfield-name suffix
phases[2].runs[2].scenario.p_fa1.0000e-5not statedno units entry and no unit suffix
phases[2].runs[2].scenario.p_md0.001not statedno units entry and no unit suffix
phases[2].runs[2].scenario.seed71field-units schema: input entry `seed`, matched by field name
phases[2].runs[2].scenario.sigma_uere_m1mfield-name suffix
phases[2].runs[2].scenario.time.duration_s300sfield-name suffix
phases[2].runs[2].scenario.time.step_s30sfield-units schema: input entry `timeline.step_s`, matched by field name
phases[2].runs[2].scenario.user.altitude_km0.4kmfield-name suffix
phases[2].runs[2].scenario.user.inclination_deg45degfield-name suffix
phases[2].runs[2].scenario.user.raan_deg10degfield-name suffix
phases[2].runs[2].scenario.user.u0_deg0degfield-name suffix
seed202609281field-units schema: units entry `seed`
timeline.step_s1sfield-units schema: units entry `timeline.step_s`
titleL-band jamming from the spectrum, clock holdover and a Galileo-only fallbacktexta text input carries no unit

3. Results

Result chart
Result chart (also written to campaign-spectrum-holdover-integrity.chart.svg)

Scalar results

ResultValueUnit
reproducibility.campaign_hash1ce2687e8ded87c7fcb679798d3887c994934dc791b43fed638e9d5d87f0264atext
reproducibility.run_digestdd09401aa42b43d2d073648f8aae12b35fccefd825c256f2a35e6b2b774304bbtext
reproducibility.runs_total8count
seed202609281
timeline.channels.alarm.labelalarm flag: 1 while any monitor of the phase alarmstext
timeline.channels.alarm.unit1text
timeline.channels.alert_limit_m.labelvertical alert limittext
timeline.channels.alert_limit_m.unitmtext
timeline.channels.cn0_e1_dbhz.labelcn0_e1_dbhztext
timeline.channels.cn0_e1_dbhz.unitdB-Hztext
timeline.channels.cn0_floor_dbhz.labeltracking-loss floor of the receivertext
timeline.channels.cn0_floor_dbhz.unitdB-Hztext
timeline.channels.cn0_l1ca_dbhz.labelcn0_l1ca_dbhztext
timeline.channels.cn0_l1ca_dbhz.unitdB-Hztext
timeline.channels.guard_ns.labeltime-error guard (the run's own threshold)text
timeline.channels.guard_ns.unitnstext
timeline.channels.protection_level_m.labelvertical protection leveltext
timeline.channels.protection_level_m.unitmtext
timeline.channels.time_error_ns.labelclock time errortext
timeline.channels.time_error_ns.unitnstext
timeline.duration_s910s
timeline.step_s1s

Numeric columns

ColumnCountMinMaxFirstLastUnit
timeline.channels.alarm.values[]91101001
timeline.channels.alert_limit_m.values[]31150505050m
timeline.channels.cn0_e1_dbhz.values[]9114.6944.9844.9844.98dB-Hz
timeline.channels.cn0_floor_dbhz.values[]91125252525dB-Hz
timeline.channels.cn0_l1ca_dbhz.values[]9113.3843.4843.4817.98dB-Hz
timeline.channels.guard_ns.values[]91150505050ns
timeline.channels.protection_level_m.values[]3115.67042421.63589221.6358925.670424m
timeline.channels.time_error_ns.values[]911-0.0731745.06319301.358894ns
timeline.phases[].carried.time_error_ns10000ns
timeline.phases[].runs[].skip_s80000s
timeline.phases[].t0_s306100610s
timeline.phases[].t1_s31091010910s
timeline.t_s[]91109100910s

3a. Aggregation of member runs

Mode chain, 8 member runs.

Run digest (SHA-256 over the member result digests, in dispatch order): dd09401aa42b43d2d073648f8aae12b35fccefd825c256f2a35e6b2b774304bb

Chain phases

phasestart (s)end (s)duration (s)ended bymember kindscarried in
onset01010end_at timeline.bands[0].first_loss_t_s = 10 sclock, spectrum, integritynothing carried
holdover10610600duration_sclock, spectrumtime_error_ns = 0
galileo-fallback610910300duration_sclock, spectrum, integritynothing carried

3b. Animation and exports

Animation of the run's time series
The run's own samples drawing in behind a moving time cursor (the animated drawing of --animate svg; it shows the finished picture under reduced motion and in print).

The interactive player is written by kshana scenarios/campaign-spectrum-holdover-integrity.toml --animate html.

ExportAppliesFiles or reason
czml
https://github.com/AnalyticalGraphicsInc/czml-writer/wiki/CZML-Structure
yeswritten by kshana scenarios/campaign-spectrum-holdover-integrity.toml --export all
kml
https://www.ogc.org/standard/kml/
yeswritten by kshana scenarios/campaign-spectrum-holdover-integrity.toml --export all
geojson
https://www.rfc-editor.org/rfc/rfc7946
yeswritten by kshana scenarios/campaign-spectrum-holdover-integrity.toml --export all
stk
https://help.agi.com/stk/#stk/importfiles-02.htm
yeswritten by kshana scenarios/campaign-spectrum-holdover-integrity.toml --export all
sigmf
https://github.com/sigmf/SigMF/blob/main/sigmf-spec.md
nono member scenario of the campaign has anything this format describes; export a member on its own to see its reason

4. Events timeline

phase onset (ended by end_at timeline.phase holdover (ended by duration_s)phase galileo-fallback (ended by durat0 s227.5 s455 s682.5 s910 s
Windows as bars, point events as dots, on the run's own time axis.
Start (s)End (s)EventSource
010phase onset (ended by end_at timeline.bands[0].first_loss_t_s = 10 s)result `timeline.phases[0]`
10610phase holdover (ended by duration_s)result `timeline.phases[1]`
610910phase galileo-fallback (ended by duration_s)result `timeline.phases[2]`

5. Verification labels

Each row is a verification-matrix row this run's kinds exercise, with the label and the oracle the matrix gives it (src/verification.rs, docs/VERIFICATION-MATRIX.md). A label grades the capability as the matrix records it; it does not grade this scenario's configuration, and a VALIDATED row does not make the run's inputs measured. A PARTNER row is a discipline the run relies on that Kshana does not provide.

Capability (matrix requirement)LabelUsed bySource: oracleTest evidence
Frequency stability characterisation
Allan/modified/Hadamard deviation + power-law noise ID with χ² CIs
VALIDATED
exercised
clockNIST SP 1065 (Riley) / Stable32 reference deviations on NBS14 (ExternalDataset)tests/allan_reference.rs (NBS14 vs Stable32 to 1e-4); allan::tests
Integrity (RAIM/ARAIM/SBAS)
Snapshot/MHSS RAIM, ARAIM P_HMI budget, SBAS DO-229E combination
VALIDATED
exercised
integrityDO-229E/DO-316 K-factors; real IGS SP3 geometry (ExternalDataset)tests/igs_real_data.rs, tests/araim_dual_real_data.rs (real IGS SP3 + Celestrak TLE)
GNSS geometry / dilution of precision (DOP)
GDOP/PDOP/HDOP/VDOP/TDOP from line-of-sight geometry via Q=(HᵀH)⁻¹ with a local ENU split
VALIDATED
exercised
integritygnss_lib_py 1.0.4 (Stanford NAV Lab) DOP — independent library, matched to 1e-6 relative (ExternalDataset)tests/dop_reference.rs (8 geometries, well-conditioned → near-singular)
RAIM/ARAIM integrity statistical kernel (χ² / non-central χ² / normal laws)
The distributional core every protection level rests on: the snapshot fault-detection threshold χ²₁₋ₚfₐ(dof), the missed-detection non-centrality pbias=√λ, and the K_fa/K_md/K_V solution-separation multipliers
VALIDATED
exercised
integritySciPy 1.17.0 (scipy.stats.chi2/.norm/.ncx2 + optimize.brentq) — independent library (Cephes/Boost), a different algorithm from Kshana's incomplete-gamma series; matched to ≤1e-6 rel. Kernel only. The ARAIM MHSS P_HMI budget *allocation* is no longer without a published numeric oracle — the WG-C ARAIM Technical Subgroup's own worked example now backs the separate 'ARAIM MHSS protection levels against published reference vectors' row, matched at the reference's own TOL_PL = 5e-2 m — so this row's scope is the statistical kernel and that row carries the allocation (see docs/ARAIM_REFERENCE.md) (ExternalDataset)tests/raim_reference.rs (171 cases: χ² CDF/quantile, normal CDF/quantile, non-central χ² CDF, pbias across the P_fa/P_md/redundancy ranges)
GNSS-denied clock holdover
Closed-form coast-error growth + holdover-to-threshold; quantum-clock classes
MODELLED
exercised
clockMulti-step clock_state covariance recursion (same-codebase cross-check); the underlying coast-variance & holdover-inversion kernel is externally validated vs scipy (see 'Clock-holdover coast-variance & threshold inversion'). The per-class red-noise-floor holdover figures stay MODELLED (ReferenceImpl)holdover::tests (vs multi-step Kalman covariance recursion; white-FM exact; round-trip); coast-variance kernel externally validated in tests/gnss_denied_clock_holdover_reference.rs (vs scipy Van-Loan/brentq)
Onboard clock state estimation
3-state (phase/freq/drift) van-Loan Kalman clock, Joseph-stabilised
MODELLED
exercised
clockfilterpy 1.4.5 KalmanFilter (R. Labbe, MIT), with F via scipy.linalg.expm and Q via the Van-Loan 1978 block-matrix — an independent reference implementation reproducing kshana's full filter trajectory. Cross-implementation consistency: the clock physics / Allan calibration are not externally validated, so this stays MODELLED (ReferenceImpl)clock_state::tests (analytic van-Loan Q; NEES; PSD positivity); tests/clock_state_reference.rs (full predict+update trajectory — state x and 3×3 covariance P over 1925 steps / 4 parameter sets vs filterpy 1.4.5; worst |relΔ| 2.8e-14)
Spoofing detection
Clock-aided χ², RAIM, AGC, SQM fused per-epoch security FoM
MODELLED
exercised
clockTEXBAT scenario parameters (Humphreys 2012) — characterisation, not pinned vectors (ExternalDataset)tests/spoof_texbat_validation.rs (TEXBAT parameter characterisation)
Reproducibility & software assurance
Deterministic, scenario-hashed, SBOM + cross-platform golden gates
MODELLED
exercised
every runSBOM conformance to the official CycloneDX 1.5 JSON Schema (+ valid SPDX identifiers) — an external published standard, zero validation errors over the full dependency graph; the FoM-determinism / byte-reproducibility part remains a pinned self-consistency check, so the row stays MODELLED (ExternalDataset)tests/golden.rs, tests/determinism.rs, tests/cross_platform_golden.rs; tests/reproducibility_software_assurance_reference.rs (the generated SBOM validates with zero errors against the official CycloneDX 1.5 JSON Schema over the full 66-component shipped graph: default + python + wasm features, dev-dependencies excluded)
Navigation RF payload & antenna hardware design
Not provided — Kshana models signal performance, not payload/antenna hardware
PARTNER
relied on, not provided
spectrumnone: a partner-owned discipline, with no module and no test by design (NoneKind)none: a partner-owned discipline
Closed-form L-band signal power spectral densities and spectral separation coefficients
Unit-area power spectral densities of GPS L1 C/A and L2C (BPSK(1)), GPS L5 and Galileo E5a (BPSK(10)), sine-BOC(1,1) and Galileo E1 MBOC(6,1,1/11) (navsignal::Modulation::psd, with an MBOC variant added), their numerically located nulls and maxima (spectrum::psd_nulls_hz, psd_peak_hz, main_lobe_null_to_null_hz), and the spectral separation coefficient of a signal against any spectrum at any offset (navsignal::spectral_separation_coeff_offset) or against a tone, flat noise, a chirp or matched noise (spectrum::Jammer::ssc), with the anti-jam coefficient Q = 1/(R_c kappa)
VALIDATED
exercised
spectrumPublished textbook values: the BPSK(n) main lobe of 2n x 1.023 MHz null to null and the anti-jam coefficients Q = 1 for a narrowband (CW) jammer and Q = 1.5 for a spread-spectrum jammer matched to C/A (Kaplan & Hegarty, Understanding GPS/GNSS, 3rd ed., section 9.4); the BOC(m,n) main lobes centred at plus or minus m x 1.023 MHz (Betz, Binary Offset Carrier Modulations for Radionavigation, NAVIGATION 48(4), 2001); the spectral separation coefficients -61.8, -64.8 and -67.8 dB/Hz for C/A with C/A, BOC(1,1) with BOC(1,1) and C/A with BOC(1,1) (Betz 2001; Hein et al., MBOC: The New Optimized Spreading Modulation Recommended for Galileo L1 OS and GPS L1C, Inside GNSS, May/June 2006), reproduced here from their Parseval autocorrelation closed forms. The BOC(1,1) maximum is not at 1.023 MHz: the lobe spans the carrier null to 2.046 MHz and peaks at 0.759 MHz, and the test pins both. The MBOC mix is the ICD definition, checked for unit area and linearity only (ExternalDataset)spectrum::tests (bpsk_main_lobe_null_to_null_is_two_n_times_1_023_mhz — BPSK(1) 2.046 MHz and BPSK(10) 20.46 MHz located numerically on the closed form; boc11_lobes_are_centred_at_plus_minus_1_023_mhz — carrier null, first null at 2.046 MHz, lobe centre 1.023 MHz, and the exact maximum at 0.7590 MHz against an independent Newton solve of tan y = 2y; ssc_matches_parseval_closed_forms — C/A x C/A 2/(3R_c) = -61.86 dB/Hz, BOC(1,1) x BOC(1,1) 1/(3R_c) = -64.87 dB/Hz, C/A x BOC(1,1) 1/(6R_c) = -67.88 dB/Hz, each within 0.02 dB; q_values_match_kaplan_hegarty — CW at the carrier Q = 1, matched-spectrum noise Q = 1.5, flat null-to-null noise Q = 2.215; mboc_is_a_unit_area_one_eleventh_mix)
L-band spectrum waterfall with per-band J/S and effective C/N0 under a scripted jammer timeline
The `spectrum` kind: a frequency-by-time grid of the L-band power spectral density (thermal floor k T_sys with T_sys = T_ant + 290 K (F - 1), the signals at their interface-specification minimum received powers, and continuous-wave, narrowband, chirp and matched-noise jammers with on/off times), each cell averaged over its bin and row (chirps exactly over whole and partial sweeps, jammers by duty), per-band effective C/N0 = [1/(C/N0) + sum (J/S) kappa]^-1 per row, J/S per band, in-band J/S, and an SVG waterfall with C/N0 bars. The report carries a cross-check against the `jamming` kind's chain on the same link inputs
MODELLED
exercised
spectrumReduction to the existing `jamming` kind's anti-jam equation and link budget (the same code, called on the same inputs), and the k T0 F noise-floor closed form. The signal spectra underneath are the validated row above; the jammer powers, timeline and front-end bandwidths are scenario inputs, the spectra are continuous (no spreading-code lines), and no automatic gain control, blanking or antenna pattern acts on the jammer. No measured jammed spectrum is in the repository to check the composite against. The `jamming` kind's representative Q table (broadband 1.0, CW 1.5) differs from the Q this model derives from the spectra (CW at the carrier 1.0, matched 1.5, flat null-to-null 2.2); the report prints both (InternalConsistency)spectrum::tests (agrees_with_the_jamming_kind_chain — J/S equal to jamming::j_over_s_db and effective C/N0 equal to jamming::effective_cn0_dbhz with Q = 1/(R_c kappa) to 1e-9 dB, and the 32.105 dB anchor of the jamming kind's own test; noise_floor_is_kt0f; chirp_window_splits_whole_and_partial_sweeps; duty_weights_partial_rows; demo_scenario_runs_and_denies_l1_while_l5_survives; defaults_run_with_no_jammer; bad_inputs_are_refused)
SigMF recording input and output, and Welch spectral estimates of complex IQ
sigmf: read and write Signal Metadata Format recordings (JSON .sigmf-meta with the core global, captures and annotations fields; raw .sigmf-data as cf32_le, ci16_le or ci8, the integer decoders shared with realdata::iqif::load_iq), all on strings and byte buffers. spectrum::welch_psd: Hann-windowed, overlapped, averaged periodograms, density-scaled, on an in-crate radix-2 transform (spectrum::fft_in_place). spectrum::synthesise_iq draws the model as IQ, and the `spectrum` kind's [iq] section runs model to IQ to SigMF to Welch and compares with the model; its [recording] section estimates a real recording (native builds)
MODELLED
exercised
spectrumRound-trip identities, a direct discrete Fourier transform, and the white-noise, Parseval and Hann equivalent-noise-bandwidth closed forms. The SigMF field names follow the published specification (github.com/sigmf/SigMF), but no externally produced recording is in the repository, so reading a third-party file is untested here and the row stays Modelled. A synthesised periodic chirp shows lines, Fresnel ripple and edge tails the smooth model omits: total power agrees within 2 %, per-bin densities near a chirp do not (InternalConsistency)sigmf::tests (cf32_round_trip_is_exact_to_single_precision; ci16_round_trip_is_within_half_a_code; ci16_is_little_endian_i_then_q; integer_encoding_counts_saturation; metadata_uses_the_core_namespace; unsupported_types_and_channels_are_refused; sample_start_offsets_into_the_data); spectrum::tests (fft_matches_a_direct_dft; welch_reads_white_noise_as_variance_over_fs_and_keeps_a_tone_s_power — floor within 2 % of variance over sample rate, Parseval total within 2 %, Hann equivalent noise bandwidth 1.5 bins; noise_like_synthesis_is_unbiased_through_welch — median Welch-minus-model within 0.1 dB through a ci16_le round trip; synthesised_iq_through_sigmf_reproduces_the_model_spectrum)
A chained mission across scenario kinds on one shared timeline
The `campaign` kind's phases: each phase runs one or more scenarios of existing kinds through run_toml, reads their outputs into named channels (clock time error and guard, mean effective carrier-to-noise density ratio and tracking floor, vertical protection level and alert limit, position error, satellites tracking, alarm flags) by per-kind presets or explicit result paths, places them at the phase start and holds them onto a common grid, with phase boundaries and events; state is handed on by carry (a channel continues from the previous phase's end value), handoff (a previous phase's number written into the next scenario) and end_at (a phase ends at a time a run computed, such as a spoofing monitor's detection time); a campaign hash and a digest over every member result
MODELLED
exercised
campaignComposition identities against the stand-alone runs of the same kinds: a one-phase campaign reproduces the stand-alone output bit for bit, the carried offset equals the previous run's own last sample, and the phase ended by end_at has exactly the run's detection time as its length. The additive carry across a phase boundary and the zero-order hold are modelling choices, and each phase is as good as the kind that ran it; no chained mission has been checked against a measured one (InternalConsistency)tests/campaign_composition_reference.rs (a_one_phase_clock_campaign_reproduces_the_standalone_run_bit_for_bit, a_one_phase_integrity_campaign_reproduces_the_standalone_run_bit_for_bit, a_one_phase_jamming_campaign_reproduces_the_standalone_run_bit_for_bit — the member result byte-identical to the stand-alone run and every aligned value equal to the stand-alone series; the_chained_mission_hands_state_on_and_ends_the_spoofing_phase_on_detection; a_handoff_writes_the_previous_phase_number_into_the_next_scenario; malformed_campaigns_fail_loudly)

6. Not modelled, and assumptions

Each item is quoted from where it is stated: the result document, the kind catalogue, the scenario file, or the verification matrix's reason a MODELLED row stays modelled.

StatementSource
MODELLED composition of existing scenario kinds. Every number is read from a real run of the named kind; the chaining (additive carry of a channel across a phase boundary, zero-order hold onto the timeline grid, a phase ended at a computed time) is a modelling choice, and each phase carries the label of the kind that produced it.result `label`
MODELLED: the additive carry and the zero-order hold are modelling choices, and each phase carries the label of the kind that ran it.kind catalogue (`kshana kinds --json`)
MODELLED: the chaining is a modelling choice (additive carry, zero-order hold), and each phase is as good as the kind that ran it. E1 recovering under the CW tone rests on the spectrum kind's continuous-spectrum treatment (a CW tone on the MBOC carrier null couples nothing); a real tone would couple through the code's spectral lines.scenario file comment, lines 30 to 33
GNSS-denied clock holdover is MODELLED, not validated: checked against a separate implementation in this same codebase — independent of the unit under test, but not externally authoritative.verification matrix (docs/MODELLED-RATIONALE.md)
Onboard clock state estimation is MODELLED, not validated: checked against a separate implementation in this same codebase — independent of the unit under test, but not externally authoritative.verification matrix (docs/MODELLED-RATIONALE.md)
Spoofing detection is MODELLED, not validated: a sub-claim is externally checked, but the whole capability composes modelled pieces, so the capability stays Modelled.verification matrix (docs/MODELLED-RATIONALE.md)
Reproducibility & software assurance is MODELLED, not validated: a sub-claim is externally checked, but the whole capability composes modelled pieces, so the capability stays Modelled.verification matrix (docs/MODELLED-RATIONALE.md)
L-band spectrum waterfall with per-band J/S and effective C/N0 under a scripted jammer timeline is MODELLED, not validated: checked against its own closed-form / analytic identity — catches transcription and coefficient errors, but is not an external oracle.verification matrix (docs/MODELLED-RATIONALE.md)
SigMF recording input and output, and Welch spectral estimates of complex IQ is MODELLED, not validated: checked against its own closed-form / analytic identity — catches transcription and coefficient errors, but is not an external oracle.verification matrix (docs/MODELLED-RATIONALE.md)
A chained mission across scenario kinds on one shared timeline is MODELLED, not validated: checked against its own closed-form / analytic identity — catches transcription and coefficient errors, but is not an external oracle.verification matrix (docs/MODELLED-RATIONALE.md)

7. Reproducibility record

Command to reproducekshana scenarios/campaign-spectrum-holdover-integrity.toml
Working directoryRun the command from the directory the original run was started in: the scenario path, and any relative data path inside the scenario, resolve against it. Check the scenario file against scenario_sha256 first.
Engine version0.29.0
Source commitnot recorded: this engine was built without the KSHANA_GIT_COMMIT environment variable; the engine version identifies the release
Scenario filecampaign-spectrum-holdover-integrity.toml
Scenario file SHA-256 (Secure Hash Algorithm 256-bit)88f7d33f660c94afa81cd60ec0de435be8f4dc34b00bf544b28a58d9841d53f7
Result scenario_hash1ce2687e8ded87c7fcb679798d3887c994934dc791b43fed638e9d5d87f0264a (the kind's own fingerprint of the scenario; not the file digest)
Result document SHA-256e1c0060106fcd1a45ec3daafbfd6c5756be1713cbf109d7d13f741a4c856060c (campaign-spectrum-holdover-integrity.result.json)
Seed20260928 (scenario `seed`)
Platformmacos / aarch64 (unix)
DeterminismSame scenario bytes, seed and engine build give a byte-identical result document and report; this report carries no timestamp. Floating-point results are pinned per platform; another operating system or architecture may differ in the last digits.

To print this page to a Portable Document Format (PDF) file, use the browser's print dialog and choose “Save as PDF”; the print stylesheet fits A4 and US Letter paper, repeats table headers across pages and starts the inputs, results, labels and reproducibility sections on a new page. The engine writes no PDF itself. report.json carries the same content as this page.