diff --git a/internal/core/eval/eval.go b/internal/core/eval/eval.go
index bc5a477..4b81ce0 100644
--- a/internal/core/eval/eval.go
+++ b/internal/core/eval/eval.go
@@ -36,6 +36,8 @@
 	"cuelang.org/go/internal/core/debug"
 )
 
+var Debug = false
+
 // TODO TODO TODO TODO TODO TODO  TODO TODO TODO  TODO TODO TODO  TODO TODO TODO
 //
 // - Reuse work from previous cycles. For instance, if we can guarantee that a
@@ -110,18 +112,12 @@
 }
 
 type Evaluator struct {
-	r       adt.Runtime
-	index   adt.StringIndexer
-	closeID adt.ID
+	r     adt.Runtime
+	index adt.StringIndexer
 
 	stats Stats
 }
 
-func (e *Evaluator) nextID() adt.ID {
-	e.closeID++
-	return e.closeID
-}
-
 func (e *Evaluator) Eval(v *adt.Vertex) errors.Error {
 	if v.Value == nil {
 		ctx := adt.NewContext(e.r, e, v)
@@ -326,6 +322,36 @@
 	}
 	saved := *v
 
+	var closedInfo *acceptor
+	if v.Parent != nil {
+		closedInfo, _ = v.Parent.Closed.(*acceptor)
+	}
+
+	if !v.Label.IsInt() && closedInfo != nil {
+		ci := closedInfo
+		// Visit arcs recursively to validate and compute error.
+		switch ok, err := ci.verifyArc(c, v.Label, v); {
+		case err != nil:
+			// Record error in child node to allow recording multiple
+			// conflicts at the appropriate place, to allow valid fields to
+			// be represented normally and, most importantly, to avoid
+			// recursive processing of a disallowed field.
+			v.Value = err
+			v.SetValue(c, adt.Finalized, err)
+			return shared
+
+		case !ok: // hidden field
+			// A hidden field is except from checking. Ensure that the
+			// closedness doesn't carry over into children.
+			// TODO: make this more fine-grained per package, allowing
+			// checked restrictions to be defined within the package.
+			closedInfo = closedInfo.clone()
+			for i := range closedInfo.Canopy {
+				closedInfo.Canopy[i].IsDef = false
+			}
+		}
+	}
+
 	defer c.PopArc(c.PushArc(v))
 
 	e.stats.UnifyCount++
@@ -344,6 +370,11 @@
 		// validation has taken place.
 		*v = saved
 		v.Value = cycle
+
+		if closedInfo != nil {
+			v.Closed = closedInfo.clone()
+		}
+
 		v.UpdateStatus(adt.Evaluating)
 
 		// If the result is a struct, it needs to be closed if:
@@ -352,6 +383,9 @@
 		//      recursively.
 		//   3) this node embeds a closed struct.
 		needClose := v.Label.IsDef()
+		// if needClose {
+		// 	closedInfo.isClosed = true
+		// }
 
 		n := &nodeContext{
 			kind:       adt.TopKind,
@@ -366,7 +400,7 @@
 		for _, x := range v.Conjuncts {
 			// TODO: needed for reentrancy. Investigate usefulness for cycle
 			// detection.
-			n.addExprConjunct(x, true)
+			n.addExprConjunct(x)
 		}
 
 		if i == 0 {
@@ -561,42 +595,6 @@
 }
 
 func (n *nodeContext) updateClosedInfo() {
-	ctx := n.ctx
-
-	var c *CloseDef
-	if a, _ := n.node.Closed.(*acceptor); a != nil {
-		c = a.tree
-		n.needClose = n.needClose || a.isClosed
-	}
-
-	replace := n.replace
-	if replace == nil {
-		replace = map[adt.ID]*CloseDef{}
-	}
-
-	// Mark any used CloseID to keep, if not already replaced.
-	for _, x := range n.optionals {
-		if _, ok := replace[x.id]; !ok {
-			replace[x.id] = nil
-		}
-	}
-	for _, a := range n.node.Arcs {
-		for _, c := range a.Conjuncts {
-			if c.Env != nil {
-				if _, ok := replace[c.ID()]; !ok {
-					replace[c.ID()] = nil
-				}
-			}
-		}
-	}
-
-	updated := updateClosed(c, replace)
-	if updated == nil && n.needClose {
-		updated = &CloseDef{Src: n.node}
-	}
-
-	// TODO retrieve from env.
-
 	if err := n.getErr(); err != nil {
 		if b, _ := n.node.Value.(*adt.Bottom); b != nil {
 			err = adt.CombineErrors(nil, b, err)
@@ -606,35 +604,34 @@
 		// later. Logically we're done.
 	}
 
-	m := &acceptor{
-		tree:     updated,
-		fields:   n.optionals,
-		isClosed: n.needClose,
-		openList: n.openList,
-		isList:   n.node.IsList(),
-	}
-	if updated != nil || len(n.optionals) > 0 {
-		n.node.Closed = m
+	if n.node.IsList() {
+		return
 	}
 
-	// Visit arcs recursively to validate and compute error.
-	for _, a := range n.node.Arcs {
-		if updated != nil {
-			a.Closed = m
+	a, _ := n.node.Closed.(*acceptor)
+	if a == nil {
+		if !n.node.IsList() && !n.needClose {
+			return
 		}
-		if updated != nil && m.isClosed {
-			if accept := n.nodeShared.accept; accept != nil {
-				if !accept.Accept(n.ctx, a.Label) {
-					label := a.Label.SelectorString(ctx)
-					n.node.Value = ctx.NewErrf(
-						"field `%s` not allowed by Acceptor", label)
-				}
-			} else if err := m.verifyArcAllowed(n.ctx, a.Label); err != nil {
-				n.node.Value = err
+		a = closedInfo(n.node)
+	}
+
+	// TODO: set this earlier.
+	n.needClose = n.needClose || a.isClosed
+	a.isClosed = n.needClose
+
+	// TODO: consider removing this. Now checking is done at the top of
+	// evalVertex, skipping one level of checks happens naturally again
+	// for Value.Unify (API).
+	ctx := n.ctx
+
+	if accept := n.nodeShared.accept; accept != nil {
+		for _, a := range n.node.Arcs {
+			if !accept.Accept(n.ctx, a.Label) {
+				label := a.Label.SelectorString(ctx)
+				n.node.Value = ctx.NewErrf(
+					"field `%s` not allowed by Acceptor", label)
 			}
-			// TODO: use continue to not process already failed fields,
-			// or at least don't record recursive error.
-			// continue
 		}
 	}
 }
@@ -737,23 +734,15 @@
 	dynamicFields []envDynamic
 	ifClauses     []envYield
 	forClauses    []envYield
-	optionals     []fieldSet // env + field
-	// NeedClose:
-	// - node starts definition
-	// - embeds a definition
-	// - parent node is closing
+	// TODO: remove this and annotate directly in acceptor.
 	needClose bool
-	openList  bool
 	aStruct   adt.Expr
 	hasTop    bool
-	newClose  *CloseDef
-	// closeID   adt.ID // from parent, or if not exist, new if introducing a def.
-	replace map[adt.ID]*CloseDef
 
 	// Expression conjuncts
 	lists  []envList
 	vLists []*adt.Vertex
-	exprs  []conjunct
+	exprs  []adt.Conjunct
 
 	hasCycle    bool // has conjunct with structural cycle
 	hasNonCycle bool // has conjunct without structural cycle
@@ -764,6 +753,15 @@
 	isFinal      bool
 }
 
+func closedInfo(n *adt.Vertex) *acceptor {
+	a, _ := n.Closed.(*acceptor)
+	if a == nil {
+		a = &acceptor{}
+		n.Closed = a
+	}
+	return a
+}
+
 func (n *nodeContext) updateNodeType(k adt.Kind, v adt.Expr) bool {
 	ctx := n.ctx
 	kind := n.kind & k
@@ -883,11 +881,6 @@
 	}
 }
 
-type conjunct struct {
-	adt.Conjunct
-	top bool
-}
-
 type envDynamic struct {
 	env   *adt.Environment
 	field *adt.DynamicField
@@ -923,7 +916,7 @@
 // addExprConjuncts will attempt to evaluate an adt.Expr and insert the value
 // into the nodeContext if successful or queue it for later evaluation if it is
 // incomplete or is not value.
-func (n *nodeContext) addExprConjunct(v adt.Conjunct, top bool) {
+func (n *nodeContext) addExprConjunct(v adt.Conjunct) {
 	env := v.Env
 	id := v.CloseID
 
@@ -933,14 +926,14 @@
 
 	case *adt.BinaryExpr:
 		if x.Op == adt.AndOp {
-			n.addExprConjunct(adt.MakeConjunct(env, x.X, id), false)
-			n.addExprConjunct(adt.MakeConjunct(env, x.Y, id), false)
+			n.addExprConjunct(adt.MakeConjunct(env, x.X, id))
+			n.addExprConjunct(adt.MakeConjunct(env, x.Y, id))
 		} else {
-			n.evalExpr(v, top)
+			n.evalExpr(v)
 		}
 
 	case *adt.StructLit:
-		n.addStruct(env, x, id, top)
+		n.addStruct(env, x, id)
 
 	case *adt.ListLit:
 		n.lists = append(n.lists, envList{env: env, list: x, id: id})
@@ -949,20 +942,16 @@
 		if n.disjunctions != nil {
 			_ = n.disjunctions
 		}
-		n.addDisjunction(env, x, id, top)
+		n.addDisjunction(env, x, id)
 
 	default:
 		// Must be Resolver or Evaluator.
-		n.evalExpr(v, top)
-	}
-
-	if top {
-		n.updateReplace(v.CloseID)
+		n.evalExpr(v)
 	}
 }
 
 // evalExpr is only called by addExprConjunct.
-func (n *nodeContext) evalExpr(v adt.Conjunct, top bool) {
+func (n *nodeContext) evalExpr(v adt.Conjunct) {
 	// Require an Environment.
 	ctx := n.ctx
 
@@ -997,7 +986,7 @@
 			}
 		}
 		if arc == nil {
-			n.exprs = append(n.exprs, conjunct{v, top})
+			n.exprs = append(n.exprs, v)
 			break
 		}
 
@@ -1059,21 +1048,22 @@
 			defer func() { arc.SelfCount-- }()
 		}
 
+		if arc.Label.IsDef() { // should test whether closed, not isDef?
+			c := closedInfo(n.node)
+			closeID = c.InsertDefinition(v.CloseID, x)
+			n.needClose = true // TODO: is this still necessary?
+		}
+
 		// TODO: uncommenting the following almost works, but causes some
 		// faulty results in complex cycle handling between disjunctions.
 		// The reason is that disjunctions must be eliminated if checks in
 		// values on which they depend fail.
 		ctx.Unify(ctx, arc, adt.Finalized)
 
-		if arc.Label.IsDef() { // should test whether closed, not isDef?
-			id := n.eval.nextID()
-			n.insertClosed(arc, id, cyclic, arc)
-		} else {
-			for _, c := range arc.Conjuncts {
-				c = updateCyclic(c, cyclic, arc)
-				c.CloseID = closeID
-				n.addExprConjunct(c, top)
-			}
+		for _, c := range arc.Conjuncts {
+			c = updateCyclic(c, cyclic, arc)
+			c.CloseID = closeID
+			n.addExprConjunct(c)
 		}
 
 	case adt.Evaluator:
@@ -1081,7 +1071,7 @@
 		// Could be unify?
 		val, complete := ctx.Evaluate(v.Env, v.Expr())
 		if !complete {
-			n.exprs = append(n.exprs, conjunct{v, top})
+			n.exprs = append(n.exprs, v)
 			break
 		}
 
@@ -1092,7 +1082,7 @@
 			if ok && b.IsIncomplete() && len(v.Conjuncts) > 0 {
 				for _, c := range v.Conjuncts {
 					c.CloseID = closeID
-					n.addExprConjunct(c, top)
+					n.addExprConjunct(c)
 				}
 				break
 			}
@@ -1139,68 +1129,41 @@
 	return adt.MakeConjunct(env, c.Expr(), c.CloseID)
 }
 
-func (n *nodeContext) insertClosed(arc *adt.Vertex, id adt.ID, cyclic bool, deref *adt.Vertex) {
-	n.needClose = true
-
-	current := n.newClose
-	n.newClose = nil
-
-	for _, c := range arc.Conjuncts {
-		c = updateCyclic(c, cyclic, deref)
-		c.CloseID = id
-		n.addExprConjunct(c, false)
-	}
-
-	current, n.newClose = n.newClose, current
-
-	if current == nil {
-		current = &CloseDef{ID: id, Src: arc}
-	}
-	n.addAnd(current)
-}
-
 func (n *nodeContext) addValueConjunct(env *adt.Environment, v adt.Value, id adt.ID) {
 	n.updateCyclicStatus(env)
 
+	ctx := n.ctx
+
 	if x, ok := v.(*adt.Vertex); ok {
-		needClose := false
-		if isStruct(x) {
-			n.aStruct = x
-			// TODO: find better way to mark as struct.
-			// For instance, we may want to add a faux
-			// Structlit for topological sort.
-			// return
-
-			if x.IsClosed(n.ctx) {
-				needClose = true
-			}
-
-			n.node.AddStructs(x.Structs...)
+		if m, ok := x.Value.(*adt.StructMarker); ok && m.NeedClose {
+			ci := closedInfo(n.node)
+			ci.isClosed = true // TODO: remove
+			id = ci.InsertDefinition(id, x)
+			ci.Canopy[id].IsClosed = true
+			ci.Canopy[id].IsDef = false
 		}
 
 		if !x.IsData() && len(x.Conjuncts) > 0 {
 			cyclic := env != nil && env.Cyclic
-			if needClose {
-				n.insertClosed(x, id, cyclic, nil)
+
+			if isComplexStruct(x) {
+				closedInfo(n.node).InsertSubtree(id, n, x, cyclic)
 				return
 			}
+
 			for _, c := range x.Conjuncts {
 				c = updateCyclic(c, cyclic, nil)
 				c.CloseID = id
-				n.addExprConjunct(c, false) // TODO: Pass from eval
+				n.addExprConjunct(c) // TODO: Pass from eval
 			}
 			return
 		}
 
-		if x.IsList() {
-			n.vLists = append(n.vLists, x)
-			return
-		}
-
 		// TODO: evaluate value?
 		switch v := x.Value.(type) {
 		case *adt.ListMarker:
-			panic("unreachable")
+			n.vLists = append(n.vLists, x)
+			return
 
 		case *adt.StructMarker:
 			for _, a := range x.Arcs {
@@ -1237,11 +1200,9 @@
 		return
 	}
 
-	ctx := n.ctx
-
 	switch x := v.(type) {
 	case *adt.Disjunction:
-		n.addDisjunctionValue(env, x, id, true)
+		n.addDisjunctionValue(env, x, id)
 
 	case *adt.Conjunction:
 		for _, x := range x.Values {
@@ -1251,7 +1212,13 @@
 	case *adt.Top:
 		n.hasTop = true
 		// TODO: Is this correct. Needed for elipsis, but not sure for others.
-		n.optionals = append(n.optionals, fieldSet{env: env, id: id, isOpen: true})
+		// n.optionals = append(n.optionals, fieldSet{env: env, id: id, isOpen: true})
+		if a, _ := n.node.Closed.(*acceptor); a != nil {
+			// Embedding top indicates that now all possible values are allowed
+			// and that we should no longer enforce closedness within this
+			// conjunct.
+			a.node(id).IsDef = false
+		}
 
 	case *adt.BasicType:
 		// handled above
@@ -1320,8 +1287,7 @@
 func (n *nodeContext) addStruct(
 	env *adt.Environment,
 	s *adt.StructLit,
-	closeID adt.ID,
-	top bool) {
+	closeID adt.ID) {
 
 	n.updateCyclicStatus(env) // to handle empty structs.
 
@@ -1382,24 +1348,16 @@
 
 		case adt.Expr:
 			hasEmbed = true
+			hasOther = x
+
+			// add embedding to optional
+
+			// TODO(perf): only do this if addExprConjunct below will result in
+			// a fieldSet. Otherwise the entry will just be removed next.
+			id := closedInfo(n.node).InsertEmbed(closeID, x)
 
 			// push and opo embedding type.
-			id := n.eval.nextID()
-
-			current := n.newClose
-			n.newClose = nil
-
-			hasOther = x
-			n.addExprConjunct(adt.MakeConjunct(childEnv, x, id), false)
-
-			current, n.newClose = n.newClose, current
-
-			if current == nil {
-				current = &CloseDef{Src: s, ID: id} // TODO: isClosed?
-			} else {
-				// n.needClose = true
-			}
-			n.addOr(closeID, current)
+			n.addExprConjunct(adt.MakeConjunct(childEnv, x, id))
 
 		case *adt.BulkOptionalField:
 			n.aStruct = s
@@ -1430,7 +1388,7 @@
 		opt.MatchAndInsert(ctx, arc)
 	}
 
-	n.optionals = append(n.optionals, opt)
+	closedInfo(n.node).insertFieldSet(closeID, &opt)
 
 	for _, d := range s.Decls {
 		switch x := d.(type) {
@@ -1451,9 +1409,9 @@
 	arc.AddConjunct(x)
 
 	if isNew {
-		for _, o := range n.optionals {
+		closedInfo(n.node).visitAllFieldSets(func(o *fieldSet) {
 			o.MatchAndInsert(ctx, arc)
-		}
+		})
 	}
 	return arc
 }
@@ -1497,7 +1455,7 @@
 	exprs := n.exprs
 	n.exprs = n.exprs[:0]
 	for _, x := range exprs {
-		n.addExprConjunct(x.Conjunct, x.top)
+		n.addExprConjunct(x)
 
 		// collect and and or
 	}
@@ -1570,7 +1528,7 @@
 		}
 
 		for _, st := range sa {
-			n.addStruct(st.env, st.s, d.id, true)
+			n.addStruct(st.env, st.s, d.id)
 		}
 	}
 
@@ -1717,7 +1675,8 @@
 			continue // error generated earlier, if applicable.
 		}
 
-		n.optionals = append(n.optionals, a.fields...)
+		// TODO: why not necessary?
+		// n.optionals = append(n.optionals, a.fields...)
 
 		for _, arc := range elems[len(newElems):] {
 			l.MatchAndInsert(c, arc)
@@ -1729,10 +1688,10 @@
 			continue
 		}
 
-		f := fieldSet{pos: l.list, env: l.env, id: l.id}
+		f := &fieldSet{pos: l.list, env: l.env, id: l.id}
 		f.AddEllipsis(c, l.elipsis)
 
-		n.optionals = append(n.optionals, f)
+		closedInfo(n.node).insertFieldSet(l.id, f)
 
 		for _, arc := range elems[l.n:] {
 			f.MatchAndInsert(c, arc)
@@ -1750,7 +1709,9 @@
 		}
 	}
 
-	n.openList = isOpen
+	ci := closedInfo(n.node)
+	ci.isList = true
+	ci.openList = isOpen
 
 	if m, ok := n.node.Value.(*adt.ListMarker); !ok {
 		n.node.SetValue(c, adt.Partial, &adt.ListMarker{
