diff --git a/bootstrap.js b/bootstrap.js
index 7a124fe40d96dd84156fa72d339071ca0fc0e011..6db957fc552e42724e6172c92ed2c0f2910463fc 100644
--- a/bootstrap.js
+++ b/bootstrap.js
@@ -41,7 +41,15 @@ function bootloop() {
     console.error('loop halting, mgr bailing')
     return
   }
-  setTimeout(bootloop)
+  if(window.run) setTimeout(bootloop)
+}
+
+window.run = true
+
+window.halt = (err) => {
+  window.run = false
+  console.error('HALTING')
+  throw new Error(err)
 }
 
 window.onload = () => {
@@ -51,7 +59,7 @@ window.onload = () => {
     // manager wants view handle to render hunk DOM elements into plane ...
     // there's only one of each, so just
     window.tlv = tlv
-    window.nrol = nrol 
+    window.nrol = nrol
   }).then(() => {
     // make ah graph,
     // outHunkIndex, outIndex, inHunkIndex, inIndex, debug
diff --git a/core/scope.js b/core/scope.js
index 8f20ddc5d2e327aab1275e0c4805b5799dceb153..b2f2503ff8b919862c5931de6498c0db36cf3457 100644
--- a/core/scope.js
+++ b/core/scope.js
@@ -291,16 +291,18 @@ export default function Scope(wrapper, tlv) {
 
   let open = (context) => {
     // new plane every time!
-    context.plane = $('<div>').addClass('subplane').addClass('block').attr('id', `${def.name}_plane`).get(0)
+    // handle to our context's container (the link)
+    let ldef = context.within
+    if (!ldef) throw new Error("no apparent link container for this context")
+    context.plane = $('<div>').addClass('block').addClass('subplane').attr('id', `${ldef.name}_plane`).get(0)
     context.plane.position = () => {
-      return { x: 0, y: blocks.getBlockStackHeight(def.blocks) }
+      return { x: 0, y: blocks.getBlockStackHeight(ldef.blocks) }
     }
     if (!context.size) context.size = { x: 800, y: 600 }
-    dt.writeContainerSize(context.size)
+    dt.writeContainerSize(context.plane, context.size)
     // blocks should have handles,
     context.plane.handle = context // this is a throwaway ... and maybe ah bugfarm
     // the context should be .within an ldef, we want this block to carry the plane around,
-    let ldef = context.within
     ldef.blocks.push(context.plane)
     ldef.blocks[0].take(context.plane) // 'parent' block, for positioning, kind of awkward
     // existence
@@ -312,17 +314,19 @@ export default function Scope(wrapper, tlv) {
       size.x += deltas.x
       size.y += deltas.y
       dt.writeContainerSize(context.plane, size)
-      repositionDef(def)
+      blocks.repositionDef(ldef)
       // reposition all defs in the downstream: we might be squishing them about:
       for (let dsdef of context.defs) {
-        repositionDef(dsdef)
+        blocks.repositionDef(dsdef)
       }
     } // end onresize,
     // place,
-    repositionDef(def)
+    blocks.repositionDef(ldef)
     // toggle button state,
-    $(squid).html('<i class="em em-shell"></i> collapse link')
-    $(squid).one('click', close)
+    $(ldef.squid).html('<i class="em em-shell"></i> collapse link')
+    $(ldef.squid).one('click', (evt) => {
+      context.open = false
+    })
     /*
     if (def.states[0].value) { // if is-connecting,
       context.refresh().then(() => {
@@ -336,13 +340,23 @@ export default function Scope(wrapper, tlv) {
 
 
   let close = (context) => {
-    console.error('nah')
-    /*
-    // 'ldef.contains' is a ptr to the context (view) that is w i t h i n the link, accoring
-    // to our earlier piping, ldef.contains = view returned here
-    wipeContext(ldef.contains)
+    let ldef = context.within
+    if (!ldef) throw new Error("no apparent link container for this context")
+    // we should be prudent about also closing downstream links,
+    // for now here's a wrench across the terminals,
+    for (let def of context.defs) {
+      if (def.type == 'link') {
+        context.getLinkContext(def).then((sub) => {
+          if (sub && sub.open) {
+            throw new Error('need to recurse through and close downstream')
+          }
+        })
+      }
+    }
+    // ok, cleanup:
+    blocks.wipeContext(context)
     $(ldef.contains.plane).remove()
-    // arduous: rm from ldef, and from titleblock,
+    // arduous: rm plane-as-block from ldef, and from titleblock,
     let bi = ldef.blocks.findIndex((cand) => {
       return (cand === ldef.contains.plane)
     })
@@ -351,16 +365,19 @@ export default function Scope(wrapper, tlv) {
     } else {
       console.error('lost plane block ... ')
     }
-    titleblock.remove(ldef.contains.plane)
-    delete ldef.contains.plane
-    // . then->
-
-    $(squid).html('<i class="em em-squid"></i> expand link')
-    $(squid).one('click', open)
-    repositionDef(ldef)
-    */
+    ldef.blocks[0].remove(ldef.contains.plane)
+    // she gone, burn the letters
+    delete context.plane
+    // plenty of fish,
+    $(ldef.squid).html('<i class="em em-squid"></i> expand link')
+    $(ldef.squid).one('click', (evt) => {
+      context.open = true
+    })
+    blocks.repositionDef(ldef)
   }
 
+  let once = false
+
   this.check = () => {
     // check levels recursively,
     let recursor = (context) => {
@@ -369,20 +386,20 @@ export default function Scope(wrapper, tlv) {
         if (def.type == 'link') {
           // find the context it's connected to,
           def.context.getLinkContext(def).then((nc) => { // next context,
-            if (nc.open && !nc.plane) { // open, no plane, so we build one:
-              console.log('opening')
-              console.log(nc.plane) // nc / linkcontext maybe not what you think it is ?
-              here you are 
-              open(nc)
-            }
-            if (nc.plane && !nc.open) { // exist, but should be closed, run that
-              close(nc)
-            }
-            if (nc.plane) { // if plane still up, we passed the last if, recurse down
-              recursor(nc)
+            if (nc) {
+              if (nc.open && !nc.plane) { // open, no plane, so we build one:
+                open(nc)
+              }
+              if (nc.plane && !nc.open) { // exist, but should be closed, run that
+                close(nc)
+              }
+              if (nc.plane) { // if plane still up, we passed the last if, recurse down
+                recursor(nc)
+              }
             }
-          }).catch(() => {
-            // noop, no context,
+          }).catch((err) => {
+            window.halt(err)
+            //throw new Error(err) // I would prefer that these halt,
           })
         }
       }
diff --git a/hunks/view.js b/hunks/view.js
index 3b3e12cf09cb3abf695fd708273216f227ac4eb7..55af914fcc30f22340a7d6b5b29b6b56b7b1fb04 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -1094,20 +1094,24 @@ function View() {
 
   this.makeLinkContext = (ldef) => {
     return new Promise((resolve, reject) => {
-      this.getLinkContext(ldef).then((context) => {
-        resolve(context)
-      }).catch(async () => {
-        // none, make one,
-        try {
-          let vdef = await window.tlv.requestAddHunk('view')
-          await this.buildRoute(vdef.outputs[0], ldef.inputs[1])
-          await this.buildRoute(ldef.outputs[1], vdef.inputs[0])
-          let view = vdef.hunk // views are always toplevel hunks, so they always have these handles
-          resolve(view)
-        } catch (err) {
-          console.error(err)
-          reject()
+      this.getLinkContext(ldef).then(async (context) => {
+        if(context){
+          resolve(context)
+        } else {
+          // build it, cn it, continue,
+          try {
+            let vdef = await window.tlv.requestAddHunk('view')
+            await this.buildRoute(vdef.outputs[0], ldef.inputs[1])
+            await this.buildRoute(ldef.outputs[1], vdef.inputs[0])
+            let view = vdef.hunk // views are always toplevel hunks, so they always have these handles
+            resolve(view)
+          } catch (err) {
+            console.error(err)
+            reject()
+          }
         }
+      }).catch((err) => {
+        reject(err)
       })
     })
   }
@@ -1126,7 +1130,7 @@ function View() {
           reject('looking for context, traces to non-view... ')
         }
       } else {
-        reject()
+        resolve() // resolve w/ response that no context exists for this link,
       }
     })
   }
diff --git a/view/blocks.js b/view/blocks.js
index 7f8556cdcd8beb5c14375195956f2e0c20dda133..c95391e74440dd9be5c5e82eade78bfe4dd201b4 100644
--- a/view/blocks.js
+++ b/view/blocks.js
@@ -54,9 +54,9 @@ let getBlockStackWidth = (blocks) => {
 let getBlockStackRightWidth = (blocks) => {
   let x = getBlockStackWidth(blocks)
   let y = 0
-  for(let bl of blocks) {
-    if($(bl).is('.output')) {
-      if(y < bl.clientWidth) y = bl.clientWidth
+  for (let bl of blocks) {
+    if ($(bl).is('.output')) {
+      if (y < bl.clientWidth) y = bl.clientWidth
     }
   }
   return (x + y + 5)
@@ -64,9 +64,9 @@ let getBlockStackRightWidth = (blocks) => {
 
 let getBlockStackLeftWidth = (blocks) => {
   let x = 0
-  for(let bl of blocks){
-    if($(bl).is('.input')){
-      if(x < bl.clientWidth) x = bl.clientWidth
+  for (let bl of blocks) {
+    if ($(bl).is('.input')) {
+      if (x < bl.clientWidth) x = bl.clientWidth
     }
   }
   return (x += 5)
@@ -75,29 +75,25 @@ let getBlockStackLeftWidth = (blocks) => {
 // oboy,
 let makeLink = (ldef, titleblock) => {
   // ok, we have a new link,
-  if(!ldef.upstream){
-    let squid = $('<div>').addClass('loosebutton').addClass('block').get(0)
-    squid.position = () => {
-      return { x: 0, y: -squid.clientHeight - 5 }
+  if (!ldef.upstream) {
+    ldef.squid = $('<div>').addClass('loosebutton').addClass('block').get(0)
+    ldef.squid.position = () => {
+      return { x: 0, y: -ldef.squid.clientHeight - 5 }
     }
-    squid.handle = ldef
-    titleblock.take(squid)
-    ldef.blocks.push(squid)
-    let open = (evt) => {
+    ldef.squid.handle = ldef
+    titleblock.take(ldef.squid)
+    ldef.blocks.push(ldef.squid)
+    $(ldef.squid).html('<i class="em em-squid"></i> expand link')
+    $(ldef.squid).one('click', (evt) => {
       ldef.context.makeLinkContext(ldef).then((context) => {
         context.open = true
       })
-    }
-    let close = (evt) => {
-      ldef.contains.open = false
-    }
-    $(squid).html('<i class="em em-squid"></i> expand link')
-    $(squid).one('click', open)
+    })
   } else {
     // static title,
     titleblock.position = () => {
       let y = 0;
-      for(let opd of ldef.outputs){
+      for (let opd of ldef.outputs) {
         y += opd.block.clientHeight + 5
       }
       return { x: 0, y: y }
@@ -444,16 +440,16 @@ let repositionBlock = (block) => {
 
 let repositionDef = (def) => {
   // context bounds ...
-  if(!def.context.plane) {
+  if (!def.context.plane) {
     // not completely unlikely, invisible views refreshing, perhaps... but those
     // should come thru ah reposition check-switch, not here direct, so
     console.warn('reposition for invisible def, wyd?')
     return
   }
   // hmmm ... ok, for our siblings' children, we are subject to not-overrun them,
-  for(let df of def.context.defs){
-    if(def.contains){
-      if(def.contains.plane){
+  for (let df of def.context.defs) {
+    if (def.contains) {
+      if (def.contains.plane) {
         // this one's tricky: we have potentially many-sub-planes, let's just
         // stick to not-excaping-our-own-bounds for now,
       }
@@ -461,7 +457,7 @@ let repositionDef = (def) => {
   }
   // ok, for our parents:
   // ah ... titles drag blocks, not defs ... maybe they should drag defs.
-  if(def.context.within){
+  if (def.context.within) {
     let bw = def.context.plane.clientWidth
     let bh = def.context.plane.clientHeight
     // clip to bounds, plus some margin...
@@ -469,10 +465,10 @@ let repositionDef = (def) => {
     let wl = getBlockStackLeftWidth(def.blocks)
     let h = getBlockStackHeight(def.blocks)
     // cover bottom left:
-    if(def.position.x + wr > bw) def.position.x = bw - wr
-    if(def.position.y + h > bh) def.position.y = bh - h
-    if(def.position.x - wl < 0) def.position.x = wl
-    if(def.position.y < 0) def.position.y = 0
+    if (def.position.x + wr > bw) def.position.x = bw - wr
+    if (def.position.y + h > bh) def.position.y = bh - h
+    if (def.position.x - wl < 0) def.position.x = wl
+    if (def.position.y < 0) def.position.y = 0
   }
   // arrange,
   if (def.blocks) {
@@ -515,6 +511,10 @@ export default {
   redrawDef, // to add / update anything
   repositionDef, // to move anything
   repositionBlock, // to move by block (dragging children along)
+  getBlockStackHeight, // total height of states, title
+  getBlockStackWidth, // states width
+  getBlockStackLeftWidth, // total left
+  getBlockStackRightWidth, // total right
   redrawContexWires, // when context link topology changes
   wipeContext // to shutdown / cleanup
 }