From 8b08bffd3b80f28dca8e847a9230f5daf50dbd68 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 05:43:12 +0100 Subject: [PATCH] A-177: a compiled seat verb carries its approval mark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit catalogue.Verb gains NeedsApproval, copied by SeatsFromDefinitions from the definition's verb, so the manifest validator and every reader of the seat list read a verb's mark from one place. Compiled only, never read from a manifest's own verb. Builds: design 46 7-approval-mark §2, §4; lead answer A-177 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- go/catalogue/seat_from_definition.go | 2 +- go/catalogue/state_test.go | 6 ++++++ go/catalogue/verbs.go | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/go/catalogue/seat_from_definition.go b/go/catalogue/seat_from_definition.go index 7882915b..c0c5c544 100644 --- a/go/catalogue/seat_from_definition.go +++ b/go/catalogue/seat_from_definition.go @@ -23,7 +23,7 @@ func SeatFromDefinition(d seatdef.Definition) Seat { for _, v := range d.Verbs { s.Serves = append(s.Serves, Verb{Name: v.Name, Description: v.Description, Input: seatdef.ResolveRefs(v.Input, d.Defs), Output: seatdef.ResolveRefs(v.Answer, d.Defs), - Optional: v.Optional, Replaces: v.Replaces}) + Optional: v.Optional, Replaces: v.Replaces, NeedsApproval: v.NeedsApproval}) } for _, st := range d.States { s.States = append(s.States, st.Name) diff --git a/go/catalogue/state_test.go b/go/catalogue/state_test.go index 8e912168..8532ef3a 100644 --- a/go/catalogue/state_test.go +++ b/go/catalogue/state_test.go @@ -109,4 +109,10 @@ func TestSeatRead(t *testing.T) { len(s.AcceptedOn) != 1 || s.AcceptedOn[0] != "check.step" { t.Errorf("the seat's states = %v, views = %v, accepted on = %v", s.States, s.Views, s.AcceptedOn) } + // A-177 (design 46 approval mark §2, §4): a compiled verb carries its definition's approval mark. + marked := SeatFromDefinition(seatdef.Definition{Seat: "node-login-shell", + Verbs: []seatdef.Verb{{Name: "execute", NeedsApproval: true}, {Name: "read"}}}) + if len(marked.Serves) != 2 || !marked.Serves[0].NeedsApproval || marked.Serves[1].NeedsApproval { + t.Errorf("the compiled verbs' marks = %+v", marked.Serves) + } } diff --git a/go/catalogue/verbs.go b/go/catalogue/verbs.go index 550020e1..bd921dd9 100644 --- a/go/catalogue/verbs.go +++ b/go/catalogue/verbs.go @@ -37,6 +37,11 @@ type Verb struct { // A command line is matched by its words in order, the first being the command's name; `edit // /etc/hosts` and `HOSTALIASES` name the guard's two local work-arounds for a mesh name. Replaces []string `json:"replaces,omitempty"` + // NeedsApproval is the verb's approval mark as its seat's definition gives it (seatdef.Verb.NeedsApproval): the + // operator approves a call of it first, for every holder (design 46 *The approval mark* §2, §4; lead answer A-177), + // read from here by the manifest validator and every reader of the seat list. Never read from a manifest's own + // verb (a module marks in its needs-approval) nor said: compiled from the definition alone, as Optional. + NeedsApproval bool `json:"-"` } func (v *Verb) UnmarshalJSON(raw []byte) error {