mesh/delivery merged: source.main moved to novox/mesh-tools@f4b4fb908f37
mesh/delivery-group group fix/1966-seat-reads-bootstrap merged: every member is merged
mesh/check failed (2): mesh-delivery-checker: no published of the tagged version of go-sdk of mesh-delivery…; and 1 more | 7572627affde on f4b4fb908f37
A seat verb whose holder announced an empty schema was judged as taking nothing: shanks' tool runner refused "mesh-module-assigner.propose takes no argument changes, why — it takes nothing". The console now judges such a call by the verb's input in the seat's definition this runner holds; where it holds none (it waits for the seat list, holding only the bootstrapped definitions), the arguments go to the holder, which judges its own input, and mesh_describe says the definition is not held instead of showing an empty schema. Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
74 lines
4.2 KiB
Go
74 lines
4.2 KiB
Go
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-module-assigner", Name: "push", Seat: true, Scope: "mesh",
|
|
Input: json.RawMessage(`{"type":"object","properties":{"node":{"type":"string"},"behind":{"type":"string"}}}`)}
|
|
mesh := target{Address: "mesh-module-assigner.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)
|
|
}
|
|
|
|
// Issue 1966: a seat verb its holder announced with an empty schema is judged by the definition this runner holds;
|
|
// where it holds none (it waits for the seat list, holding the bootstrapped ones), the arguments go to the holder,
|
|
// which judges them, and mesh_describe says the definition is not held.
|
|
empty := json.RawMessage(`{"type":"object","properties":{}}`)
|
|
propose := target{Address: "mesh-module-assigner.propose", Seat: true,
|
|
Tool: Tool{Module: "mesh-module-assigner", Name: "propose", Seat: true, Scope: "mesh", Input: empty}}
|
|
if sent, err := argumentsAsSent(propose, map[string]any{"changes": []any{}, "why": "w"}); err != nil || sent["why"] != "w" {
|
|
t.Fatalf("a held definition's arguments were refused: %v %v", sent, err)
|
|
}
|
|
if _, err := argumentsAsSent(propose, map[string]any{"chnages": 1}); err == nil || !strings.Contains(err.Error(), "chnages") {
|
|
t.Fatalf("an argument the held definition does not declare was sent: %v", err)
|
|
}
|
|
unheld := target{Address: "mesh-not-yet-read.act", Seat: true,
|
|
Tool: Tool{Module: "mesh-not-yet-read", Name: "act", Seat: true, Scope: "mesh", Input: empty}}
|
|
if sent, err := argumentsAsSent(unheld, map[string]any{"changes": 1}); err != nil || sent["changes"] != 1 {
|
|
t.Fatalf("a seat whose definition is not held refused its arguments: %v %v", sent, err)
|
|
}
|
|
if _, held := seatDefinitionHeld(unheld); held || !strings.Contains(notHeld("mesh-not-yet-read"), "no definition of mesh-not-yet-read") {
|
|
t.Fatal("a definition not held is said to be held")
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
}
|