Judge only the verbs of a mesh seat a module invokes, not its holder (issue 774)

The seat-invoke rule refused mesh-config, mesh-healers and messenger calling the controller's verbs, and
mesh-self-check calling the watchman's seat, over a catalogue that holds no manifest of their holders: the
controller answers its seat itself, and the watchman lives in mesh-delivery. mesh-control's
TestModuleCheckPassesTheCatalogue (the captured mesh-catalog) failed on it. A mesh seat is held by the mesh or by a
module of any repository, so one repository's catalogue cannot say it has no holder: for a mesh seat only the verb
is judged; a seat a module declares is still judged for a claimant. Over the captured catalogue, the live
mesh-catalog alone, and mesh-catalog, mesh-control, mesh-delivery and mesh-host together: no refusal.
This commit is contained in:
2026-10-30 18:25:59 +01:00
parent 61b67d61e2
commit 942f906222
2 changed files with 12 additions and 4 deletions
+6 -2
View File
@@ -29,7 +29,8 @@ func SeatInvoke(invoke string) (seat, verb string, ok bool) {
// seatInvokeProblems are the `seat:<seat>.<verb>` a module or one of its processes invokes that nothing answers: a seat
// no module declares and the mesh does not define, a verb the seat does not promise, or a seat with no holder (a
// mesh seat no module claims, unless its node's engine holds it, ADR 0563 §1).
// seat a module declares and no module claims; a mesh seat's holder, the mesh itself or a module of any repository,
// is not judged).
func seatInvokeProblems(shelf Shelf, declared map[string]SeatDeclaration) []string {
claimed := map[string]bool{}
for _, m := range shelf {
@@ -51,7 +52,10 @@ func seatInvokeProblems(shelf Shelf, declared map[string]SeatDeclaration) []stri
var verbs []Verb
held := claimed[seat]
if s, isMesh := SeatNamed(seat); isMesh {
verbs, held = s.Serves, held || claimed[s.Name] || s.HeldByTheEngine
// A mesh seat is held by the mesh itself or by a module of any repository: one repository's catalogue
// cannot say it has no holder, so only its verbs are judged (the lead, 2026-10-30: mesh-control's check
// runs over the captured mesh-catalog alone, whose mesh-self-check calls the watchman's seat).
verbs, held = s.Serves, true
} else if d, isModule := declared[seat]; isModule {
verbs = d.Serves
} else {
+6 -2
View File
@@ -71,8 +71,12 @@ func TestUsingASeatNobodyDeclaresIsRefused(t *testing.T) {
Manifest{Module: "shop", Invokes: []string{"seat:telegram-sendr.status"}}, telegram(), true},
{"a verb of a declared seat nobody claims", `a verb of the seat "telegram-sender", ` + UnheldSeat,
Manifest{Module: "shop", Invokes: []string{"seat:telegram-sender.status"}}, unclaimed, true},
{"a verb of a mesh seat nobody claims", `a verb of the seat "mesh-controller", ` + UnheldSeat,
Manifest{Module: "shop", Invokes: []string{"seat:mesh-controller.root-free"}}, telegram(), true},
{"a verb of a mesh seat whose holder lives in another repository", "",
Manifest{Module: "shop", Invokes: []string{"seat:mesh-watchdogs.signals"}}, telegram(), false},
{"a verb a mesh seat does not promise", `the seat mesh-controller serves no verb "root-freed"`,
Manifest{Module: "shop", Invokes: []string{"seat:mesh-controller.root-freed"}}, telegram(), false},
{"the controller's verb: the controller answers its seat", "",
Manifest{Module: "shop", Invokes: []string{"seat:mesh-controller.root-free"}}, telegram(), false},
{"the engine's verb: every node's engine holds its seat", "",
Manifest{Module: "shop", Invokes: []string{"seat:node-engine.root-free"}}, telegram(), false},
{"a verb the engine's seat does not promise", `the seat node-engine serves no verb "root-freed"`,