From 5fc1dbd264379148c46b8122d6154036f7ee7c84 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 12:14:07 +0100 Subject: [PATCH] WM11, CK12, EN1 (manifest half): finding stream, the keeper's ask and MAJOR.MINOR version in the manifests of the watchman, the checker and enrolment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds: design 47 G §383, §387, §368 (the findings writer half waits for the generated writer of §439) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- modules/mesh-delivery-checker/manifest_test.go | 5 +++-- modules/mesh-delivery-checker/module.json | 8 +++++--- modules/mesh-delivery-watchman/manifest_test.go | 13 ++++++++++++- modules/mesh-delivery-watchman/module.json | 6 +++++- .../cmd/mesh-enrolment/tokens_test.go | 2 +- modules/mesh-enrolment/module.json | 8 ++++++-- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/modules/mesh-delivery-checker/manifest_test.go b/modules/mesh-delivery-checker/manifest_test.go index 29506cab..78a167bb 100644 --- a/modules/mesh-delivery-checker/manifest_test.go +++ b/modules/mesh-delivery-checker/manifest_test.go @@ -41,6 +41,7 @@ type stream struct { Name string `json:"name"` Events []string `json:"events"` MaxAgeDays int `json:"max-age-days,omitempty"` + MaxMiB int `json:"max-mib,omitempty"` Retention string `json:"retention,omitempty"` } @@ -140,7 +141,7 @@ func TestManifestDeclarations(t *testing.T) { // 1678/AC1 // The checker is woken by a build module's report of a toolchain, as the indexer is: the bucket may not exist when it starts. // And a group's check by the package registry seats' published of its tagged versions (design 51 *Tagged versions*). if want := []string{"go-package-registry.published", "mesh-build-go.toolchain.reported", "mesh-build-node.toolchain.reported", - "mesh-catalog.catalog-revision", "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-assigner.views.assignments", "mesh-delivery-indexer.views.candidates", "mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules", + "mesh-catalog.catalog-revision", "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-conditions.findings-asked", "mesh-delivery-assigner.views.assignments", "mesh-delivery-indexer.views.candidates", "mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules", "mesh-delivery-indexer.views.packages", "mesh-delivery-indexer.views.predefined", "mesh-delivery-indexer.views.seat-definitions", "npm-package-registry.published"}; !reflect.DeepEqual(sorted(m.Consumes), want) { t.Errorf("consumes = %v, want %v", m.Consumes, want) } @@ -154,7 +155,7 @@ func TestManifestDeclarations(t *testing.T) { // 1678/AC1 // Its family asks (design 51 *Tagged versions*, design 26): tag-wanted and verdict, seven days, apart from checks so a // waiter on a verdict does not wake on a tag ask; a stream that keeps its history, the predefined form of an event family // (ADR 0592 §6, the manifest validator). - if want := []stream{{Name: "checks", Events: []string{"preview.**", "owed.**", "try.**"}}, {Name: "asks", Events: []string{"verdict", "tag-wanted"}, Retention: "history"}}; !reflect.DeepEqual(m.Streams, want) { + if want := []stream{{Name: "checks", Events: []string{"preview.**", "owed.**", "try.**"}}, {Name: "asks", Events: []string{"verdict", "tag-wanted"}, Retention: "history"}, {Name: "mesh-delivery-checker-findings", Events: []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, MaxAgeDays: 7, MaxMiB: 16}}; !reflect.DeepEqual(m.Streams, want) { t.Errorf("streams = %+v, want %+v", m.Streams, want) } // Only the checker's account publishes try.* on its stream checks: the stream is declared by its owner alone, and no other diff --git a/modules/mesh-delivery-checker/module.json b/modules/mesh-delivery-checker/module.json index 02b78a1e..3ed9b598 100644 --- a/modules/mesh-delivery-checker/module.json +++ b/modules/mesh-delivery-checker/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-checker", - "version": "1", + "version": "0.1", "slug": "checker", "claims": [ { @@ -28,11 +28,13 @@ "mesh-delivery-indexer.views.packages", "mesh-delivery-indexer.views.predefined", "mesh-delivery-indexer.views.seat-definitions", - "npm-package-registry.published" + "npm-package-registry.published", + "mesh-conditions.findings-asked" ], "streams": [ { "name": "checks", "events": ["preview.**", "owed.**", "try.**"] }, - { "name": "asks", "events": ["verdict", "tag-wanted"], "retention": "history" } + { "name": "asks", "events": ["verdict", "tag-wanted"], "retention": "history" }, + { "name": "mesh-delivery-checker-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 } ], "state": [ { "name": "asks", "history": 1 }, diff --git a/modules/mesh-delivery-watchman/manifest_test.go b/modules/mesh-delivery-watchman/manifest_test.go index e8d37103..ddf43111 100644 --- a/modules/mesh-delivery-watchman/manifest_test.go +++ b/modules/mesh-delivery-watchman/manifest_test.go @@ -57,6 +57,12 @@ type manifest struct { Consumes []string `json:"consumes"` Invokes []string `json:"invokes"` State []state `json:"state"` + Streams []struct { + Name string `json:"name"` + Events []string `json:"events"` + MaxAgeDays int `json:"max-age-days"` + MaxMiB int `json:"max-mib"` + } `json:"streams"` OwnSecrets map[string]string `json:"own-secrets"` SecretsOwner string `json:"secrets-owner"` Resources []map[string]any `json:"resources"` @@ -103,6 +109,11 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6 if !regexp.MustCompile(`^[0-9]+\.[0-9]+$`).MatchString(m.Version) { t.Errorf("version = %q, want MAJOR.MINOR", m.Version) } + // Design 47 G §387: the finding stream, 7 days and 16 MiB, and the keeper's ask. + if len(m.Streams) != 1 || m.Streams[0].Name != "mesh-delivery-watchman-findings" || m.Streams[0].MaxAgeDays != 7 || m.Streams[0].MaxMiB != 16 || + !reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) { + t.Errorf("streams = %+v, want the finding stream", m.Streams) + } // DLV-M5 (ADR 0615 §1): the assigner's wants and the indexer's modules are their owners' states, asked by their read // tools and followed by their views families, never read. for _, r := range m.Reads { @@ -116,7 +127,7 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6 t.Errorf("invokes = %v, want %v", m.Invokes, want) } // DLV-M5 its first views, 1585/T20 the indexer's take-in events, and DLV-W1 (ADR 0595 §4): the accepted verdicts and the bus module's created and refused, durably. - if want := []string{"mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", "mesh-delivery-indexer.take-in.taken", "mesh-delivery-indexer.views.modules", "mesh-catalog.manifest-accepted", "mesh-delivery.source-moved", "mesh-delivery.filling", "mesh-delivery.full", "mesh-delivery.room", "mesh-delivery.record-opened", "mesh-delivery.record-ended", "mesh-catalog.filling", "mesh-catalog.full", "mesh-catalog.room", "mesh-wants.filling", "mesh-wants.full", "mesh-wants.room", "mesh-grants.filling", "mesh-grants.full", "mesh-grants.room", "mesh-pipeline-runner.pipeline-started", "mesh-pipeline-runner.step-started", "mesh-pipeline-runner.step-ended", "mesh-broker.created", "mesh-broker.refused"}; !reflect.DeepEqual(m.Consumes, want) { + if want := []string{"mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", "mesh-delivery-indexer.take-in.taken", "mesh-delivery-indexer.views.modules", "mesh-catalog.manifest-accepted", "mesh-delivery.source-moved", "mesh-delivery.filling", "mesh-delivery.full", "mesh-delivery.room", "mesh-delivery.record-opened", "mesh-delivery.record-ended", "mesh-catalog.filling", "mesh-catalog.full", "mesh-catalog.room", "mesh-wants.filling", "mesh-wants.full", "mesh-wants.room", "mesh-grants.filling", "mesh-grants.full", "mesh-grants.room", "mesh-pipeline-runner.pipeline-started", "mesh-pipeline-runner.step-started", "mesh-pipeline-runner.step-ended", "mesh-broker.created", "mesh-broker.refused", "mesh-conditions.findings-asked"}; !reflect.DeepEqual(m.Consumes, want) { t.Errorf("consumes = %v, want %v", m.Consumes, want) } // 1952/WM1: the watchman holds the seat mesh-watchdogs at mesh scope, its first seat (novox/hq ADR 0564 §1, §4). diff --git a/modules/mesh-delivery-watchman/module.json b/modules/mesh-delivery-watchman/module.json index bd081f2f..908c9988 100644 --- a/modules/mesh-delivery-watchman/module.json +++ b/modules/mesh-delivery-watchman/module.json @@ -30,6 +30,9 @@ "mesh-delivery-indexer.indexer_read_modules", "seat:mesh-hand-acts.hand-act" ], + "streams": [ + { "name": "mesh-delivery-watchman-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 } + ], "consumes": [ "mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", @@ -55,7 +58,8 @@ "mesh-pipeline-runner.step-started", "mesh-pipeline-runner.step-ended", "mesh-broker.created", - "mesh-broker.refused" + "mesh-broker.refused", + "mesh-conditions.findings-asked" ], "tools": [ "watchman_findings", diff --git a/modules/mesh-enrolment/cmd/mesh-enrolment/tokens_test.go b/modules/mesh-enrolment/cmd/mesh-enrolment/tokens_test.go index 5cb2e3f2..fa8dfbe3 100644 --- a/modules/mesh-enrolment/cmd/mesh-enrolment/tokens_test.go +++ b/modules/mesh-enrolment/cmd/mesh-enrolment/tokens_test.go @@ -119,7 +119,7 @@ func theManifestSaysWhatTheCodeDoes(t *testing.T) { for _, e := range EndEvents { heard = append(heard, Seat+"."+e) } - heard = append(heard, assignerModule+".views."+assignmentsState) + heard = append(heard, assignerModule+".views."+assignmentsState, "mesh-conditions.findings-asked") // the keeper's ask (design 47 G §387) if !slices.Equal(m.Consumes, heard) { t.Errorf("consumes %v, the end events are %v", m.Consumes, heard) } diff --git a/modules/mesh-enrolment/module.json b/modules/mesh-enrolment/module.json index 302cdf2b..506c568a 100644 --- a/modules/mesh-enrolment/module.json +++ b/modules/mesh-enrolment/module.json @@ -1,6 +1,6 @@ { "module": "mesh-enrolment", - "version": "1", + "version": "0.1", "runs-as": "mesh-enrolment", "claims": [ { @@ -16,12 +16,16 @@ ] } ], + "streams": [ + { "name": "mesh-enrolment-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 } + ], "consumes": [ "mesh-node-enroller.node-enrolled", "mesh-node-enroller.enrolment-refused", "mesh-node-enroller.enrolment-revoked", "mesh-node-enroller.enrolment-expired", - "mesh-delivery-assigner.views.assignments" + "mesh-delivery-assigner.views.assignments", + "mesh-conditions.findings-asked" ], "uses": [ "operator-channel"