delivery and catalogue import neither overlay nor buildcpu, so a change to the network generator or the build share code rebuilds only their own importers (ADR 0593 §1)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 18:25:11 +01:00
parent acef75d398
commit ba82dd64b1
4 changed files with 76 additions and 11 deletions
+14
View File
@@ -0,0 +1,14 @@
package buildcpu
import (
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// The share's names the composer gives are the build modules' (catalogue writes them too, so it does not import this).
func TestTheShareNamesAgreeWithTheCatalogues(t *testing.T) {
if ShareSetting != catalogue.BuildCPUShareSetting || ShareWord != catalogue.BuildCPUShareWord || DefaultPercent != catalogue.BuildCPUDefaultPercent {
t.Fatal("buildcpu's share names differ from catalogue's")
}
}
+16 -6
View File
@@ -2,18 +2,28 @@ package catalogue
import (
"strconv"
)
"git.novox.be/novox/mesh-sdk/go/buildcpu"
// The build processor share's names (novox/hq ADR 0553 §3, §4), written here as well as in the build modules' package
// (BuildCPUShareSetting, ShareWord, DefaultPercent), so a manifest reader does not reach the build runner's code; a
// test of the build modules keeps them agreeing.
const (
// BuildCPUShareSetting is the node-engine's config value of the node's processor share for its builds, in percent.
BuildCPUShareSetting = "build-cpu-share"
// BuildCPUShareWord is the word the composer gives every yielding module: the node's share, in percent.
BuildCPUShareWord = "MESH_BUILD_CPU_SHARE"
// BuildCPUDefaultPercent is the share where nothing sets one.
BuildCPUDefaultPercent = 50
)
// yieldsOf is how the runtime of its own a module is served by gives way on this node (novox/hq ADR 0553), or nil when
// it does not, and the word its steps size their threads from:
//
// - a module holding a seat that yields (Seat.Yields, the build seats) runs at idle priority under the node's one share
// of its processors: the node-engine's own config build-cpu-share (buildcpu.ShareSetting) as this node's layers give
// of its processors: the node-engine's own config build-cpu-share (BuildCPUShareSetting) as this node's layers give
// it, its default where none does. Every yielding module of the node carries the same share, so the node-engine's
// one yielding slice has one quota (ADR 0553 §2, §3).
// - its word: that share (buildcpu.ShareWord), which a step divides by its own module's capacity (ADR 0553 §4).
// - its word: that share (BuildCPUShareWord), which a step divides by its own module's capacity (ADR 0553 §4).
//
// Never a refusal: a share out of range is the default, so a mistyped value bounds the builds at the default and never
// stops the node's whole composition.
@@ -27,16 +37,16 @@ func (r Resolution) yieldsOf(m Manifest, with Rendering) (map[string]any, map[st
engine = e
}
}
share := buildcpu.DefaultPercent
share := BuildCPUDefaultPercent
for _, s := range Effective(engine, with.Settings[engineModule]) {
if s.Key == buildcpu.ShareSetting {
if s.Key == BuildCPUShareSetting {
if n, ok := percentOf(s.Value); ok {
share = n
}
}
}
return map[string]any{"priority": "idle", "cpu-share": share},
map[string]string{buildcpu.ShareWord: strconv.Itoa(share)}
map[string]string{BuildCPUShareWord: strconv.Itoa(share)}
}
// yields is whether a module claims a seat that yields.
+25 -5
View File
@@ -5,19 +5,39 @@ import (
"fmt"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/overlay"
)
// The private network's names as its manifest says them, written here as well as in overlay (Name, Requirement,
// Addressing, TheNetwork), which delivery does not import so its many readers do not reach the network's generator;
// a test keeps them agreeing.
const (
overlayName = "mesh-wireguard"
overlayRequirement = "private-network"
overlayAddressing = "mesh-addressing"
overlayTheNetwork = "the-private-network"
)
// overlayManifest is overlay.Manifest(): the module the mesh provides for itself.
func overlayManifest() map[string]any {
return map[string]any{
"module": overlayName,
"version": "1",
"computed": overlayName,
"provides": []string{overlayRequirement, overlayAddressing},
"claims": []map[string]any{{"name": overlayTheNetwork, "scope": "node"}},
}
}
// The modules the mesh provides itself (issue 1126): no repository holds them, so the indexer reads none; their
// manifests come with mesh-sdk, built in code, and always win over any other. Today the private network alone
// (overlay.Name), built by nobody and run inside each node's own composition. One predicate for every part that judges
// (overlay's mesh-wireguard), built by nobody and run inside each node's own composition. One predicate for every part that judges
// or composes a placement: CheckPlacements, the seat's holder, the composer's input (frombus) and the grants part.
// ProvidedModules is every module the mesh provides itself, sorted.
func ProvidedModules() []string { return []string{overlay.Name} }
func ProvidedModules() []string { return []string{overlayName} }
// ProvidedByMesh says whether the mesh provides module itself, so a placement may name it with no repository holding it.
func ProvidedByMesh(module string) bool { return module == overlay.Name }
func ProvidedByMesh(module string) bool { return module == overlayName }
// ProvidedManifest is a provided module's manifest, as its readers parse it, and its raw JSON; an error for a module the
// mesh does not provide or a manifest its own reader refuses.
@@ -25,7 +45,7 @@ func ProvidedManifest(module string) (catalogue.Manifest, []byte, error) {
if !ProvidedByMesh(module) {
return catalogue.Manifest{}, nil, fmt.Errorf("delivery: the mesh provides no module %s", module)
}
raw, err := json.Marshal(overlay.Manifest())
raw, err := json.Marshal(overlayManifest())
if err != nil {
return catalogue.Manifest{}, nil, err
}
+21
View File
@@ -0,0 +1,21 @@
package delivery_test
import (
"encoding/json"
"testing"
"git.novox.be/novox/mesh-sdk/go/delivery"
"git.novox.be/novox/mesh-sdk/go/overlay"
)
// The private network's manifest delivery provides is overlay's, though delivery does not import overlay.
func TestTheProvidedNetworkIsOverlays(t *testing.T) {
_, raw, err := delivery.ProvidedManifest(overlay.Name)
if err != nil {
t.Fatal(err)
}
want, _ := json.Marshal(overlay.Manifest())
if string(raw) != string(want) {
t.Fatalf("delivery provides\n%s\noverlay says\n%s", raw, want)
}
}