The bus module's tools hold no grant of the seat's acting verbs (design 25 § 12.3): nats_create, nats_apply, nats_recreate and nats_drop write a request into the keeper's own state requests, stamped with stdio.CallerOf (a name in the arguments is never the caller), and read its end back. recreate and drop raise the operator's ask first, its option binding exactly that act; the keeper acts only on the router's warrant for it (Warrant.For, Option.Performs), after a snapshot of the entry's streams (bussnap, moved from the snapshot command with a streams filter), says recreated or dropped, and records every act as a hand act through mesh-hand-acts. A drop removes an orphan alone. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
71 lines
2.7 KiB
Go
71 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
"git.novox.be/novox/mesh-sdk/go/asks"
|
|
|
|
"nats-tools/internal/keeper"
|
|
)
|
|
|
|
// A person's acting tools hand their request to the keeper (design 25 § 12.3; CAT-N8): stamped with the caller the
|
|
// tool runner proved, whatever name the arguments give; a create's end read back; a drop raises the operator's ask
|
|
// first, binding exactly that act, and is not acted on by the tool.
|
|
func TestAPersonsRequestIsHandedToTheKeeperAsTheProvedCaller(t *testing.T) {
|
|
held := map[string]keeper.Request{}
|
|
var raised []asks.Ask
|
|
rs := requestStore{
|
|
Put: func(key string, r keeper.Request) error {
|
|
if r.Verb == keeper.VerbCreate {
|
|
// The keeper's end, as its watch writes it.
|
|
r.Done, r.Outcome = time.Unix(1, 0), "created"
|
|
}
|
|
held[key] = r
|
|
return nil
|
|
},
|
|
Get: func(key string) (*keeper.Request, error) {
|
|
r, ok := held[key]
|
|
if !ok {
|
|
return nil, nil
|
|
}
|
|
return &r, nil
|
|
},
|
|
Ask: func(a asks.Ask) error { raised = append(raised, a); return nil },
|
|
Now: func() time.Time { return time.Date(2026, 11, 4, 12, 0, 0, 0, time.UTC) },
|
|
Wait: func(time.Duration) {},
|
|
}
|
|
tools := map[string]stdio.Tool{}
|
|
for _, tl := range requestTools(rs) {
|
|
tools[tl.Name] = tl
|
|
}
|
|
out, err := tools["nats_create"].Run(map[string]any{"module": "m", "local": "log", "why": "a test", "caller": "person.mallory"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if r := out.(*keeper.Request); r.Caller != stdio.Unproven || r.Outcome != "created" {
|
|
t.Errorf("answered %+v: acted for the caller the runtime proved (here none, %q), never person.mallory", r, stdio.Unproven)
|
|
}
|
|
out, err = tools["nats_drop"].Run(map[string]any{"module": "m", "local": "old", "why": "no manifest asks for it"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
answer := out.(map[string]any)
|
|
r := held[answer["request"].(string)]
|
|
if len(raised) != 1 || r.Ask != raised[0].ID || !r.Done.IsZero() {
|
|
t.Fatalf("raised %+v, held %+v: the ask raised, the request waiting for it", raised, r)
|
|
}
|
|
binds, _ := asks.ActDigest(asks.Act{"verb": "drop", "module": "m", "local": "old"})
|
|
if o, _ := raised[0].Option("go"); o.Level != asks.Destroy || o.Binds != binds || !strings.Contains(raised[0].Explanation, "snapshot") {
|
|
t.Errorf("the ask is %+v: its option destroys exactly this drop, after a snapshot", raised[0])
|
|
}
|
|
if _, err := tools["nats_drop"].Run(map[string]any{"module": "m", "local": "old"}); err == nil || !strings.Contains(err.Error(), "says why") {
|
|
t.Errorf("a drop without why: %v", err)
|
|
}
|
|
if got, _ := tools["nats_drop"].Run(map[string]any{"request": r.ID}); got.(*keeper.Request).ID != r.ID {
|
|
t.Errorf("reading the request back answered %+v", got)
|
|
}
|
|
}
|