Names N2b: a part's holder function reads the seat-holders view it follows

HoldersIn is the one holder function a part gives seatlist.Part.Holders: the modules holding a seat on
any node, from the seat-holders view as the part last heard it (a views follower's or a watched state's
values), so a callers entry `seat:<seat>` is resolved with no call per checked call.

Builds: design 47 G A-295, A-210

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 18:55:07 +01:00
parent b088bdaaef
commit bf06f0f6f3
2 changed files with 43 additions and 4 deletions
+35
View File
@@ -9,6 +9,8 @@ package seatlist
import (
"encoding/json"
"fmt"
"slices"
"strings"
)
const (
@@ -50,3 +52,36 @@ func HolderOf(call HolderCaller, seat string) (string, error) {
}
return "", fmt.Errorf("no module holds the seat %s on record", seat)
}
// HoldersIn is a part's holder function (Part.Holders, design 47 G A-295): the modules holding a seat on any node, read from
// values, the seat-holders view of the seat that places modules as the part last heard it (a views follower's or a watched
// state's Values), so a callers entry `seat:<seat>` is resolved with no call per checked call. The view keys a seat held once
// `<seat>` and a node seat `<seat>.<node>`; none while the view cannot be read or nobody holds the seat.
func HoldersIn[V ~[]byte](values func() (map[string]V, error)) func(seat string) []string {
return func(seat string) []string {
keys, err := values()
if err != nil {
return nil
}
var out []string
for key, raw := range keys {
if key != seat && !strings.HasPrefix(key, seat+".") {
continue
}
var held struct {
Holders []struct {
Module string `json:"module"`
} `json:"holders"`
}
if json.Unmarshal([]byte(raw), &held) != nil {
continue
}
for _, h := range held.Holders {
if h.Module != "" && !slices.Contains(out, h.Module) {
out = append(out, h.Module)
}
}
}
return out
}
}
+8 -4
View File
@@ -289,10 +289,14 @@ func TestTheTwoToolsReadTheHeldListAndReadItAgainForTheirCallers(t *testing.T) {
if err := RefusalWith("seat_list_again", bySeat, "ace.mesh-delivery-watchman", part.holdersOf); err == nil {
t.Fatal("a seat entry allowed a module before the part was given its holders")
}
part.Holders(func(seat string) []string {
return map[string][]string{"mesh-healers": {"mesh-delivery-watchman"}}[seat]
})
for caller, allowed := range map[string]bool{"ace.mesh-delivery-watchman": true, "ace.mesh-build-go": false, "person.jo": true} {
// HoldersIn reads the seat-holders view as the part last heard it: a seat held once by `<seat>`, a node seat by
// `<seat>.<node>`, and no other seat's key.
view := map[string][]byte{"mesh-healers": []byte(`{"seat":"mesh-healers","holders":[{"module":"mesh-delivery-watchman","node":"g14"}]}`),
"node-tool-runner.ace": []byte(`{"seat":"node-tool-runner","node":"ace","holders":[{"module":"node-tools","node":"ace"}]}`),
"mesh-healers-x": []byte(`{"holders":[{"module":"mesh-build-go"}]}`)}
part.Holders(HoldersIn(func() (map[string][]byte, error) { return view, nil }))
bySeat = append(bySeat, "seat:node-tool-runner")
for caller, allowed := range map[string]bool{"ace.mesh-delivery-watchman": true, "ace.mesh-build-go": false, "person.jo": true, "g14.node-tools": true} {
if err := RefusalWith("seat_list_again", bySeat, caller, part.holdersOf); (err == nil) != allowed {
t.Errorf("again by %s through the seat entry: %v, want allowed %v", caller, err, allowed)
}