From ea6fbd31dbfbc429191c2dda60ae795bf9748f5b Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 14:06:03 +0100 Subject: [PATCH] DLV-I16: the judge refuses a contracts module claiming a seat, naming the seat A module whose package carries generated-from holds contracts only (design 26). Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- modules/mesh-delivery-indexer/judge/rules.go | 25 +++++++++++++++++++ .../mesh-delivery-indexer/judge/rules_test.go | 11 +++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index e369eb96..87520fc2 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -239,6 +239,30 @@ func seriesProblems(module string, a catalogue.Artifact) []string { return problems } +// contractsProblems refuses a contracts module that claims a seat, naming each seat (DLV-I16; ADR 0608 §5, design 26 +// *Contracts modules*): a module whose package carries the contracts marker, generated-from, holds contracts only. +func contractsProblems(m catalogue.Manifest) []string { + if m.Build == nil || len(m.Claims) == 0 { + return nil + } + marked := "" + for _, a := range m.Build.Artifacts { + if a.GeneratedFrom != "" { + marked = a.Name + break + } + } + if marked == "" { + return nil + } + var problems []string + for _, c := range m.Claims { + problems = append(problems, fmt.Sprintf("%s: its package %q carries generated-from, so it is a contracts module, which "+ + "holds contracts only and claims no seat; it claims %s (design 26)", m.Module, marked, c.Name)) + } + return problems +} + // checkBuild is the manifest's own account of what it builds. func buildProblems(b *catalogue.Build, module string) []string { if b == nil { @@ -2792,6 +2816,7 @@ func parseManifest(raw []byte, predefined catalogue.PredefinedList) (catalogue.M } } problems = append(problems, buildProblems(m.Build, m.Module)...) + problems = append(problems, contractsProblems(m)...) // A file's text in a template file of the module's repository (novox/hq ADR 0349 §2): only a file, never beside // content, only under files/, and packed by the module's build. problems = append(problems, templateProblems(m)...) diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index 983acb06..2424ea49 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -2330,6 +2330,7 @@ func TestAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { } // 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. + const claims = " claiming mesh-vault" 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"}`, ""}, @@ -2339,8 +2340,16 @@ func TestAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { {`{"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`}, + {`{"name":"go","kind":"package","language":"go","paths":["go"],"generated-from":"."}`, ""}, + // DLV-I16 (design 26): a contracts module claims no seat, refused naming it. + {`{"name":"go","kind":"package","language":"go","paths":["go"],"generated-from":"."}` + claims, + `a contracts module, which holds contracts only and claims no seat; it claims mesh-vault`}, } { - _, err := ParseManifest([]byte(`{"module":"a","version":"1","build":{"artifacts":[` + c.artifact + `]}}`)) + raw := `{"module":"a","version":"1","build":{"artifacts":[` + c.artifact + `]}}` + if before, ok := strings.CutSuffix(c.artifact, claims); ok { + raw = `{"module":"a","version":"1","claims":[{"name":"mesh-vault","scope":"mesh"}],"build":{"artifacts":[` + before + `]}}` + } + _, err := ParseManifest([]byte(raw)) switch { case c.refused == "" && err != nil: t.Errorf("%s refused: %v", c.artifact, err)