diff --git a/node-tools/go.mod b/node-tools/go.mod index 94262f0..d88a8a1 100644 --- a/node-tools/go.mod +++ b/node-tools/go.mod @@ -8,7 +8,6 @@ require ( ) require ( - git.novox.be/novox/mesh-delivery/sdk v0.0.0-00010101000000-000000000000 git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103221822-85ba0a9a70d8 github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect github.com/google/go-tpm v0.9.8 // indirect diff --git a/node-tools/internal/console/firstviews.go b/node-tools/internal/console/firstviews.go index 8f9930d..0bb995c 100644 --- a/node-tools/internal/console/firstviews.go +++ b/node-tools/internal/console/firstviews.go @@ -2,10 +2,11 @@ package console import ( "context" + "errors" "log" "strings" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" ) // FirstViewer is the tool runner's four first views as the console shows them (novox/hq ADR 0615 §6; issue 1966 TLS-6): a @@ -29,9 +30,14 @@ func (s *Surface) firstViewsAnswer(ctx context.Context, name string, args map[st if why = strings.TrimSpace(why); why == "" { why = "asked by hand with no reason given" } - // A hand act, recorded in the runner's log with who asked and why (novox/hq ADR 0615 §6). + // A hand act, recorded through the seat mesh-hand-acts (novox/hq ADR 0615 §6, ADR 0565 §10) before it is done, and in the + // runner's log. One that cannot be recorded is said, and the ask is not made. log.Printf("[mesh-tools] hand act: %s asked the four first views again: %s", s.who, why) - out := map[string]any{"asked again": why} + if err := s.recordAct(map[string]any{"what": "asked the tool runner's four first views again", "why": why, + "cause": "first-view-again", "verb": verbFirstAgain}); err != nil { + return failure("the hand act was not recorded through mesh-hand-acts, so the first views were not asked again: " + err.Error()) + } + out := map[string]any{"asked again": why, "recorded": "mesh-hand-acts.hand-act"} if errs := fv.Again(ctx, why); len(errs) > 0 { var msgs []string for _, e := range errs { @@ -42,3 +48,18 @@ func (s *Surface) firstViewsAnswer(ctx context.Context, name string, args map[st out["first views"] = fv.Status() return answerText(out) } + +// recordAct records one act done by hand through the seat mesh-hand-acts (its verb hand-act); Surface.Record replaces the call +// in a test. +func (s *Surface) recordAct(args map[string]any) error { + if s.Record != nil { + return s.Record(args) + } + if s.conn == nil { + return errNoBus + } + _, err := s.conn.Ask("mesh-hand-acts.hand-act", args, "") + return err +} + +var errNoBus = errors.New("no bus connection") diff --git a/node-tools/internal/console/firstviews_test.go b/node-tools/internal/console/firstviews_test.go index 3a8e2da..20c1c17 100644 --- a/node-tools/internal/console/firstviews_test.go +++ b/node-tools/internal/console/firstviews_test.go @@ -3,10 +3,11 @@ package console import ( "context" "encoding/json" + "errors" "strings" "testing" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" ) // viewer is a Source that also holds first views. @@ -32,7 +33,8 @@ func TestTheConsoleShowsAndAsksAgainTheRunnersFirstViews(t *testing.T) { return string(c) } v := &viewer{} - s := &Surface{src: v, who: "desk.node-tools"} + var recorded []map[string]any + s := &Surface{src: v, who: "desk.node-tools", Record: func(a map[string]any) error { recorded = append(recorded, a); return nil }} if got := text(s.discover(context.Background(), "mesh_first_views", nil)); !strings.Contains(got, "mesh-delivery-assigner") || !strings.Contains(got, "placement") { t.Errorf("mesh_first_views shows %s", got) } @@ -40,6 +42,14 @@ func TestTheConsoleShowsAndAsksAgainTheRunnersFirstViews(t *testing.T) { if len(v.asked) != 1 || v.asked[0] != "doubted" || !strings.Contains(text(got), "asked again") { t.Errorf("mesh_first_view_again asked %v and answered %s", v.asked, text(got)) } + if len(recorded) != 1 || recorded[0]["why"] != "doubted" || recorded[0]["cause"] != "first-view-again" { + t.Errorf("the hand act recorded is %v", recorded) + } + // An act that cannot be recorded is not done. + refusing := &Surface{src: v, who: "desk.node-tools", Record: func(map[string]any) error { return errors.New("no answer") }} + if r := refusing.discover(context.Background(), "mesh_first_view_again", map[string]any{"why": "x"}); r["isError"] != true || len(v.asked) != 1 { + t.Errorf("an unrecorded hand act was done: %s (asked %v)", text(r), v.asked) + } for _, name := range []string{"mesh_first_views", "mesh_first_view_again"} { none := &Surface{src: busSource{}, who: "desk.node-tools"} if r := none.discover(context.Background(), name, nil); r["isError"] != true || !strings.Contains(text(r), "holds no first views") { diff --git a/node-tools/internal/console/mcp.go b/node-tools/internal/console/mcp.go index 971c38f..70490d6 100644 --- a/node-tools/internal/console/mcp.go +++ b/node-tools/internal/console/mcp.go @@ -61,6 +61,8 @@ type Surface struct { // Flat announces the whole catalogue, as the console did before ADR 0195: for a person reading // it or a client that wants it. Off by default; MESH_CONSOLE_FLAT=1 turns it on. Flat bool + // Record, when set, records a hand act in place of the seat mesh-hand-acts' verb (a test's). + Record func(args map[string]any) error } // MethodSeats is the console's JSON-RPC method beside MCP's that answers every seat's verbs and holders, in the shape diff --git a/node-tools/internal/firstview/firstview.go b/node-tools/internal/firstview/firstview.go index cf6db43..78fc4a8 100644 --- a/node-tools/internal/firstview/firstview.go +++ b/node-tools/internal/firstview/firstview.go @@ -15,7 +15,7 @@ import ( "sync" "time" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" "github.com/novox/mesh-tools/node-tools/internal/bus" ) diff --git a/node-tools/internal/firstview/firstview_test.go b/node-tools/internal/firstview/firstview_test.go index 0fddaa4..ae2d5a0 100644 --- a/node-tools/internal/firstview/firstview_test.go +++ b/node-tools/internal/firstview/firstview_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" "github.com/novox/mesh-tools/node-tools/internal/bus" )