diff --git a/modules/claude-code/cmd/claude-code/proposals.go b/modules/claude-code/cmd/claude-code/proposals.go index 9f878b66..897c0a77 100644 --- a/modules/claude-code/cmd/claude-code/proposals.go +++ b/modules/claude-code/cmd/claude-code/proposals.go @@ -696,7 +696,7 @@ type ProposalStore interface { Get(key string) (json.RawMessage, bool, error) } -// Recorder records a warrant in the controller's hand-act log: the controller reads the warrant from the +// Recorder records a warrant in the hand-act log of the seat mesh-hand-acts: the controller reads the warrant from the // router's own record, never from this module. type Recorder func(ask string) error @@ -708,9 +708,9 @@ func (sdkAskBus) Publish(subject string, body any, id string) error { func (sdkAskBus) Record(id string) (*stdio.StateEntry, error) { return stdio.SeatRecord("", id) } func (sdkAskBus) Kinds() ([]stdio.KindHeld, error) { return stdio.SeatKinds() } -// recordWarrant asks the controller to record a warrant this module acted on. +// recordWarrant asks the seat mesh-hand-acts (ADR 0565 clause 11) to record a warrant this module acted on. func recordWarrant(ask string) error { - _, err := stdio.Ask("seat:mesh-controller.warranted", map[string]any{"asker": Module, "ask": ask}) + _, err := stdio.Ask("seat:mesh-hand-acts.warranted", map[string]any{"asker": Module, "ask": ask}) return err } diff --git a/modules/claude-code/cmd/claude-code/warrant_seat_test.go b/modules/claude-code/cmd/claude-code/warrant_seat_test.go new file mode 100644 index 00000000..07f4bfd8 --- /dev/null +++ b/modules/claude-code/cmd/claude-code/warrant_seat_test.go @@ -0,0 +1,31 @@ +package main + +import ( + "encoding/json" + "os" + "slices" + "strings" + "testing" +) + +// The warrant is recorded through the seat mesh-hand-acts, which the manifest invokes, and no verb of the controller +// is invoked (ADR 0565 clause 11, issue 1953). +func TestTheWarrantIsRecordedThroughTheHandActSeat(t *testing.T) { + raw, err := os.ReadFile("../../module.json") + if err != nil { + t.Fatal(err) + } + var m struct { + Invokes []string `json:"invokes"` + } + if err := json.Unmarshal(raw, &m); err != nil { + t.Fatal(err) + } + if !slices.Equal(m.Invokes, []string{"seat:mesh-hand-acts.warranted"}) { + t.Errorf("invokes = %v", m.Invokes) + } + src, _ := os.ReadFile("proposals.go") + if !strings.Contains(string(src), `"seat:mesh-hand-acts.warranted"`) || strings.Contains(string(src), "seat:mesh-controller.warranted") { + t.Error("recordWarrant does not ask the hand-act seat alone") + } +} diff --git a/modules/claude-code/module.json b/modules/claude-code/module.json index 9f85df0c..48f1a194 100644 --- a/modules/claude-code/module.json +++ b/modules/claude-code/module.json @@ -22,6 +22,9 @@ "uses": [ "operator-channel" ], + "invokes": [ + "seat:mesh-hand-acts.warranted" + ], "state": [ "servers", "holdings",