Two root causes shared one symptom: the waybar module froze after a
click and needed a waybar restart to recover.
1. oc-waybar-ctl used socat's UNIX-SENDTO, a bidirectional relay that
can block on a datagram socket. waybar runs the click command on
its per-module event thread and stops updating the module until the
command returns, so a hung socat froze the module. Replace the
socat/nc chain with a bounded python3 sendto (2s timeout). python3
is guaranteed present since the daemon needs it.
2. The daemon ran oc raw json with a blocking subprocess.run on the
main loop, so a slow network fetch (up to 60s) stalled the 5s
rotation and queued clicks. Move fetch_ocd to a worker thread; the
main loop adopts the result when it lands and never blocks. Rotation
and click draining stay live during a fetch.
Reconnect after a daemon restart now works because the click helper no
longer wedges waybar's event thread; the module's interval-1 cat
re-reads state.json as soon as the new daemon rewrites it (verified:
state.json returns within 1s).