From ee302090403214edd3978b479f4dbb628b5917a8 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 23:05:15 +0100 Subject: [PATCH] =?UTF-8?q?=C2=A7706=20(grants=20part's=20unit=20case):=20?= =?UTF-8?q?the=20assigner=20is=20granted=20the=20conditions=20it=20reads?= =?UTF-8?q?=20and=20nothing=20of=20the=20watchman's=20findings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A module that invokes the seat mesh-conditions' verb conditions and consumes condition-raised, condition-changed and condition-cleared is composed exactly those subjects, and no read of another module's findings. Builds: design 47 G §706 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- modules/mesh-grants/conditions_test.go | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 modules/mesh-grants/conditions_test.go diff --git a/modules/mesh-grants/conditions_test.go b/modules/mesh-grants/conditions_test.go new file mode 100644 index 00000000..c1ea97f7 --- /dev/null +++ b/modules/mesh-grants/conditions_test.go @@ -0,0 +1,46 @@ +package manifest + +import ( + "slices" + "strings" + "testing" + + "mesh-grants/internal/grants" +) + +// TestTheAssignerIsGrantedTheConditionsItReadsAndNothingOfTheWatchmansFindings is design 47 G §706's grants case: a module that invokes the +// seat mesh-conditions' verb conditions and consumes its events condition-raised, condition-changed and condition-cleared is granted +// exactly those (the verb's tool subjects, the three events' seat subjects), and no read of another module's findings (the watchman's). +func TestTheAssignerIsGrantedTheConditionsItReadsAndNothingOfTheWatchmansFindings(t *testing.T) { + b := fixture() + b.manifestOf("mod-assigner", `{"module":"mod-assigner","version":"1","own-secrets":{"broker":"/var/lib/a/broker"},`+ + `"consumes":["mesh-conditions.condition-raised","mesh-conditions.condition-changed","mesh-conditions.condition-cleared"],`+ + `"invokes":["seat:mesh-conditions.conditions"]}`) + b.assign("a", "mod-assigner") + var user grants.User + for _, u := range shadowOf(t, b) { + if u.User == "a.mod-assigner" { + user = u + } + } + if user.User == "" { + t.Fatal("no user a.mod-assigner is composed") + } + for _, e := range []string{"condition-raised", "condition-changed", "condition-cleared"} { + if !slices.Contains(user.Subscribe, "mesh.seat.mesh-conditions.event."+e) { + t.Errorf("the module is not granted to hear mesh-conditions' %s: %v", e, user.Subscribe) + } + } + if !slices.Contains(user.Publish, "mesh.seat.mesh-conditions.tool.conditions") { + t.Errorf("the module is not granted to call mesh-conditions' conditions: %v", user.Publish) + } + for _, s := range append(slices.Clone(user.Publish), user.Subscribe...) { + if strings.Contains(s, "watchman") && strings.Contains(s, "findings") || strings.Contains(s, "mesh-conditions.event.finding") { + t.Errorf("the module is granted a read of findings it does not read: %s", s) + } + if strings.HasPrefix(s, "mesh.seat.mesh-conditions.event.") && !strings.HasSuffix(s, "condition-raised") && !strings.HasSuffix(s, "condition-changed") && + !strings.HasSuffix(s, "condition-cleared") { + t.Errorf("the module is granted an event of mesh-conditions it does not consume: %s", s) + } + } +}