Compose no placed user from the node-engine's manifest in the controller's bus composer too, as mesh-sdk #136 does (issue 774)
mesh-sdk #136 (42988a7) keeps the node-engine's manifest out of every placed user in buscompose: where a placement names it, no user, no process and nothing the tool runner carries; the node's account alone writes the engine's state, and a second writer has the writers table refuse the whole list (met twice on 2026-10-30: mesh-host_acts, then mesh-host_health). The controller still composes the bus's users with its own copy (internal/broker Users), which lacked the guard. The same two predicates, Composed and CarriedByRunner, now guard it. Read on the bus at 18:30: the bus follows the grants part's list (mesh-grants_user-list.sealed), so the controller's copy is not what the bus loads; it still composes the bus module's files and the controller's own grants, where a refusal would stop that composition. Quick fix: the same guard here. Thorough fix: delete the controller's copy of the bus composer and use buscompose (about 18,000 lines of internal/broker with its tests, its genesis list and its golden file). Chose quick: the controller is being deprecated and the grants part already holds the list; the copy goes with the controller's composition of the bus module, not in a sweep. Research 072 piece: 03-domains, mesh-grants (membership and grants leave the controller): until the copy is removed, it composes as the SDK does.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package broker
|
||||
|
||||
import "testing"
|
||||
|
||||
// Sweep 2026-10-30 (issue 774), the guard of mesh-sdk #136 in the controller's copy: where a placement names the
|
||||
// node-engine's manifest, it adds no user, no process and nothing the tool runner carries; a module beside it does.
|
||||
func TestTheNodeEnginesManifestComposesNoPlacedUser(t *testing.T) {
|
||||
engine := Declared{Module: EngineModule, Serves: []string{"health"}, State: []Bucket{{Name: "health"}},
|
||||
Processes: []ProcessPrincipal{{Process: "apply"}}}
|
||||
beside := Declared{Module: "power", Serves: []string{"power_draw"}}
|
||||
for name, c := range map[string]struct {
|
||||
assigned []Declared
|
||||
module bool
|
||||
}{
|
||||
"with the runner": {[]Declared{{Module: RuntimeModule, NoAccount: true}, engine, beside}, false},
|
||||
"without the runner": {[]Declared{engine, beside}, true},
|
||||
} {
|
||||
users, err := Users(Records{Nodes: []string{"anchor"}, Assigned: map[string][]Declared{"anchor": c.assigned}})
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", name, err)
|
||||
}
|
||||
besideSeen := false
|
||||
for _, u := range users {
|
||||
if u.Module == EngineModule && (u.Kind == KindModule || u.Kind == KindProcess) {
|
||||
t.Errorf("%s: the node-engine's manifest composed a %v user", name, u.Kind)
|
||||
}
|
||||
besideSeen = besideSeen || u.Module == beside.Module
|
||||
for _, carried := range u.Carries {
|
||||
if carried.Module == EngineModule {
|
||||
t.Errorf("%s: the tool runner carries the node-engine's manifest", name)
|
||||
}
|
||||
besideSeen = besideSeen || carried.Module == beside.Module
|
||||
}
|
||||
}
|
||||
if !besideSeen {
|
||||
t.Errorf("%s: the module beside it is composed nowhere", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,11 @@ func Users(r Records) ([]Principal, error) {
|
||||
}
|
||||
}
|
||||
for _, d := range r.Assigned[node] {
|
||||
// **The node-engine's manifest is no placed module's** (novox/hq ADR 0563 §2, §3; sweep 2026-10-30, issue
|
||||
// 774): the guard mesh-sdk #136 put in buscompose, kept here while the controller composes with its own copy.
|
||||
if !Composed(d) {
|
||||
continue
|
||||
}
|
||||
// **A process account is its own, delivered in its own secret** (broker-<process id>, novox/hq
|
||||
// ADR 0436 §1, §2), never the module's `broker` — so it is composed whether or not the module
|
||||
// itself has an account, and is never carried by the machine's runtime, which runs as the
|
||||
@@ -227,7 +232,7 @@ func Users(r Records) ([]Principal, error) {
|
||||
if runtimeHere {
|
||||
var carried []Declared
|
||||
for _, d := range r.Assigned[node] {
|
||||
if d.RunsAs == "" && runnerServes(d) {
|
||||
if CarriedByRunner(d) {
|
||||
// Never a restricted stream for what the tool runner carries (novox/hq ADR 0376 §1).
|
||||
d.Hears = ComposedHears(d)
|
||||
carried = append(carried, d)
|
||||
@@ -454,3 +459,15 @@ func declaredStreamsOf(r Records) []string {
|
||||
sort.Strings(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// EngineModule is the node-engine's manifest's module name (mesh-sdk buscompose.EngineModule).
|
||||
const EngineModule = "mesh-host"
|
||||
|
||||
// Composed says a placed module is composed as one: its own user, its processes and what the runner carries of it. The
|
||||
// node-engine's manifest is not, though a placement may name it: each node's engine speaks as the node's account, which
|
||||
// alone writes the engine's state (ADR 0563 §2, §3); granted to another account it is a second writer, and the writers
|
||||
// table refuses the whole list (issue 774: mesh-host_acts, then mesh-host_health, 2026-10-30). mesh-sdk buscompose.Composed.
|
||||
func Composed(d Declared) bool { return d.Module != EngineModule }
|
||||
|
||||
// CarriedByRunner says the machine's tool runner carries this placed module (mesh-sdk buscompose.CarriedByRunner).
|
||||
func CarriedByRunner(d Declared) bool { return Composed(d) && d.RunsAs == "" && runnerServes(d) }
|
||||
|
||||
Reference in New Issue
Block a user