From 3543e7818bc05a342c7d6445a3e3b5302e084af3 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 13 Nov 2026 11:42:54 +0100 Subject: [PATCH] D5 judge-process-bus-consumes: a process hears only what its module consumes A process's `bus.consumes` (read by mesh-sdk since S2) is judged as V5 judges what a process names of its module's `requires`: an event its module consumes is accepted, another is refused, naming it. Builds: design 47 G A-340, A-343 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- modules/mesh-delivery-indexer/judge/rules.go | 8 ++++++++ modules/mesh-delivery-indexer/judge/rules_test.go | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index e0afd1d2..05fa7edc 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -4034,6 +4034,14 @@ func ProcessBusProblems(m catalogue.Manifest) []string { m.Module, id, e, m.Module)) } } + // Design 47 G A-340: a process hears only what its module consumes, as V5 lets it name only what its module asks for. + for _, e := range b.Consumes { + if !slices.Contains(m.Consumes, e) { + problems = append(problems, fmt.Sprintf( + "%s's process %s's bus consumes %q, which %s does not consume (design 47 G A-340)", + m.Module, id, e, m.Module)) + } + } for _, q := range b.Queues { if !streams[q] { problems = append(problems, fmt.Sprintf( diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index b7497f0a..fb8bec60 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -2459,7 +2459,7 @@ func caseAProcessBusNamesOnlyTheModulesOwn(t *testing.T) { // its events stream and a state of its key-value state, and a name it does not ask for there is refused as before. asked := func(bus string) string { raw := mailSenderProcessManifest(t, bus) - return strings.Replace(raw, `"resources"`, `"requires":[{"name":"mail-events","storage":"stream","template":"events",`+ + return strings.Replace(raw, `"resources"`, `"consumes":["mesh-conditions.findings-asked"],"requires":[{"name":"mail-events","storage":"stream","template":"events",`+ `"options":{"events":["mail.send.queued"]}},{"name":"mail-kept","storage":"key-value","template":"state"}],"resources"`, 1) } for name, c := range map[string]struct{ bus, says string }{ @@ -2467,6 +2467,9 @@ func caseAProcessBusNamesOnlyTheModulesOwn(t *testing.T) { "a state asked for by template": {`{"state":["mail-kept"]}`, ""}, "an event the events stream does not hold": {`{"emits":["mail.send.lost"]}`, "mail.send.lost"}, "a state the module does not ask for": {`{"state":["mail-other"]}`, "mail-other"}, + // Design 47 G A-340: a process's bus may name, under consumes, an event its module consumes, judged as V5 judges. + "an event the module consumes": {`{"consumes":["mesh-conditions.findings-asked"]}`, ""}, + "an event the module does not consume": {`{"consumes":["mesh-conditions.other"]}`, `consumes "mesh-conditions.other"`}, } { _, err := ParseManifest([]byte(asked(c.bus))) if (c.says == "") != (err == nil) || (err != nil && !strings.Contains(err.Error(), c.says)) {