diff --git a/core/scope.js b/core/scope.js
index b2f2503ff8b919862c5931de6498c0db36cf3457..999c2fbbf81a0478efa476c70c9a4bb89e25c5d5 100644
--- a/core/scope.js
+++ b/core/scope.js
@@ -294,14 +294,21 @@ export default function Scope(wrapper, tlv) {
     // 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)
+    if(context.plane){
+      $(ldef.context.plane).append(context.plane)
+    } else {
+      context.plane = $('<div>').addClass('block').addClass('subplane').attr('id', `${ldef.name}_plane`).get(0)
+    }
     context.plane.position = () => {
       return { x: 0, y: blocks.getBlockStackHeight(ldef.blocks) }
     }
-    if (!context.size) context.size = { x: 800, y: 600 }
+    if (!context.size){
+      context.size = { x: 800, y: 600 }
+    }
     dt.writeContainerSize(context.plane, context.size)
     // blocks should have handles,
     context.plane.handle = context // this is a throwaway ... and maybe ah bugfarm
+    context.setCompleteRedraw() // set a flag so that we'll draw it next round,
     // the context should be .within an ldef, we want this block to carry the plane around,
     ldef.blocks.push(context.plane)
     ldef.blocks[0].take(context.plane) // 'parent' block, for positioning, kind of awkward
@@ -314,6 +321,8 @@ export default function Scope(wrapper, tlv) {
       size.x += deltas.x
       size.y += deltas.y
       dt.writeContainerSize(context.plane, size)
+      context.size = size
+      // reposition the def's blocks - right side moves,
       blocks.repositionDef(ldef)
       // reposition all defs in the downstream: we might be squishing them about:
       for (let dsdef of context.defs) {
@@ -327,15 +336,6 @@ export default function Scope(wrapper, tlv) {
     $(ldef.squid).one('click', (evt) => {
       context.open = false
     })
-    /*
-    if (def.states[0].value) { // if is-connecting,
-      context.refresh().then(() => {
-        // ?
-      }).catch((err) => {
-        console.error(err)
-      })
-    }
-    */
   }
 
 
@@ -387,7 +387,7 @@ export default function Scope(wrapper, tlv) {
           // find the context it's connected to,
           def.context.getLinkContext(def).then((nc) => { // next context,
             if (nc) {
-              if (nc.open && !nc.plane) { // open, no plane, so we build one:
+              if (nc.open && !$.contains(document, nc.plane)) { // open, no plane, so we build one:
                 open(nc)
               }
               if (nc.plane && !nc.open) { // exist, but should be closed, run that
@@ -398,7 +398,8 @@ export default function Scope(wrapper, tlv) {
               }
             }
           }).catch((err) => {
-            window.halt(err)
+            console.error(err)
+            window.halt()
             //throw new Error(err) // I would prefer that these halt,
           })
         }
diff --git a/hunks/view.js b/hunks/view.js
index 55af914fcc30f22340a7d6b5b29b6b56b7b1fb04..69a8a82298bf0e27e0ae3b8ca5c7e31db0836faf 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -118,7 +118,7 @@ function View() {
   // when we make big changes, just nuke 'em
   // mostly, this is useful for any deleted hunks, or the refresh
   this.hasCompleteRedraw = false
-  let setCompleteRedraw = () => {
+  this.setCompleteRedraw = () => {
     this.hasCompleteRedraw = true
   }
 
@@ -316,13 +316,13 @@ function View() {
   // dessicate
   this.cleanDef = (def) => {
     // take it down to its constituent, non-circular elements.
-    console.log(`view cleans ${def.ind}`)
+    console.log(`VIEW CLEANS ${def.ind}`)
     // rm everything ...
     for (let key in def) {
       if (def.hasOwnProperty(key)) {
         if (key == 'type' || key == 'name' || key == 'ind' ||
-            key == 'context' || key == 'inputs' || key == 'outputs' || key == 'states' ||
-            key == 'contains' || key == 'downstream' || key == 'upstream') {
+          key == 'context' || key == 'inputs' || key == 'outputs' || key == 'states' ||
+          key == 'contains' || key == 'downstream' || key == 'upstream') {
           // these we keep,
         } else {
           delete def[key]
@@ -410,7 +410,7 @@ function View() {
   } // end update
 
   let rmAllWires = (pdef) => {
-    for(let cn of pdef.conn){
+    for (let cn of pdef.conn) {
       let rci = cn.conn.findIndex((cand) => {
         return (cand === pdef)
       })
@@ -433,9 +433,23 @@ function View() {
     for (let op of od.outputs) {
       rmAllWires(op)
     }
+    // keep position,
+    if (od.position) spec.position = od.position
     // and replace it in the list,
+    if (od.upstream) {
+      spec.upstream = od.upstream
+      spec.upstream.downstream = spec
+    }
+    if (od.downstream) {
+      spec.downstream = od.downstream
+      spec.downstream.upstream = spec
+    }
+    if (od.contains) {
+      spec.contains = od.contains
+      spec.contains.within = spec
+    }
     defs[spec.ind] = spec
-    setCompleteRedraw()
+    this.setCompleteRedraw()
     // occasionally useful,
     return spec
   }
@@ -487,7 +501,7 @@ function View() {
     // and now our .ind properties are untruthful, update those
     onDefReorder()
     // and x2thegrave
-    setCompleteRedraw()
+    this.setCompleteRedraw()
   }
 
   let onDefReorder = () => {
@@ -779,7 +793,7 @@ function View() {
       // there are other references to them someplace ... then GC will keepalive
       defs.length = 0
       // here we can set flag for complete redraw, as we've just tabula'd the table,
-      setCompleteRedraw()
+      this.setCompleteRedraw()
       // hello first,
       this.sayHelloToManager().then(() => {
         this.queryManager().then((brief) => {
@@ -814,6 +828,10 @@ function View() {
                   reconcileStartupConn(df)
                 }
                 // set this flag to trigger a complete redraw,
+                // and then...
+                for (let df of defs) {
+                  this.getLinkContext(df.ind)
+                }
                 resolve(this)
               }
             }).catch((err) => {
@@ -1053,22 +1071,6 @@ function View() {
   /* ------------------------- PIPING -------------------------- */
   /* ---------------------------    ---------------------------- */
 
-  let relink = (indice) => {
-    if (defs[indice].type !== 'link') {
-      return
-    }
-    let ldef = defs[indice]
-    // if we are within some other context,
-    if (this.within) {
-      // where this.within is <ptr to linkdef> in another view,
-      if (ldef.states[1].value == this.within.ind) {
-        // soul-bond w/ the link,
-        ldef.upstream = this.within // link -> link,
-        this.within.downstream = ldef
-      }
-    }
-  }
-
   // no matter upstream / downstream,
   let thru = (ldef) => {
     if (ldef.upstream) return ldef.upstream
@@ -1078,7 +1080,7 @@ function View() {
 
   // return inputdef-to-which connected,
   // assume always 1d path, bail if not
-  this.trace = (opdef) => {
+  this.trace = (opdef, tolink) => {
     // for now we are 1d, cannot traverse links,
     if (opdef.conn.length !== 1) return
     // trace is fun bc it recurses thru itself,
@@ -1095,7 +1097,7 @@ function View() {
   this.makeLinkContext = (ldef) => {
     return new Promise((resolve, reject) => {
       this.getLinkContext(ldef).then(async (context) => {
-        if(context){
+        if (context) {
           resolve(context)
         } else {
           // build it, cn it, continue,
@@ -1104,6 +1106,8 @@ function 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
+            ldef.contains = view
+            view.within = ldef
             resolve(view)
           } catch (err) {
             console.error(err)
@@ -1116,18 +1120,45 @@ function View() {
     })
   }
 
+  let relink = (indice) => {
+    if (defs[indice].type !== 'link') {
+      return
+    }
+    let ldef = defs[indice]
+    // if we are within some other context,
+    if (this.within) {
+      // where this.within is <ptr to linkdef> in another view,
+      if (ldef.states[1].value == this.within.ind) {
+        // soul-bond w/ the link,
+        ldef.upstream = this.within // link -> link,
+        this.within.downstream = ldef
+      }
+    }
+  }
+
   // for any link, find / build a route up to a view, from its' 1st input / output - that are assumed to be manager
   // message ports to the manager within that link...
   this.getLinkContext = (ldef) => {
+    if (ldef.type != 'link') return
     return new Promise((resolve, reject) => {
-      let tr = this.trace(ldef.outputs[1])
+      let tr = this.trace(ldef.outputs[1], true) // option to run modified trace to find first link
+      /*
+      ok, when you recurse you're looking through the link's output,
+      which hooks to the manager. sometimes this is an 'interior' link
+      this traces not up-to-a-view, but back-to-the-manager,
+      this can be made useful ... and this function should maybe more aptly be named
+      getLinkInteriorContext ... ok, party party
+      */
       if (tr) {
         if (tr.parent.type == 'view') {
           tr.parent.hunk.within = ldef
           ldef.contains = tr.parent.hunk
+          relink(ldef.ind)
           resolve(tr.parent.hunk)
         } else {
-          reject('looking for context, traces to non-view... ')
+          // when it's an interior link, this is the case
+          // but we don't really need to handle it...
+          resolve()
         }
       } else {
         resolve() // resolve w/ response that no context exists for this link,
@@ -1171,6 +1202,7 @@ function View() {
         // ok, we are now going to try to build a route between *contexts*
         // mapping a trace of links between them,
         let recursor = (context, entrance, trace) => {
+          console.log('REC thru', context, entrance)
           for (let df of context.defs) {
             if (df.type === 'link' && df !== entrance) {
               if (thru(df)) {
@@ -1189,6 +1221,8 @@ function View() {
                 } else {
                   recursor(thru(df).context, thru(df), traceClone(trace))
                 }
+              } else {
+                console.log('no thru', df)
               }
             }
           }
@@ -1371,14 +1405,16 @@ function View() {
           // so first we check for an existing hunk,
           let nd
           if (defs[spec.ind] === undefined) {
+            console.log("NEW", spec.ind)
             nd = newDef(spec)
             //console.log('the nd', nd)
           } else {
             if (verbose) console.log('updating hunk at', spec.ind)
+            console.log("UPDATE", spec.ind)
             nd = updateDef(spec)
           }
           // we manage our connectivity to other views,
-          relink(spec.ind)
+          this.getLinkContext(spec.ind)
           // set the flag, then call the callback
           setDefUpdate(spec.ind)
           // the promise-this callback,
@@ -1393,7 +1429,9 @@ function View() {
             console.error('received hunk replace for non existent hunk')
             console.error('here is the spec:', repSpec)
           } else {
+            console.log("REPLACE", repSpec.ind)
             replaceDef(repSpec)
+            this.getLinkContext(repSpec.ind)
             if (cbd) cbd.callback(nd)
           }
           break
diff --git a/view/blocks.js b/view/blocks.js
index c95391e74440dd9be5c5e82eade78bfe4dd201b4..04166ab2cbf89208389b88888f21f5ffbe49f244 100644
--- a/view/blocks.js
+++ b/view/blocks.js
@@ -87,6 +87,7 @@ let makeLink = (ldef, titleblock) => {
     $(ldef.squid).one('click', (evt) => {
       ldef.context.makeLinkContext(ldef).then((context) => {
         context.open = true
+        context.refresh()
       })
     })
   } else {
@@ -216,7 +217,7 @@ let wipeWires = (context) => {
   }
   // since some of those defs / having wires / may have been deleted,
   // we also need to rm any strays.
-  $(context.plane).find('.wire').remove()
+  $(context.plane).children('.wire').remove()
 }
 
 // this will scrape the def, removing any of its div elements, etc
@@ -237,7 +238,7 @@ let cleanDef = (def) => {
         // however, links are still a mess.
       }
       // don't wipe .hunks,
-      if ($(bl).is('.block')) $(bl).remove()
+      if ($(bl).is('.block') && !$(bl).is('.subplane')) $(bl).remove()
     }
     // rasa, courtesy of the boss
     def.context.cleanDef(def)
@@ -272,7 +273,7 @@ let rebuildDef = (def, position) => {
     if (position) {
       def.position = { x: position.x, y: position.y }
     } else {
-      def.position = { x: 200, y: 200 }
+      def.position = { x: 350, y: 150 }
     }
   }
 
diff --git a/view/contextmenu.js b/view/contextmenu.js
index 12f73f5453af025d18f3bf1ff93a2aa1b33bea58..97ec1c6e3f0c8fa5f033d26ef819d538b3619db8 100644
--- a/view/contextmenu.js
+++ b/view/contextmenu.js
@@ -307,7 +307,7 @@ function planeMenu(evt, context) {
               } else {
                 def.position = { x: 250, y: 250 }
               }
-              blocks.repositionDef(def)
+              if(def.blocks) blocks.repositionDef(def)
               successDisplay('hunk alive!')
               //console.log('one hunk as promised', def)
             }).catch((err) => {