Index: cloudsync/utils/watchdog.py =================================================================== diff -u -rbc93cd656618402440375e4fdf986a1b42212e19 -r4c51787148b0f3db26bdc8e27d7632e7f972a86a --- cloudsync/utils/watchdog.py (.../watchdog.py) (revision bc93cd656618402440375e4fdf986a1b42212e19) +++ cloudsync/utils/watchdog.py (.../watchdog.py) (revision 4c51787148b0f3db26bdc8e27d7632e7f972a86a) @@ -27,7 +27,7 @@ import os from logging import Logger from threading import Event, Thread -from time import sleep, time +from time import monotonic, sleep # Default sentinel file path — cs.py monitors this to trigger process restart @@ -169,7 +169,10 @@ if last_ts == 0: is_stale = False else: - age = time() - last_ts + # F13 — compare in monotonic time. A wall-clock step + # (operator `date` command or ntpd correction) must not + # trip the watchdog; only real elapsed idle time matters. + age = monotonic() - last_ts if age > entry["max_idle_s"]: is_stale = True stale_reason = ("progress stale %.1fs > max_idle_s %s"