From 5fe7e3e6bae0d161a786f635a8f6a83d92ac8f46 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 23:09:34 +0100 Subject: [PATCH 1/7] Put core-credentials back in the bus's, the provisioner's and its client's manifests (L3 final, issue 774) The indexer whose judge knows the word runs now, so the word returns; the new node-engine keeps what runs for a manifest that lacks it. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- modules/mesh-provisioner-client/module.json | 1 + .../cmd/mesh-provisioner/provisioner_test.go | 5 ----- modules/mesh-provisioner/module.json | 1 + modules/nats/cmd/nats-tools/manifest_test.go | 5 ----- modules/nats/module.json | 1 + 5 files changed, 3 insertions(+), 10 deletions(-) diff --git a/modules/mesh-provisioner-client/module.json b/modules/mesh-provisioner-client/module.json index 095128a8..8fca6444 100644 --- a/modules/mesh-provisioner-client/module.json +++ b/modules/mesh-provisioner-client/module.json @@ -7,6 +7,7 @@ "scope": "node" } ], + "core-credentials": true, "own-secrets": { "provisioner-broker": "${dir:state}/broker" }, diff --git a/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go b/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go index 1328bde9..c856a63b 100644 --- a/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go +++ b/modules/mesh-provisioner/cmd/mesh-provisioner/provisioner_test.go @@ -295,11 +295,6 @@ func TestTheManifestDeclaresWhatTheCodeKeeps(t *testing.T) { if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } - // No "core-credentials" until the indexer whose judge knows the word runs (issue 774): the running judge refuses it, - // and a refused manifest holds the bus's user list, so the indexer that knows it is never granted. It comes back then. - if strings.Contains(string(raw), `"core-credentials"`) { - t.Error("the manifest says \"core-credentials\" before the judge that reads it runs") - } if m.Module != "mesh-provisioner" || m.RunsAs != "mesh-provisioner" || m.OwnSecrets["broker"] == "" { t.Errorf("an account of its own: module %q, runs-as %q, own secrets %v", m.Module, m.RunsAs, m.OwnSecrets) } diff --git a/modules/mesh-provisioner/module.json b/modules/mesh-provisioner/module.json index 12d4c27c..7b512a6f 100644 --- a/modules/mesh-provisioner/module.json +++ b/modules/mesh-provisioner/module.json @@ -46,6 +46,7 @@ "plans", "refused" ], + "core-credentials": true, "own-secrets": { "broker": "${dir:state}/broker" }, diff --git a/modules/nats/cmd/nats-tools/manifest_test.go b/modules/nats/cmd/nats-tools/manifest_test.go index 9ac143ba..57b4a3fc 100644 --- a/modules/nats/cmd/nats-tools/manifest_test.go +++ b/modules/nats/cmd/nats-tools/manifest_test.go @@ -43,11 +43,6 @@ func TestTheBussManifestMountsItsProgramsIntoTheUpstreamImage(t *testing.T) { if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } - // No "core-credentials" until the indexer whose judge knows the word runs (issue 774): the running judge refuses it, - // and a refused manifest holds the bus's user list, so the indexer that knows it is never granted. It comes back then. - if strings.Contains(string(raw), `"core-credentials"`) { - t.Error("the manifest says \"core-credentials\" before the judge that reads it runs") - } if m.Build.On != nil { t.Error("build.on is declared: nothing is built on a base image any more") } diff --git a/modules/nats/module.json b/modules/nats/module.json index f9083c93..93f518d7 100644 --- a/modules/nats/module.json +++ b/modules/nats/module.json @@ -21,6 +21,7 @@ } ], "bus-users": "/var/lib/nats-module/conf/accounts.conf", + "core-credentials": true, "own-secrets": { "broker": "${dir:mesh-state}/broker", "broker-nats-tools": "${dir:tools-secret}/broker-nats-tools" From d632071317cd1b92f46657b5d37d5d0f2f7b34be Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 23:09:59 +0100 Subject: [PATCH 2/7] =?UTF-8?q?nats=20provides=20bus-state,=20so=20a=20mod?= =?UTF-8?q?ule=20that=20keeps=20bus=20state=20has=20a=20provider=20to=20wa?= =?UTF-8?q?it=20for=20(ADR=200614=20=C2=A75,=20issue=20774)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- modules/nats/cmd/nats-tools/manifest_test.go | 17 +++++++++++++++++ modules/nats/module.json | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/modules/nats/cmd/nats-tools/manifest_test.go b/modules/nats/cmd/nats-tools/manifest_test.go index 57b4a3fc..93e0a8b3 100644 --- a/modules/nats/cmd/nats-tools/manifest_test.go +++ b/modules/nats/cmd/nats-tools/manifest_test.go @@ -32,6 +32,13 @@ func TestTheBussManifestMountsItsProgramsIntoTheUpstreamImage(t *testing.T) { } `json:"backup"` } `json:"own"` } `json:"data"` + Provides []struct { + Name string `json:"name"` + Scope string `json:"scope"` + Credential struct { + Form string `json:"form"` + } `json:"credential"` + } `json:"provides"` Tools []string `json:"tools"` Emits []string `json:"emits"` Resources []map[string]any `json:"resources"` @@ -43,6 +50,16 @@ func TestTheBussManifestMountsItsProgramsIntoTheUpstreamImage(t *testing.T) { if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } + // The bus provides "bus-state" beside "mesh-bus" (ADR 0614 §5): a module whose manifest keeps bus state requires it. + provided := map[string]string{} + for _, p := range m.Provides { + provided[p.Name] = p.Scope + "/" + p.Credential.Form + } + for _, name := range []string{"mesh-bus", "bus-state"} { + if provided[name] != "mesh/none" { + t.Errorf("provision %q is %q: the bus provides it mesh-wide with no credential", name, provided[name]) + } + } if m.Build.On != nil { t.Error("build.on is declared: nothing is built on a base image any more") } diff --git a/modules/nats/module.json b/modules/nats/module.json index 93f518d7..3e58475c 100644 --- a/modules/nats/module.json +++ b/modules/nats/module.json @@ -12,6 +12,13 @@ "credential": { "form": "none" } + }, + { + "name": "bus-state", + "scope": "mesh", + "credential": { + "form": "none" + } } ], "claims": [ From 4026392a6e6cac349efbb19a34ab4490792e28be Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 23:11:05 +0100 Subject: [PATCH 3/7] =?UTF-8?q?artifact-store-tools=20reads=20the=20defini?= =?UTF-8?q?tions=20through=20the=20seat=20mesh-catalog's=20verbs=20modules?= =?UTF-8?q?=20and=20module=20(ADR=200604=20=C2=A73,=20issue=20774)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verb module takes no commit; a definition is kept by the commit its answer names. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- modules/artifact-store-tools/README.md | 2 +- .../cmd/artifact-store-tools/definitions.go | 21 ++++++++++--------- .../artifact-store-tools/definitions_test.go | 2 +- .../cmd/artifact-store-tools/store_test.go | 7 ++++--- modules/artifact-store-tools/go.mod | 2 +- modules/artifact-store-tools/go.sum | 4 ++-- modules/artifact-store-tools/module.json | 4 ++-- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/modules/artifact-store-tools/README.md b/modules/artifact-store-tools/README.md index 1b747f8f..5a38db8f 100644 --- a/modules/artifact-store-tools/README.md +++ b/modules/artifact-store-tools/README.md @@ -61,7 +61,7 @@ record names leaves its platform manifests unrecorded with it. **What the definitions pin** (hq issue 323). A definition may pin an image of the store the mesh did not make: pushed before the mesh built it, and pinned under the store's current name or a name it had before. No record of the controller names it, yet a machine runs it, so `artifact_store_references` reads every -definition the catalogue holds (`mesh-catalog.catalog_modules`, then `catalog_module` for each, eight at +definition the catalogue holds (the seat mesh-catalog's verbs `modules`, then `module` for each, eight at a time and within twenty seconds) and finds every `/@sha256:…` in any of its strings, under each of the store's names: `artifact-store://`, the store's address as the controller answers it, and the names it had before. Those are the mesh's setting `older-store-names` (space-separated, `none` by diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/definitions.go b/modules/artifact-store-tools/cmd/artifact-store-tools/definitions.go index ef4ef966..d62bf5a6 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/definitions.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/definitions.go @@ -23,10 +23,11 @@ import ( // manifest's. const NamesFileEnv = "MESH_ARTIFACT_STORE_NAMES_FILE" -// CatalogueModules and CatalogueModule are the catalog's tools these definitions are read through. +// CatalogueModules and CatalogueModule are the verbs of the seat mesh-catalog these definitions are read through +// (ADR 0604 §3); the answers are catalogue.CatalogModules and catalogue.CatalogOne. const ( - CatalogueModules = "mesh-catalog.catalog_modules" - CatalogueModule = "mesh-catalog.catalog_module" + CatalogueModules = "seat:mesh-catalog.modules" + CatalogueModule = "seat:mesh-catalog.module" ) // DefinitionsTimeout bounds reading every definition, below the runtime's thirty-second call limit; what @@ -279,11 +280,8 @@ func (c *Catalogue) definition(m catalogueEntry, names StoreNames, nameKey strin return pins, "" } } - args := map[string]any{"module": m.Module} - if m.Commit != "" { - args["commit"] = m.Commit - } - raw, err := c.Ask(CatalogueModule, args) + // The verb takes no commit: it answers the trunk's module, and the answer names the commit it is at. + raw, err := c.Ask(CatalogueModule, map[string]any{"module": m.Module}) if err != nil { return nil, "could not be asked: " + err.Error() } @@ -293,6 +291,7 @@ func (c *Catalogue) definition(m catalogueEntry, names StoreNames, nameKey strin } var one struct { Module *struct { + Commit string `json:"commit"` Manifest json.RawMessage `json:"manifest"` } `json:"module"` Error string `json:"error"` @@ -301,9 +300,11 @@ func (c *Catalogue) definition(m catalogueEntry, names StoreNames, nameKey strin return nil, "not readable: " + firstOf(one.Error, errText(err), "no manifest in the answer") } pins := PinsIn(one.Module.Manifest, names) - if m.Commit != "" { + // Kept by the commit the answer names, which may be newer than the list's: a definition and its commit never + // change together. + if at := firstOf(one.Module.Commit, m.Commit); at != "" { c.mu.Lock() - c.kept[key] = pins + c.kept[m.Module+"@"+at+"|"+nameKey] = pins c.mu.Unlock() } return pins, "" diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/definitions_test.go b/modules/artifact-store-tools/cmd/artifact-store-tools/definitions_test.go index 316baf2c..c46cb12c 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/definitions_test.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/definitions_test.go @@ -211,7 +211,7 @@ func TestReferencesReadTheDefinitionsUnderTheStoresOlderNames(t *testing.T) { } } if before != 2 || after != 2 { - t.Errorf("asked catalog_module %d times, then %d: each definition at its commit is read once", before, after) + t.Errorf("asked the seat's module %d times, then %d: each definition at its commit is read once", before, after) } } diff --git a/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go b/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go index c8a527d3..ea6fdccd 100644 --- a/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go +++ b/modules/artifact-store-tools/cmd/artifact-store-tools/store_test.go @@ -366,8 +366,8 @@ func (a *asked) ask(key string, body any) (json.RawMessage, error) { if a.failing[name] { return nil, fmt.Errorf("no answer") } - if args["commit"] != "c-"+name { - return nil, fmt.Errorf("asked %s at %v", name, args["commit"]) + if _, has := args["commit"]; has { + return nil, fmt.Errorf("asked %s at %v: the seat's verb takes no commit", name, args["commit"]) } manifest, has := a.definitions[name] if !has { @@ -375,7 +375,8 @@ func (a *asked) ask(key string, body any) (json.RawMessage, error) { break } // The catalogue's tool answers through the runtime as the protocol's content list. - raw, _ := json.Marshal(map[string]any{"module": map[string]any{"module": name, "manifest": json.RawMessage(manifest)}}) + raw, _ := json.Marshal(catalogue.CatalogOne{Module: catalogue.CatalogModule{ + CatalogEntry: catalogue.CatalogEntry{Module: name, Commit: "c-" + name}, Manifest: json.RawMessage(manifest)}}) return json.Marshal(map[string]any{"content": []map[string]any{{"type": "text", "text": string(raw)}}}) case "collect": if args["confirm"] == "true" { diff --git a/modules/artifact-store-tools/go.mod b/modules/artifact-store-tools/go.mod index dfdeecbe..f157cfd2 100644 --- a/modules/artifact-store-tools/go.mod +++ b/modules/artifact-store-tools/go.mod @@ -3,7 +3,7 @@ module artifactstoretools go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/artifact-store-tools/go.sum b/modules/artifact-store-tools/go.sum index 43cc4ec7..abad2969 100644 --- a/modules/artifact-store-tools/go.sum +++ b/modules/artifact-store-tools/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAuqVBXbybSqhLNOGX5rUOrn9T0cHNCDUQF7IQ= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 h1:RtAFbUJRP1qO9AIMM2ue+cXNzqj7WZ7IOlSqNvttwuU= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/artifact-store-tools/module.json b/modules/artifact-store-tools/module.json index eda3a100..54cc5916 100644 --- a/modules/artifact-store-tools/module.json +++ b/modules/artifact-store-tools/module.json @@ -19,8 +19,8 @@ ], "invokes": [ "seat:mesh-hand-acts.hand-act", - "mesh-catalog.catalog_modules", - "mesh-catalog.catalog_module" + "seat:mesh-catalog.modules", + "seat:mesh-catalog.module" ], "reads": [ "mesh-delivery-assigner.wants", From be749c9513f97fe5424e8eb47141e87f53b2e500 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 23:11:32 +0100 Subject: [PATCH 4/7] =?UTF-8?q?The=20old=20catalog=20module=20drops=20its?= =?UTF-8?q?=20claim=20of=20the=20seat=20mesh-catalog=20and=20is=20deprecat?= =?UTF-8?q?ed;=20a=20check=20refuses=20a=20second=20claimant=20(ADR=200604?= =?UTF-8?q?=20=C2=A76,=20issue=20774)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- checks/manifests/main_test.go | 44 ++++++++++++++++++++++++++++++++ modules/mesh-catalog/README.md | 2 +- modules/mesh-catalog/module.json | 6 ----- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/checks/manifests/main_test.go b/checks/manifests/main_test.go index 0cee3e20..252fa559 100644 --- a/checks/manifests/main_test.go +++ b/checks/manifests/main_test.go @@ -5,6 +5,8 @@ import ( "path/filepath" "strings" "testing" + + "git.novox.be/novox/mesh-sdk/go/catalogue" ) // The tree's manifests are ones a judge can read, and no module is named twice. A row is a catalogue of its own: a @@ -48,3 +50,45 @@ func TestEveryManifestDecodesAndNamesOneModule(t *testing.T) { t.Fatalf("the catalogue holds manifests no judge can read:\n%s", strings.Join(real, "\n")) } } + +// No manifest of this catalogue claims the seat mesh-catalog: the indexer of the delivery holds it, and the module that +// held it before has dropped its claim (ADR 0604 §6). A row is a tree of its own: a manifest claiming it is named. +func TestNoManifestClaimsTheSeatMeshCatalog(t *testing.T) { + claimants := func(root string) []string { + files, err := filepath.Glob(filepath.Join(root, "modules", "*", "module.json")) + if err != nil { + t.Fatal(err) + } + var out []string + for _, f := range files { + raw, err := os.ReadFile(f) + if err != nil { + t.Fatal(err) + } + m, err := catalogue.Decode(raw) + if err != nil { + continue // Problems names it + } + for _, c := range m.Claims { + if c.Name == "mesh-catalog" { + out = append(out, m.Module) + } + } + } + return out + } + row := t.TempDir() + if err := os.MkdirAll(filepath.Join(row, "modules", "a"), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(row, "modules", "a", "module.json"), + []byte(`{"module":"a","version":"1","claims":[{"name":"mesh-catalog","scope":"mesh"}]}`), 0o644); err != nil { + t.Fatal(err) + } + if got := claimants(row); len(got) != 1 || got[0] != "a" { + t.Fatalf("a manifest claiming the seat is named, got %v", got) + } + if got := claimants(filepath.Join("..", "..")); len(got) != 0 { + t.Errorf("the catalogue's manifests %v claim the seat mesh-catalog: the indexer of the delivery holds it", got) + } +} diff --git a/modules/mesh-catalog/README.md b/modules/mesh-catalog/README.md index 32e34d2f..a058f007 100644 --- a/modules/mesh-catalog/README.md +++ b/modules/mesh-catalog/README.md @@ -1,6 +1,6 @@ # mesh-catalog -The `mesh-catalog` module of the mesh catalogue: claims the seat `mesh-catalog`. +The `mesh-catalog` module of the mesh catalogue: deprecated. It no longer claims the seat `mesh-catalog`: the indexer of the delivery claims it and serves its verbs from the bus (ADR 0604). This module stays, with its tools, until it is retired. ## Files it does not know diff --git a/modules/mesh-catalog/module.json b/modules/mesh-catalog/module.json index c5ad61a4..fe30560e 100644 --- a/modules/mesh-catalog/module.json +++ b/modules/mesh-catalog/module.json @@ -5,12 +5,6 @@ "capabilities": [ "container-runtime" ], - "claims": [ - { - "name": "mesh-catalog", - "scope": "mesh" - } - ], "requires": [ "postgres-database" ], From 093967af9b2fdaede6d0cba39334ba4d8c6e4bd4 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 3 Nov 2026 23:43:11 +0100 Subject: [PATCH 5/7] Pin mesh-sdk 85ba0a9a70d8, the group's head of feat/l3-final (issue 774) Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- modules/artifact-store-tools/go.mod | 2 +- modules/artifact-store-tools/go.sum | 4 ++-- modules/mesh-provisioner-client/go.mod | 2 +- modules/mesh-provisioner-client/go.sum | 4 ++-- modules/mesh-provisioner/go.mod | 2 +- modules/mesh-provisioner/go.sum | 4 ++-- modules/nats/go.mod | 2 +- modules/nats/go.sum | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/artifact-store-tools/go.mod b/modules/artifact-store-tools/go.mod index f157cfd2..f2499370 100644 --- a/modules/artifact-store-tools/go.mod +++ b/modules/artifact-store-tools/go.mod @@ -3,7 +3,7 @@ module artifactstoretools go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/artifact-store-tools/go.sum b/modules/artifact-store-tools/go.sum index abad2969..7679a5dc 100644 --- a/modules/artifact-store-tools/go.sum +++ b/modules/artifact-store-tools/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 h1:RtAFbUJRP1qO9AIMM2ue+cXNzqj7WZ7IOlSqNvttwuU= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 h1:XEbIVImp6yGjA91rp0iZBoDdL5KfamjOuDLwWvqh0hc= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/mesh-provisioner-client/go.mod b/modules/mesh-provisioner-client/go.mod index ea5c9d1f..ed1b3885 100644 --- a/modules/mesh-provisioner-client/go.mod +++ b/modules/mesh-provisioner-client/go.mod @@ -3,7 +3,7 @@ module mesh-provisioner-client go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 golang.org/x/sys v0.48.0 diff --git a/modules/mesh-provisioner-client/go.sum b/modules/mesh-provisioner-client/go.sum index abad2969..7679a5dc 100644 --- a/modules/mesh-provisioner-client/go.sum +++ b/modules/mesh-provisioner-client/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 h1:RtAFbUJRP1qO9AIMM2ue+cXNzqj7WZ7IOlSqNvttwuU= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 h1:XEbIVImp6yGjA91rp0iZBoDdL5KfamjOuDLwWvqh0hc= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/mesh-provisioner/go.mod b/modules/mesh-provisioner/go.mod index 03d2bf48..e16ce001 100644 --- a/modules/mesh-provisioner/go.mod +++ b/modules/mesh-provisioner/go.mod @@ -3,7 +3,7 @@ module mesh-provisioner go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-provisioner/go.sum b/modules/mesh-provisioner/go.sum index abad2969..7679a5dc 100644 --- a/modules/mesh-provisioner/go.sum +++ b/modules/mesh-provisioner/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 h1:RtAFbUJRP1qO9AIMM2ue+cXNzqj7WZ7IOlSqNvttwuU= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 h1:XEbIVImp6yGjA91rp0iZBoDdL5KfamjOuDLwWvqh0hc= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/nats/go.mod b/modules/nats/go.mod index a6aa5c98..609dc37e 100644 --- a/modules/nats/go.mod +++ b/modules/nats/go.mod @@ -3,7 +3,7 @@ module nats-tools go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 github.com/klauspost/compress v1.20.0 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 diff --git a/modules/nats/go.sum b/modules/nats/go.sum index abad2969..7679a5dc 100644 --- a/modules/nats/go.sum +++ b/modules/nats/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929 h1:RtAFbUJRP1qO9AIMM2ue+cXNzqj7WZ7IOlSqNvttwuU= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103174208-b7abe203a929/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 h1:XEbIVImp6yGjA91rp0iZBoDdL5KfamjOuDLwWvqh0hc= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= From 448f1ef48188ccc3ce15ce4463b1ad953a674859 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 00:44:17 +0100 Subject: [PATCH 6/7] Give mesh-provisioner and mesh-provisioner-client new manifest bytes (version 2), the recovery of the moment for stale verdicts The running indexer holds refusals from 21:14 for the exact bytes of these manifests, which carry core-credentials again. A new digest is read afresh; the thorough fix of stale verdicts is in the indexer in this group (issue 774). Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- modules/mesh-provisioner-client/module.json | 2 +- modules/mesh-provisioner/module.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mesh-provisioner-client/module.json b/modules/mesh-provisioner-client/module.json index 8fca6444..61959a9f 100644 --- a/modules/mesh-provisioner-client/module.json +++ b/modules/mesh-provisioner-client/module.json @@ -1,6 +1,6 @@ { "module": "mesh-provisioner-client", - "version": "1", + "version": "2", "claims": [ { "name": "node-provisioner", diff --git a/modules/mesh-provisioner/module.json b/modules/mesh-provisioner/module.json index 7b512a6f..1c6f4c74 100644 --- a/modules/mesh-provisioner/module.json +++ b/modules/mesh-provisioner/module.json @@ -1,6 +1,6 @@ { "module": "mesh-provisioner", - "version": "1", + "version": "2", "runs-as": "mesh-provisioner", "claims": [ { From 6c09be4a703eae461e237e11a80a23da5b9febb9 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 00:46:08 +0100 Subject: [PATCH 7/7] Keep a module's report under a bounded context the client's stop does not cancel (issue 774) The test of a node coming back stops the client before the report of zsh is kept; the cancelled Put left s.applied without zsh, so leftModules never removed it (2 of 20 runs failed under -race, also at origin/main). Thorough: report() keeps under context.WithoutCancel with a 5 s bound; the same test now passes 40 of 40. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn --- .../cmd/mesh-provisioner-client/client.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/mesh-provisioner-client/cmd/mesh-provisioner-client/client.go b/modules/mesh-provisioner-client/cmd/mesh-provisioner-client/client.go index 44c8e504..ee345c4a 100644 --- a/modules/mesh-provisioner-client/cmd/mesh-provisioner-client/client.go +++ b/modules/mesh-provisioner-client/cmd/mesh-provisioner-client/client.go @@ -970,7 +970,11 @@ func (c *Client) report(ctx context.Context, kvs map[string]jetstream.KeyValue, logf("[provisioner-client] the report of %s: %v", r.Module, err) return } - if _, err := kvs[AppliedBucket].Put(ctx, c.Node+"."+r.Module, body); err != nil { + // Kept under a context the client's stop does not cancel, bounded: a report made as the client stops is still kept, + // or s.applied would never name the module and a later pass would never remove it (leftModules). + keep, done := context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second) + defer done() + if _, err := kvs[AppliedBucket].Put(keep, c.Node+"."+r.Module, body); err != nil { logf("[provisioner-client] the report of %s could not be kept: %v", r.Module, err) } else { s.applied[r.Module] = true