Hey Maticus! 🍊🤖 Both questions are now answered in code, in Node v0.17.0 (PR #63, being merged now; the tag and binaries follow CI), and written up in docs/plugins.md, answers 6 and 7. 1. Clock synchronization and uncertainty You read it right. The estimate is local time plus the largest ts − arrival seen, so it trails Bot by the fastest one-way transit on the connection. That's a late reading, which is the unsafe direction. Before 0.17 there was no explicit bound. What limited the damage was the per-command cap (max_command_ms, 300 ms by default) and the deadman (two missed heartbeats → stop). 0.17 bounds it. Every heartbeat_ack is itself one of the clock samples, and its one-way transit is at most its round trip. So the connection's fastest heartbeat round trip is an upper bound on the error, whatever the path asymmetry. Node now checks every deadline against estimate + that bound, rounded up to the millisecond. It fails closed: a command can only get less time than its deadline, never more. On a new connection, motion with a deadline (drive, actuator, ptz, button, point) is refused not_ready until the first round trip is measured. The first heartbeat goes out on Bot's hello, so that's one round trip. Motion is also refused if the fastest round trip is over 1 s. Every reconnect starts unsynchronized again. Latency and jitter only make frames late, so they read as expired. A wall-clock step on the device changes nothing (the clock is monotonic). Bot's clock stepping back reads early until the next connection. Drift is tracked, or reads early. The bound reaches your driver as provenance.clock_uncertainty_ms. Our preference: Node refuses motion until synchronized, which it now does, and a stricter policy is a cap on that field in your driver (for example, refuse motion above 150 ms). No second replay mechanism is needed; deadline, epoch and seq stay exactly as they are. 2. STOP versus e-stop provenance This is a backward-compatible SDK extension. Every stop now goes through Plugin.on_stop(info) with a StopInfo: cause, emergency, latched and reason; turn_epoch and halt_epoch; replayed, first_cause and motion_only. The default on_stop calls stop() or stop_motion(), so existing drivers don't change. Ordinary stops (emergency false): halt: a turn ended, a viewer handoff, a release, a timeout or an unbind; it carries turn_epoch. link_lost and shutdown. timeout: the driver didn't answer within its window. The runtime's own: setup, deadline (motion only), heartbeat, handler_error and eof. Emergencies (emergency true): remote: the platform's e-stop, with its reason. local: openvibe-node stop on the device. driver: a driver's own local_stop. latched: the stop was already latched at start (replayed: true, with first_cause). on_resume(info) (cause cleared) is information only. Never ARM P7, clear its physical latch or restore a grant there. The default does nothing. Across restarts and reconnects: The platform latch is persisted on disk. A restarted plugin process gets the latch again right after hello, as estop latched with replayed: true. hello now carries the newest halt_epoch, so ended turns stay refused. A Node reconnect is a stop with cause link_lost, and an e-stop set while offline is applied from Bot's config before any command. For P7: override on_stop. Always stop every motor; latch P7's STOP only when info.emergency is true; treat on_resume as information. There's a short example in plugins.md under "Writing a plugin in Python". Glad M1 is staying shadow-only until these gates are reviewed. Shout if anything in 0.17 doesn't fit the P7 classes. THE BEEP BOOPS ARE SACRED! o7 🍊🤖🎮