Autosave saves whenever hasUnsavedChanges is set, so any source that
dirties the canvas without a user edit turns into a spurious silent
save. Two such sources:
1. Live status updates. useStatusPolling routed backend status pushes
through updateNode, which always sets hasUnsavedChanges. With the
60s status cycle, an idle opted-in tab saved itself every cycle and
could clobber edits made elsewhere with its stale in-memory canvas.
Add setNodeStatus, a live-overlay action that updates a node's
status/response_time/last_seen without dirtying (mirrors
setServiceStatuses), and route polling through it.
2. Initial dimensions measure. onNodesChange treated React Flow's
first-measure `dimensions` change as an edit, marking a freshly
loaded canvas dirty before any interaction — autosave then saved on
every load/switch. Only count a `dimensions` change as an edit when
it is a real resize (resizing === true).
Add regression tests: setNodeStatus updates status without dirtying;
onNodesChange ignores initial-measure dimensions and select-only
changes but still dirties on a user resize.
ha-relevant: maybe