From 0871fa7cc4073b34d1483da7fb8461aaaa0f4fb4 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 5 Nov 2026 14:59:39 +0100 Subject: [PATCH] =?UTF-8?q?Node-engine:=20the=20value=20version=20comes=20?= =?UTF-8?q?from=20mesh-sdk=20go/keys,=20not=20go/delivery=20(H-2,=20ADR=20?= =?UTF-8?q?0634=20=C2=A71,=20=C2=A74;=20issue=201966)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i --- internal/compose/frombus/export.go | 3 ++- internal/link/handacts.go | 4 ++-- internal/link/have.go | 9 +++++---- internal/link/have_test.go | 19 ++++++++++--------- internal/link/record.go | 3 ++- internal/link/session.go | 3 ++- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/internal/compose/frombus/export.go b/internal/compose/frombus/export.go index 8726c0f..432e7fb 100644 --- a/internal/compose/frombus/export.go +++ b/internal/compose/frombus/export.go @@ -2,6 +2,7 @@ package frombus import ( "fmt" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "sort" "strconv" @@ -27,7 +28,7 @@ func Export(in compose.Input, node string) (delivery.Placement, error) { } // At the version a placement key is read at, with a list of modules even when none is placed: the export is the // seed's value, and the reader refuses a value of version 0 or without its modules. - p := delivery.Placement{V: delivery.Version, Node: node, Modules: []delivery.PlacedModule{}, Decided: delivery.NodeDecided{ + p := delivery.Placement{V: sdkkeys.Version, Node: node, Modules: []delivery.PlacedModule{}, Decided: delivery.NodeDecided{ Endpoint: n.Place.Endpoint, Site: n.Place.Site, Hub: n.Place.Hub, Address: n.Place.Address, PublicDomain: n.PublicDomain, Account: n.Account, AccountHome: n.AccountHome, AgentAccount: n.AgentAccount, AgentHome: n.AgentAccountHome, Adopted: n.Adopted, Taken: n.Taken}} diff --git a/internal/link/handacts.go b/internal/link/handacts.go index 6592603..cfffffd 100644 --- a/internal/link/handacts.go +++ b/internal/link/handacts.go @@ -7,6 +7,7 @@ import ( "encoding/json" "errors" "fmt" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "sort" "strconv" "strings" @@ -17,7 +18,6 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/delivery" ) // The node seat node-engine's acts (novox/hq ADR 0563). @@ -273,7 +273,7 @@ func (h *HandActs) Call(c EngineCall) (any, error) { return nil, errors.New("this engine states no manifest reads yet: its node agent has not started") } reads, at := h.ManifestReads() - return nodeengine.ManifestReadsAnswer{V: delivery.Version, Node: h.Node, ManifestReads: reads, + return nodeengine.ManifestReadsAnswer{V: sdkkeys.Version, Node: h.Node, ManifestReads: reads, StatedAt: at.UTC().Format(time.RFC3339Nano)}, nil case "acts": if id := arg("id"); id != "" { diff --git a/internal/link/have.go b/internal/link/have.go index 213f0d6..af8ac34 100644 --- a/internal/link/have.go +++ b/internal/link/have.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "github.com/novox/mesh-host/internal/compositions" "sort" "strings" @@ -205,7 +206,7 @@ func resourceWords(r ResourceHealth) string { // nodeFacts is the node's own facts of a report, each as the JSON the report carries it in. func nodeFacts(r Report) delivery.HaveNode { - n := delivery.HaveNode{V: delivery.Version} + n := delivery.HaveNode{V: sdkkeys.Version} carry := func(into *json.RawMessage, empty bool, v any) { if empty { return @@ -375,7 +376,7 @@ func (q *Session) writeHaves(ctx context.Context, bus Bus) { sort.Strings(modules) for _, module := range modules { f := s.modules[module] - h := delivery.Have{V: delivery.Version, FP: f.FP, Composed: f.Composed, Build: f.Build, + h := delivery.Have{V: sdkkeys.Version, FP: f.FP, Composed: f.Composed, Build: f.Build, Phase: delivery.PhaseRunning, Health: delivery.HealthUnknown, Detail: f.Detail} h.Kept = f.Kept if delivery.Phase(f.Phase) == delivery.PhaseWaitingYes { @@ -507,7 +508,7 @@ func (q *Session) writeRemoved(ctx context.Context, b HaveBucket, node string) b delete(s.removed, module) continue } - h := delivery.Have{V: delivery.Version, Build: s.removed[module], Phase: delivery.PhaseRemoved, + h := delivery.Have{V: sdkkeys.Version, Build: s.removed[module], Phase: delivery.PhaseRemoved, Health: delivery.HealthUnknown, Detail: "the applied declaration no longer holds the module"} raw, err := delivery.EncodeHave(h) if err != nil { @@ -730,7 +731,7 @@ func (q *Session) NoteNode(ctx context.Context, composed string, sealed composit s.nodeComposed = composed s.nodeSealed = sealed if s.node == nil { - n := delivery.HaveNode{V: delivery.Version} + n := delivery.HaveNode{V: sdkkeys.Version} s.node = &n } s.mu.Unlock() diff --git a/internal/link/have_test.go b/internal/link/have_test.go index d2b9466..11669f6 100644 --- a/internal/link/have_test.go +++ b/internal/link/have_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "github.com/novox/mesh-host/internal/compositions" "slices" "strings" @@ -178,8 +179,8 @@ func TestAnAppliedModuleIsWrittenRunningAndAFailedOneFailed(t *testing.T) { // 1132/AC5: a have equal to the bucket's value is not written; a different one is written over the last revision. func TestAHaveIsWrittenOnlyWhenItDiffers(t *testing.T) { l := newHaveLink() - l.put(t, "n1.a", delivery.Have{V: delivery.Version, Build: "b-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) - l.put(t, "n1.b", delivery.Have{V: delivery.Version, Build: "b-0", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) + l.put(t, "n1.a", delivery.Have{V: sdkkeys.Version, Build: "b-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) + l.put(t, "n1.b", delivery.Have{V: sdkkeys.Version, Build: "b-0", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) q, _ := aHaveQueue(l) q.SayFacts(context.Background(), appliedModules()) if l.kv["n1.a"].rev != 1 { @@ -258,7 +259,7 @@ func TestTheNodeKeyCarriesTheNodesFacts(t *testing.T) { t.Fatal(err) } enc := func(v any) json.RawMessage { b, _ := json.Marshal(v); return b } - want := delivery.HaveNode{V: delivery.Version, Windows: enc(rep.Windows), Busy: enc(rep.Busy), Strays: enc(rep.Strays), + want := delivery.HaveNode{V: sdkkeys.Version, Windows: enc(rep.Windows), Busy: enc(rep.Busy), Strays: enc(rep.Strays), Filters: enc(rep.Filters), Profile: enc(rep.Profile)} if !delivery.SameHaveNode(got, want) { t.Errorf("the node key holds %+v, want %+v", got, want) @@ -280,7 +281,7 @@ func TestTheNodeKeyCarriesTheNodesFacts(t *testing.T) { if got, err = delivery.DecodeHaveNode(l.kv["n1.node"].value); err != nil || got.Record == nil { t.Fatalf("the node key holds no record: %+v, %v", got, err) } - wantRecord := delivery.NodeRecord{V: delivery.Version, Node: "n1", TunnelKey: "tk", SealingKey: "sk", ServingKey: "pk", + wantRecord := delivery.NodeRecord{V: sdkkeys.Version, Node: "n1", TunnelKey: "tk", SealingKey: "sk", ServingKey: "pk", Certificate: "cert", Trusts: keys.Trusts, Capabilities: []string{"apt", "bus-state-calls", "ledger-calls", "systemd"}, OutwardLinks: []string{"eth0"}, NetworksSaid: true, Networks: []catalogue.AttachedNetwork{{Link: "eth0", Network: "192.0.2.0/24"}}, Contract: NodeKeyContract, ManifestReads: catalogue.ManifestReads()} // what it reads of a manifest: its contract's (ADR 0614 ยง4) @@ -460,7 +461,7 @@ func TestARemovedModuleAddedBackIsWrittenWithItsNewPhase(t *testing.T) { // bucket is not created again. func TestAModuleNeverWrittenIsNotWrittenRemoved(t *testing.T) { l := newHaveLink() - l.put(t, "n1.c", delivery.Have{V: delivery.Version, Build: "b-9", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) + l.put(t, "n1.c", delivery.Have{V: sdkkeys.Version, Build: "b-9", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) q, _ := aHaveQueue(l) q.SayFacts(context.Background(), appliedModules()) q.SayFacts(context.Background(), onlyA()) @@ -502,8 +503,8 @@ func TestARefusedRemovalIsWrittenByTheNextPass(t *testing.T) { // before: one of them the new declaration lacks is written removed, one that is not in the bucket is not created. func TestARestartedNodeEngineWritesTheRemovalFromTheReportsBefore(t *testing.T) { l := newHaveLink() - l.put(t, "n1.a", delivery.Have{V: delivery.Version, Build: "b-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) - l.put(t, "n1.b", delivery.Have{V: delivery.Version, Build: "b-2", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) + l.put(t, "n1.a", delivery.Have{V: sdkkeys.Version, Build: "b-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) + l.put(t, "n1.b", delivery.Have{V: sdkkeys.Version, Build: "b-2", Phase: delivery.PhaseRunning, Health: delivery.HealthOK}) q, _ := aHaveQueue(l) // fresh: nothing written by this process r := onlyA() r.Before = []string{"a", "b", "c"} @@ -652,7 +653,7 @@ func TestAModuleSaidAgainOverAnOlderEnginesUnknownIsWrittenWithThisEnginesHealth l := newHaveLink() fp := "src2:" + strings.Repeat("a", 64) dig := "sha256:" + strings.Repeat("b", 64) - l.put(t, "n1.xorg", delivery.Have{V: delivery.Version, FP: fp, Composed: dig, Phase: delivery.PhaseRunning, + l.put(t, "n1.xorg", delivery.Have{V: sdkkeys.Version, FP: fp, Composed: dig, Phase: delivery.PhaseRunning, Health: delivery.HealthUnknown}) q, _ := aHaveQueue(l) if !q.SayHealth(context.Background(), *healthOf(map[string]string{"web": StateHealthy})) { @@ -748,7 +749,7 @@ func TestADeclarationReportMovesAHealthAndARemovalForgetsIt(t *testing.T) { // key that does not exist is not made up and is said once; a writer that drops the list again is written over. func TestAUserListReachesTheHaveOfAModuleNoApplyHereSays(t *testing.T) { l := newHaveLink() - older := delivery.Have{V: delivery.Version, Build: "build-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK} + older := delivery.Have{V: sdkkeys.Version, Build: "build-1", Phase: delivery.PhaseRunning, Health: delivery.HealthOK} l.put(t, "n1.nats", older) q, said := aHaveQueue(l) dig := "sha256:" + strings.Repeat("c", 64) diff --git a/internal/link/record.go b/internal/link/record.go index fc19e2a..cd6a30d 100644 --- a/internal/link/record.go +++ b/internal/link/record.go @@ -2,6 +2,7 @@ package link import ( "encoding/json" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "slices" "sort" "sync" @@ -60,7 +61,7 @@ func recordOf(node string, r Report, keys RecordKeys) *delivery.NodeRecord { if err != nil || json.Unmarshal(raw, &p) != nil { return nil } - rec := &delivery.NodeRecord{V: delivery.Version, Node: node, TunnelKey: keys.TunnelKey, SealingKey: keys.SealingKey, + rec := &delivery.NodeRecord{V: sdkkeys.Version, Node: node, TunnelKey: keys.TunnelKey, SealingKey: keys.SealingKey, ServingKey: keys.ServingKey, Certificate: keys.Certificate, Authority: keys.Authority, Trusts: keys.Trusts, ManifestReads: manifestReads()} for _, c := range p.Capabilities { diff --git a/internal/link/session.go b/internal/link/session.go index ed8bb75..9af5818 100644 --- a/internal/link/session.go +++ b/internal/link/session.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + sdkkeys "git.novox.be/novox/mesh-sdk/go/keys" "strings" "sync" "time" @@ -413,7 +414,7 @@ func (q *Session) SayReads() { } q.reads.linked = true q.reads.Unlock() - q.SayEngine(nodeengine.EventManifestReadsChanged, nodeengine.ManifestReadsChangedEvent{V: delivery.Version, + q.SayEngine(nodeengine.EventManifestReadsChanged, nodeengine.ManifestReadsChangedEvent{V: sdkkeys.Version, Node: q.Membership.Node, ManifestReads: manifestReads(), At: time.Now().UTC().Format(time.RFC3339Nano), Why: why}) }