From e20eb05a9b1416078cce5657e1b3c4eaff3d7b7b Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 13:08:15 +0100 Subject: [PATCH] =?UTF-8?q?DLV-J4:=20the=20judge=20refuses=20keeps=20on=20?= =?UTF-8?q?a=20tools=20bundle's=20bus,=20the=20bus=20module's=20included?= =?UTF-8?q?=20(ADR=200626=20=C2=A71,=20=C2=A73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- modules/mesh-delivery-indexer/judge/rules.go | 9 +++++++-- modules/mesh-delivery-indexer/judge/rules_test.go | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index 46931311..6db28dad 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -3984,8 +3984,8 @@ func processAccountProblems(m catalogue.Manifest, processID, user string) []stri } // busKeeps says the process resource r's bus declares `keeps` (novox/hq ADR 0626 §1): read from the resource as -// written, since catalogue.ProcessBus does not carry the key yet (a request to mesh-sdk). Any value but false or absent -// counts, so a refusal is never dodged by its spelling. +// written rather than through catalogue.ProcessBus, so any value but false or absent counts and a refusal is never dodged +// by its spelling. func busKeeps(r map[string]any) bool { b, _ := r["bus"].(map[string]any) v, present := b["keeps"] @@ -4050,6 +4050,11 @@ func toolsBusProblems(m catalogue.Manifest) []string { continue } b := *a.Bus + if b.Keeps { + problems = append(problems, fmt.Sprintf("%s's tools bundle %s's bus keeps the bus's entries; only the keeper, the "+ + "process of the module holding %s with its own bus account, may (novox/hq ADR 0626 §1, §3)", m.Module, a.Name, + catalogue.BrokerSeat)) + } if len(b.Queues) > 0 || b.Asks { problems = append(problems, fmt.Sprintf("%s's tools bundle %s's bus consumes a queue or reads asks; a tools "+ "bundle runs per call and holds no consumer (novox/hq ADR 0564 Limits 4)", m.Module, a.Name)) diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index c18ab3bf..3368d42f 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -2484,6 +2484,8 @@ func TestAProcessDeclaresItsBusAndIsAccepted(t *testing.T) { {name: "a removal outside the set", manifest: tools(broker, `{"removes":["EVENTS.a_m"]}`), refused: "not one of"}, {name: "a removal beside a grant", manifest: tools(broker, `{"removes":["mesh-host_acts"],"invokes":["nats.nats_streams"]}`), refused: "with nothing else"}, {name: "another module's tools removing", manifest: tools(`[]`, `{"removes":["mesh-host_acts"]}`), refused: "only the bus module"}, + // ADR 0626 §1, §3: only the keeper process keeps the bus's entries, never a tools bundle, the bus module's included. + {name: "the bus module's tools keeping", manifest: tools(broker, `{"keeps":true}`), refused: "only the keeper"}, {name: "a tools bundle consuming a queue", manifest: tools(broker, `{"queues":["x"]}`), refused: "holds no consumer"}, {name: "a process removing", manifest: mailSenderProcessManifest(t, `{"removes":["mesh-host_acts"]}`), refused: "only a tools bundle"}, // The runtime's account reads the account's secret: it lies where others may pass (the host agent, 2026-10-29).