This is a recorded replay of simulated data, not a live installation. Every value here comes from the red-team simulator.
position jump
A crude spoof. The reported position leaps away from the surveyed antenna, which cannot physically move. The step detector fires on the first bad fix, and the time channels stay clean — telling you the attack is on position, not on the clock.
ALARM
last agreed 0s before the end
glonass_cn0_spread: OKgps_cn0_spread: OKgps_position_error: ALARMgps_time_offset: OKntp_time_offset: OKroughtime_time_offset: OK
What each chart shows
Every formula below is the one the code runs, with its source location. Thresholds are not repeated here — they come from the daemon's own published settings.
gps_time_offset
Variable
gps_time_offset — seconds
Source
The time field of each $GPRMC sentence, against the receiving host's own clock.
Description
How far GPS-reported UTC sits from local time. A time spoof drags this away while the independent references stay put — which is the disagreement the monitor exists to notice.
The per-satellite carrier-to-noise values in each $GPGSV cycle, one channel per constellation.
Description
Spread of signal strength across the satellites in view. A real sky fades with elevation, so healthy spread is wide; a simulator transmitting every channel at equal power collapses it toward zero.
The per-satellite carrier-to-noise values in each $GPGSV cycle, one channel per constellation.
Description
Spread of signal strength across the satellites in view. A real sky fades with elevation, so healthy spread is wide; a simulator transmitting every channel at equal power collapses it toward zero.
A Roughtime server's signed response, verified with Ed25519 and a Merkle inclusion proof for our nonce.
Description
Cryptographically verified time minus local time. An attacker cannot forge this without the server's private key, which is what separates it from plain NTP.
The same three detectors run on every channel above. Thresholds are per channel and are the ones the daemon actually applied — the dotted bands on each chart are drawn from them.
Detector
Rule
Source
step
alarm when abs(x − target) > threshold
discrepancy/step.py:31
cusum
S⁺ = max(0, S⁺ + (x − target − k)); S⁻ = max(0, S⁻ + (target − x − k)); alarm when max(S⁺, S⁻) > h, then reset
discrepancy/cusum.py:55-58
staleness
alarm when now − last_sample.timestamp > max_sample_age_s