From e6806d5698158ed8825853d6cb457d59c30cfb78 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 12:43:55 +0100 Subject: [PATCH] CAT-CC2: the instructions' seat table reads the seat set mesh-contracts compiles, not mesh-sdk's catalogue Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- .../claude-code/cmd/claude-code/guard_test.go | 12 ++++++------ .../cmd/claude-code/insteadof_test.go | 12 ++++++------ modules/claude-code/cmd/claude-code/main.go | 4 ++-- modules/claude-code/cmd/claude-code/mesh.go | 18 +++++++++--------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/modules/claude-code/cmd/claude-code/guard_test.go b/modules/claude-code/cmd/claude-code/guard_test.go index 5ea512ea8..7acf464d2 100644 --- a/modules/claude-code/cmd/claude-code/guard_test.go +++ b/modules/claude-code/cmd/claude-code/guard_test.go @@ -9,25 +9,25 @@ import ( "strings" "testing" - "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-contracts/go/seats" ) // meshForTheGuard is a mesh of two machines and the verbs that replace what an agent runs over ssh, as the // seats' contract and the modules' manifests say them. func meshForTheGuard() GuardData { - seats := []catalogue.Seat{ - {Name: "mesh-placement", Scope: catalogue.ScopeMesh, Serves: []catalogue.Verb{ + defined := []seats.Seat{ + {Name: "mesh-placement", Scope: "mesh", Serves: []seats.Verb{ {Name: "placement", Description: "Read placement: one node's key.", Replaces: []string{"hostnamectl", "uptime"}}}}, - {Name: "node-service-manager", Scope: catalogue.ScopeNode, Serves: []catalogue.Verb{ + {Name: "node-service-manager", Scope: "node", Serves: []seats.Verb{ {Name: "status", Description: "One unit as the service manager sees it now: its states.", Replaces: []string{"systemctl status", "systemctl is-active"}}, {Name: "restart", Description: "Restart one unit.", Replaces: []string{"systemctl restart"}}, {Name: "journal", Description: "The last lines of one unit's journal.", Replaces: []string{"journalctl"}}}}, - {Name: "node-hostname", Scope: catalogue.ScopeNode, Serves: []catalogue.Verb{ + {Name: "node-hostname", Scope: "node", Serves: []seats.Verb{ {Name: "add", Description: "Add one address and its names to the operator's lines of /etc/hosts.", Replaces: []string{"edit /etc/hosts", "HOSTALIASES"}}}}, } modules := []ModuleTools{{Module: "docker", On: []string{"anchor"}, Replaces: map[string][]string{"docker_logs": {"docker logs"}, "docker_list": {"docker ps"}}}, {Module: "systemd", On: []string{"anchor", "laptop"}}} - return GuardData{Node: "laptop", Replacements: ReplacementsOf(seats, modules), Machines: []Machine{ + return GuardData{Node: "laptop", Replacements: ReplacementsOf(defined, modules), Machines: []Machine{ {Name: "anchor", Domains: []string{"anchor" + InternalSuffix, "anchor.example"}, Addresses: []string{"192.0.2.10", "10.10.0.1"}}, {Name: "laptop", Domains: []string{"laptop" + InternalSuffix}, Addresses: []string{"10.10.0.4"}}, }} diff --git a/modules/claude-code/cmd/claude-code/insteadof_test.go b/modules/claude-code/cmd/claude-code/insteadof_test.go index 0be167b24..a157fc7fe 100644 --- a/modules/claude-code/cmd/claude-code/insteadof_test.go +++ b/modules/claude-code/cmd/claude-code/insteadof_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-contracts/go/seats" "git.novox.be/novox/mesh-sdk/go/delivery" ) @@ -33,12 +33,12 @@ func (b aBus) Get(read, key string) ([]byte, bool, error) { } // someSeats are two seats as the seats' contract says them: one held once for the mesh, one on every machine. -func someSeats() []catalogue.Seat { - return []catalogue.Seat{ - {Name: "mesh-placement", Scope: catalogue.ScopeMesh, Serves: []catalogue.Verb{ +func someSeats() []seats.Seat { + return []seats.Seat{ + {Name: "mesh-placement", Scope: "mesh", Serves: []seats.Verb{ {Name: "placement", Description: "Read placement: one node's key.", Replaces: []string{"hostnamectl", "uptime"}}, {Name: "propose", Description: "Propose a change."}}}, - {Name: "node-service-manager", Scope: catalogue.ScopeNode, Serves: []catalogue.Verb{ + {Name: "node-service-manager", Scope: "node", Serves: []seats.Verb{ {Name: "status", Description: "One unit as the service manager sees it now: its states, whether it starts at boot.", Replaces: []string{"systemctl status", "systemctl is-active"}}, {Name: "journal", Description: "The last lines of one unit's journal.", Replaces: []string{"journalctl"}}}}, } @@ -195,7 +195,7 @@ func TestTheMachinesRunningAModuleAreReadFromPlacement(t *testing.T) { // Issue 1126 B13 AC1 (ADR 0590): over the seats the mesh defines, the rendered instructions, their table among them, // name no address of the controller, which is not placed: each job is named by the seat that owns it now. func TestTheRenderedInstructionsNameNoControllerAddress(t *testing.T) { - m, err := ReadMeshToolsFrom(aMesh(t), catalogue.Seats(), resolving) + m, err := ReadMeshToolsFrom(aMesh(t), seats.List(), resolving) if err != nil { t.Fatal(err) } diff --git a/modules/claude-code/cmd/claude-code/main.go b/modules/claude-code/cmd/claude-code/main.go index 3f9abce8d..6dfa03c7f 100644 --- a/modules/claude-code/cmd/claude-code/main.go +++ b/modules/claude-code/cmd/claude-code/main.go @@ -21,9 +21,9 @@ import ( "strings" "time" + "git.novox.be/novox/mesh-contracts/go/seats" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/asks" - "git.novox.be/novox/mesh-sdk/go/catalogue" ) func say(format string, args ...any) { @@ -291,7 +291,7 @@ func tools(p Paths, servers ServerState, view *ServerView, config ConfigState, c Description: "Write Claude Code's managed directory now, from the mesh's facts, this module's settings and the servers registered here — after reading the bus again for what each tool replaces and which machines the mesh has (the instructions' table and the shell's guard).", Run: func(map[string]any) (any, error) { answer := map[string]any{} - if m, err := ReadMeshToolsFrom(busStates{}, catalogue.Seats(), lookup); err != nil { + if m, err := ReadMeshToolsFrom(busStates{}, seats.List(), lookup); err != nil { answer["asked"] = "the bus could not be read in full (" + err.Error() + "); what was kept is rendered" } else { KeepMeshTools(p, m) diff --git a/modules/claude-code/cmd/claude-code/mesh.go b/modules/claude-code/cmd/claude-code/mesh.go index d27b234b4..ba1b40600 100644 --- a/modules/claude-code/cmd/claude-code/mesh.go +++ b/modules/claude-code/cmd/claude-code/mesh.go @@ -5,7 +5,7 @@ package main // replaces, and the mesh's machines by every name and address a session could reach one by. // // Read from the bus at start and every few minutes (issue 1126 B13; the controller that answered this before is -// not placed, novox/hq ADR 0590): the seats' verbs from the seats' contract (mesh-sdk catalogue), the modules' +// not placed, novox/hq ADR 0590): the seats' verbs from the seats' contract (mesh-contracts), the modules' // own tools from the manifests the indexer keeps (`mesh-delivery-indexer.modules` and `.manifests`), and the // machines and where each module runs from the seat mesh-placement's `placement`. Kept in the module's state so // a render never waits for the bus, and rendered whenever it changes. Nothing here is written by hand: a verb @@ -23,7 +23,7 @@ import ( "strings" "time" - "git.novox.be/novox/mesh-sdk/go/catalogue" + "git.novox.be/novox/mesh-contracts/go/seats" "git.novox.be/novox/mesh-sdk/go/delivery" ) @@ -217,14 +217,14 @@ func firstSentence(s string) string { // ReplacementsOf is every seat verb and module tool that says it replaces a command: the seats' verbs first, in the // seats' order, then the modules' own tools by module and tool. -func ReplacementsOf(seats []catalogue.Seat, modules []ModuleTools) []Replacement { +func ReplacementsOf(defined []seats.Seat, modules []ModuleTools) []Replacement { var out []Replacement - for _, s := range seats { + for _, s := range defined { for _, v := range s.Serves { if len(v.Replaces) == 0 { continue } - out = append(out, Replacement{Address: s.Name + "." + v.Name, NodeScoped: s.Scope == catalogue.ScopeNode, Seat: true, + out = append(out, Replacement{Address: s.Name + "." + v.Name, NodeScoped: s.Scope == "node", Seat: true, Does: firstSentence(v.Description), Replaces: v.Replaces}) } } @@ -257,15 +257,15 @@ func lookup(name string) []string { // ReadMeshToolsFrom reads the bus now: the seats' verbs, the placed modules' own tools, and every node placement names // with its domains and addresses. A part that cannot be read is left out and said in the error; what was read is kept. -func ReadMeshToolsFrom(st States, seats []catalogue.Seat, resolve func(string) []string) (MeshTools, error) { +func ReadMeshToolsFrom(st States, defined []seats.Seat, resolve func(string) []string) (MeshTools, error) { var m MeshTools placed, err := placements(st) if err != nil { - m.Replacements = ReplacementsOf(seats, nil) + m.Replacements = ReplacementsOf(defined, nil) return m, err } modules, merr := modulesTools(st, runsOn(placed)) - m.Replacements = ReplacementsOf(seats, modules) + m.Replacements = ReplacementsOf(defined, modules) for node, p := range placed { machine := Machine{Name: node, Domains: []string{node + InternalSuffix}} if d := strings.ToLower(strings.TrimSpace(p.Decided.PublicDomain)); d != "" { @@ -340,7 +340,7 @@ const MeshToolsEvery = 10 * time.Minute // refreshMeshTools reads the bus at start and every few minutes, and renders when what it said changed. func refreshMeshTools(p Paths) { for { - m, err := ReadMeshToolsFrom(busStates{}, catalogue.Seats(), lookup) + m, err := ReadMeshToolsFrom(busStates{}, seats.List(), lookup) if err != nil { say("reading what each tool replaces and which machines the mesh has: %v", err) }