mesh-delivery-sdk graph: a reader of the seat list waits for its holder by the verb edge and a foundation part on a cycle with it does not (D-31; ADR 0614 §2, ADR 0636 §1; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 15:06:29 +01:00
parent 6f22665c98
commit b5a75693f5
+39
View File
@@ -15,6 +15,7 @@ import (
// TestGraphEdges: the module graph's cycle, dependents and providers, each from the edges alone (ADR 0603 §2, ADR 0604 §1).
func TestGraphEdges(t *testing.T) {
t.Run("a node's value", nodeValues)
t.Run("a reader of the seat list waits for its holder", readersOfTheSeatList)
fp := "src2:" + strings.Repeat("b", 64)
node := func(repository, path string, edit func(*Node)) Node {
n := Node{FP: fp, Repository: repository, Path: path}
@@ -252,3 +253,41 @@ func nodeValues(t *testing.T) {
}
}
}
// readersOfTheSeatList (D-31): a module whose manifest invokes the seat mesh-catalog's seat-definitions waits, by the verb
// edge, for the module that claims the seat and serves the verb, so the delivery plan puts the holder first (ADR 0614 §2); a
// foundation part the holder itself invokes lies on a cycle with it and the edge is left out, so the part is carried by the
// bootstrapped three until the holder's new build runs (ADR 0636 §1).
func readersOfTheSeatList(t *testing.T) {
const list = "seat:mesh-catalog.seat-definitions"
fp := "src2:" + strings.Repeat("c", 64)
node := func(edit func(*Node)) Node {
n := Node{FP: fp, Repository: "novox/mesh-delivery", Path: "modules/x"}
edit(&n)
return n
}
g := Graph{
"indexer": node(func(n *Node) {
n.Serves = []string{list, "seat:mesh-catalog.modules"}
n.Invokes = []string{"seat:node-engine.composed"}
}),
"checker": node(func(n *Node) { n.Invokes = []string{list} }),
"node-agent": node(func(n *Node) { n.Invokes = []string{list}; n.Serves = []string{"seat:node-engine.composed"} }),
}
if got := g.Servers(list); !reflect.DeepEqual(got, []string{"indexer"}) {
t.Errorf("servers of the seat list = %v", got)
}
if got := g.Before("checker"); !reflect.DeepEqual(got, []string{"indexer"}) {
t.Errorf("the checker waits for %v, want the indexer", got)
}
g.LeaveOut()
if got := g.Before("checker"); !reflect.DeepEqual(got, []string{"indexer"}) {
t.Errorf("after the cycles are left out the checker waits for %v, want the indexer", got)
}
if got := g["node-agent"].LeftOut; !reflect.DeepEqual(got, []string{list}) {
t.Errorf("the node-agent leaves out %v, want the seat list (a cycle with the holder)", got)
}
if got := g.Before("node-agent"); len(got) != 0 {
t.Errorf("the node-agent waits for %v, want nothing: the bootstrap carries it", got)
}
}