Time and the clock
In Spek, time is the schedule. Height equals slot number, so a block's time is never declared: it follows from its height. That makes the clock a consensus input, and Spek does not take it from the operating system.
Why the header has no timestamp
With genesis timestamp G, the slot being mined right now, and the block at height h, are
time_derived_timeslot = (now − G) / 30
settled_tip = time_derived_timeslot − 1
derived_timestamp(h) = G + 30·h
A slot is unsettled while it is being mined and settled once it closes. A block at height h can only ever have timestamp G + 30h, so there is no timestamp field to grind, no median-time-past rule, and no tolerance window to validate.
Where time comes from
A wrong clock puts a node in the wrong slot, so each node keeps its own verified clock from Roughtime servers. Every response is authenticated end to end: the server's long-term key signs a delegation, the delegated key signs the response, and the node's own request is bound into the signed reply, so a recorded answer cannot be replayed.
- One vote per operator. Servers are queried in parallel. Each operator, counted by who holds the keys rather than by address, casts one vote: the median of its own samples. Votes more than 2 seconds from the median of votes are discarded, at least 3 voting operators must remain, and the median of what remains is adopted. Extra servers under one operator add availability, never extra votes.
- Step bound. A new median is accepted outright only within 5 seconds of where the node's clock already is. A larger backward step is refused; a larger forward step needs corroboration.
The hardware clock between syncs
Between syncs a node projects verified time forward on the raw hardware oscillator, not on the system clock the host's NTP daemon disciplines. That clock follows whatever the NTP daemon is told: a measured on-path NTP offset walked an earlier design a full slot in about six minutes while its drift gauge read zero.
Raw oscillators run 30–100 ppm off on ordinary and cloud hosts, so the node learns its oscillator's rate from successive syncs and corrects for it. Each sync may move the learned rate by at most 50 ppm, and the rate is clamped at 250 ppm, so a steered quorum cannot install a large false rate in one step. A node syncs hourly while it learns the rate, and every 4 hours once a sync confirms the rate to within 5 ppm.
No verified time, no blocks
A node that has never acquired a verified baseline does not sign blocks. Everything else, relaying, serving and syncing, continues. An opt-out exists for the case where every configured server is down, and it is loud.