Keep a mesh seat's node argument, and refuse what a call would drop

The console took node out of every schema and every call, so the
controller's push, plan, assign, pin and settings were described without
the machine and called without it: a push naming one machine ran as a
push of every machine behind (hq issue 244). node is now taken out only
where the address names the machine, a different machine there is
refused, and an argument a seat's verb does not declare is refused.
This commit is contained in:
jochen
2026-10-06 00:37:15 +02:00
parent 93c1ad8c4a
commit 3a7c9645e0
2 changed files with 122 additions and 9 deletions
@@ -0,0 +1,52 @@
package console
import (
"encoding/json"
"strings"
"testing"
)
// novox/hq issue 244: `node` is taken out only where the address names the machine. A seat held once
// for the mesh takes the machine it acts on as `node`, and is described and called with it — on
// 2026-10-05 the controller's push was described as taking nothing, and a push naming one machine
// ran as a push of every machine behind.
func TestAMeshSeatsNodeIsItsOwnArgument(t *testing.T) {
push := Tool{Module: "mesh-controller", Name: "push", Seat: true, Scope: "mesh",
Input: json.RawMessage(`{"type":"object","properties":{"node":{"type":"string"},"behind":{"type":"string"}}}`)}
mesh := target{Address: "mesh-controller.push", Tool: push, Seat: true}
props := schemaAsPassed(mesh)["properties"].(map[string]any)
if _, has := props["node"]; !has {
t.Fatalf("a mesh seat's verb was described without its node: %v", props)
}
sent, err := argumentsAsSent(mesh, map[string]any{"node": "g1"})
if err != nil || sent["node"] != "g1" {
t.Fatalf("a mesh seat's verb was called without the machine it was given: %v %v", sent, err)
}
// An argument the seat's verb does not declare is refused, naming it, never sent to be dropped.
if _, err := argumentsAsSent(mesh, map[string]any{"machine": "g1"}); err == nil || !strings.Contains(err.Error(), "machine") {
t.Fatalf("an undeclared argument was sent: %v", err)
}
// A machine's seat: the address names the machine, so `node` is out of the schema; given the same
// machine again it is taken out, given another it is refused.
shelf := Tool{Module: "node-shelf", Name: "list", Seat: true, Scope: "node",
Input: json.RawMessage(`{"type":"object","properties":{"limit":{"type":"string"}}}`)}
onDesk := target{Address: "desk/node-shelf.list", Node: "desk", Tool: shelf, Seat: true}
if _, has := schemaAsPassed(onDesk)["properties"].(map[string]any)["node"]; has {
t.Fatal("a machine's seat was described with a node the address already names")
}
if sent, err := argumentsAsSent(onDesk, map[string]any{"node": "desk", "limit": "3"}); err != nil || sent["node"] != nil || sent["limit"] != "3" {
t.Fatalf("the same machine named twice: %v %v", sent, err)
}
if _, err := argumentsAsSent(onDesk, map[string]any{"node": "bench"}); err == nil || !strings.Contains(err.Error(), "bench") {
t.Fatalf("another machine in the arguments than in the address was dropped: %v", err)
}
// A module's tool is its own: what it takes beyond node is the module's to judge.
beta := target{Address: "desk/beta.three", Node: "desk", Tool: Tool{Module: "beta", Name: "three"}}
if sent, err := argumentsAsSent(beta, map[string]any{"node": "desk", "verbose": true}); err != nil || sent["verbose"] != true || sent["node"] != nil {
t.Fatalf("a module's tool: %v %v", sent, err)
}
}