diff --git a/internal/core/eval/closed.go b/internal/core/eval/closed.go
index 175b08d..a33c324 100644
--- a/internal/core/eval/closed.go
+++ b/internal/core/eval/closed.go
@@ -14,34 +14,35 @@
 
 package eval
 
-// The file implements the majority of the closed struct semantics.
-// The data is recorded in the Closed field of a Vertex.
+// The file implements the majority of the closed struct semantics. The data is
+// recorded in the Closed field of a Vertex.
 //
 // Each vertex has a set of conjuncts that make up the values of the vertex.
 // Each Conjunct may originate from various sources, like an embedding, field
 // definition or regular value. For the purpose of computing the value, the
-// source of the conjunct is irrelevant. The origin does matter, however, if
-// for determining whether a field is allowed in a closed struct. The Closed
-// field keeps track of the kind of origin for this purpose.
+// source of the conjunct is irrelevant. The origin does matter, however, for
+// determining whether a field is allowed in a closed struct. The Closed field
+// keeps track of the kind of origin for this purpose.
 //
-// More precisely, the CloseDef struct explains how the conjuncts of an arc
-// were combined and define a logical expression on the field sets
-// computed for each conjunct.
+// More precisely, the CloseDef struct explains how the conjuncts of an arc were
+// combined for instance due to a conjunction with closed struct or through an
+// embedding. Each Vertex may be associated with a slice of CloseDefs. The
+// position of a CloseDef in a file corresponds to an adt.ID.
 //
-// While evaluating each conjunct, nodeContext keeps track what changes need to
-// be made to ClosedDef based on the evaluation of the current conjuncts.
-// For instance, if a field references a definition, all other previous
-// checks are useless, as the newly referred to definitions define an upper
-// bound and will contain all the information that is necessary to determine
-// whether a field may be included.
+// While evaluating each conjunct, new CloseDefs are added to indicate how a
+// conjunct relates to its parent as needed. For instance, if a field references
+// a definition, all other previous checks are useless, as the newly referred to
+// definitions define an upper bound and will contain all the information that
+// is necessary to determine whether a field may be included.
 //
 // Most of the logic in this file concerns itself with the combination of
 // multiple CloseDef values as well as traversing the structure to validate
-// whether an arc is allowed. The actual fieldSet logic is in optional.go
-// The overal control and use of the functionality in this file is used
-// in eval.go.
+// whether an arc is allowed. The actual fieldSet logic is in optional.go The
+// overall control and use of the functionality in this file is used in eval.go.
 
 import (
+	"fmt"
+
 	"cuelang.org/go/internal/core/adt"
 )
 
@@ -66,17 +67,34 @@
 // `b` originated from an embedding, as otherwise `e` may not be allowed.
 //
 type acceptor struct {
-	tree     *CloseDef
-	fields   []fieldSet
+	Canopy []CloseDef
+	Fields []*fieldSet
+
+	// TODO: remove (unused as not fine-grained enough)
+	// isClosed is now used as an approximate filter.
 	isClosed bool
 	isList   bool
 	openList bool
 }
 
+func (a *acceptor) clone() *acceptor {
+	canopy := make([]CloseDef, len(a.Canopy))
+	copy(canopy, a.Canopy)
+	for i := range canopy {
+		canopy[i].IsClosed = false
+	}
+	return &acceptor{
+		Canopy:   canopy,
+		isClosed: a.isClosed,
+	}
+}
+
 func (a *acceptor) Accept(c *adt.OpContext, f adt.Feature) bool {
 	if a.isList {
 		return a.openList
 	}
+
+	// TODO: remove these two checks and always pass InvalidLabel.
 	if !a.isClosed {
 		return true
 	}
@@ -86,19 +104,19 @@
 	if f.IsInt() {
 		return a.openList
 	}
-	return a.verifyArcAllowed(c, f) == nil
+	return a.verifyArcAllowed(c, f, nil)
 }
 
 func (a *acceptor) MatchAndInsert(c *adt.OpContext, v *adt.Vertex) {
-	for _, fs := range a.fields {
+	a.visitAllFieldSets(func(fs *fieldSet) {
 		fs.MatchAndInsert(c, v)
-	}
+	})
 }
 
 func (a *acceptor) OptionalTypes() (mask adt.OptionalType) {
-	for _, f := range a.fields {
+	a.visitAllFieldSets(func(f *fieldSet) {
 		mask |= f.OptionalTypes()
-	}
+	})
 	return mask
 }
 
@@ -114,302 +132,474 @@
 // Acceptor. This could be implemented as an allocation-free wrapper type around
 // a Disjunction. This will require a bit more API cleaning, though.
 func newDisjunctionAcceptor(x *adt.Disjunction) adt.Acceptor {
-	tree := &CloseDef{Src: x}
-	sets := []fieldSet{}
+	n := &acceptor{}
+
 	for _, d := range x.Values {
 		if a, _ := d.Closed.(*acceptor); a != nil {
-			sets = append(sets, a.fields...)
-			tree.List = append(tree.List, a.tree)
+			offset := n.InsertSubtree(0, nil, d, false)
+			a.visitAllFieldSets(func(f *fieldSet) {
+				g := *f
+				g.id += offset
+				n.insertFieldSet(g.id, &g)
+			})
 		}
 	}
-	if len(tree.List) == 0 && len(sets) == 0 {
-		return nil
-	}
-	return &acceptor{tree: tree, fields: sets}
+
+	return n
 }
 
-// CloseDef defines how individual FieldSets (corresponding to conjuncts)
+// CloseDef defines how individual fieldSets (corresponding to conjuncts)
 // combine to determine whether a field is contained in a closed set.
 //
-// Nodes with a non-empty List and IsAnd is false represent embeddings.
-// The ID is the node that contained the embedding in that case.
-//
-// Nodes with a non-empty List and IsAnd is true represent conjunctions of
-// definitions. In this case, a field must be contained in each definition.
-//
-// If a node has both conjunctions of definitions and embeddings, only the
-// former are maintained. Conjunctions of definitions define an upper bound
-// of the set of allowed fields in that case and the embeddings will not add
-// any value.
+// A CloseDef combines multiple conjuncts and embeddings. All CloseDefs are
+// stored in slice. References to other CloseDefs are indices within this slice.
+// Together they define the top of the tree of the expression tree of how
+// conjuncts combine together (a canopy).
 type CloseDef struct {
-	Src   adt.Node // for error reporting
-	ID    adt.ID
-	IsAnd bool
-	List  []*CloseDef
+	Src adt.Node
+
+	// And is used to track the IDs of a set of conjuncts. If IsDef or IsClosed
+	// is true, a field is only allowed if at least one of the corresponding
+	// fieldsets associated with this node or its embeddings allows it.
+	//
+	// And nodes are linked in a ring, meaning that the last node points back
+	// to the first node. This allows a traversal of all and nodes to commence
+	// at any point in the ring.
+	And adt.ID
+
+	// NextEmbed indicates the first ID for a linked list of embedded
+	// expressions. The node corresponding to the actual embedding is at
+	// position NextEmbed+1. The linked-list nodes all have a value of -1 for
+	// And. NextEmbed is 0 for the last element in the list.
+	NextEmbed adt.ID
+
+	// IsDef indicates this node is associated with a definition and that all
+	// expressions are recursively closed. This value is "sticky" when a child
+	// node copies the closedness data from a parent node.
+	IsDef bool
+
+	// IsClosed indicates this node is associated with the result of close().
+	// A child vertex should not "inherit" this value.
+	IsClosed bool
 }
 
-// isOr reports whether this is a node representing embeddings.
-func isOr(c *CloseDef) bool {
-	return len(c.List) > 0 && !c.IsAnd
+func (n *CloseDef) isRequired() bool {
+	return n.IsDef || n.IsClosed
 }
 
-// updateClosed transforms c into a new node with all non-AND nodes with an
-// ID matching one in replace substituted with the replace value.
-//
-// Vertex only keeps track of a flat list of conjuncts and does not keep track
-// of the hierarchy of how these were derived. This function allows rewriting
-// a CloseDef tree based on replacement information gathered during evaluation
-// of this flat list.
-//
-func updateClosed(c *CloseDef, replace map[adt.ID]*CloseDef) *CloseDef { // used in eval.go
-	// Insert an entry for CloseID 0 if we are about to replace it. By default
-	// 0, which is the majority case, is omitted.
-	if c != nil && replace[0] != nil && !containsClosed(c, 0) {
-		c = &CloseDef{IsAnd: true, List: []*CloseDef{c, {}}}
-	}
+const embedRoot adt.ID = -1
 
-	switch {
-	case c == nil:
-		and := []*CloseDef{}
-		for _, c := range replace {
-			if c != nil {
-				and = append(and, c)
-			}
+type Entry = fieldSet
+
+func (c *acceptor) visitAllFieldSets(f func(f *fieldSet)) {
+	for _, set := range c.Fields {
+		for ; set != nil; set = set.next {
+			f(set)
 		}
-		switch len(and) {
-		case 0:
-		case 1:
-			c = and[0]
-		default:
-			c = &CloseDef{IsAnd: true, List: and}
-		}
-		// needClose
-	case len(replace) > 0:
-		c = updateClosedRec(c, replace)
 	}
-	return c
 }
 
-func updateClosedRec(c *CloseDef, replace map[adt.ID]*CloseDef) *CloseDef {
-	if c == nil {
+func (c *acceptor) visitAnd(id adt.ID, f func(id adt.ID, n CloseDef) bool) bool {
+	for i := id; ; {
+		x := c.Canopy[i]
+
+		if !f(i, x) {
+			return false
+		}
+
+		if i = x.And; i == id {
+			break
+		}
+	}
+	return true
+}
+
+func (c *acceptor) visitOr(id adt.ID, f func(id adt.ID, n CloseDef) bool) bool {
+	if !f(id, c.Canopy[id]) {
+		return false
+	}
+	return c.visitEmbed(id, f)
+}
+
+func (c *acceptor) visitEmbed(id adt.ID, f func(id adt.ID, n CloseDef) bool) bool {
+	for i := c.Canopy[id].NextEmbed; i != 0; i = c.Canopy[i].NextEmbed {
+		if id := i + 1; !f(id, c.Canopy[id]) {
+			return false
+		}
+	}
+	return true
+}
+
+func (c *acceptor) node(id adt.ID) *CloseDef {
+	if len(c.Canopy) == 0 {
+		c.Canopy = append(c.Canopy, CloseDef{})
+	}
+	return &c.Canopy[id]
+}
+
+func (c *acceptor) fieldSet(at adt.ID) *fieldSet {
+	if int(at) >= len(c.Fields) {
 		return nil
 	}
-
-	// If c is a leaf or AND node, replace it outright. If both are an OR node,
-	// merge the lists.
-	if len(c.List) == 0 || !c.IsAnd {
-		switch sub, ok := replace[c.ID]; {
-		case sub != nil:
-			if isOr(sub) && isOr(c) {
-				sub.List = append(sub.List, c.List...)
-			}
-			return sub
-
-		case !ok:
-			if len(c.List) == 0 {
-				return nil // drop from list
-			}
-		}
-	}
-
-	changed := false
-	buf := make([]*CloseDef, len(c.List))
-	k := 0
-	for _, c := range c.List {
-		n := updateClosedRec(c, replace)
-		changed = changed || n != c
-		if n != nil {
-			buf[k] = n
-			k++
-		}
-	}
-	if !changed {
-		return c
-	}
-
-	switch k {
-	case 0:
-		return nil
-	case 1:
-		return buf[0]
-	default:
-		return &CloseDef{Src: c.Src, ID: c.ID, IsAnd: c.IsAnd, List: buf[:k]}
-	}
+	return c.Fields[at]
 }
 
-// UpdateReplace is called after evaluating a conjunct at the top of the arc
-// to update the replacement information with the gathered CloseDef info.
-func (n *nodeContext) updateReplace(id adt.ID) { // used in eval.go
-	if n.newClose == nil {
-		return
+func (c *acceptor) insertFieldSet(at adt.ID, e *fieldSet) {
+	c.node(0) // Ensure the canopy is at least length 1.
+	if len(c.Fields) < len(c.Canopy) {
+		a := make([]*fieldSet, len(c.Canopy))
+		copy(a, c.Fields)
+		c.Fields = a
 	}
-
-	if n.replace == nil {
-		n.replace = make(map[adt.ID]*CloseDef)
-	}
-
-	n.replace[id] = updateClose(n.replace[id], n.newClose)
-	n.newClose = nil
+	e.next = c.Fields[at]
+	c.Fields[at] = e
 }
 
-// appendList creates a new CloseDef with the elements of the list of orig
-// and updated appended. It will take the ID of orig. It does not alter
-// either orig or update.
-func appendLists(orig, update *CloseDef) *CloseDef {
-	list := make([]*CloseDef, len(orig.List)+len(update.List))
-	copy(list[copy(list, orig.List):], update.List)
-	c := *orig
-	c.List = list
-	return &c
+// InsertDefinition appends a new CloseDef to Canopy representing a reference to
+// a definition at the given position. It returns the position of the new
+// CloseDef.
+func (c *acceptor) InsertDefinition(at adt.ID, src adt.Node) (id adt.ID) {
+	if len(c.Canopy) == 0 {
+		c.Canopy = append(c.Canopy, CloseDef{})
+	}
+	if int(at) >= len(c.Canopy) {
+		panic(fmt.Sprintf("at >= len(canopy) (%d >= %d)", at, len(c.Canopy)))
+	}
+	// New there is a new definition, the parent location (invariant) is no
+	// longer a required entry and could be dropped if there were no more
+	// fields.
+	//    #orig: #d     // only fields in #d are sufficient to check.
+	//    #orig: {a: b}
+	c.Canopy[at].IsDef = false
+
+	id = adt.ID(len(c.Canopy))
+	y := CloseDef{
+		Src:       src,
+		And:       c.Canopy[at].And,
+		NextEmbed: 0,
+		IsDef:     true,
+	}
+	c.Canopy[at].And = id
+	c.Canopy = append(c.Canopy, y)
+
+	return id
 }
 
-// updateClose merges update into orig without altering either.
-//
-// The merge takes into account whether it is an embedding node or not.
-// Most notably, if an "And" node is combined with an embedding, the
-// embedding information may be discarded.
-func updateClose(orig, update *CloseDef) *CloseDef {
-	switch {
-	case orig == nil:
-		return update
-	case isOr(orig):
-		if !isOr(update) {
-			return update
-		}
-		return appendLists(orig, update)
-	case isOr(update):
-		return orig
-	case len(orig.List) == 0 && len(update.List) == 0:
-		return &CloseDef{IsAnd: true, List: []*CloseDef{orig, update}}
-	case len(orig.List) == 0:
-		update.List = append(update.List, orig)
-		return update
-	default: // isAnd(orig)
-		return appendLists(orig, update)
+// InsertEmbed appends a new CloseDef to Canopy representing the use of an
+// embedding at the given position. It returns the position of the new CloseDef.
+func (c *acceptor) InsertEmbed(at adt.ID, src adt.Node) (id adt.ID) {
+	if len(c.Canopy) == 0 {
+		c.Canopy = append(c.Canopy, CloseDef{})
 	}
+	if int(at) >= len(c.Canopy) {
+		panic(fmt.Sprintf("at >= len(canopy) (%d >= %d)", at, len(c.Canopy)))
+	}
+
+	id = adt.ID(len(c.Canopy))
+	y := CloseDef{
+		And:       -1,
+		NextEmbed: c.Canopy[at].NextEmbed,
+	}
+	z := CloseDef{Src: src, And: id + 1}
+	c.Canopy[at].NextEmbed = id
+	c.Canopy = append(c.Canopy, y, z)
+
+	return id + 1
 }
 
-func (n *nodeContext) addAnd(c *CloseDef) { // used in eval.go
-	switch {
-	case n.newClose == nil:
-		n.newClose = c
-	case isOr(n.newClose):
-		n.newClose = c
-	case len(n.newClose.List) == 0:
-		n.newClose = &CloseDef{
-			IsAnd: true,
-			List:  []*CloseDef{n.newClose, c},
-		}
-	default:
-		n.newClose.List = append(n.newClose.List, c)
-	}
-}
-
-func (n *nodeContext) addOr(parentID adt.ID, c *CloseDef) { // used in eval.go
-	switch {
-	case n.newClose == nil:
-		d := &CloseDef{ID: parentID, List: []*CloseDef{{ID: parentID}}}
-		if c != nil {
-			d.List = append(d.List, c)
-		}
-		n.newClose = d
-	case isOr(n.newClose):
-		d := n.newClose
-		if c != nil {
-			d.List = append(d.List, c)
-		}
-	}
-}
-
-// verifyArcAllowed checks whether f is an allowed label within the current
-// node. It traverses c considering the "or" semantics of embeddings and the
-// "and" semantics of conjunctions. It generates an error if a field is not
-// allowed.
-func (n *acceptor) verifyArcAllowed(ctx *adt.OpContext, f adt.Feature) *adt.Bottom {
-	defer ctx.ReleasePositions(ctx.MarkPositions())
-
-	// TODO(perf): this will also generate a message for f == 0. Do something
-	// more clever and only generate this when it is a user error.
-	filter := f.IsString() || f == adt.InvalidLabel
-	if filter && !n.verifyArcRecursive(ctx, n.tree, f) {
-		collectPositions(ctx, n.tree)
-		label := f.SelectorString(ctx)
-		return ctx.NewErrf("field `%s` not allowed", label)
-	}
-	return nil
-}
-
-func (n *acceptor) verifyArcRecursive(ctx *adt.OpContext, c *CloseDef, f adt.Feature) bool {
-	if len(c.List) == 0 {
-		return n.verifyDefinition(ctx, c.ID, f)
-	}
-	if c.IsAnd {
-		for _, c := range c.List {
-			if !n.verifyArcRecursive(ctx, c, f) {
-				return false
-			}
-		}
+// isComplexStruct reports whether the Closed information should be copied as a
+// subtree into the parent node using InsertSubtree. If not, the conjuncts can
+// just be inserted at the current ID.
+func isComplexStruct(v *adt.Vertex) bool {
+	m, _ := v.Value.(*adt.StructMarker)
+	if m == nil {
 		return true
 	}
-	for _, c := range c.List {
-		if n.verifyArcRecursive(ctx, c, f) {
-			return true
-		}
+	a, _ := v.Closed.(*acceptor)
+	if a == nil {
+		return false
 	}
-	return false
+	if a.isClosed {
+		return true
+	}
+	switch len(a.Canopy) {
+	case 0:
+		return false
+	case 1:
+		// TODO: should we check for closedness?
+		x := a.Canopy[0]
+		return x.isRequired()
+	}
+	return true
 }
 
-// verifyDefinition reports whether f is a valid member for any of the fieldSets
-// with the same closeID.
-func (n *acceptor) verifyDefinition(ctx *adt.OpContext, closeID adt.ID, f adt.Feature) (ok bool) {
-	for _, o := range n.fields {
-		if o.id != closeID {
-			continue
+// InsertSubtree inserts the closedness information of v into c as an embedding
+// at the current position and inserts conjuncts of v into n (if not nil).
+// It inserts it as an embedding and not and to cover either case. The idea is
+// that one of the values were supposed to be closed, a separate node entry
+// would already have been created.
+func (c *acceptor) InsertSubtree(at adt.ID, n *nodeContext, v *adt.Vertex, cyclic bool) adt.ID {
+	if len(c.Canopy) == 0 {
+		c.Canopy = append(c.Canopy, CloseDef{})
+	}
+	if int(at) >= len(c.Canopy) {
+		panic(fmt.Sprintf("at >= len(canopy) (%d >= %d)", at, len(c.Canopy)))
+	}
+
+	a := closedInfo(v)
+	a.node(0)
+
+	id := adt.ID(len(c.Canopy))
+	y := CloseDef{
+		And:       embedRoot,
+		NextEmbed: c.Canopy[at].NextEmbed,
+	}
+	c.Canopy[at].NextEmbed = id
+
+	c.Canopy = append(c.Canopy, y)
+	id = adt.ID(len(c.Canopy))
+
+	// First entry is at the embedded node location.
+	c.Canopy = append(c.Canopy, a.Canopy...)
+
+	// Shift all IDs for the new offset.
+	for i, x := range c.Canopy[id:] {
+		if x.And != -1 {
+			c.Canopy[int(id)+i].And += id
+		}
+		if x.NextEmbed != 0 {
+			c.Canopy[int(id)+i].NextEmbed += id
+		}
+	}
+
+	if n != nil {
+		for _, c := range v.Conjuncts {
+			c = updateCyclic(c, cyclic, nil)
+			c.CloseID += id
+			n.addExprConjunct(c)
+		}
+	}
+
+	return id
+}
+
+func (c *acceptor) verifyArc(ctx *adt.OpContext, f adt.Feature, v *adt.Vertex) (found bool, err *adt.Bottom) {
+
+	defer ctx.ReleasePositions(ctx.MarkPositions())
+
+	c.node(0) // ensure at least a size of 1.
+	if c.verify(ctx, f) {
+		return true, nil
+	}
+
+	// TODO: also disallow non-hidden definitions.
+	if !f.IsString() && f != adt.InvalidLabel {
+		return false, nil
+	}
+
+	if v != nil {
+		for _, c := range v.Conjuncts {
+			if pos := c.Field(); pos != nil {
+				ctx.AddPosition(pos)
+			}
+		}
+	}
+
+	// collect positions from tree.
+	for _, c := range c.Canopy {
+		if c.Src != nil {
+			ctx.AddPosition(c.Src)
+		}
+	}
+
+	label := f.SelectorString(ctx)
+	return false, ctx.NewErrf("field `%s` not allowed", label)
+}
+
+func (c *acceptor) verifyArcAllowed(ctx *adt.OpContext, f adt.Feature, v *adt.Vertex) bool {
+
+	// TODO: also disallow non-hidden definitions.
+	if !f.IsString() && f != adt.InvalidLabel {
+		return true
+	}
+
+	defer ctx.ReleasePositions(ctx.MarkPositions())
+
+	c.node(0) // ensure at least a size of 1.
+	return c.verify(ctx, f)
+}
+
+func (c *acceptor) verify(ctx *adt.OpContext, f adt.Feature) bool {
+	ok, required := c.verifyAnd(ctx, 0, f)
+	return ok || (!required && !c.isClosed)
+}
+
+// verifyAnd reports whether f is contained in all closed conjuncts at id and,
+// if not, whether the precense of at least one entry is required.
+func (c *acceptor) verifyAnd(ctx *adt.OpContext, id adt.ID, f adt.Feature) (found, required bool) {
+	for i := id; ; {
+		x := c.Canopy[i]
+
+		if ok, req := c.verifySets(ctx, i, f); ok {
+			found = true
+		} else if ok, isClosed := c.verifyEmbed(ctx, i, f); ok {
+			found = true
+		} else if req || x.isRequired() {
+			// Not found for a closed entry so this indicates a failure.
+			return false, true
+		} else if isClosed {
+			// The node itself isn't closed, but an embedding indicates it
+			// should. See cue/testdata/definitions/embed.txtar.
+			required = true
 		}
 
+		if i = x.And; i == id {
+			break
+		}
+	}
+
+	return found, required
+}
+
+// verifyEmbed reports whether any of the embeddings for the node at id allows f
+// and, if not, whether the embeddings imply that the enclosing node should be
+// closed. The latter is the case when embedded struct itself is closed.
+func (c *acceptor) verifyEmbed(ctx *adt.OpContext, id adt.ID, f adt.Feature) (found, isClosed bool) {
+
+	for i := c.Canopy[id].NextEmbed; i != 0; i = c.Canopy[i].NextEmbed {
+		ok, req := c.verifyAnd(ctx, i+1, f)
+		if ok {
+			return true, false
+		}
+		if req {
+			isClosed = true
+		}
+	}
+	return false, isClosed
+}
+
+func (c *acceptor) verifySets(ctx *adt.OpContext, id adt.ID, f adt.Feature) (found, required bool) {
+	o := c.fieldSet(id)
+	if o == nil {
+		return false, false
+	}
+	for ; o != nil; o = o.next {
 		if len(o.additional) > 0 || o.isOpen {
-			return true
+			return true, false
 		}
 
 		for _, g := range o.fields {
 			if f == g.label {
-				return true
+				return true, false
 			}
 		}
 
 		for _, b := range o.bulk {
 			if b.check.Match(ctx, f) {
-				return true
+				return true, false
 			}
 		}
 	}
-	for _, o := range n.fields {
+
+	// TODO: this is the same location where code is registered as the old code,
+	// but
+	for o := c.Fields[id]; o != nil; o = o.next {
 		if o.pos != nil {
 			ctx.AddPosition(o.pos)
 		}
 	}
-	return false
+	return false, false
 }
 
-func collectPositions(ctx *adt.OpContext, c *CloseDef) {
-	if c.Src != nil {
-		ctx.AddPosition(c.Src)
-	}
-	for _, x := range c.List {
-		collectPositions(ctx, x)
-	}
+type info struct {
+	referred bool
+	up       adt.ID
+	replace  adt.ID
+	reverse  adt.ID
 }
 
-// containsClosed reports whether c contains any CloseDef with ID x,
-// recursively.
-func containsClosed(c *CloseDef, x adt.ID) bool {
-	if c.ID == x && !c.IsAnd {
-		return true
+func (c *acceptor) Compact(all []adt.Conjunct) (compacted []CloseDef) {
+	a := c.Canopy
+	if len(a) == 0 {
+		return nil
 	}
-	for _, e := range c.List {
-		if containsClosed(e, x) {
-			return true
+
+	marked := make([]info, len(a))
+
+	c.markParents(0, marked)
+
+	// Mark all entries that cannot be dropped.
+	for _, x := range all {
+		c.markUsed(x.CloseID, marked)
+	}
+
+	// Compute compact numbers and reverse.
+	k := adt.ID(0)
+	for i, x := range marked {
+		if x.referred {
+			marked[i].replace = k
+			marked[k].reverse = adt.ID(i)
+			k++
 		}
 	}
-	return false
+
+	compacted = make([]CloseDef, k)
+
+	for i := range compacted {
+		orig := c.Canopy[marked[i].reverse]
+
+		and := orig.And
+		if and != embedRoot {
+			and = marked[orig.And].replace
+		}
+		compacted[i] = CloseDef{
+			Src:   orig.Src,
+			And:   and,
+			IsDef: orig.IsDef,
+		}
+
+		last := adt.ID(i)
+		for or := orig.NextEmbed; or != 0; or = c.Canopy[or].NextEmbed {
+			if marked[or].referred {
+				compacted[last].NextEmbed = marked[or].replace
+				last = marked[or].replace
+			}
+		}
+	}
+
+	// Update conjuncts
+	for i, x := range all {
+		all[i].CloseID = marked[x.ID()].replace
+	}
+
+	return compacted
+}
+
+func (c *acceptor) markParents(parent adt.ID, info []info) {
+	// Ands are arranged in a ring, so check for parent, not 0.
+	c.visitAnd(parent, func(i adt.ID, x CloseDef) bool {
+		c.visitEmbed(i, func(j adt.ID, x CloseDef) bool {
+			info[j-1].up = i
+			info[j].up = i
+			c.markParents(j, info)
+			return true
+		})
+		return true
+	})
+}
+
+func (c *acceptor) markUsed(id adt.ID, marked []info) {
+	if marked[id].referred {
+		return
+	}
+
+	if id > 0 && c.Canopy[id-1].And == embedRoot {
+		marked[id-1].referred = true
+	}
+
+	for i := id; !marked[i].referred; i = c.Canopy[i].And {
+		marked[i].referred = true
+	}
+
+	c.markUsed(marked[id].up, marked)
 }
diff --git a/internal/core/eval/closed_test.go b/internal/core/eval/closed_test.go
index 45511f6..9c1d3d7 100644
--- a/internal/core/eval/closed_test.go
+++ b/internal/core/eval/closed_test.go
@@ -15,164 +15,448 @@
 package eval
 
 import (
+	"fmt"
+	"strings"
 	"testing"
 
 	"cuelang.org/go/internal/core/adt"
-	"github.com/google/go-cmp/cmp"
 )
 
-func TestRewriteClosed(t *testing.T) {
+func TestInsert(t *testing.T) {
 	testCases := []struct {
-		desc    string
-		close   *CloseDef
-		replace map[adt.ID]*CloseDef
-		want    *CloseDef
+		tree   []CloseDef
+		typ    func(c *acceptor, at adt.ID, p adt.Node) adt.ID
+		at     adt.ID
+		wantID adt.ID
+		out    string
 	}{{
-		desc:  "introduce new",
-		close: nil,
-		replace: map[adt.ID]*CloseDef{
-			0: {ID: 2, IsAnd: false, List: nil},
-		},
-		want: &CloseDef{
-			ID: 0x02,
-		},
+		tree:   nil,
+		at:     0,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 1,
+		out:    "&( 0[] *1[])",
 	}, {
-		desc: "auto insert missing 0",
-		close: &CloseDef{
-			ID: 1,
-		},
-		replace: map[adt.ID]*CloseDef{
-			0: {ID: 2, IsAnd: false, List: nil},
-			1: nil, // keep 1
-		},
-		want: &CloseDef{
-			IsAnd: true,
-			List:  []*CloseDef{{ID: 1}, {ID: 2}},
-		},
+		tree:   []CloseDef{{}},
+		at:     0,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 1,
+		out:    "&( 0[] *1[])",
 	}, {
-		desc: "a: #A & #B",
-		close: &CloseDef{
-			ID: 1,
-		},
-		replace: map[adt.ID]*CloseDef{
-			1: {ID: 1, IsAnd: true, List: []*CloseDef{{ID: 2}, {ID: 3}}},
-		},
-		want: &CloseDef{
-			ID:    0x01,
-			IsAnd: true,
-			List:  []*CloseDef{{ID: 2}, {ID: 3}},
-		},
+		tree:   []CloseDef{0: {And: 1}, {And: 0, IsDef: true}},
+		at:     0,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 2,
+		out:    "&( 0[] *2[] *1[])",
 	}, {
-		desc: "eliminateUnusedToEmpty",
-		close: &CloseDef{
-			ID: 1,
-		},
-		replace: map[adt.ID]*CloseDef{
-			0: nil,
-		},
-		want: nil,
+		tree:   []CloseDef{0: {And: 1}, 1: {And: 0, IsDef: true}},
+		at:     1,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 2,
+		out:    "&( 0[] 1[] *2[])",
 	}, {
-		// Eliminate an embedding for which there are no more entries.
-		desc: "eliminateOneEmbedding",
-		close: &CloseDef{
-			ID: 0,
-			List: []*CloseDef{
-				{ID: 2},
-				{ID: 3},
-			},
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 2, IsDef: true},
+			2: {And: 0, IsDef: true},
 		},
-		replace: map[adt.ID]*CloseDef{2: nil},
-		want:    &CloseDef{ID: 2},
+		at:     1,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 3,
+		out:    "&( 0[] 1[] *3[] *2[])",
 	}, {
-		desc: "eliminateAllEmbeddings",
-		close: &CloseDef{
-			ID: 2,
-			List: []*CloseDef{
-				{ID: 2},
-				{ID: 3},
-			},
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 0, NextEmbed: 2, IsDef: true},
+			2: {And: embedRoot},
+			3: {And: 3},
 		},
-		replace: map[adt.ID]*CloseDef{0: {ID: 4}, 4: nil},
-		want:    &CloseDef{ID: 4},
+		at:     1,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 4,
+		out:    "&( 0[] 1[&( 3[])] *4[])",
 	}, {
-		// Do not eliminate an embedding that has a replacement.
-		desc: "eliminateOneEmbeddingByMultiple",
-		close: &CloseDef{
-			ID: 0,
-			List: []*CloseDef{
-				{ID: 2},
-				{ID: 3},
-			},
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 0, NextEmbed: 2, IsDef: true},
+			2: {And: embedRoot},
+			3: {And: 3},
 		},
-		replace: map[adt.ID]*CloseDef{
-			2: nil,
-			3: {ID: 3, IsAnd: true, List: []*CloseDef{{ID: 4}, {ID: 5}}},
-		},
-		want: &CloseDef{
-			ID: 0x00,
-			List: []*CloseDef{
-				{ID: 2},
-				{ID: 3, IsAnd: true, List: []*CloseDef{{ID: 4}, {ID: 5}}},
-			},
-		},
+		at:     3,
+		typ:    (*acceptor).InsertDefinition,
+		wantID: 4,
+		out:    "&( 0[] *1[&( 3[] *4[])])",
 	}, {
-		// Select b within a
-		// a: {      // ID: 0
-		//     #A    // ID: 1
-		//     #B    // ID: 2
-		//     b: #C // ID: 0
-		// }
-		// #C: {
-		//     b: #D // ID: 3
-		// }
-		//
-		desc: "embeddingOverruledByField",
-		close: &CloseDef{
-			ID: 0,
-			List: []*CloseDef{
-				{ID: 1},
-				{ID: 2},
-				{ID: 0},
-			},
-		},
-		replace: map[adt.ID]*CloseDef{0: {ID: 3}},
-		want:    &CloseDef{ID: 3},
+		tree:   nil,
+		at:     0,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 2,
+		out:    "&( 0[&( 2[])])",
 	}, {
-		// Select b within a
-		// a: {      // ID: 0
-		//     #A    // ID: 1
-		//     #B    // ID: 2
-		//     b: #C // ID: 0
-		// }
-		// #C: {
-		//     b: #D & #E // ID: 3 & 4
-		// }
-		//
-		desc: "embeddingOverruledByMultiple",
-		close: &CloseDef{
-			ID: 0,
-			List: []*CloseDef{
-				{ID: 1},
-				{ID: 2},
-				{ID: 0},
-			},
+		tree:   []CloseDef{{}},
+		at:     0,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 2,
+		out:    "&( 0[&( 2[])])",
+	}, {
+		tree:   []CloseDef{0: {And: 1}, 1: {And: 0, IsDef: true}},
+		at:     1,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 3,
+		out:    "&( 0[] *1[&( 3[])])",
+	}, {
+		tree:   []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		at:     0,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 4,
+		out:    "&( 0[&( 4[])&( 2[])])",
+	}, {
+		tree:   []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		at:     1,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 4,
+		out:    "&( 0[&( 2[])&( 4[])])",
+	}, {
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 2},
+			2: {And: 0},
 		},
-		replace: map[adt.ID]*CloseDef{
-			0: {IsAnd: true, List: []*CloseDef{{ID: 3}, {ID: 4}}},
-		},
-		want: &CloseDef{
-			ID:    0,
-			IsAnd: true,
-			List:  []*CloseDef{{ID: 3}, {ID: 4}},
-		},
+		at:     2,
+		typ:    (*acceptor).InsertEmbed,
+		wantID: 4,
+		out:    "&( 0[] 1[] 2[&( 4[])])",
 	}}
+	for i, tc := range testCases {
+		t.Run(fmt.Sprint(i), func(t *testing.T) {
+			c := &acceptor{Canopy: tc.tree}
+			got := tc.typ(c, tc.at, nil)
 
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			got := updateClosed(tc.close, tc.replace)
-			if !cmp.Equal(got, tc.want) {
-				t.Error(cmp.Diff(got, tc.want))
+			if got != tc.wantID {
+				t.Errorf("id: got %d; want %d", got, tc.wantID)
+			}
+
+			w := &strings.Builder{}
+			// fmt.Fprintf(w, "%#v", c.Canopy)
+			writeConjuncts(w, c)
+			if got := w.String(); got != tc.out {
+				t.Errorf("id: got %s; want %s", got, tc.out)
 			}
 		})
 	}
 }
+
+func TestInsertSubtree(t *testing.T) {
+	testCases := []struct {
+		tree []CloseDef
+		at   adt.ID
+		sub  []CloseDef
+		out  string
+	}{{
+		tree: nil,
+		at:   0,
+		sub:  nil,
+		out:  "&( 0[&( 2[])])",
+	}, {
+		tree: []CloseDef{{}},
+		at:   0,
+		sub:  nil,
+		out:  "&( 0[&( 2[])])",
+	}, {
+		tree: []CloseDef{0: {And: 1}, {And: 0, IsDef: true}},
+		at:   0,
+		sub:  []CloseDef{{}},
+		out:  "&( 0[&( 3[])] *1[])",
+	}, {
+		tree: []CloseDef{0: {And: 1}, {And: 0, IsDef: true}},
+		at:   0,
+		sub:  []CloseDef{{And: 1}, {And: 0, IsDef: true}},
+		out:  "&( 0[&( 3[] *4[])] *1[])",
+	}, {
+		tree: []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		at:   0,
+		sub:  []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		out:  "&( 0[&( 4[&( 6[])])&( 2[])])",
+	}, {
+		tree: []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		at:   2,
+		sub:  []CloseDef{0: {NextEmbed: 1}, 1: {And: embedRoot}, 2: {And: 2}},
+		out:  "&( 0[&( 2[&( 4[&( 6[])])])])",
+	}}
+	for i, tc := range testCases {
+		t.Run(fmt.Sprint(i), func(t *testing.T) {
+			c := &acceptor{Canopy: tc.tree}
+			d := &acceptor{Canopy: tc.sub}
+			n := &nodeContext{nodeShared: &nodeShared{node: &adt.Vertex{}}}
+			c.InsertSubtree(tc.at, n, &adt.Vertex{Closed: d}, false)
+
+			w := &strings.Builder{}
+			// fmt.Fprintf(w, "%#v", c.Canopy)
+			writeConjuncts(w, c)
+			if got := w.String(); got != tc.out {
+				t.Errorf("id: got %s; want %s", got, tc.out)
+			}
+		})
+	}
+}
+func TestVerifyArcAllowed(t *testing.T) {
+	fields := func(a ...adt.Feature) []adt.Feature { return a }
+	results := func(a ...bool) []bool { return a }
+	fieldSets := func(a ...[]adt.Feature) [][]adt.Feature { return a }
+
+	testCases := []struct {
+		desc     string
+		isClosed bool
+		tree     []CloseDef
+		fields   [][]adt.Feature
+		check    []adt.Feature
+		want     []bool
+	}{{
+		desc:     "required and remains closed with embedding",
+		isClosed: true,
+		tree: []CloseDef{
+			{And: 0},
+		},
+		fields: fieldSets(
+			fields(1),
+		),
+		check: fields(2),
+		want:  results(false),
+	}, {
+
+		// 	desc:  "empty tree accepts everything",
+		// 	tree:  nil,
+		// 	check: feats(1),
+		// 	want:  results(true),
+		// }, {
+		desc: "feature required in one",
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 0, IsDef: true},
+		},
+		fields: fieldSets(
+			fields(1),
+			fields(2),
+		),
+		check: fields(1, 2, 3, 4),
+		want:  results(false, true, false, false),
+	}, {
+		desc: "feature required in both",
+		tree: []CloseDef{
+			0: {And: 1, IsDef: true},
+			1: {And: 0, IsDef: true},
+		},
+		fields: fieldSets(
+			fields(1, 3),
+			fields(2, 3),
+		),
+		check: fields(1, 2, 3, 4),
+		want:  results(false, false, true, false),
+	}, {
+		desc: "feature required in neither",
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 0},
+		},
+		fields: fieldSets(
+			fields(1, 3),
+			fields(2, 3),
+		),
+		check: fields(1, 2, 3, 4),
+		want:  results(true, true, true, true),
+	}, {
+		desc: "closedness of embed",
+		tree: []CloseDef{
+			0: {And: 1},
+			1: {And: 0, IsDef: true, NextEmbed: 2},
+			2: {And: -1},
+			3: {And: 4},
+			4: {And: 3, IsDef: true},
+		},
+		fields: fieldSets(
+			fields(3, 4),
+			fields(),
+			fields(),
+			fields(),
+			fields(3),
+		),
+		check: fields(1, 3, 4),
+		want:  results(false, true, false),
+	}, {
+		desc: "implied required through embedding",
+		tree: []CloseDef{
+			0: {And: 0, NextEmbed: 1},
+			1: {And: -1},
+			2: {And: 3},
+			3: {And: 2, IsDef: true},
+		},
+		fields: fieldSets(
+			fields(3, 4),
+			fields(),
+			fields(),
+			fields(3, 2),
+		),
+		check: fields(1, 2, 3, 4),
+		want:  results(false, true, true, true),
+	}, {
+		desc: "implied required through recursive embedding",
+		tree: []CloseDef{
+			0: {And: 0, NextEmbed: 1},
+			1: {And: -1},
+			2: {And: 2, NextEmbed: 3},
+			3: {And: -1},
+			4: {And: 5},
+			5: {And: 4, IsDef: true},
+		},
+		fields: fieldSets(
+			fields(3, 4),
+			fields(),
+			fields(),
+			fields(),
+			fields(),
+			fields(3, 2),
+		),
+		check: fields(1, 2, 3, 4),
+		want:  results(false, true, true, true),
+	}, {
+		desc: "nil fieldSets",
+		tree: []CloseDef{
+			0: {And: 0, NextEmbed: 1},
+			1: {And: -1},
+			2: {And: 3},
+			3: {And: 2, IsDef: true},
+		},
+		fields: fieldSets(
+			nil,
+			nil,
+			fields(1),
+			fields(2),
+		),
+		check: fields(1, 2, 3),
+		want:  results(false, true, false),
+	}, {
+		desc: "required and remains closed with embedding",
+		tree: []CloseDef{
+			{And: 1},
+			{And: 0, NextEmbed: 2, IsDef: true},
+			{And: -1},
+			{And: 3},
+		},
+		fields: fieldSets(
+			fields(1),
+			fields(),
+			nil,
+			fields(2),
+		),
+		check: fields(0, 1, 2, 3),
+		want:  results(false, false, true, false),
+	}}
+	for i, tc := range testCases {
+		t.Run(fmt.Sprint(i, "/", tc.desc), func(t *testing.T) {
+			c := &acceptor{Canopy: tc.tree, isClosed: tc.isClosed}
+			for _, f := range tc.fields {
+				if f == nil {
+					c.Fields = append(c.Fields, nil)
+					continue
+				}
+				fs := &fieldSet{}
+				c.Fields = append(c.Fields, fs)
+				for _, id := range f {
+					fs.fields = append(fs.fields, field{label: id})
+				}
+			}
+
+			ctx := &adt.OpContext{}
+
+			for i, f := range tc.check {
+				got := c.verify(ctx, f)
+				if got != tc.want[i] {
+					t.Errorf("%d/%d: got %v; want %v", i, f, got, tc.want[i])
+				}
+			}
+		})
+	}
+}
+
+func TestCompact(t *testing.T) {
+	testCases := []struct {
+		desc      string
+		tree      []CloseDef
+		conjuncts []adt.ID
+		out       string
+	}{{
+		desc:      "leave nil as is",
+		tree:      nil,
+		conjuncts: []adt.ID{0, 0},
+		out:       "nil",
+	}, {
+		desc:      "simplest case",
+		tree:      []CloseDef{{}},
+		conjuncts: []adt.ID{0, 0},
+		out:       "&( 0[])",
+	}, {
+		desc:      "required ands should not be removed",
+		tree:      []CloseDef{{And: 1}, {And: 0, IsDef: true}},
+		conjuncts: []adt.ID{0, 0},
+		out:       "&( 0[] *1[])",
+		// }, {
+		// 	// TODO:
+		// 	desc:      "required ands should not be removed",
+		// 	tree:      []Node{{And: 1}, {And: 0, Required: false}},
+		// 	conjuncts: []adt.ID{1},
+		// 	out:       "&( 0[] 1[])",
+	}, {
+		desc:      "remove embedding",
+		tree:      []CloseDef{{NextEmbed: 1}, {And: embedRoot}, {And: 2}},
+		conjuncts: []adt.ID{0},
+		out:       "&( 0[])",
+	}, {
+		desc:      "keep embedding if used",
+		tree:      []CloseDef{{NextEmbed: 1}, {And: embedRoot}, {And: 2}},
+		conjuncts: []adt.ID{0, 2},
+		out:       "&( 0[&( 2[])])",
+	}}
+	for _, tc := range testCases {
+		t.Run(tc.desc, func(t *testing.T) {
+			c := &acceptor{Canopy: tc.tree}
+			all := []adt.Conjunct{}
+			for _, id := range tc.conjuncts {
+				all = append(all, adt.Conjunct{CloseID: id})
+			}
+
+			c.Canopy = c.Compact(all)
+
+			w := &strings.Builder{}
+			// fmt.Fprintf(w, "%#v", c.Canopy)
+			writeConjuncts(w, c)
+			if got := w.String(); got != tc.out {
+				t.Errorf("id: got %s; want %s", got, tc.out)
+			}
+		})
+	}
+}
+
+func writeConjuncts(w *strings.Builder, c *acceptor) {
+	if len(c.Canopy) == 0 {
+		w.WriteString("nil")
+		return
+	}
+	writeAnd(w, c, 0)
+}
+
+func writeAnd(w *strings.Builder, c *acceptor, id adt.ID) {
+	w.WriteString("&(")
+	c.visitAnd(id, func(id adt.ID, n CloseDef) bool {
+		w.WriteString(" ")
+		if n.IsDef || n.IsClosed {
+			w.WriteString("*")
+		}
+		fmt.Fprintf(w, "%d[", id)
+		c.visitEmbed(id, func(id adt.ID, n CloseDef) bool {
+			writeAnd(w, c, id)
+			return true
+		})
+		w.WriteString("]")
+		return true
+	})
+	w.WriteString(")")
+}
diff --git a/internal/core/eval/disjunct.go b/internal/core/eval/disjunct.go
index 6028093..9d06174 100644
--- a/internal/core/eval/disjunct.go
+++ b/internal/core/eval/disjunct.go
@@ -88,7 +88,6 @@
 	values      []disjunct
 	numDefaults int
 	cloneID     adt.ID
-	isEmbed     bool
 }
 
 type disjunct struct {
@@ -96,7 +95,7 @@
 	isDefault bool
 }
 
-func (n *nodeContext) addDisjunction(env *adt.Environment, x *adt.DisjunctionExpr, cloneID adt.ID, isEmbed bool) {
+func (n *nodeContext) addDisjunction(env *adt.Environment, x *adt.DisjunctionExpr, cloneID adt.ID) {
 	a := []disjunct{}
 
 	numDefaults := 0
@@ -113,10 +112,10 @@
 	})
 
 	n.disjunctions = append(n.disjunctions,
-		envDisjunct{env, a, numDefaults, cloneID, isEmbed})
+		envDisjunct{env, a, numDefaults, cloneID})
 }
 
-func (n *nodeContext) addDisjunctionValue(env *adt.Environment, x *adt.Disjunction, cloneID adt.ID, isEmbed bool) {
+func (n *nodeContext) addDisjunctionValue(env *adt.Environment, x *adt.Disjunction, cloneID adt.ID) {
 	a := []disjunct{}
 
 	for i, v := range x.Values {
@@ -124,7 +123,7 @@
 	}
 
 	n.disjunctions = append(n.disjunctions,
-		envDisjunct{env, a, x.NumDefaults, cloneID, isEmbed})
+		envDisjunct{env, a, x.NumDefaults, cloneID})
 }
 
 func (n *nodeContext) updateResult() (isFinal bool) {
@@ -298,7 +297,7 @@
 	v := d.values[k]
 	n.isFinal = n.isFinal && k == len(d.values)-1
 	c := adt.MakeConjunct(d.env, v.expr, d.cloneID)
-	n.addExprConjunct(c, d.isEmbed)
+	n.addExprConjunct(c)
 
 	for n.expandOne() {
 	}
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{
diff --git a/internal/core/eval/eval_test.go b/internal/core/eval/eval_test.go
index 1344a76..bf61212 100644
--- a/internal/core/eval/eval_test.go
+++ b/internal/core/eval/eval_test.go
@@ -115,7 +115,9 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	t.Error(debug.NodeString(r, v, nil))
+
+	// t.Error(debug.NodeString(r, v, nil))
+	// eval.Debug = true
 
 	e := eval.New(r)
 	ctx := e.NewContext(v)
