         runtime.exportedEdges = []
         runtime.edgesForInspection = []
 
-        return sendMessage(runtime, request).then (response) ->
-          sendAck connection, response
+        return sendMessage(runtime, request)
     else if command is "addnode"
         graph.processes[payload.id] = payload
+        graph.componentMap[payload.id] = payload.component
+        # TODO: respect nodeId from runtime
         graph.nodeMap[payload.id] = { id: graph.currentNodeId++ }
-        graph.componentMap[payload.id] = payload.component
-        # TODO: wait for nodeId from runtime, update nodeMap then
         return sendMessage(runtime, request).then (response) ->
-          sendAck connection, response
+          return response
 
     else if command is "removenode"
         return sendMessage(runtime, request).then (response) ->
           delete graph.processes[payload.id]
           delete graph.nodeMap[payload.id]
           delete graph.componentMap[payload.id]
-          sendAck connection, response
+          return response
 
     else if command is "renamenode"
         node = graph.processes[payload.from]
         graph.processes[payload.to] = node
-        return sendMessage(runtime, request).then (response) ->
-          sendAck connection, response
+        return sendMessage(runtime, request)
     else if command is "changenode"
         # FIXME: ignored
-        sendAck connection, request
-        return Promise.resolve()
+        return Promise.resolve(request)
     else if command is "addedge"
         graph.connections.push protocol.wsConnectionFormatToFbp(payload)
-        return sendMessage(runtime, request).then (response) ->
-          sendAck connection, response
+        return sendMessage(runtime, request)
     else if command is "removeedge"
         graph.connections = connectionsWithoutEdge(graph.connections, protocol.wsConnectionFormatToFbp(payload))
-        return sendMessage(runtime, request).then (response) ->
-          sendAck connection, response
+        return sendMessage(runtime, request)
     else if command is "changeedge"
         # FIXME: ignored
-        sendAck connection, { protocol: 'graph', command: command, payload: payload }
-        return Promise.resolve()
+        return Promise.resolve { protocol: 'graph', command: command, payload: payload }
     else if command is "addinitial"
         graph.connections.push protocol.wsConnectionFormatToFbp(payload)
         return sendMessage(runtime, request).then (response) ->
-          sendAck connection, request # TODO: use response from RT
+          return Promise.resolve(request) # TODO: use response from RT
     else if command is "removeinitial"
         # TODO: send to runtime side, wait for response
         graph.connections = connectionsWithoutEdge(graph.connections, protocol.wsConnectionFormatToFbp(payload))
-        sendAck connection, request
-        return Promise.resolve()
+        return Promise.resolve(request)
 
     else if command is "addinport"
         graph.inports[payload.public] =
             process: payload.node
             port: payload.port
         sendExportedPorts connection, runtime
-        sendAck connection, request
-        return Promise.resolve()
+        return Promise.resolve(request)
     else if command is "removeinport"
         delete graph.inports[payload.public]
         sendExportedPorts connection, runtime
-        sendAck connection, request
-        return Promise.resolve()
+        return Promise.resolve(request)
     else if command is "addoutport"
         graph.outports[payload.public] =
             process: payload.node

    if not p
      console.error("handler for #{contents.protocol}:#{contents.command} did not return a Promise")

    p.catch (err) ->
        payload = { message: err.message }
        connection.send { protocol: contents.protocol, command: 'error', payload: payload }

        console.error('FBP PROTOCOL error:', err)
        console.error(err.stack)

          r.id = runtime.options.id

        return runtime.device.ping().then () ->
          response =
            protocol: "runtime"
            command: "runtime"
            payload: r
          sendExportedPorts connection, runtime
          return response

    else if command is 'packet'
        if payload.event is 'data'
            buffer = sendPacketCmd runtime, payload.port, payload.event, payload.payload
            runtime.device.sendMany(buffer)
            .then () ->
                return { protocol: 'runtime', command: 'packetsent', payload: payload }
        else
            return Promise.resolve(request)

    else
        return Promise.reject("Unknown FBP command runtime:#{command}: #{payload}")
