Files
mesh-catalog/modules/mesh-hand-acts/cmd/mesh-hand-acts/tools.go
T
jschoubben 0bfc72d230 Make the controller checks strict: nothing names the placed-nowhere controller
controllerdeps refuses any manifest naming the controller's seat, states or
buckets, the lease and the entries once kept to its write among them, and
any module file naming one of its buckets (ADR 0590 §5). The words check
refuses a controller address in any text a module shows. The handacts check
and noplacement's list of assignments readers are folded into it (issue 1126 B10).

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 12:29:56 +01:00

126 lines
5.4 KiB
Go

package main
// The seat's verbs (novox/hq ADR 0565 §10, §15): hand-act and warranted record, hand-acts reads both logs and, with
// warrants, every warrant recorded. A recovery is a call: a warrant whose act was lost is written again by asking
// warranted again, from the router's record.
import (
"encoding/json"
"fmt"
"sort"
"strings"
stdio "git.novox.be/novox/mesh-sdk/go"
)
// Verbs are the seat's verbs, as the manifest claims them.
var Verbs = []string{"hand-act", "hand-acts", "warranted"}
// Tool names.
const (
HandActTool = Seat + ".hand-act"
HandActsTool = Seat + ".hand-acts"
WarrantedTool = Seat + ".warranted"
// CopiedTool reads where the one-time copy of the controller's hand acts stands, CopyTool does it (copy.go).
CopiedTool = "hand_acts_copied"
CopyTool = "hand_acts_copy"
)
func obj(props map[string]any, required ...string) map[string]any {
m := map[string]any{"type": "object", "properties": props}
if len(required) > 0 {
m["required"] = required
}
return m
}
func str(d string) map[string]any { return map[string]any{"type": "string", "description": d} }
// Tools are what the runtime serves.
func Tools(l *Log) []stdio.Tool {
return []stdio.Tool{
{Name: HandActTool,
Description: "Record one act done by hand (novox/hq ADR 0565 §10): what was done, why, its cause in a word or a " +
"condition's kind (the word a second act for the same reason uses, which is how a repair done twice is " +
"found) and the condition it addresses. Who did it is the caller the runtime proves. verb is the act's " +
"verb as the log names it: a repair when not given, `hand-act drill` for a drill, or a recorder's own " +
"(`conditions silence`, `config set`). Said as act-recorded.",
Input: obj(map[string]any{"what": str("what was done"), "why": str("why, in a sentence"),
"cause": str("the cause, in a word or a condition's kind"), "condition": str("the condition's key, if any"),
"verb": str("the act's verb in the log; a repair when not given")}, "what", "why"),
Run: func(a map[string]any) (any, error) {
return l.HandAct(stdio.CallerOf(a), arg(a, "verb"), arg(a, "what"), arg(a, "why"), arg(a, "cause"), arg(a, "condition"))
}},
{Name: HandActsTool,
Description: "What was done by hand lately, from this seat's log (the controller's acts were copied into it), newest first: each act with who, why, its cause and which log holds it, and the causes repaired by " +
"hand twice or more within a fortnight (a healer is wanted). Narrowed by cause and who; warrants=true lists " +
"every warrant recorded instead.",
Input: obj(map[string]any{"days": map[string]any{"type": "number", "description": "how many days back (default 14)"},
"cause": str("only this cause"), "who": str("only acts whose who contains this"),
"warrants": str("\"true\": every warrant recorded, `<asker>.<ask>` with its act")}),
Run: func(a map[string]any) (any, error) {
if strings.EqualFold(arg(a, "warrants"), "true") || a["warrants"] == true {
return l.Warrants()
}
return l.HandActs(days(a), arg(a, "cause"), arg(a, "who")), nil
}},
{Name: WarrantedTool,
Description: "Record an asker's act on the operator's warrant (ADR 0274, ADR 0259): read from the router's own " +
"record of that ask — who chose, through which channel, with which proofs and which answer — never from the " +
"caller, once per ask; refused for an ask still open, ended without a choice, or another asker's.",
Input: obj(map[string]any{"asker": str("the module that asked"), "ask": str("its ask's id")}, "asker", "ask"),
Run: func(a map[string]any) (any, error) {
return l.Warranted(stdio.CallerOf(a), arg(a, "asker"), arg(a, "ask"))
}},
{Name: CopiedTool,
Description: "Where the one-time copy of the controller's hand acts into this seat's log ended (novox/hq research 072 " +
"row 26): the marker with when, by what and how many acts were copied, and how full the log is. The copy " +
"cannot run any more: the controller's log is no longer read. Changes nothing.",
Input: obj(map[string]any{}),
Run: func(map[string]any) (any, error) { return l.Copied() }},
{Name: CopyTool,
Description: "Answers that the copy is over (the controller's hand-act log " +
"is no longer read, novox/hq ADR 0571 §13) with the marker of the copy that was made; copies nothing.",
Input: obj(map[string]any{"top_up": str("\"true\": after the copy is done, append the acts written since")}),
Run: func(a map[string]any) (any, error) {
return l.Copy("tool, called by "+stdio.CallerOf(a), a["top_up"] == true || strings.EqualFold(arg(a, "top_up"), "true"))
}},
}
}
// Warrants is every warrant recorded, by key.
func (l *Log) Warrants() (any, error) {
keys, err := l.Store.Keys(WarrantsState)
if err != nil {
return nil, fmt.Errorf("the warrants cannot be read: %w", err)
}
sort.Strings(keys)
rows := map[string]json.RawMessage{}
for _, k := range keys {
if raw, found, err := l.Store.Get(WarrantsState, k); err == nil && found {
rows[k] = raw
}
}
return map[string]any{"warrants": rows, "count": len(rows)}, nil
}
func arg(a map[string]any, k string) string {
s, _ := a[k].(string)
return strings.TrimSpace(s)
}
func days(a map[string]any) int {
switch v := a["days"].(type) {
case float64:
if v > 0 {
return int(v)
}
case string:
var n int
if _, err := fmt.Sscan(v, &n); err == nil && n > 0 {
return n
}
}
return 14
}