Kept: the operator-channel client keeps an asked call's act, arguments and recorded mark

An asker that asks for a call (the tool runner's approval gate) keeps beside the ask the
act its options bind, the call's whole arguments, and whether its run is in the hand-act
log; Take keeps all three as it marks the ask.

Builds: design 46 7-approval-mark §13

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 05:00:12 +01:00
parent 74c157284f
commit 49e26f5d27
2 changed files with 21 additions and 0 deletions
@@ -58,12 +58,21 @@ func (c *Client) now() time.Time {
}
// Kept is one ask as the module keeps it.
//
// An asker that asks for a call keeps beside it the act the ask binds, the call's whole arguments, and whether the act's
// run was recorded in the hand-act log (design 46 7-approval-mark §13): Take keeps all three as it marks the ask.
type Kept struct {
Ask seat.Ask `json:"ask"`
Asked time.Time `json:"asked"`
Acted bool `json:"acted,omitempty"`
Ended string `json:"ended,omitempty"`
Answer *seat.Warrant `json:"answer,omitempty"`
// Act is the act the ask's options bind, as its asker digested it.
Act Act `json:"act,omitempty"`
// Arguments are the asked call's arguments whole.
Arguments json.RawMessage `json:"arguments,omitempty"`
// Recorded says the act's run is in the hand-act log (`mesh-hand-acts.warranted` answered).
Recorded bool `json:"recorded,omitempty"`
}
func (c *Client) key(id string) string { return c.KeyPrefix + "ask." + id }
@@ -167,9 +167,21 @@ func TestAKeyPrefixIsPutBeforeEveryKeyOfTheClientsOwnStateAndNotBeforeWhere(t *t
if _, ok := store.vals[tc.key]; len(store.vals) != 1 || !ok {
t.Fatalf("prefix %q: keys written %v, want %s", tc.prefix, store.vals, tc.key)
}
// Design 46 7-approval-mark §13: the act and the call's arguments kept beside the ask stay as Take marks it.
e, _ := store.Get(tc.key)
var k Kept
_ = json.Unmarshal(e.Value, &k)
k.Act, k.Arguments = releaseHQ, json.RawMessage(`{"delivery":"hq"}`)
if _, err := store.Update(tc.key, k, e.Revision); err != nil {
t.Fatal(err)
}
if h, err := c.Take(askedWarrant(), func(seat.Option, seat.Warrant) error { return nil }); h != Acted || err != nil {
t.Fatalf("prefix %q: the warrant was not read from %s: %s %v", tc.prefix, tc.key, h, err)
}
raw := string(store.vals[tc.key])
if !strings.Contains(raw, `"act":{"delivery":"hq","verb":"release"}`) || !strings.Contains(raw, `"arguments":{"delivery":"hq"}`) || strings.Contains(raw, `"recorded"`) {
t.Errorf("prefix %q: the kept ask after Take is %s", tc.prefix, raw)
}
if _, _, err := c.Where("an-asker.d-1"); err != nil || asked != "an-asker.d-1" {
t.Errorf("prefix %q: Where read %q", tc.prefix, asked)
}