warranted takes no word of the caller's: the record is the router's alone (hq ADR 0274 review)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed

A caller's own line, recorded first under the one id the ask decides, would stand for every node's.
This commit is contained in:
jochen
2026-10-10 03:52:04 +02:00
parent 0e5aed1253
commit abd3078491
4 changed files with 23 additions and 23 deletions
+2 -2
View File
@@ -537,10 +537,10 @@ func (a *verbArguments) commandLine() ([]string, error) {
}
return argv, nil
case "warranted":
if err := need("asker", "ask", "what"); err != nil {
if err := need("asker", "ask"); err != nil {
return nil, err
}
return []string{"hand-act", "warrant", "--asker", str("asker"), "--ask", str("ask"), str("what")}, nil
return []string{"hand-act", "warrant", "--asker", str("asker"), "--ask", str("ask")}, nil
case "hand-acts":
argv := []string{"hand-acts", "--json"}
if d := str("days"); d != "" {
+9 -12
View File
@@ -2,13 +2,14 @@ package main
// A module's act on the operator's warrant, recorded in the hand-act log (novox/hq ADR 0274, ADR 0259 §6).
//
// mesh-controller hand-act warrant --asker <module> --ask <id> <what was done>
// mesh-controller hand-act warrant --asker <module> --ask <id>
//
// The verb `warranted` runs it. A module that asks the operator (an asker) acts on the warrant with its own grants;
// the controller's log is where a person's decisions are read back, so the module asks the controller to record
// it. **What is recorded is the router's word, never the caller's**: the controller reads the router's own record
// of that asker's ask — the bus lets only the router write it — and records who chose, through which channel, with
// which proofs, and which answer. The caller gives only what it did, said as its own words. Recorded once per
// which proofs, and which answer. The caller gives nothing but which ask: a word of its own, recorded first under
// the one id, would stand for every node's (the review of 2026-10-10). Recorded once per
// ask, under an id the ask decides, however many of the module's instances ask; an ask still open, ended without
// a choice, or another asker's is refused and nothing is written.
@@ -19,7 +20,6 @@ import (
"flag"
"fmt"
"regexp"
"strings"
"github.com/nats-io/nats.go"
@@ -36,7 +36,7 @@ func warrantedID(asker, ask string) string { return "warrant-" + asker + "-" + a
// warrantedAct is the entry for an asker's act on the warrant the router recorded for its ask (state, w), or why
// none is written.
func warrantedAct(asker, ask, what, caller, state string, w *asks.Warrant) (link.HandAct, error) {
func warrantedAct(asker, ask, caller, state string, w *asks.Warrant) (link.HandAct, error) {
switch {
case !askerModule.MatchString(asker):
return link.HandAct{}, fmt.Errorf("%q is not a module's name", asker)
@@ -44,8 +44,6 @@ func warrantedAct(asker, ask, what, caller, state string, w *asks.Warrant) (link
return link.HandAct{}, errors.New("the controller records its own acts on a warrant as it performs them")
case !asks.UsableID(ask):
return link.HandAct{}, fmt.Errorf("%q is not an ask's id", ask)
case strings.TrimSpace(what) == "":
return link.HandAct{}, errors.New("say what was done on the warrant")
case state == "" || w == nil:
return link.HandAct{}, fmt.Errorf("the router holds no closed record of %s's ask %s", asker, ask)
case state == "open":
@@ -57,7 +55,7 @@ func warrantedAct(asker, ask, what, caller, state string, w *asks.Warrant) (link
case w.AskDigest == "":
return link.HandAct{}, fmt.Errorf("the router's warrant for %s's ask %s names no ask digest", asker, ask)
}
return link.HandAct{ID: warrantedID(asker, ask), Verb: handActWarrant, Args: []string{strings.TrimSpace(what)},
return link.HandAct{ID: warrantedID(asker, ask), Verb: handActWarrant, Args: []string{fmt.Sprintf("%s acted on %s, chosen on its ask %s", asker, w.Label, ask)},
Why: fmt.Sprintf("%s (ask %s of %s)", w.Says(), ask, asker), By: byWords(*w), Cause: conditions.CauseOperatorAnswer,
Via: viaWords(*w), Ask: ask, Proofs: w.Proofs, RequestedBy: asker + ", recorded at the word of " + caller,
Outcome: "done by " + asker, At: w.At.UTC()}, nil
@@ -94,9 +92,8 @@ func handActWarrantCommand(ctx context.Context, args []string) error {
if err != nil {
return err
}
what := strings.TrimSpace(strings.Join(positionals, " "))
if *asker == "" || *ask == "" || what == "" {
return errors.New("hand-act warrant --asker <module> --ask <id> <what was done on the warrant>")
if *asker == "" || *ask == "" || len(positionals) > 0 {
return errors.New("hand-act warrant --asker <module> --ask <id>: what is recorded is the router's record, and nothing else")
}
open, err := openStores(ctx)
if err != nil {
@@ -115,7 +112,7 @@ func handActWarrantCommand(ctx context.Context, args []string) error {
if err != nil {
return err
}
act, err := warrantedAct(*asker, *ask, what, link.Caller(), state, w)
act, err := warrantedAct(*asker, *ask, link.Caller(), state, w)
if err != nil {
return fmt.Errorf("%w. Nothing was recorded", err)
}
@@ -127,7 +124,7 @@ func handActWarrantCommand(ctx context.Context, args []string) error {
fmt.Printf("already recorded as %s: %s\n", act.ID, act.Why)
return nil
}
fmt.Printf("recorded as %s: %s, through %s; %s\n", act.ID, act.Why, act.Via, what)
fmt.Printf("recorded as %s: %s, through %s\n", act.ID, act.Why, act.Via)
return nil
})
}
+9 -6
View File
@@ -21,15 +21,15 @@ func chosenWarrant() *asks.Warrant {
// What is recorded of a module's act on a warrant is the router's word (novox/hq ADR 0274): who chose, how and
// with which proofs; the caller gives only what it did. Nothing is recorded without a person's choice.
func TestAWarrantIsRecordedFromTheRoutersRecordAlone(t *testing.T) {
act, err := warrantedAct("claude-code", "instr-1", "claude-code proposal instr-1 approved on shanks",
"node-tools.shanks", "chosen", chosenWarrant())
act, err := warrantedAct("claude-code", "instr-1", "node-tools.shanks", "chosen", chosenWarrant())
if err != nil {
t.Fatal(err)
}
if act.ID != "warrant-claude-code-instr-1" || act.Verb != handActWarrant || act.Cause != conditions.CauseOperatorAnswer ||
act.By != "the operator, as telegram identity 42" || act.Ask != "instr-1" || !slices.Equal(act.Proofs, []string{"P1"}) ||
!strings.Contains(act.Why, "the operator, via telegram (user id verified), chose Approve") ||
!strings.Contains(act.RequestedBy, "node-tools.shanks") {
!strings.Contains(act.RequestedBy, "node-tools.shanks") ||
!slices.Equal(act.Args, []string{"claude-code acted on Approve, chosen on its ask instr-1"}) {
t.Fatalf("recorded as %+v", act)
}
for name, c := range map[string]struct {
@@ -53,18 +53,21 @@ func TestAWarrantIsRecordedFromTheRoutersRecordAlone(t *testing.T) {
return w
}},
} {
if _, err := warrantedAct(c.asker, c.ask, "did it", "x", c.state, c.w()); err == nil {
if _, err := warrantedAct(c.asker, c.ask, "x", c.state, c.w()); err == nil {
t.Errorf("%s: recorded", name)
}
}
}
func TestTheWarrantedVerbRunsTheWarrantLineWithoutAWhy(t *testing.T) {
argv, err := argvFor("warranted", map[string]any{"asker": "claude-code", "ask": "instr-1", "what": "approved on shanks"})
if _, err := argvFor("warranted", map[string]any{"asker": "claude-code", "ask": "instr-1", "what": "a word of the caller's"}); err == nil {
t.Error("the caller's own words were taken into the record")
}
argv, err := argvFor("warranted", map[string]any{"asker": "claude-code", "ask": "instr-1"})
if err != nil {
t.Fatal(err)
}
if !slices.Equal(argv, []string{"hand-act", "warrant", "--asker", "claude-code", "--ask", "instr-1", "approved on shanks"}) {
if !slices.Equal(argv, []string{"hand-act", "warrant", "--asker", "claude-code", "--ask", "instr-1"}) {
t.Fatalf("%v", argv)
}
if repairingCommand(argv) != "" {
+3 -3
View File
@@ -341,12 +341,12 @@ var ControllerVerbs = []Verb{
{Name: "warranted", Description: "Record in the hand-act log what a module did on the operator's warrant (novox/hq " +
"ADR 0274, ADR 0259): who chose, through which channel, with which proofs and which answer are read from the " +
"router's own record of that module's ask, never from the caller; recorded once per ask however often it is " +
"asked. Refused for an ask still open, ended without a choice, or not that module's.",
"asked; the caller names the ask and says nothing else. Refused for an ask still open, ended without a choice, " +
"or not that module's.",
Input: schema(map[string]string{
"asker": "the module that asked, e.g. claude-code",
"ask": "its ask's id",
"what": "what it did on the warrant, in a line",
}, []string{"asker", "ask", "what"})},
}, []string{"asker", "ask"})},
{Name: "hand-acts", Description: "What was done by hand lately — pushes, plans ended, consumers re-made, acts " +
"recorded — who, why and the cause of each, and which causes repeat: each repeat is a healer the mesh lacks.",
Input: schema(map[string]string{"days": "how many days back (default 14)"}, nil)},