provisioner_retire_approve and provisioner_retire_reject name no removed controller verb either: they ask nobody, and the operator's answer on the operator channel is named in why and by (ADR 0570 §5, ADR 0604 §8)

This commit is contained in:
2026-11-03 16:51:14 +01:00
parent 6e2f08f96a
commit fdedf290d5
2 changed files with 10 additions and 8 deletions
+7 -5
View File
@@ -482,7 +482,7 @@ func (h *Harness) retirementBody(change string, consumers []map[string]any, extr
}
// RetirementTools are the four tools every provider serves for retirement, the same names in every
// module: the controller's `retire` and `cleanup` verbs ask them on the provider's machine.
// module: a caller asks them on the provider's machine, with the operator's answer named in why and by.
func RetirementTools(h *Harness) []stdio.Tool {
if h == nil {
return nil
@@ -493,7 +493,7 @@ func RetirementTools(h *Harness) []stdio.Tool {
who := map[string]any{
"why": map[string]any{"type": "string", "description": "why — required, kept in the hand-act log"},
"by": map[string]any{"type": "string", "description": "who decided"},
"via": map[string]any{"type": "string", "description": "mesh-controller when asked through its verbs"},
"via": map[string]any{"type": "string", "description": "the part or session that asks, when not the caller itself"},
}
withSet := map[string]any{"consumers": map[string]any{"type": "array", "items": map[string]any{"type": "string"},
"description": "the set, exactly as provisioner_retirement names it"}}
@@ -518,7 +518,8 @@ func RetirementTools(h *Harness) []stdio.Tool {
}},
{Name: "provisioner_retire_approve",
Description: "Retire exactly the set waiting for a person (or the set rejected earlier): access disabled, data " +
"kept and marked to delete. Use the controller's `retire approve`, which records the hand act.",
"kept and marked to delete. It asks nobody: the operator's answer on the operator channel to the provisioner's " +
"ask (novox/hq ADR 0570 §5) is named in why and by, which the hand-act log keeps.",
Input: withSet,
Run: func(args map[string]any) (any, error) {
ctx, cancel := ask()
@@ -530,8 +531,9 @@ func RetirementTools(h *Harness) []stdio.Tool {
return map[string]any{"retired": orEmptyList(done)}, nil
}},
{Name: "provisioner_retire_reject",
Description: "Keep the set waiting for a person active. Use the controller's `retire reject`.",
Input: withSet,
Description: "Keep the set waiting for a person active. It asks nobody: the operator's answer on the operator channel " +
"(novox/hq ADR 0570 §5) is named in why and by, which the hand-act log keeps.",
Input: withSet,
Run: func(args map[string]any) (any, error) {
kept, err := h.Reject(strs(args["consumers"]), argString(args, "why"), argString(args, "by"), argString(args, "via"))
if err != nil {
+3 -3
View File
@@ -482,9 +482,9 @@ func TestTheToolsAnswer(t *testing.T) {
tools := map[string]func(map[string]any) (any, error){}
for _, tool := range RetirementTools(w.h) {
tools[tool.Name] = tool.Run
// L3: the delete names no removed controller verb, and says who must be asked first (ADR 0604 §8).
if tool.Name == "provisioner_delete" && (strings.Contains(tool.Description, "controller") || !strings.Contains(tool.Description, "operator channel")) {
t.Errorf("provisioner_delete says %q", tool.Description)
// L3: the delete, approve and reject name no removed controller verb, and say where the operator answers (ADR 0604 §8).
if tool.Name != "provisioner_retirement" && (strings.Contains(tool.Description, "controller") || !strings.Contains(tool.Description, "operator channel")) {
t.Errorf("%s says %q", tool.Name, tool.Description)
}
}
if len(tools) != 4 {