From c6087129ce0512fb4d3925f9447b91c4b9d4156e Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 8 Oct 2026 16:37:34 +0200 Subject: [PATCH] Tell a bundle the kinds its membership names --- node-tools/internal/bus/seat.go | 21 +++++++++++++++++++++ node-tools/internal/launch/launch.go | 2 +- node-tools/internal/runtime/runtime.go | 6 ++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/node-tools/internal/bus/seat.go b/node-tools/internal/bus/seat.go index 5eafb12..b07bf20 100644 --- a/node-tools/internal/bus/seat.go +++ b/node-tools/internal/bus/seat.go @@ -31,6 +31,27 @@ type SeatTraffic struct { Answers []string `json:"answers,omitempty"` Workers []SeatWorker `json:"workers,omitempty"` Records []string `json:"records,omitempty"` + // Kinds are the holders of every kinded bench the module uses or watches, with what each promises: the + // controller's record of their claims (novox/hq ADR 0259 ยง5). + Kinds []KindHeld `json:"kinds,omitempty"` +} + +// KindHeld is one kind of a kinded bench and who holds it. +type KindHeld struct { + Seat string `json:"seat"` + Kind string `json:"kind"` + Module string `json:"module"` + Node string `json:"node"` + Capabilities []string `json:"capabilities,omitempty"` +} + +// SeatKinds is the kinds the module's membership names, as the controller issued them. +func (c *Conn) SeatKinds(module string) ([]KindHeld, error) { + t, err := c.trafficOf(module) + if err != nil { + return nil, err + } + return append([]KindHeld{}, t.Kinds...), nil } // SeatWorker is one work queue a holder takes from. diff --git a/node-tools/internal/launch/launch.go b/node-tools/internal/launch/launch.go index 67f56d8..007e3ef 100644 --- a/node-tools/internal/launch/launch.go +++ b/node-tools/internal/launch/launch.go @@ -258,7 +258,7 @@ func Start(module, entry string, env []string, mesh Bus, logf func(string, ...an subscriber = c mu.Unlock() err = mesh.Subscribe(deliver) - case "mesh/seat.publish", "mesh/seat.prove", "mesh/seat.record": + case "mesh/seat.publish", "mesh/seat.prove", "mesh/seat.record", "mesh/seat.kinds": var answered json.RawMessage if answered, err = mesh.Seat(strings.TrimPrefix(m.Method, "mesh/seat."), m.Params, nil); err == nil { result = answered diff --git a/node-tools/internal/runtime/runtime.go b/node-tools/internal/runtime/runtime.go index be9919f..c100d5d 100644 --- a/node-tools/internal/runtime/runtime.go +++ b/node-tools/internal/runtime/runtime.go @@ -717,6 +717,12 @@ func (b *moduleBus) Seat(verb string, params json.RawMessage, handOn func(string return json.Marshal(map[string]any{"sequence": seq}) case "prove": return conn.SeatProve(b.module, asked.Subject, asked.Body) + case "kinds": + kinds, err := conn.SeatKinds(b.module) + if err != nil { + return nil, err + } + return json.Marshal(kinds) case "record": entry, err := conn.SeatRecord(b.module, asked.Bucket, asked.Key) if err != nil || entry == nil {