Record a module's act on the operator's warrant from the router's own record (hq ADR 0274)
A module that asks the operator acts with its own grants, and the hand-act log is where a person's decisions are read back. The new verb warranted records who chose, how and with which proofs from the router's record, never the caller's word, once per ask however many instances ask.
This commit is contained in:
@@ -338,6 +338,15 @@ var ControllerVerbs = []Verb{
|
||||
"why": "what the drill tests",
|
||||
"condition": "the key of the condition the drill is meant to raise, if any (optional)",
|
||||
}, []string{"what", "why"})},
|
||||
{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.",
|
||||
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"})},
|
||||
{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)},
|
||||
|
||||
@@ -122,6 +122,33 @@ func RecordHandAct(ctx context.Context, conn *nats.Conn, act HandAct) (HandAct,
|
||||
return act, err
|
||||
}
|
||||
|
||||
// RecordHandActOnce writes one entry under the id it carries, only where none is: an act recorded once however
|
||||
// often it is asked, such as a module's act on a warrant, asked by each of its instances (novox/hq ADR 0274). It
|
||||
// answers false, with no error, when the entry was already there.
|
||||
func RecordHandActOnce(ctx context.Context, conn *nats.Conn, act HandAct) (bool, error) {
|
||||
if act.ID == "" || strings.TrimSpace(act.Why) == "" {
|
||||
return false, errors.New("an act recorded once carries its id and why")
|
||||
}
|
||||
if act.At.IsZero() {
|
||||
act.At = time.Now().UTC()
|
||||
}
|
||||
kv, err := handActs(ctx, conn)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
body, err := json.Marshal(act)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if _, err := kv.Create(ctx, act.ID, body); err != nil {
|
||||
if errors.Is(err, jetstream.ErrKeyExists) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// HandActs is every entry since a moment, oldest first.
|
||||
func HandActs(ctx context.Context, conn *nats.Conn, since time.Time) ([]HandAct, error) {
|
||||
kv, err := handActs(ctx, conn)
|
||||
|
||||
@@ -57,3 +57,30 @@ func TestNatsAnActByHandIsKeptWithWhyAndARepeatIsFound(t *testing.T) {
|
||||
t.Fatalf("%q", acts[2].ID)
|
||||
}
|
||||
}
|
||||
|
||||
// An act on a warrant asked by each of a module's instances is recorded once (novox/hq ADR 0274).
|
||||
func TestNatsAnActRecordedOnceIsWrittenOnce(t *testing.T) {
|
||||
js := aBus(t)
|
||||
api, err := jetstream.New(js.Conn())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = api.DeleteKeyValue(t.Context(), broker.HandActsBucket)
|
||||
if err := js.EnsureControllerBuckets(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
act := HandAct{ID: "warrant-claude-code-instr-1", Verb: "warrant", Why: "the operator chose Approve", By: "the operator"}
|
||||
if _, err := RecordHandActOnce(t.Context(), js.Conn(), HandAct{Verb: "warrant", Why: "x"}); err == nil {
|
||||
t.Fatal("an act without its id was written")
|
||||
}
|
||||
for i, want := range []bool{true, false, false} {
|
||||
written, err := RecordHandActOnce(t.Context(), js.Conn(), act)
|
||||
if err != nil || written != want {
|
||||
t.Fatalf("ask %d: written %v, %v", i, written, err)
|
||||
}
|
||||
}
|
||||
acts, err := HandActs(t.Context(), js.Conn(), time.Now().Add(-time.Hour))
|
||||
if err != nil || len(acts) != 1 || acts[0].ID != act.ID {
|
||||
t.Fatalf("%v %+v", err, acts)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user