CAT-V1: retire takes ask beside warrant, as the seat definition now has it

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 12:12:54 +01:00
parent 6b929c9057
commit 25e5d00aba
5 changed files with 29 additions and 23 deletions
@@ -127,6 +127,6 @@ func (v toolVault) Retire(r RetireRequest) error {
if json.Unmarshal(answer, &rec) != nil || rec.Act.ID == "" {
return fmt.Errorf("mesh-hand-acts recorded the warrant and named no act")
}
_, err = v.ask(VaultRetireAsk, map[string]any{"node": r.Node, "module": r.Module, "name": r.Name, "warrant": rec.Act.ID})
_, err = v.ask(VaultRetireAsk, map[string]any{"node": r.Node, "module": r.Module, "name": r.Name, "warrant": rec.Act.ID, "ask": r.Ask})
return err
}
@@ -135,14 +135,15 @@ func enrolmentTools(env *Env) []toolDef {
"through mesh-hand-acts for this verb naming exactly this node, module and name and the ask of the operator's Approve " +
"(`warrant`, the act's id), read back here.",
Input: map[string]any{"node": node, "module": str("the module whose secret it is"), "name": str("the secret's name"),
"warrant": str("the operator's warrant for this node, module and name: the id of the hand act recorded through mesh-hand-acts")},
"warrant": str("the operator's warrant for this node, module and name: the id of the hand act recorded through mesh-hand-acts"),
"ask": str("the id of the operator's ask the warrant answers")},
run: func(caller string, a map[string]any) (any, error) {
v, err := env.ready()
if err != nil {
return nil, err
}
return v.RetireOwn(caller, RetireArgs{Node: arg(a, "node"), Module: arg(a, "module"), Name: arg(a, "name"),
Warrant: arg(a, "warrant")})
Warrant: arg(a, "warrant"), Ask: arg(a, "ask")})
}},
{Name: "node_logins",
Description: "Every node's key of the vault's state node-logins: the login its node-engine dials as and, while a rotation " +
@@ -547,7 +547,7 @@ func TestTheVaultWholeMintsOnTheBusWhoeverHoldsTheLease(t *testing.T) {
t.Fatalf("a refused retire said %s", m.Subject)
}
// The call is the definition's input, the answer its answer, and the event its body on its subject (CAT-V4).
input, _ := json.Marshal(meshvault.RetireInput{Node: "g14", Module: "dunst", Name: "token", Warrant: "act-ok"})
input, _ := json.Marshal(meshvault.RetireInput{Node: "g14", Module: "dunst", Name: "token", Warrant: "act-ok", Ask: "ret-1"})
var args map[string]any
_ = json.Unmarshal(input, &args)
raw, err = p.call(Seat+"."+meshvault.VerbRetire, "novox.mesh-config", args)
@@ -27,10 +27,10 @@ const OwnRetiredEvent = "own-retired"
// RetireVerb is the seat's verb, and the verb of the hand act that warrants it (`mesh-vault.retire`).
const RetireVerb = "retire"
// RetireArgs are `retire`'s arguments, as the seat's definition names them: the secret by node, module and name, and the
// warrant, the id of the hand act that warrants it.
// RetireArgs are `retire`'s arguments, as the seat's definition names them: the secret by node, module and name, the
// warrant (the id of the hand act that warrants it) and the ask of the operator's Approve it answers.
type RetireArgs struct {
Node, Module, Name, Warrant string
Node, Module, Name, Warrant, Ask string
}
// OwnRetiredBody is the body of own-retired, exactly the seat definition's (node, module, name, ask, caller).
@@ -62,6 +62,9 @@ func (v *Vault) fromRetireCallers(caller string) error {
// warrantsRetire reads the hand act back and refuses what it does not warrant for exactly this secret; it answers the
// ask the act names.
func (v *Vault) warrantsRetire(caller string, a RetireArgs) (ask string, err error) {
if strings.TrimSpace(a.Ask) == "" {
return "", fmt.Errorf("retire names the ask of the operator's Approve it answers (`ask`)")
}
if strings.TrimSpace(a.Warrant) == "" {
return "", fmt.Errorf("retire carries the hand act that warrants it (`warrant`): record it through mesh-hand-acts first (design 32)")
}
@@ -87,9 +90,9 @@ func (v *Vault) warrantsRetire(caller string, a RetireArgs) (ask string, err err
named = append(named, strings.Fields(arg)...)
}
// The warrant is bound to the node, module and name it was asked for, and names the ask: those four words, no others.
if len(named) != 4 || named[0] != a.Node || named[1] != a.Module || named[2] != a.Name {
return "", fmt.Errorf("the hand act %s names %q, not %s %s %s and its ask: a warrant retires nothing else",
a.Warrant, strings.Join(named, " "), a.Node, a.Module, a.Name)
if len(named) != 4 || named[0] != a.Node || named[1] != a.Module || named[2] != a.Name || named[3] != a.Ask {
return "", fmt.Errorf("the hand act %s names %q, not %s %s %s and ask %s: a warrant retires nothing else",
a.Warrant, strings.Join(named, " "), a.Node, a.Module, a.Name, a.Ask)
}
return named[3], nil
}
@@ -115,17 +115,19 @@ func TestRetireRemovesAnOwnSecretOnlyOnTheWarrantOfTheListedCaller(t *testing.T)
args RetireArgs
want string
}{
{"no act", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token"}, "carries the hand act"},
{"an act that does not exist", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "nope"}, "holds no hand act"},
{"an act for another name", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-name"}, "a warrant retires nothing else"},
{"an act for another node", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-node"}, "a warrant retires nothing else"},
{"an act of another caller", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-caller"}, "was recorded by g14.claude-code"},
{"an act for another verb", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-verb"}, "warrants no retirement"},
{"an act that names no ask", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "no-ask"}, "a warrant retires nothing else"},
{"an act older than a day", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "old"}, "older than"},
{"a caller not on the list", "g14.claude-code", RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-caller"}, "retire-callers"},
{"an unproven caller", stdio.Unproven, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok"}, "retire-callers"},
{"the tool runner's ledgers", caller, RetireArgs{Node: "g14", Module: "node-tools", Name: "ledgers", Warrant: "ledgers"}, "bus account or the tool runner's ledgers"},
{"no act", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Ask: "ret-1"}, "carries the hand act"},
{"an act that does not exist", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "nope", Ask: "ret-1"}, "holds no hand act"},
{"an act for another name", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-name", Ask: "ret-1"}, "a warrant retires nothing else"},
{"an act for another node", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-node", Ask: "ret-1"}, "a warrant retires nothing else"},
{"an act of another caller", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-caller", Ask: "ret-1"}, "was recorded by g14.claude-code"},
{"an act for another verb", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-verb", Ask: "ret-1"}, "warrants no retirement"},
{"an ask other than the act's", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok", Ask: "ret-2"}, "a warrant retires nothing else"},
{"no ask", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok"}, "names the ask"},
{"an act that names no ask", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "no-ask", Ask: "ret-1"}, "a warrant retires nothing else"},
{"an act older than a day", caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "old", Ask: "ret-1"}, "older than"},
{"a caller not on the list", "g14.claude-code", RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "other-caller", Ask: "ret-1"}, "retire-callers"},
{"an unproven caller", stdio.Unproven, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok", Ask: "ret-1"}, "retire-callers"},
{"the tool runner's ledgers", caller, RetireArgs{Node: "g14", Module: "node-tools", Name: "ledgers", Warrant: "ledgers", Ask: "ret-1"}, "bus account or the tool runner's ledgers"},
} {
t.Run(tc.name, func(t *testing.T) {
before := len(v.bus.events)
@@ -141,7 +143,7 @@ func TestRetireRemovesAnOwnSecretOnlyOnTheWarrantOfTheListedCaller(t *testing.T)
})
}
before := len(v.bus.events)
got, err := v.RetireOwn(caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok"})
got, err := v.RetireOwn(caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok", Ask: "ret-1"})
if err != nil || !got.Retired {
t.Fatalf("retire answered %+v, %v", got, err)
}
@@ -162,7 +164,7 @@ func TestRetireRemovesAnOwnSecretOnlyOnTheWarrantOfTheListedCaller(t *testing.T)
t.Error("own-retired shares a name with an event a waiter hears")
}
// Asked again for what is gone: nothing to retire.
if _, err := v.RetireOwn(caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok"}); err == nil ||
if _, err := v.RetireOwn(caller, RetireArgs{Node: "g14", Module: "dunst", Name: "token", Warrant: "ok", Ask: "ret-1"}); err == nil ||
!strings.Contains(err.Error(), "nothing to retire") {
t.Errorf("a second retire answered %v", err)
}