mesh-issues and mesh-knowledge: pin mesh-sdk at its merge of CallerOf; mesh-knowledge reads the caller from the runtime (hq issue 365)
mesh/merge-gate pass: builds mesh-issues, mesh-knowledge → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@a3f4387e2630 (merged as 300406e0 into main, walk plan-17917125412…
mesh/merge-gate pass: builds mesh-issues, mesh-knowledge → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@a3f4387e2630 (merged as 300406e0 into main, walk plan-17917125412…
Both pin mesh-sdk/go at 4cf45b5 (mesh-sdk#20 merged). mesh-knowledge's one reading of the caller, callerOf, now answers stdio.CallerOf, so a call on the caller-named subject is recorded as its caller's bus user and any other as unproven, never from the arguments.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
)
|
||||
|
||||
// whoCalled serves one tool that answers callerOf of its arguments, over the SDK's stdio loop as the runtime
|
||||
// launches a bundle, and sends it one call with params.
|
||||
func whoCalled(t *testing.T, params map[string]any) string {
|
||||
t.Helper()
|
||||
inR, inW := io.Pipe()
|
||||
outR, outW := io.Pipe()
|
||||
go func() {
|
||||
_ = stdio.ServeOn("mesh-knowledge", []stdio.Tool{{Name: "who", Run: func(args map[string]any) (any, error) {
|
||||
return callerOf(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'))
|
||||
got := make(chan string, 1)
|
||||
go func() {
|
||||
lines := bufio.NewScanner(outR)
|
||||
if lines.Scan() {
|
||||
var m struct {
|
||||
Result struct {
|
||||
Content []struct {
|
||||
Text string `json:"text"`
|
||||
} `json:"content"`
|
||||
} `json:"result"`
|
||||
}
|
||||
_ = json.Unmarshal(lines.Bytes(), &m)
|
||||
var who string
|
||||
if len(m.Result.Content) > 0 {
|
||||
_ = json.Unmarshal([]byte(m.Result.Content[0].Text), &who)
|
||||
}
|
||||
got <- who
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case who := <-got:
|
||||
return who
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("the call was not answered")
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// **Who called is the caller the runtime proved** (hq issue 365): read from the call's runtime-written `_meta`,
|
||||
// never from its arguments; Unproven where the runtime named none.
|
||||
func TestTheCallerIsTheOneTheRuntimeProved(t *testing.T) {
|
||||
if got := whoCalled(t, map[string]any{"name": "who", "arguments": map[string]any{"caller": "novox.node-tools"},
|
||||
"_meta": map[string]any{stdio.MetaCaller: "shanks.node-tools"}}); got != "shanks.node-tools" {
|
||||
t.Errorf("callerOf answered %q, want the runtime's caller", got)
|
||||
}
|
||||
if got := whoCalled(t, map[string]any{"name": "who", "arguments": map[string]any{"caller": "novox.node-tools"}}); got != Unproven {
|
||||
t.Errorf("a call the runtime named no caller for answered %q, want %s", got, Unproven)
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,13 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
)
|
||||
|
||||
// Unproven is who acted, as recorded, while the runtime does not tell a module who called it (hq issue 365). The
|
||||
// caller is never taken from an argument.
|
||||
const Unproven = "unproven"
|
||||
// Unproven is who acted, as recorded, where the runtime proves no caller (hq issue 365): the SDK's word. The caller
|
||||
// is never taken from an argument.
|
||||
const Unproven = stdio.Unproven
|
||||
|
||||
// proven says whether a caller is one the runtime proved.
|
||||
func proven(caller string) bool { return caller != "" && caller != Unproven }
|
||||
|
||||
@@ -103,11 +103,10 @@ func serve(k *KB, status string) {
|
||||
}
|
||||
}
|
||||
|
||||
// callerOf is who called, as the runtime proves it: the one place the caller is read, so the change that brings it
|
||||
// is this one function. The runtime does not hand a module its caller yet (hq issue 365): the SDK's tool call carries
|
||||
// a name and arguments only, so the SDK must first pass the runtime's proven caller to a tool. Until it does, every
|
||||
// caller is Unproven. It is never read from the call's arguments, so no caller can name another.
|
||||
func callerOf(map[string]any) string { return Unproven }
|
||||
// callerOf is who called, as the runtime proves it: the one place the caller is read. The tool runner takes the
|
||||
// caller's bus user from the subject the call arrived on and hands it through the SDK (hq issue 365); Unproven where
|
||||
// it proves none. It is never read from the call's arguments, so no caller can name another.
|
||||
func callerOf(args map[string]any) string { return stdio.CallerOf(args) }
|
||||
|
||||
// hear subscribes to the router's word on this module's asks, asked again until the runtime takes it.
|
||||
func hear(k *KB) {
|
||||
|
||||
Reference in New Issue
Block a user