diff --git a/hunks/manager.js b/hunks/manager.js
index eb78d842b4a662410691121be1e927b0c4f868cb..7465ae541511c97ccdfddf738fec874e7e7e99a8 100644
--- a/hunks/manager.js
+++ b/hunks/manager.js
@@ -409,12 +409,21 @@ function Manager() {
     this.log(`manager hello`)
   }
 
+  // just a tiny helper
+  let idSafeReply = (msgid, bytes) => {
+    if(msgid){
+      bytes = [MK.MSGID, msgid].concat(bytes)
+    }
+    writeMessage(bytes)
+  }
+
   this.loop = () => {
     // getting messages
     if (msgsin.io) {
       let msg = msgsin.get()
       if (msgverbose) console.log('MGR RX MSG:', msg)
       if (!Array.isArray(msg)) throw new Error(`manager throwing object message, having header ${msg.header}`)
+      this.isConnectedTo = true
       // once
       let resp = new Array()
       let inc = 0
@@ -428,38 +437,28 @@ function Manager() {
       switch (msg[inc]) {
         case MK.HELLO:
           if (msgverbose) console.log('MGR MSG is hello')
-          this.isConnectedTo = true
-          if(msgid){
-            writeMessage([MK.MSGID, msgid, MK.HELLO])
-          } else {
-            writeMessage([MK.HELLO])
-          }
+          idSafeReply(msgid, [MK.HELLO])
           break
-        case MK.REQDESCRIBESELF:
-          if (msgverbose) console.log('MGR MSG is a brief request')
-          this.isConnectedTo = true
-          // with ids, this is ok
-          resp.push(MK.BRIEF)
-          MSGS.writeTo(resp, gg.interpreterName, 'string')
-          MSGS.writeTo(resp, gg.interpreterVersion, 'string')
-          MSGS.writeTo(resp, hunks.length, 'uint16')
-          MSGS.writeTo(resp, writeLinkList().length, 'uint16')
-          writeMessage(resp)
-          // now start sending hunks,
-          for (let hnk of hunks) {
-            let serhunk = [MK.HUNKALIVE]
-            serializeHunk(hnk, serhunk)
-            writeMessage(serhunk)
-          }
-          // and links,
-          let links = writeLinkList()
-          for (let lnk of links) {
-            let serlink = [MK.LINKALIVE]
-            MSGS.writeTo(serlink, lnk.outInd, 'uint16')
-            MSGS.writeTo(serlink, lnk.outputInd, 'uint8')
-            MSGS.writeTo(serlink, lnk.inInd, 'uint16')
-            MSGS.writeTo(serlink, lnk.inputInd, 'uint8')
-            writeMessage(serlink)
+        case MK.QUERY:
+          // do we have an index ?
+          if (msg.length > inc + 1){
+            let queryIndex = MSGS.readFrom(msg, inc + 1, 'uint16')
+            if (msgverbose) console.log(`MGR MSG is a hunk query for ${queryIndex}`)
+            if(hunks[queryIndex] === undefined){
+              // write and return an error
+              idSafeReply(msgid, someNewErrMsg)
+            } else {
+              serializeHunk(hnk, serhunk)
+              idSafeReply(msgid, serhunk)
+            }
+          } else {
+            if (msgverbose) console.log('MGR MSG is a top level query')
+            // with ids, this is ok
+            resp.push(MK.BRIEF)
+            MSGS.writeTo(resp, gg.interpreterName, 'string')
+            MSGS.writeTo(resp, gg.interpreterVersion, 'string')
+            MSGS.writeTo(resp, hunks.length, 'uint16')
+            idSafeReply(msgid, resp)
           }
           break
         case MK.REQLISTAVAIL:
diff --git a/hunks/view.js b/hunks/view.js
index adc8ded3ea4b32c5832c0404187c9d1c939128d0..445cb8a73976ce8c4a34a81a5ca762c0e7db7514 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -140,20 +140,6 @@ function View() {
   }
   // END INIT CODE
 
-  this.refresh = () => {
-    // wipe ya docs, and ask yonder manager for a complete description
-    // everything is friggen jquery, so check it out
-    console.log("REFRESHING THE VIEW")
-    $(this.plane).children('.def').remove()
-    // also,
-    defs.length = 0
-    // hello first,
-    this.sayHelloToManager().then(() => {
-      console.log('hello, as promised')
-      writeMessage([MK.REQDESCRIBESELF])
-    })
-  }
-
   let mouseWheelListener = (evt) => {
     if (!$(evt.target).is('.view') && !$(evt.target).is('#floater')) {
       return false
@@ -251,213 +237,9 @@ function View() {
   }
 
   /* ---------------------------    ---------------------------- */
-  /* ---------------------- FORCE LAYOUT ----------------------- */
+  /* ----------------------- REDRAWING ------------------------- */
   /* ---------------------------    ---------------------------- */
 
-  // ok, my thoughts on this
-  /*
-
-  when you're up with big programs, spend a day / a handful, just making the UI sing
-  - https://bl.ocks.org/mbostock/3750558
-
-  at the moment this is kind of 'fine'
-   - starting condition is mostly random (and elsewhere) - maybe some graph analysis
-    - for who-is-generally-downstream-of-whomst
-    - this is nice code golf for boring times when you have lots of graphs
-   - still not looking at links for layout force: do that first
-   - want to connect this notion with the 'design patterns' ides ...
-    - (links) find (comm/*) connected, arrange in a stack
-    - (view) finds (link) connected, also stackup ...
-     - the links / split through views -> this is actually a lot of the work,
-     - and it's not unimportant
-
-  */
-
-  let blocks = new Array()
-  let flsimrun = false
-  let flsim = {}
-  let flnodes = []
-
-  let finAlpha = 0.1
-  let sizemultiple = 0.5
-
-  // happens when items added, deleted (changing topology)
-  let updateForceLoop = () => {
-    // init and/or update
-    if (!flsimrun && blocks.length > 3) {
-      // Case for starting sim
-      msgbox.write('starting force sim')
-      flsimrun = true
-      // start with two nodes
-      let positions = this.getAllHunkPositions()
-      let sizes = this.getAllHunkSizes()
-      for (let i in positions) {
-        let nd = {
-          index: i,
-          x: positions[i].x,
-          y: positions[i].y,
-          vx: 0,
-          vy: 0,
-          r: sizes[i].width * sizemultiple
-        }
-        flnodes.push(nd)
-      }
-      flsim = d3.forceSimulation(flnodes)
-        .force('charge', d3.forceManyBody().strength(250))
-        .force('center', d3.forceCenter(600, 600))
-        .force('collide', d3.forceCollide((node, i, nodes) => {
-          return node.r
-        }))
-        .alphaMin(finAlpha)
-        .on('tick', flTick)
-        .on('end', flEnd)
-    } else if (blocks.length <= 3) {
-      // donot
-    } else {
-      // case for adding / rming from sim
-      msgbox.write('UPD8 Force Sim')
-      let positions = this.getAllHunkPositions()
-      let sizes = this.getAllHunkSizes()
-      if (positions.length > flnodes.length) {
-        let last = positions.length - 1
-        //console.log('to add new node like', positions[last])
-        let nd = {
-          index: last,
-          x: positions[last].x,
-          y: positions[last].y,
-          vx: 0,
-          vy: 0,
-          r: sizes[last].width * sizemultiple
-        }
-        flnodes.push(nd)
-        // console.log('SIM adds now this', newNode.x, newNode.y)
-      } else {
-        //msgbox.write("SIM DELETE CASE NOT WRITTEN")
-      }
-      flsim.nodes(flnodes)
-      flsim.alpha(1)
-        .alphaMin(finAlpha)
-        .restart()
-    }
-  }
-
-  // happens when things perterbed in existing state (i.e. drags)
-  let kickForceLoop = () => {
-    // hmm... but fix the one you're dragging, say?
-    flsim.alpha(1).restart()
-  }
-
-  let flTick = () => {
-    // called on sim update
-    let blks = $(this.plane).children('.block').not('#NROL39_0').not('#TLView')
-    if (blks.length !== flnodes.length) {
-      console.log('FLOOP NODES MISMATCH', blks.length, flnodes.length)
-    } else {
-      for (let i = 0; i < blks.length; i++) {
-        blks[i].style.left = flnodes[i].x + 'px'
-        blks[i].style.top = flnodes[i].y + 'px'
-      }
-    }
-    this.drawLinks()
-    if ($(msgbox.zeCheckbox).prop('checked')) {
-      this.zoomExtents()
-    }
-  }
-
-  let flEnd = () => {
-    console.log('FIN DU SIM')
-  }
-
-  this.zoomExtents = () => {
-    // to zoom-extends
-    let psns = this.getAllHunkPositions()
-    let sizes = this.getAllHunkSizes()
-    // bless up, these are all in 0,0 relative space
-    let minxy = {
-      x: 0,
-      y: 0
-    }
-    let maxxy = {
-      x: 500,
-      y: 500
-    }
-    let maxx, minx, maxy, miny
-    for (let ind in psns) {
-      maxx = psns[ind].x + sizes[ind].width
-      minx = psns[ind].x
-      maxy = psns[ind].y + sizes[ind].height
-      miny = psns[ind].y
-      // max cases
-      if (maxx > maxxy.x) {
-        maxxy.x = maxx
-      }
-      if (maxy > maxxy.y) {
-        maxxy.y = maxy
-      }
-      // min cases
-      if (minx < minxy.x) {
-        minxy.x = minx
-      }
-      if (miny < minxy.y) {
-        minxy.y = miny
-      }
-    }
-    // margin
-    let margin = 100
-    minxy.x -= margin
-    minxy.y -= margin
-    maxxy.x += margin
-    maxxy.y += margin
-    // ok, compare bounding box to current frustrum ?
-    let ct = dt.readTransform(this.plane)
-    let wd = this.dom.clientWidth
-    let ht = this.dom.clientHeight
-    // to find scale, do
-    let pfsx = (wd) / (maxxy.x - minxy.x)
-    let pfsy = (ht) / (maxxy.y - minxy.y)
-    let pfs = Math.min(pfsx, pfsy)
-    // write em
-    ct.s = pfs
-    ct.x = -minxy.x * pfs
-    ct.y = -minxy.y * pfs
-    dt.writeTransform(this.plane, ct)
-    dt.writeBackgroundTransform(this.dom, ct)
-  }
-
-  this.getAllHunkPositions = () => {
-    // returns positions as numbers,
-    let nds = $(this.plane).children('.block')
-    let positions = new Array()
-    for (let nd of nds) {
-      if ($(nd).attr('id') === "NROL39_0" || $(nd).attr('id') === "TLView") {
-        //console.log('skip')
-      } else {
-        let pos = dt.readXY(nd)
-        pos.id = nd.id
-        positions.push(pos)
-      }
-    }
-    return positions
-    // should do transform here ?
-  }
-
-  this.getAllHunkSizes = () => {
-    let nds = $(this.plane).children('.block')
-    let sizes = new Array()
-    for (let nd of nds) {
-      if ($(nd).attr('id') === "NROL39_0" || $(nd).attr('id') === "TLView") {
-        //console.log('skip')
-      } else {
-        let sz = dt.readSize(nd)
-        sz.id = nd.id
-        sizes.push(sz)
-      }
-    }
-    return sizes
-  }
-
-  // here is where you rm'd drawing & moving
-
   this.drawLinks = () => {
     // drawing from scratch every time ! could be faster, probably
     bzt.clear(this.plane)
@@ -726,7 +508,9 @@ function View() {
   /* ----------------- HOTMESSES -> SERIALMSGS ----------------- */
   /* ---------------------------    ---------------------------- */
 
-  // mostly, this is an experiment for returning promises
+  // herein lay each of our unit requests, as promises,
+
+  // hello is a ping,
   this.sayHelloToManager = () => {
     return new Promise((resolve, reject) => {
       let helloTime = performance.now()
@@ -734,13 +518,35 @@ function View() {
       promiseThis([MK.HELLO], () => {
         msgbox.write(`manager says hello, took ${performance.now() - helloTime}ms`)
         resolve()
-      }, () => {
-        // 2nd callback for error cases ?
-        reject()
+      }, (errmsg) => {
+        reject(errmsg)
       })
     })
   }
 
+  this.queryManager = (ind) => {
+    return new Promise((resolve, reject) => {
+      if (ind) {
+        msgbox.write(`querying manager for hunk at ${ind}`)
+        let req = [MK.QUERY]
+        MSGS.writeTo(req, ind, 'uint16')
+        promiseThis(req, (def) => {
+          resolve(def)
+        }, (errmsg) => {
+          reject(errmsg)
+        })
+      } else {
+        msgbox.write(`querying top level of manager`)
+        promiseThis([MK.QUERY], (brief) => {
+          msgbox.write(``)
+          resolve(brief)
+        }, (errmsg) => {
+          reject(errmsg)
+        })
+      }
+    })
+  }
+
   this.requestAddHunk = (name, states) => {
     let msg = [MK.REQADDHUNK]
     MSGS.writeTo(msg, name, 'string')
@@ -803,6 +609,27 @@ function View() {
     }
   }
 
+  /* ---------------------------    ---------------------------- */
+  /* ------------------------ RECEPIES ------------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.refresh = () => {
+    // wipe ya docs, and ask yonder manager for a complete description
+    // everything is friggen jquery, so check it out
+    console.log("REFRESHING THE VIEW")
+    $(this.plane).children('.def').remove()
+    // also,
+    defs.length = 0
+    // hello first,
+    this.sayHelloToManager().then(() => {
+      console.log('hello, so ready to refresh')
+      this.queryManager().then((brief) => {
+        // should have a list then, do that brief then ?
+        console.log('promise brief', brief)
+      })
+    })
+  }
+
   /* ---------------------------    ---------------------------- */
   /* --------------------- MESSAGES OUTPUT --------------------- */
   /* ---------------------------    ---------------------------- */
@@ -825,7 +652,7 @@ function View() {
   let callbackSets = new Array()
   let cbid = 0
 
-  let promiseThis = (bytes, callback) => {
+  let promiseThis = (bytes, callback, errback) => {
     cbid++
     if (cbid > 254) {
       cbid = 0
@@ -834,7 +661,8 @@ function View() {
     callbackSets.push({
       key: bytes[0],
       id: cbid,
-      callback: callback
+      callback: callback,
+      errback: errback
     })
     // so our header is like - we don't explicitly type the id, it's a byte
     let head = [MK.MSGID, cbid]
@@ -860,7 +688,7 @@ function View() {
       let inc = 0
       // track the msg id response, and that callback
       let msgid, cbd
-      if(msg[0] === MK.MSGID){
+      if (msg[0] === MK.MSGID) {
         msgid = msg[1]
         inc = 2
         // and find the callback we registered
@@ -873,12 +701,16 @@ function View() {
       switch (msg[inc]) {
         case MK.ERR:
           if (msgverbose) console.log('VIEW MSG is an error')
-          msgbox.write(MSGS.readFrom(msg, inc + 1, 'string').item)
+          let errmsg = MSGS.readFrom(msg, inc + 1, 'string').item
+          console.error('view caught err from manager')
+          console.error(errmsg)
+          msgbox.write(errmsg)
+          if (cbd) cbd.errback(errmsg)
           break
         case MK.HELLO:
           if (msgverbose) console.log('VIEW MSG is hello')
           // that callback baybiiiie
-          if(cbd){
+          if (cbd) {
             cbd.callback()
           } else {
             msgbox.write(`manager says hello!`)
@@ -890,7 +722,7 @@ function View() {
           msgbox.write('manger sends program brief, will begin loading...')
           // serial -> js, by procedure du jakhey
           let brief = {}
-          inc ++
+          inc++
           // reading strings returns item, increment
           temp = MSGS.readFrom(msg, inc, 'string')
           inc += temp.increment
@@ -901,12 +733,12 @@ function View() {
           temp = MSGS.readFrom(msg, inc, 'uint16')
           inc += temp.increment
           brief.numHunks = temp.item
-          brief.numLinks = MSGS.readFrom(msg, inc, 'uint16').item
           // set local,
           this.interpreterName = brief.interpreterName
           this.interpreterVersion = brief.interpreterVersion
           // and write it down
           msgbox.briefState.setFromBrief(brief)
+          if (cbd) cbd.callback(brief)
           break
         case MK.LISTOFAVAIL:
           if (msgverbose) console.log('VIEW MSG is a list of available items')
diff --git a/typeset.js b/typeset.js
index 8d2cd7e480957d4068502e49fa665241d76c74bd..ad72239ca72d8c9a93118d9ab622a0a73769d40e 100644
--- a/typeset.js
+++ b/typeset.js
@@ -355,7 +355,7 @@ const MK = {
   // heartbeats, wakeup
   HELLO: 253, // (eom)
   // request a top-level description
-  REQDESCRIBESELF: 251, // (eom)
+  QUERY: 251, // (eom)
   BRIEF: 250, // (str) name of interpreter, # hunks, # links (and then begin firing list back)
   // please show what is available
   REQLISTAVAIL: 249, // (eom)
diff --git a/view/vfloop.js b/view/vfloop.js
new file mode 100644
index 0000000000000000000000000000000000000000..21bdb7858ccec0c616e73ea8b4c3581799f185d8
--- /dev/null
+++ b/view/vfloop.js
@@ -0,0 +1,209 @@
+// view force layout,
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- FORCE LAYOUT ----------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // ok, my thoughts on this
+  /*
+
+  when you're up with big programs, spend a day / a handful, just making the UI sing
+  - https://bl.ocks.org/mbostock/3750558
+
+  at the moment this is kind of 'fine'
+   - starting condition is mostly random (and elsewhere) - maybe some graph analysis
+    - for who-is-generally-downstream-of-whomst
+    - this is nice code golf for boring times when you have lots of graphs
+   - still not looking at links for layout force: do that first
+   - want to connect this notion with the 'design patterns' ides ...
+    - (links) find (comm/*) connected, arrange in a stack
+    - (view) finds (link) connected, also stackup ...
+     - the links / split through views -> this is actually a lot of the work,
+     - and it's not unimportant
+
+  */
+
+  let blocks = new Array()
+  let flsimrun = false
+  let flsim = {}
+  let flnodes = []
+
+  let finAlpha = 0.1
+  let sizemultiple = 0.5
+
+  // happens when items added, deleted (changing topology)
+  let updateForceLoop = () => {
+    // init and/or update
+    if (!flsimrun && blocks.length > 3) {
+      // Case for starting sim
+      msgbox.write('starting force sim')
+      flsimrun = true
+      // start with two nodes
+      let positions = this.getAllHunkPositions()
+      let sizes = this.getAllHunkSizes()
+      for (let i in positions) {
+        let nd = {
+          index: i,
+          x: positions[i].x,
+          y: positions[i].y,
+          vx: 0,
+          vy: 0,
+          r: sizes[i].width * sizemultiple
+        }
+        flnodes.push(nd)
+      }
+      flsim = d3.forceSimulation(flnodes)
+        .force('charge', d3.forceManyBody().strength(250))
+        .force('center', d3.forceCenter(600, 600))
+        .force('collide', d3.forceCollide((node, i, nodes) => {
+          return node.r
+        }))
+        .alphaMin(finAlpha)
+        .on('tick', flTick)
+        .on('end', flEnd)
+    } else if (blocks.length <= 3) {
+      // donot
+    } else {
+      // case for adding / rming from sim
+      msgbox.write('UPD8 Force Sim')
+      let positions = this.getAllHunkPositions()
+      let sizes = this.getAllHunkSizes()
+      if (positions.length > flnodes.length) {
+        let last = positions.length - 1
+        //console.log('to add new node like', positions[last])
+        let nd = {
+          index: last,
+          x: positions[last].x,
+          y: positions[last].y,
+          vx: 0,
+          vy: 0,
+          r: sizes[last].width * sizemultiple
+        }
+        flnodes.push(nd)
+        // console.log('SIM adds now this', newNode.x, newNode.y)
+      } else {
+        //msgbox.write("SIM DELETE CASE NOT WRITTEN")
+      }
+      flsim.nodes(flnodes)
+      flsim.alpha(1)
+        .alphaMin(finAlpha)
+        .restart()
+    }
+  }
+
+  // happens when things perterbed in existing state (i.e. drags)
+  let kickForceLoop = () => {
+    // hmm... but fix the one you're dragging, say?
+    flsim.alpha(1).restart()
+  }
+
+  let flTick = () => {
+    // called on sim update
+    let blks = $(this.plane).children('.block').not('#NROL39_0').not('#TLView')
+    if (blks.length !== flnodes.length) {
+      console.log('FLOOP NODES MISMATCH', blks.length, flnodes.length)
+    } else {
+      for (let i = 0; i < blks.length; i++) {
+        blks[i].style.left = flnodes[i].x + 'px'
+        blks[i].style.top = flnodes[i].y + 'px'
+      }
+    }
+    this.drawLinks()
+    if ($(msgbox.zeCheckbox).prop('checked')) {
+      this.zoomExtents()
+    }
+  }
+
+  let flEnd = () => {
+    console.log('FIN DU SIM')
+  }
+
+  this.zoomExtents = () => {
+    // to zoom-extends
+    let psns = this.getAllHunkPositions()
+    let sizes = this.getAllHunkSizes()
+    // bless up, these are all in 0,0 relative space
+    let minxy = {
+      x: 0,
+      y: 0
+    }
+    let maxxy = {
+      x: 500,
+      y: 500
+    }
+    let maxx, minx, maxy, miny
+    for (let ind in psns) {
+      maxx = psns[ind].x + sizes[ind].width
+      minx = psns[ind].x
+      maxy = psns[ind].y + sizes[ind].height
+      miny = psns[ind].y
+      // max cases
+      if (maxx > maxxy.x) {
+        maxxy.x = maxx
+      }
+      if (maxy > maxxy.y) {
+        maxxy.y = maxy
+      }
+      // min cases
+      if (minx < minxy.x) {
+        minxy.x = minx
+      }
+      if (miny < minxy.y) {
+        minxy.y = miny
+      }
+    }
+    // margin
+    let margin = 100
+    minxy.x -= margin
+    minxy.y -= margin
+    maxxy.x += margin
+    maxxy.y += margin
+    // ok, compare bounding box to current frustrum ?
+    let ct = dt.readTransform(this.plane)
+    let wd = this.dom.clientWidth
+    let ht = this.dom.clientHeight
+    // to find scale, do
+    let pfsx = (wd) / (maxxy.x - minxy.x)
+    let pfsy = (ht) / (maxxy.y - minxy.y)
+    let pfs = Math.min(pfsx, pfsy)
+    // write em
+    ct.s = pfs
+    ct.x = -minxy.x * pfs
+    ct.y = -minxy.y * pfs
+    dt.writeTransform(this.plane, ct)
+    dt.writeBackgroundTransform(this.dom, ct)
+  }
+
+  this.getAllHunkPositions = () => {
+    // returns positions as numbers,
+    let nds = $(this.plane).children('.block')
+    let positions = new Array()
+    for (let nd of nds) {
+      if ($(nd).attr('id') === "NROL39_0" || $(nd).attr('id') === "TLView") {
+        //console.log('skip')
+      } else {
+        let pos = dt.readXY(nd)
+        pos.id = nd.id
+        positions.push(pos)
+      }
+    }
+    return positions
+    // should do transform here ?
+  }
+
+  this.getAllHunkSizes = () => {
+    let nds = $(this.plane).children('.block')
+    let sizes = new Array()
+    for (let nd of nds) {
+      if ($(nd).attr('id') === "NROL39_0" || $(nd).attr('id') === "TLView") {
+        //console.log('skip')
+      } else {
+        let sz = dt.readSize(nd)
+        sz.id = nd.id
+        sizes.push(sz)
+      }
+    }
+    return sizes
+  }
+
+  // here is where you rm'd drawing & moving