From 9db65adb81c7e0c16a063a4c9c9021ad48d44a31 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 10:35:22 +0100 Subject: [PATCH] RR-3: the manifest reader reads an artifact's needs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reader release reads the manifest words G writes: version MAJOR.MINOR, a * emitter in consumes and an observer's finding stream already read; an artifact's needs is new. Builds: design 47 G §340, §409, §47, §432, §368, §386, §387 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- go/catalogue/manifest.go | 5 +++++ go/catalogue/reader_release_test.go | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 go/catalogue/reader_release_test.go diff --git a/go/catalogue/manifest.go b/go/catalogue/manifest.go index 765bdcf..9c7274b 100644 --- a/go/catalogue/manifest.go +++ b/go/catalogue/manifest.go @@ -1236,6 +1236,11 @@ type Artifact struct { // DefaultSeries (SeriesOf). Series string `json:"series,omitempty"` + // Needs are the artifact references, `:`, of the catalog graph's edges this artifact has where no + // other line of the manifest or of a seat's definition says them (design 47 G §47, §432). Read here so a reader + // release keeps a manifest that names them whole (design 47 G §340, §409); the manifest validator checks their form. + Needs []string `json:"needs,omitempty"` + // GeneratedFrom marks a package of a contracts module (novox/hq ADR 0608 §5, design 26 *Contracts modules*): the // directory, relative to the module's, of the seat definitions every file of the package is generated from. A // module carrying it holds contracts only and claims no seat, which the judge refuses naming the seat; the build diff --git a/go/catalogue/reader_release_test.go b/go/catalogue/reader_release_test.go new file mode 100644 index 0000000..d81091c --- /dev/null +++ b/go/catalogue/reader_release_test.go @@ -0,0 +1,20 @@ +package catalogue + +import "testing" + +// A manifest carrying the words design 47 G writes is read whole by the reader release (design 47 G §340, §409): +// `version` as MAJOR.MINOR (§368), a `*` emitter in `consumes` (§386), an observer's finding stream (§387) and an +// artifact's `needs` (§47, §432). +func TestTheReaderReleaseReadsTheManifestWordsGWrites(t *testing.T) { + m, err := decodeForTest([]byte(`{"module":"mesh-watcher","version":"1.4",` + + `"consumes":["*.finding-written","mesh-conditions.findings-asked"],` + + `"streams":[{"name":"mesh-watcher-findings","events":["finding-written","finding-cleared","findings-stated"],"max-age-days":7,"max-mib":16}],` + + `"build":{"artifacts":[{"name":"program","kind":"bundle","language":"go","needs":["mesh-grants:program","node-tools:runtime"]}]}}`)) + if err != nil { + t.Fatalf("a manifest with G's words was refused: %v", err) + } + if m.Version != "1.4" || m.Consumes[0] != "*.finding-written" || m.Streams[0].Name != "mesh-watcher-findings" || + len(m.Build.Artifacts[0].Needs) != 2 || m.Build.Artifacts[0].Needs[0] != "mesh-grants:program" { + t.Fatalf("read as %+v", m) + } +}