This is a recorded replay of simulated data, not a live installation. Every value here comes from the red-team simulator.
time walk
A slow time spoof. GPS is dragged away a few milliseconds per second — gently enough that no single reading looks wrong. Watch the gap open between the GPS trace and the consensus band, and note which detector catches it: the step threshold never trips, but CUSUM accumulates the drift until it does.
ALARM
last agreed 157s before the end
glonass_cn0_spread: OKgps_cn0_spread: OKgps_position_error: OKgps_time_offset: ALARMntp_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