Source arcs and interaction arcs never drew for a second observer of a swarm. The editing client looked correct; any other connected client (or MCP client like the kraken demo pipeline) showed empty wiring even though get_node returned the correct sources server-side.
set_node_wiring posts the node with state = USER_EDIT. The server fans this out as a STATE_CHANGE SSE event whose payload (StateChangeEventPayload) carries only the new state — not the node’s updated sources/inputs/formula. In EventClient, the STATE_CHANGE arm copied the new state onto the stored node but left the old meta intact. The editing client never noticed because it already held the new meta locally from its own edit; only secondary clients were affected.
ClientNodeManager.refreshNodeMeta(node: Node): fetches the authoritative node via nodeHttp.readNode from the node’s host and applies the fresh meta with updateMetaData. No-ops gracefully if the host is unknown or the HTTP call returns null.EventClient STATE_CHANGE arm: after applying the new state, if newState == NodeState.USER_EDIT, calls nodeManager.refreshNodeMeta(currentNode) to pull in the updated wiring.StateChangeEventPayload carries only state. Any code path that fansout a meta change as USER_EDIT must be complemented by a meta-fetch on the receiving side. A heavier alternative (a dedicated META_CHANGED SSE event carrying the full meta) would eliminate the extra HTTP round-trip but was intentionally deferred — the client-side refetch is the smallest correct fix.ClientNodeManagerRefreshMetaTest — verifies that refreshNodeMeta calls nodeHttp.readNode and updates the stored node’s sources, and that it is a no-op when the HTTP call returns null or when the host is unknown.