From decbce4c54382c5119fc34ae1b81bc1d8b9e5b9f Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 12:03:13 +0100 Subject: [PATCH] H-1: the node-engine claims its seat, says its findings on its own stream and hears running MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds: design 47 G §364, §387, §199, §368, §411, §438 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- cmd/mesh-host/settled_manifest_test.go | 39 ++++++++++++++++++++++++++ module.json | 18 +++++++++++- packaging/operator_keys_test.go | 4 +-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/cmd/mesh-host/settled_manifest_test.go b/cmd/mesh-host/settled_manifest_test.go index 24d4b75e..395819bf 100644 --- a/cmd/mesh-host/settled_manifest_test.go +++ b/cmd/mesh-host/settled_manifest_test.go @@ -26,3 +26,42 @@ func TestTheSettledEventIsTheManifestsConsume(t *testing.T) { t.Errorf("the engine hears %s, its manifest consumes %v", settledEvent, m.Consumes) } } + +// The manifest claims the seat node-engine, says its findings on its own stream and hears the keeper's ask and the +// node-engine seat's running (design 47 G §364, §387, §199). +func TestTheManifestClaimsItsSeatAndSaysItsFindings(t *testing.T) { + raw, err := os.ReadFile("../../module.json") + if err != nil { + t.Fatal(err) + } + var m struct { + Version string `json:"version"` + Consumes []string `json:"consumes"` + Claims []struct { + Name string `json:"name"` + Scope string `json:"scope"` + } `json:"claims"` + Streams []struct { + Name string `json:"name"` + Events []string `json:"events"` + } `json:"streams"` + } + if err := json.Unmarshal(raw, &m); err != nil { + t.Fatal(err) + } + if len(m.Claims) != 1 || m.Claims[0].Name != "node-engine" || m.Claims[0].Scope != "node" { + t.Errorf("claims = %+v, want the node seat node-engine", m.Claims) + } + if len(m.Streams) != 1 || m.Streams[0].Name != "mesh-host-findings" || + !slices.Equal(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) { + t.Errorf("streams = %+v, want mesh-host-findings with the three finding events", m.Streams) + } + for _, c := range []string{"mesh-conditions.findings-asked", "node-engine.running"} { + if !slices.Contains(m.Consumes, c) { + t.Errorf("consumes %v lacks %s", m.Consumes, c) + } + } + if m.Version != "0.1" { + t.Errorf("version = %q, want MAJOR.MINOR 0.1 (§368, §411)", m.Version) + } +} diff --git a/module.json b/module.json index 8c19c884..52f97f17 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "module": "mesh-host", - "version": "1", + "version": "0.1", "slug": "host", "build": { "artifacts": [ @@ -14,15 +14,31 @@ } ] }, + "claims": [ + { + "name": "node-engine", + "scope": "node" + } + ], "invokes": [ "seat:mesh-catalog.seat-definitions" ], "consumes": [ "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", + "mesh-conditions.findings-asked", "mesh-delivery-view.settled", + "node-engine.running", "restic.backed-up" ], + "streams": [ + { + "name": "mesh-host-findings", + "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], + "max-age-days": 7, + "max-mib": 16 + } + ], "state": [ { "name": "health" diff --git a/packaging/operator_keys_test.go b/packaging/operator_keys_test.go index 1b86b25a..d620eef7 100644 --- a/packaging/operator_keys_test.go +++ b/packaging/operator_keys_test.go @@ -66,8 +66,8 @@ func TestTheManifestConsumesTheBackupEvent(t *testing.T) { if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } - // The backup event, the status view's settled, and the two events of the seat that serves the seat list (ADR 0636 §4). - if want := []string{"mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-view.settled", "restic.backed-up"}; !slices.Equal(m.Consumes, want) { + // The backup event, the status view's settled, and the two events of the seat that serves the seat list (ADR 0636 §4), the keeper's ask (design 47 G §387) and the seat's running (§199). + if want := []string{"mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-conditions.findings-asked", "mesh-delivery-view.settled", "node-engine.running", "restic.backed-up"}; !slices.Equal(m.Consumes, want) { t.Fatalf("consumes %v, want %v", m.Consumes, want) } // 774: the acts bucket mesh-host_acts is not declared as state for now: a declared state of a module with no account