From 0729556ba39e237c52b3b85271f0b07189587c36 Mon Sep 17 00:00:00 2001 From: mesh-tools Date: Tue, 20 Oct 2026 07:06:09 +0000 Subject: [PATCH] Read the rest of the mesh and who is on the network with the current manifests: a node's kept build applies only to its own resolution, as the controller keeps a recorded module after reading both (review round 2, item 1). The test asserting the opposite failed first --- go/compose/input.go | 2 +- go/compose/network.go | 2 +- go/compose/node_test.go | 18 +++++++++++------- go/compose/resolve.go | 5 +++-- go/compose/rest.go | 7 +++---- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/go/compose/input.go b/go/compose/input.go index a7ffe25..e98a7fe 100644 --- a/go/compose/input.go +++ b/go/compose/input.go @@ -30,7 +30,7 @@ import ( // (ADR 0446 clause 2). type Input struct { // Catalogue is the shelf: every module's manifest by name (inv.Catalogue), as it is to be composed. A recorded - // module kept at the build a machine runs (keepRecorded) is that node's Kept, applied to its own resolution only. + // module kept at the build a machine runs (keepRecorded) is that node's Kept, applied to its own resolution only (never to the rest of the mesh). Catalogue map[string]catalogue.Manifest // Nodes is every node the mesh has (inv.Nodes and inv.Overlays together, one row per node). Nodes []Node diff --git a/go/compose/network.go b/go/compose/network.go index 3c54aed..1e66c51 100644 --- a/go/compose/network.go +++ b/go/compose/network.go @@ -243,7 +243,7 @@ func (c *composer) onTheNetwork() []Node { if len(n.Assigned) == 0 { continue } - got, err := catalogue.Resolve(c.shelfFor(n), n.Assigned, + got, err := catalogue.Resolve(c.in.Catalogue, n.Assigned, catalogue.Node{Name: n.Name, Site: n.Place.Site, Capabilities: n.Capabilities}, catalogue.World{Unchecked: true, Holdings: c.in.Holdings}) if err != nil { diff --git a/go/compose/node_test.go b/go/compose/node_test.go index a863392..b7be07a 100644 --- a/go/compose/node_test.go +++ b/go/compose/node_test.go @@ -6,6 +6,7 @@ import ( "testing" "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-sdk/go/overlay" ) func resourceIDs(d Declared) []string { @@ -369,20 +370,23 @@ func TestAKeptModuleChangesOnlyTheResolutionOfTheNodeThatKeepsIt(t *testing.T) { } } -// And the rest of the mesh, as a node composes against it, offers what each other node's kept build offers, not the current one. -func TestTheRestOfTheMeshReadsEachOtherNodesKeptBuild(t *testing.T) { +// Another node's kept build changes neither the rest of the mesh nor who is on the network: the controller reads both with the +// current manifests, and only then keeps a recorded module for the node it composes (recorded_kept.go keepRecorded). +func TestAnotherNodesKeptBuildDoesNotChangeTheRestOfTheMeshOrWhoIsOnTheNetwork(t *testing.T) { in := threeNodes(t) + nodeOf(t, &in, "anchor").Kept = map[string]catalogue.Manifest{"objects": {Module: "objects", Version: "0"}, overlayName(): {Module: overlayName(), Version: "0"}} w, _, _, err := TheRestOfTheMesh(in, "laptop") if err != nil || len(providers(w, "s3-bucket")) != 1 { - t.Fatalf("before: %v %v", providers(w, "s3-bucket"), err) + t.Errorf("a kept build changed what anchor offers: %v %v", providers(w, "s3-bucket"), err) } - nodeOf(t, &in, "anchor").Kept = map[string]catalogue.Manifest{"objects": {Module: "objects", Version: "0"}} - w, _, _, err = TheRestOfTheMesh(in, "laptop") - if err != nil || len(providers(w, "s3-bucket")) != 0 { - t.Errorf("a node keeping a build that offers nothing still offers: %v %v", providers(w, "s3-bucket"), err) + where, err := newComposer(in).whereEveryoneIs() + if err != nil || where["anchor"] == "" { + t.Errorf("a kept build took anchor off the network: %v %v", where, err) } } +func overlayName() string { return overlay.Name } + // Round 1, finding 6: the nodes the composition did not count as on the network are returned, said, not lost. func TestANodeNotCountedAsOnTheNetworkIsSaidInTheResult(t *testing.T) { in := aMesh(t) diff --git a/go/compose/resolve.go b/go/compose/resolve.go index 8665086..d2fffd8 100644 --- a/go/compose/resolve.go +++ b/go/compose/resolve.go @@ -233,8 +233,9 @@ func (c *composer) resolution(nodeName string) (catalogue.Resolution, error) { } // shelfFor is the catalogue as one node composes its own set: the Input's, with each recorded or core module the node keeps at the -// build it runs put in place of the current one (plan.go keepRecorded). A copy: the Input's catalogue, and so every other node's -// resolution, is untouched. +// build it runs put in place of the current one (plan.go keepRecorded). A copy: the Input's catalogue is untouched. Only the node's own planFor and +// resolution use it; the rest of the mesh and who is on the network are read with the current manifests, as the controller reads them +// before it keeps a recorded module. func (c *composer) shelfFor(node Node) map[string]catalogue.Manifest { if len(node.Kept) == 0 { return c.in.Catalogue diff --git a/go/compose/rest.go b/go/compose/rest.go index fd5aa25..f7509e2 100644 --- a/go/compose/rest.go +++ b/go/compose/rest.go @@ -71,7 +71,6 @@ func (c *composer) theRestOfTheMesh(exclude string) (catalogue.World, Passes, [] node catalogue.Node assigned []string pins map[string]catalogue.Chosen - shelf map[string]catalogue.Manifest } var others []candidate // Every machine's assignments, before the holdings are read by any resolution (novox/hq ADR 0449 clause 4): a seat @@ -95,14 +94,14 @@ func (c *composer) theRestOfTheMesh(exclude string) (catalogue.World, Passes, [] others = append(others, candidate{ node: catalogue.Node{Name: n.Name, Site: n.Place.Site, Capabilities: n.Capabilities, At: onNetwork[n.Name], PublicDomain: n.PublicDomain}, - assigned: theirs, pins: n.Pins, shelf: c.shelfFor(n)}) + assigned: theirs, pins: n.Pins}) } var left []LeftOut offered := map[string][]catalogue.Provider{} var firstHeld []catalogue.Held for _, o := range others { - got, err := catalogue.Resolve(o.shelf, o.assigned, o.node, catalogue.World{Unchecked: true, Holdings: holdings}) + got, err := catalogue.Resolve(shelf, o.assigned, o.node, catalogue.World{Unchecked: true, Holdings: holdings}) if err != nil { // Said, not skipped: a machine dropped here offers nothing and holds nothing. left = append(left, LeftOut{Node: o.node.Name, Err: err}) @@ -139,7 +138,7 @@ func (c *composer) theRestOfTheMesh(exclude string) (catalogue.World, Passes, [] // Each machine is resolved with its own pins, as its plan is. theirs := world theirs.Pinned = o.pins - got, err := catalogue.Resolve(o.shelf, o.assigned, o.node, theirs) + got, err := catalogue.Resolve(shelf, o.assigned, o.node, theirs) if err != nil { // Said only for the whole-mesh view: with one machine excluded, the view is partial by design. if exclude == "" {