Files
mesh-tools/node-tools/internal/console/approvals.go
T
jschoubben 6851ee1657 A-7 tools: mesh_approvals reads and steers what was asked; mesh_describe says a mark and its source
The mesh MCP server gains mesh_approvals: with no argument the calls asked on the machine
in the last day, newest first, with state and fingerprint, the marks the gate applies with
their sources and the catalog revision, and the state's fill against its cap (every
machine's keys together); an ask read whole with the act's digest; record asking the
hand-act again, and cancel taking an open ask back, each recorded in the hand-act log first
and refused when it cannot be. mesh_describe answers needs-approval with its source, and a
marked call that reached no one names withheld and mesh-grants.grants_user_list.

Builds: design 46 7-approval-mark §18, §6 (the mesh MCP server's withheld answer), §22 (eight tools)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:24:41 +01:00

100 lines
4.1 KiB
Go

package console
import (
"log"
"strings"
"github.com/novox/mesh-tools/node-tools/internal/approval"
)
// verbApprovals is the mesh MCP server's tool that reads and steers what the gate asked on this machine (design 46
// 7-approval-mark §18).
const verbApprovals = "mesh_approvals"
// Approvals is the gate of this machine's tool runner, as mesh_approvals and mesh_describe read it.
type Approvals interface {
List() ([]approval.Listed, error)
Read(id string) (approval.Whole, error)
Applied() []approval.Marks
Describe(module, seat, name string) (bool, string)
Again(id string) error
Cancel(id string) error
// Fill is the state approvals' bytes against its cap, every machine's keys together.
Fill() (bytes uint64, max int64, err error)
}
func approvalsTool() map[string]any {
str := func(desc string) map[string]any { return map[string]any{"type": "string", "description": desc} }
return map[string]any{"name": verbApprovals, "inputSchema": map[string]any{"type": "object", "properties": map[string]any{
"ask": str("an ask's id: its whole arguments and the act's digest"),
"record": str("an ask's id: ask mesh-hand-acts.warranted again for its run, recorded in the hand-act log first"),
"cancel": str("an ask's id: take that open ask back, recorded in the hand-act log first"),
"why": str("why, for record and cancel, kept in the hand-act log"),
}}, "description": "The calls that needed the operator's approval on this machine: with no argument, those asked in " +
"the last day, newest first, with their state and fingerprint, the marks the tool runner applies (each module's " +
"marked tools and verbs with their source and the catalog revision read) and its state's fill; `ask` reads one " +
"whole, `record` asks its hand-act again, `cancel` takes an open ask back."}
}
// approvalsAnswer is mesh_approvals.
func (s *Surface) approvalsAnswer(args map[string]any) map[string]any {
if s.Approvals == nil {
return failure("this tool runner has no approval gate")
}
str := func(k string) string { v, _ := args[k].(string); return strings.TrimSpace(v) }
why := str("why")
if why == "" {
why = "asked by hand with no reason given"
}
act := func(id, what, cause string, do func(string) error) map[string]any {
// A hand act, recorded through the seat mesh-hand-acts before it is done (§18); one that cannot be recorded is refused.
log.Printf("[mesh-tools] hand act: %s %s ask %s: %s", s.who, what, id, why)
if err := s.recordAct(map[string]any{"what": what + " ask " + id, "why": why, "cause": cause, "verb": verbApprovals}); err != nil {
return failure("the hand act was not recorded through mesh-hand-acts, so nothing was done: " + err.Error())
}
if err := do(id); err != nil {
return failure(err.Error())
}
return answerText(map[string]any{"done": what + " ask " + id, "recorded": "mesh-hand-acts.hand-act"})
}
switch {
case str("record") != "":
return act(str("record"), "asked the hand-act of", "approval-record", s.Approvals.Again)
case str("cancel") != "":
return act(str("cancel"), "cancelled", "approval-cancel", s.Approvals.Cancel)
case str("ask") != "":
w, err := s.Approvals.Read(str("ask"))
if err != nil {
return failure(err.Error())
}
return answerText(w)
}
asks, err := s.Approvals.List()
out := map[string]any{"asks": asks, "marks": s.Approvals.Applied()}
if err != nil {
out["asks"], out["asks_why"] = []approval.Listed{}, "the state approvals cannot be read: "+err.Error()
}
if b, max, err := s.Approvals.Fill(); err != nil {
out["fill_why"] = err.Error()
} else {
out["fill"] = map[string]any{"bytes": b, "max_bytes": max, "of": "every machine's keys together"}
}
return answerText(out)
}
// marked is what mesh_describe and a call that reached no one say of a marked tool or verb (§6, §18).
func (s *Surface) marked(module, seat, name string) (bool, string) {
if s.Approvals == nil {
return false, ""
}
return s.Approvals.Describe(module, seat, name)
}
// markedTool is marked for a resolved address.
func (s *Surface) markedTool(t target) (bool, string) {
if t.Seat {
return s.marked("", t.Tool.Module, t.Tool.Name)
}
return s.marked(t.Tool.Module, "", t.Tool.Name)
}