package stdio import ( "bufio" "encoding/json" "io" "testing" "time" "git.novox.be/novox/mesh-sdk/go/buscalls" ) // callWith serves one tool that answers the caller CallerOf reads from its arguments, sends it one tools/call // with the params given, and returns the caller it answered. func callWith(t *testing.T, params map[string]any) string { caller, _ := callAnswering(t, params) return caller } // callAnswering is callWith answering the call's id CallIDOf read too. func callAnswering(t *testing.T, params map[string]any) (string, string) { servesAlone(t) t.Helper() inR, inW := io.Pipe() outR, outW := io.Pipe() go func() { _ = ServeOn("tracker", []Tool{{Name: "who", Run: func(args map[string]any) (any, error) { return map[string]any{"caller": CallerOf(args), "call": CallIDOf(args)}, nil }}}, inR, outW) }() defer inW.Close() b, _ := json.Marshal(map[string]any{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": params}) _, _ = inW.Write(append(b, '\n')) lines := bufio.NewScanner(outR) done := make(chan [2]string, 1) go func() { if lines.Scan() { var m struct { Result struct { Content []struct { Text string `json:"text"` } `json:"content"` } `json:"result"` } _ = json.Unmarshal(lines.Bytes(), &m) var answer struct { Caller string `json:"caller"` Call string `json:"call"` } if len(m.Result.Content) > 0 { _ = json.Unmarshal([]byte(m.Result.Content[0].Text), &answer) } done <- [2]string{answer.Caller, answer.Call} } }() select { case got := <-done: return got[0], got[1] case <-time.After(3 * time.Second): t.Fatal("the bundle did not answer the call") return "", "" } } // **A tool reads its caller from the runtime, never from the call's arguments** (novox/hq issue 365): the // runtime names the caller it took from the subject the call arrived on in the call's `_meta`, and CallerOf // hands it to the tool by the arguments the tool was given. func TestAToolReadsTheCallerTheRuntimeNamed(t *testing.T) { got := callWith(t, map[string]any{"name": "who", "arguments": map[string]any{"title": "x"}, "_meta": map[string]any{MetaCaller: "shanks.node-tools"}}) if got != "shanks.node-tools" { t.Fatalf("the tool read caller %q, want the one the runtime named", got) } // The call's id is the runtime's too (ADR 0597 §7): read from `_meta`, never from the arguments, and none when it // is not one token. for _, c := range []struct { args, meta map[string]any want string }{ {map[string]any{}, map[string]any{MetaCaller: "shanks.node-tools", MetaCall: "c-7Hq2"}, "c-7Hq2"}, {map[string]any{}, map[string]any{MetaCaller: "shanks.node-tools"}, ""}, {map[string]any{MetaCall: "c-forged"}, map[string]any{}, ""}, {map[string]any{}, map[string]any{MetaCall: "a b"}, ""}, {map[string]any{}, map[string]any{MetaCall: 7}, ""}, } { if _, call := callAnswering(t, map[string]any{"name": "who", "arguments": c.args, "_meta": c.meta}); call != c.want { t.Errorf("args %v, meta %v: the tool read call %q, want %q", c.args, c.meta, call, c.want) } } if CallIDOf(map[string]any{"x": 1}) != "" || CallIDOf(nil) != "" { t.Error("arguments no call was handed have a call id") } if MetaCall != buscalls.MetaCall { t.Errorf("the call id's place is %q here and %q in buscalls", MetaCall, buscalls.MetaCall) } } // A caller named in the arguments is not the caller: an argument is the caller's to write. func TestACallerInTheArgumentsIsNeverTheCaller(t *testing.T) { got := callWith(t, map[string]any{"name": "who", "arguments": map[string]any{"caller": "novox.node-tools", "_meta": map[string]any{MetaCaller: "novox.node-tools"}, MetaCaller: "novox.node-tools"}}) if got != Unproven { t.Fatalf("a caller the arguments claimed was read as %q, want %q", got, Unproven) } got = callWith(t, map[string]any{"name": "who", "arguments": map[string]any{"caller": "novox.node-tools"}, "_meta": map[string]any{MetaCaller: "shanks.node-tools"}}) if got != "shanks.node-tools" { t.Fatalf("with a caller in the arguments the tool read %q, want the runtime's", got) } // A module's trusted list of callers (issue 774, ADR 0563 §8) grants the callers it names as the runtime proved them: // a module on any machine, . exactly, person. exactly; no wildcard, never one unproven. callers, err := ParseCallers([]byte(`{"callers":["node-tools","ace.claude-code","person.jo","*"]}`)) if err != nil { t.Fatal(err) } for caller, want := range map[string]bool{"shanks.node-tools": true, "ace.claude-code": true, "g14.claude-code": false, "person.jo": true, "person.node-tools": false, Unproven: false, "": false, "novox.mesh-vault": false} { if callers.Allows(caller) != want { t.Errorf("%q allowed: %v, want %v", caller, !want, want) } } if _, err := ParseCallers([]byte(`{"callers":["x"],"more":1}`)); err == nil { t.Error("a list with a field it does not know was read") } } // A runtime that names no caller — one from before issue 365, or a call on the subject that names none — is // said as Unproven, explicitly; a caller that is not a bus user's name is Unproven too. func TestACallTheRuntimeNamedNoCallerForIsUnproven(t *testing.T) { for _, params := range []map[string]any{ {"name": "who", "arguments": map[string]any{}}, {"name": "who"}, {"name": "who", "arguments": map[string]any{}, "_meta": map[string]any{}}, {"name": "who", "arguments": map[string]any{}, "_meta": map[string]any{MetaCaller: ""}}, {"name": "who", "arguments": map[string]any{}, "_meta": map[string]any{MetaCaller: "a b"}}, {"name": "who", "arguments": map[string]any{}, "_meta": map[string]any{MetaCaller: 7}}, } { if got := callWith(t, params); got != Unproven { t.Errorf("%v: the tool read caller %q, want %q", params, got, Unproven) } } } // Arguments the runtime never handed a tool have no caller. func TestArgumentsOfNoCallHaveNoCaller(t *testing.T) { if got := CallerOf(map[string]any{"x": 1}); got != Unproven { t.Fatalf("CallerOf of a map no call was given answered %q", got) } if got := CallerOf(nil); got != Unproven { t.Fatalf("CallerOf(nil) answered %q", got) } }