From 7eba326d3d5fea59687df08a001559d8eac63bc8 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 15:40:49 +0100 Subject: [PATCH] J7 (2): a judge request carries the known packages in a field of its own The names a manifest's packages may name travelled in the request's Input, whose meaning is the composition's input; Packages says them plainly, nil being no list and an empty list a list. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- go/composer/composer.go | 5 +++++ go/composer/composer_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/go/composer/composer.go b/go/composer/composer.go index dd224cf..8a33b1a 100644 --- a/go/composer/composer.go +++ b/go/composer/composer.go @@ -59,6 +59,11 @@ type Request struct { // longer read: the composer judges no manifest (novox/hq ADR 0578 §5), the indexer's judge does, and its verdicts // come in each case's Verdicts. Kept so an asker that still sends it is read. Predefined catalogue.PredefinedList `json:"predefined,omitempty"` + // Packages are the known packages a manifest's `packages` may name, each by its name in its own ecosystem (design 32: + // a Go package's go.mod module path, a TypeScript package's package.json name), for the indexer's judge (novox/hq ADR + // 0578 §5, ADR 0606 §4); the composer does not read them. Nil is no list at hand, and the judge judges no name; an + // empty list is a list, and every name is unknown to it. + Packages []string `json:"packages,omitzero"` } // Case is one catalogue composed: every module's manifest by name, and per node the manifests kept at the build it runs. diff --git a/go/composer/composer_test.go b/go/composer/composer_test.go index 108e3c7..9ee1c40 100644 --- a/go/composer/composer_test.go +++ b/go/composer/composer_test.go @@ -39,6 +39,18 @@ func TestAManifestIsItsBytesOrItsDigest(t *testing.T) { if asked != 2 || string(back.Cases[0].Manifests["demo"].Raw) != demo || string(back.Cases[0].Kept["laptop"]["demo"].Raw) != demo { t.Fatalf("filled %d times: %+v", asked, back.Cases[0]) } + // The known packages: none is no list (not on the wire), an empty list is a list, and a list reads back whole. + for _, known := range [][]string{nil, {}, {"git.novox.be/novox/mesh-sdk", "@novox/mesh-sdk"}} { + wire, err := json.Marshal(Request{V: Version, Packages: known}) + if err != nil { + t.Fatal(err) + } + back, err := Decode(wire) + if err != nil || (back.Packages == nil) != (known == nil) || strings.Join(back.Packages, ",") != strings.Join(known, ",") || + known == nil && strings.Contains(string(wire), "packages") { + t.Errorf("the known packages %#v went as %s and read back %#v (%v)", known, wire, back.Packages, err) + } + } bad := Request{V: Version, Cases: []Case{{Name: "c", Manifests: map[string]Manifest{"x": {Digest: "nope"}}}}} if err := Fill(&bad, func(string) ([]byte, error) { return nil, errors.New("not there") }); err == nil || !strings.Contains(err.Error(), "nope") { t.Fatalf("a digest the indexer does not hold: %v", err)