From fbd00c89436c53a36fd67cb8bb7dbaddf0ee7579 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 29 Oct 2026 22:10:44 +0100 Subject: [PATCH] Refuse a manifest that lists its claimed seat's event among its own emits, so a holder never says a seat event where no consumer hears it (issue 1952, second of a kind) --- go/catalogue/delivery_seat.go | 25 +++++++++++++++++++++++++ go/catalogue/manifest.go | 1 + go/catalogue/seats_test.go | 12 ++++++++++++ 3 files changed, 38 insertions(+) diff --git a/go/catalogue/delivery_seat.go b/go/catalogue/delivery_seat.go index f1d2d24..5cab2ce 100644 --- a/go/catalogue/delivery_seat.go +++ b/go/catalogue/delivery_seat.go @@ -1,5 +1,7 @@ package catalogue +import "fmt" + // The delivery's owner (novox/hq ADR 0239, to-be 47): one holder for the mesh, the module mesh-delivery, // which owns a delivery — one commit in one repository, from its pull request's head to every machine — // and a delivery group, and asks the controller for every act. A seat of the mesh's own, so the role has @@ -105,6 +107,29 @@ func SeatSays(emits []string, event string) bool { return false } +// seatEventProblems refuses a module that lists among its own `emits` an event a seat it claims says (the lead, +// 2026-10-29, issue 1952, the second of a kind: the self-check's `checked` and mesh-hand-acts' `act-recorded`). A +// consumer of `.` hears the seat's subject (SeatSays), so the holder says it there, with stdio.SeatPublish +// on `mesh.seat..event.`; said through stdio.Emit as the module's own, it lands where nobody listens. Caught +// here, when the manifest is read at the build, not when nothing is heard on the machines. +func seatEventProblems(m Manifest) []string { + var problems []string + for _, c := range m.Claims { + seat, known := SeatNamed(c.Name) + if !known || len(seat.Emits) == 0 { + continue + } + for _, e := range m.Emits { + if SeatSays(seat.Emits, e) { + problems = append(problems, fmt.Sprintf("%s lists %q among its own emits, and the seat %s it claims says it: "+ + "say it on the seat with stdio.SeatPublish(\"mesh.seat.%s.event.%s\", ...) and leave it out of emits, or "+ + "no consumer of %s.%s hears it", m.Module, e, seat.Name, seat.Name, e, seat.Name, e)) + } + } + } + return problems +} + // topicMatches is whether an event's name matches a declared pattern, `*` one dot-separated segment and // `>` or `**` the rest. func topicMatches(pattern, event string) bool { diff --git a/go/catalogue/manifest.go b/go/catalogue/manifest.go index ca3eba9..1423d11 100644 --- a/go/catalogue/manifest.go +++ b/go/catalogue/manifest.go @@ -2093,6 +2093,7 @@ func parseManifest(raw []byte, predefined PredefinedList) (Manifest, error) { problems = append(problems, declaredSeatProblems(m)...) problems = append(problems, RunsAsProblems(m)...) problems = append(problems, ProcessBusProblems(m)...) + problems = append(problems, seatEventProblems(m)...) problems = append(problems, ReadsHolderProblems(m)...) problems = append(problems, FilesHolderProblems(m)...) if m.Computed != "" && len(m.Resources) > 0 { diff --git a/go/catalogue/seats_test.go b/go/catalogue/seats_test.go index 168056e..0226c15 100644 --- a/go/catalogue/seats_test.go +++ b/go/catalogue/seats_test.go @@ -184,6 +184,18 @@ func TestAClaimOnASeatAnotherModuleDeclaresIsAccepted(t *testing.T) { if problems := CatalogueProblems(Shelf{claimant.Module: claimant, "someone": declarer}); len(problems) != 0 { t.Fatalf("a claim on a declared seat was refused: %v", problems) } + // The second of a kind (issue 1952; the lead, 2026-10-29): a holder that lists its seat's event among its own emits + // would say it where no consumer hears it, so the manifest is refused, naming the seat's subject; the seat's + // holder saying nothing of its own is accepted. + holder := func(emits string) []byte { + return []byte(`{"module":"mesh-self-check","version":"1","emits":` + emits + `,"claims":[{"name":"mesh-self-check","scope":"mesh","serves":["doctor","probes"]}]}`) + } + if _, err := ParseManifest(holder(`["checked"]`)); err == nil || !strings.Contains(err.Error(), "mesh.seat.mesh-self-check.event.checked") { + t.Errorf("a seat's event listed as the module's own: %v", err) + } + if _, err := ParseManifest(holder(`[]`)); err != nil { + t.Errorf("a holder saying its seat's event on the seat was refused: %v", err) + } } // A module may define its own seat and claim it — the mesh enforces exclusivity without knowing