From 376d0211e98be67ee9f9516d58cce61ee3ca3c3c Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 1 Nov 2026 02:29:48 +0100 Subject: [PATCH] =?UTF-8?q?checks/manifests=20decodes=20manifests=20and=20?= =?UTF-8?q?judges=20none,=20the=20checker's=20judge=20does=20(ADR=200578?= =?UTF-8?q?=20=C2=A72)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- checks/manifests/go.mod | 11 ++++++++- checks/manifests/go.sum | 14 ++++++++++++ checks/manifests/main.go | 41 ++++++++++++---------------------- checks/manifests/main_test.go | 37 +++++++++++++++--------------- checks/manifests/reads-outside | 3 +-- 5 files changed, 57 insertions(+), 49 deletions(-) diff --git a/checks/manifests/go.mod b/checks/manifests/go.mod index 98f625dc..1d2e668a 100644 --- a/checks/manifests/go.mod +++ b/checks/manifests/go.mod @@ -2,4 +2,13 @@ module checks/manifests go 1.26.0 -require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a +require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 + +require ( + github.com/klauspost/compress v1.20.0 // indirect + github.com/nats-io/nats.go v1.54.0 // indirect + github.com/nats-io/nkeys v0.4.16 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sys v0.48.0 // indirect +) diff --git a/checks/manifests/go.sum b/checks/manifests/go.sum index 0989a83d..2252671d 100644 --- a/checks/manifests/go.sum +++ b/checks/manifests/go.sum @@ -1,2 +1,16 @@ git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a h1:DcSvfEmdPBKqCg5OmXRNb269EkkPe7BsEp+RykEhkgE= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 h1:an2f0MLx9OhaDLu5i51OMPBbuGwX+aoTzqOkFLMpVfE= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= +github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= +github.com/nats-io/nats.go v1.54.0 h1:vsXoOxjHp/GmPUN+EcI7uOf/uB+iAP+kEsAFNQN0yzA= +github.com/nats-io/nats.go v1.54.0/go.mod h1:y+DZoD1oBOYfZTU681eTUiUjI0vbqYGixNVFHcjHJ0k= +github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg= +github.com/nats-io/nkeys v0.4.16/go.mod h1:llLgWoI0o4z/Q57q2R1kHfmocyhGV6VG/U18Glg1Afs= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= diff --git a/checks/manifests/main.go b/checks/manifests/main.go index 9658b260..676daa90 100644 --- a/checks/manifests/main.go +++ b/checks/manifests/main.go @@ -1,13 +1,11 @@ -// Package manifests judges every module's manifest as the node-engine reads it, and the catalogue as one shelf: each -// modules/*/module.json through mesh-sdk's ParseManifestWith against the predefined.json at the root, with its templates -// read from the tree beside it (WithTemplatesFrom), then the rules between manifests (CatalogueProblems, -// IdentityProblems, DataProblems). +// Package manifests reads every module's manifest as the catalogue's tree holds it and refuses what no judge could +// read: a module.json that does not decode, and two manifests that name one module. // -// Why it is here (issue 774): on 2026-10-30 mesh-catalog ca8d6f33 gave power's bar item two attributes its bar places -// by none of. ParseManifest refuses that, and every node-engine refused to compose at 19:13; no check of the pull -// request had parsed the manifest. That judgement was mesh-controller's `module check`, which the merge gate ran over -// every manifest before the checker moved to mesh-delivery; the checker runs this repository's Go tests and the -// composition, and no test parsed a manifest whole. This one does, in the same functions the nodes use. +// It judges no manifest (novox/hq ADR 0578 §2): the checker judges every change's manifests with the indexer's judge, the +// one judge, so the field, seat, bus and catalogue rules are said once, there. Until 2026-11 this check parsed each +// manifest with mesh-sdk's strict parser and ran the rules between manifests (issue 774, power's bar item of +// mesh-catalog ca8d6f33); that judgement moved to the checker, and what stays is the two refusals that are about the +// tree, not a manifest's rules. package manifests import ( @@ -19,43 +17,32 @@ import ( "git.novox.be/novox/mesh-sdk/go/catalogue" ) -// Problems is what is wrong with the manifests under root/modules, one line each: a manifest the mesh refuses, named by -// its path, then the rules between the manifests that parse. +// Problems is what is wrong with the tree's manifests under root/modules, one line each: a module.json whose bytes are +// no manifest (catalogue.Decode: not JSON, or a field of the wrong shape), then a module named by two manifests. func Problems(root string) ([]string, error) { files, err := filepath.Glob(filepath.Join(root, "modules", "*", "module.json")) if err != nil { return nil, err } sort.Strings(files) - list, err := catalogue.ReadPredefined(root) - if err != nil { - return nil, err - } var out []string - shelf := catalogue.Shelf{} + named := map[string]bool{} for _, f := range files { raw, err := os.ReadFile(f) if err != nil { return nil, err } rel, _ := filepath.Rel(root, f) - m, err := catalogue.ParseManifestWith(raw, list) - if err == nil { - m, err = catalogue.WithTemplatesFrom(m, filepath.Dir(f)) - } + m, err := catalogue.Decode(raw) if err != nil { out = append(out, fmt.Sprintf("%s: %v", rel, err)) continue } - if _, twice := shelf[m.Module]; twice { + if named[m.Module] { out = append(out, fmt.Sprintf("%s: %s was already given; two manifests name one module", rel, m.Module)) continue } - shelf[m.Module] = m + named[m.Module] = true } - between := catalogue.CatalogueProblems(shelf) - between = append(between, catalogue.IdentityProblems(shelf, catalogue.DefaultLongestMachine)...) - between = append(between, catalogue.DataProblems(shelf)...) - sort.Strings(between) - return append(out, between...), nil + return out, nil } diff --git a/checks/manifests/main_test.go b/checks/manifests/main_test.go index 49ba2ff6..0cee3e20 100644 --- a/checks/manifests/main_test.go +++ b/checks/manifests/main_test.go @@ -7,28 +7,27 @@ import ( "testing" ) -// Every manifest of the catalogue is one the nodes can use, and the catalogue holds together as one shelf. A row is a -// manifest written into a catalogue of its own: power's bar item as mesh-catalog ca8d6f33 gave it (issue 774) is -// refused naming the attribute, and the same item without it passes. -func TestEveryManifestIsOneTheNodesCanUse(t *testing.T) { +// 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 +// manifest that is no JSON and two manifests of one module are refused, naming the file; a manifest with a field this +// check does not know is not (it judges nothing: the checker does, ADR 0578 §2). The catalogue itself passes. +func TestEveryManifestDecodesAndNamesOneModule(t *testing.T) { for _, row := range []struct { - name, attributes, refused string + name string + files map[string]string + refused string }{ - {name: "the bar places by bar and place", attributes: `"bar":"bottom","place":"status","order":"45"`}, - {name: "an attribute the bar places by none of (ca8d6f33)", - attributes: `"bar":"bottom","place":"status","order":"45","shows":"state","state":"power.draw"`, - refused: `"shows" is none of them`}, + {name: "a manifest the judge can read", files: map[string]string{"a": `{"module":"a","version":"1"}`}}, + {name: "a field no part knows is the judge's to refuse", files: map[string]string{"a": `{"module":"a","version":"1","unheard":true}`}}, + {name: "bytes that are no manifest", files: map[string]string{"a": `{"module":`}, refused: "modules/a/module.json"}, + {name: "two manifests of one module", files: map[string]string{"a": `{"module":"x","version":"1"}`, "b": `{"module":"x","version":"1"}`}, + refused: "two manifests name one module"}, } { root := t.TempDir() - dir := filepath.Join(root, "modules", "bar-user") - if err := os.MkdirAll(filepath.Join(dir, "files"), 0o755); err != nil { - t.Fatal(err) - } - manifest := `{"module":"bar-user","version":"1","moved":true,` + - `"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]},` + - `"items":[{"collection":"contribution:node-bar:block","attributes":{` + row.attributes + `},"template":"files/bar"}]}` - for path, body := range map[string]string{"module.json": manifest, "files/bar": "{\"shows\":\"command\"}\n"} { - if err := os.WriteFile(filepath.Join(dir, path), []byte(body), 0o644); err != nil { + for dir, manifest := range row.files { + if err := os.MkdirAll(filepath.Join(root, "modules", dir), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(root, "modules", dir, "module.json"), []byte(manifest), 0o644); err != nil { t.Fatal(err) } } @@ -46,6 +45,6 @@ func TestEveryManifestIsOneTheNodesCanUse(t *testing.T) { t.Fatal(err) } if len(real) != 0 { - t.Fatalf("the catalogue holds manifests the nodes cannot use:\n%s", strings.Join(real, "\n")) + t.Fatalf("the catalogue holds manifests no judge can read:\n%s", strings.Join(real, "\n")) } } diff --git a/checks/manifests/reads-outside b/checks/manifests/reads-outside index e0af3e80..b09588e4 100644 --- a/checks/manifests/reads-outside +++ b/checks/manifests/reads-outside @@ -1,4 +1,3 @@ # What these tests read outside their package, as paths from the repository's root (issue 1936). -# every module's directory (its manifest and the templates beside it), and the list of predefined keys. +# every module's directory (its manifest), decoded. modules -predefined.json