From 20a932220965bd3b7d3c571697730ec5434bfc59 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 14:01:38 +0100 Subject: [PATCH] DLV-I13: the judge reads a package series, a package's language and the contracts marker Design 32's words: a series is . and only on the four kinds the builder numbers, a package is go or typescript, generated-from only on a package. A package is published as its source, so it names no system: today's judge refused mesh-sdk's Go package (no system) as a binary. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- modules/mesh-delivery-indexer/judge/rules.go | 37 ++++++++++++++++++- .../mesh-delivery-indexer/judge/rules_test.go | 20 ++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index 6db28dad..7a77bda6 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -208,6 +208,37 @@ func upstreamFileProblems(module string, a catalogue.Artifact) []string { return problems } +// seriesForm is a package series, `.` (design 32). +var seriesForm = regexp.MustCompile(`^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`) + +// seriesProblems are an artifact's refusals of the words of design 32's versions (DLV-I13; ADR 0606 §4, ADR 0608 §5): a +// package series well formed and only on the four kinds the builder numbers, a package in Go or TypeScript, and the +// contracts marker only on a package. +func seriesProblems(module string, a catalogue.Artifact) []string { + var problems []string + if a.Series != "" { + if !seriesForm.MatchString(a.Series) { + problems = append(problems, fmt.Sprintf("%s: %q names the package series %q, which is no . such as 0.1 (design 32)", + module, a.Name, a.Series)) + } + switch a.Kind { + case catalogue.ArtifactPackage, catalogue.ArtifactImage, catalogue.ArtifactBundle, catalogue.ArtifactArchive: + default: + problems = append(problems, fmt.Sprintf("%s: %q is a %q and names a package series; only a package, an image, a bundle "+ + "or an archive is numbered (design 32)", module, a.Name, a.Kind)) + } + } + if a.Kind == catalogue.ArtifactPackage && a.Language != "" && a.Language != "go" && a.Language != "typescript" { + problems = append(problems, fmt.Sprintf("%s: %q is a package in %q; a mesh package is go or typescript (design 32)", + module, a.Name, a.Language)) + } + if a.GeneratedFrom != "" && a.Kind != catalogue.ArtifactPackage { + problems = append(problems, fmt.Sprintf("%s: %q is a %q and names generated-from, the contracts marker, which only a "+ + "package carries (design 26)", module, a.Name, a.Kind)) + } + return problems +} + // checkBuild is the manifest's own account of what it builds. func buildProblems(b *catalogue.Build, module string) []string { if b == nil { @@ -234,6 +265,7 @@ func buildProblems(b *catalogue.Build, module string) []string { module, a.Name, a.Kind, catalogue.ArtifactImage, catalogue.ArtifactArchive, catalogue.ArtifactUpstream, catalogue.ArtifactBundle+", "+catalogue.ArtifactPackage)) } + problems = append(problems, seriesProblems(module, a)...) // **A bundle is built from the module itself, so it says a language instead.** Everything // else names what it is built from: a Dockerfile, a directory, somebody else's reference. // A bundle's source is the module's own directory by definition, and what it needs to say @@ -293,8 +325,9 @@ func buildProblems(b *catalogue.Build, module string) []string { // is pinned to one operating system at link time so a host refuses to touch a machine // it was not built for (novox/hq ADR 0005); an artifact that says nothing would be // compiled for whatever the build machine happened to be, which reads as portable and - // is not. - if compiled := compilesToABinary(a.Language); compiled && strings.TrimSpace(a.System) == "" { + // is not. A package is published as its source (a Go module, an npm package; ADR 0606 §1), never as a binary, + // so it names no system whatever its language. + if compiled := compilesToABinary(a.Language) && a.Kind != catalogue.ArtifactPackage; compiled && strings.TrimSpace(a.System) == "" { problems = append(problems, fmt.Sprintf( "%s: %q is compiled to a binary and says no system, so it would be built for "+ "whatever the build machine happens to be. Declare one artifact per "+ diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index 3368d42f..11a1fd69 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -2328,6 +2328,26 @@ func TestAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { {"name":"lib","kind":"package"}]}}`)); err == nil { t.Fatal("a package with no language was accepted") } + // DLV-I13 (design 32 *A package, its series*): a series is . on the four numbered kinds; a package is go or + // typescript; the contracts marker is a package's. + for _, c := range []struct{ artifact, refused string }{ + {`{"name":"go","kind":"package","language":"go","paths":["go"],"series":"0.2"}`, ""}, + {`{"name":"img","kind":"image","from":"Dockerfile","series":"1.0"}`, ""}, + {`{"name":"go","kind":"package","language":"go","paths":["go"],"series":"0.1.3"}`, `names the package series "0.1.3"`}, + {`{"name":"go","kind":"package","language":"go","paths":["go"],"series":"01.1"}`, `names the package series "01.1"`}, + {`{"name":"up","kind":"upstream","from":"redis:7","series":"0.1"}`, `is a "upstream" and names a package series`}, + {`{"name":"go","kind":"package","language":"go","paths":["go"],"system":"arch"}`, `names the system "arch"`}, + {`{"name":"py","kind":"package","language":"python"}`, `a mesh package is go or typescript`}, + {`{"name":"img","kind":"image","from":"Dockerfile","generated-from":"seats"}`, `only a package carries`}, + } { + _, err := ParseManifest([]byte(`{"module":"a","version":"1","build":{"artifacts":[` + c.artifact + `]}}`)) + switch { + case c.refused == "" && err != nil: + t.Errorf("%s refused: %v", c.artifact, err) + case c.refused != "" && (err == nil || !strings.Contains(err.Error(), c.refused) || !strings.Contains(err.Error(), "a:")): + t.Errorf("%s: %v, want refused naming %q", c.artifact, err, c.refused) + } + } } func TestAPathThroughAnAccessIsJudgedWithTheAccessFilledIn(t *testing.T) {