package broker import ( "slices" "sort" "strings" ) // What the mesh issues an assignment to serve and to reach (novox/hq ADR 0160). // // A module's code names its tools and its events; **where they land is the mesh's to decide**, and // it decided it twice — once in the runtime, once here, by one rule compiled into both. Now the // controller composes a membership for every module on every machine and publishes it to a subject // only that assignment reads; the runtime serves exactly what the membership says, and the account's // grant is the same composition read the other way. The shape issued today is the shape the mesh // already had, so nothing moves when a membership first arrives; only who decides it moves. // Placements is where every module runs, for deciding which instance answers for the module. type Placements struct { // Nodes is each module's machines. Nodes map[string][]string // Interchangeable is each module whose definition says its instances are the same anywhere, // so the module's plain subject is issued to all of them in one queue. Interchangeable map[string]bool // Kinds is every kind held of a kinded bench, by whom and with what capabilities (ADR 0259 §5). Kinds []KindHeld } // AnswersForTheModule says whether an instance of a module on one machine is issued the module's // plain subject: when it is the only instance, or when the definition says instances are // interchangeable. A stateful module on two machines gets only its machines' subjects, so a call // that names none reaches nothing rather than the wrong store. func (p Placements) AnswersForTheModule(module string) bool { return len(p.Nodes[module]) <= 1 || p.Interchangeable[module] } // MembershipFor composes one assignment's membership from what it declared and where everything // runs. The subjects are the ones PermissionsFor grants, derived here once more only until the // grant itself is read from the membership — which is the next step, not this one. func MembershipFor(node string, d Declared, where Placements) Membership { own := "mesh.mod." + d.Module m := Membership{ Node: node, Module: d.Module, Emits: own + ".event.{event}", Tools: own + ".tool.tools", } // This machine's address always; the module's when this instance answers for the module. m.Serves = append(m.Serves, Served{Subject: own + ".tool.{tool}." + node}) if where.AnswersForTheModule(d.Module) { m.Serves = append(m.Serves, Served{Subject: own + ".tool.{tool}", Queue: "serve." + d.Module}) } for _, s := range d.Holds { if servedOnlyByTheController(s) { continue // answered by the serving controller alone, never through a membership } for _, verb := range s.Serves { m.Seats = append(m.Seats, SeatServed{Seat: s.Name, Verb: verb, Subject: seatToolSubject(s, verb, node)}) } } m.State = stateIssuedFor(d, node) m.Logs = logsIssuedFor(d) m.Streams = streamsIssuedFor(d) m.Hears = HeardIssuedFor(node, d) m.Waits = waitsIssuedFor(d) t := SeatTrafficOf(d.Module, d.Holds, d.Uses, d.Watches) for _, s := range append(append([]Seat{}, d.Uses...), d.Watches...) { if !s.Kinded { continue } for _, k := range where.Kinds { if k.Seat == s.Name && !kindListed(t.Kinds, k) { t.Kinds = append(t.Kinds, k) } } } if len(t.Publish)+len(t.Subscribe)+len(t.Answers)+len(t.Workers)+len(t.Records)+len(t.Kinds) > 0 { m.SeatTraffic = &t } if len(d.Invokes) > 0 { m.Reaches = map[string][]string{} for _, t := range d.Invokes { if t == "*" || strings.HasPrefix(t, "seat:") { continue // every tool, or a role's: addressed by name, not resolved per instance } module, tool, ok := strings.Cut(t, ".") if !ok { continue } var reach []string if where.AnswersForTheModule(module) { reach = append(reach, "mesh.mod."+module+".tool."+tool) } nodes := append([]string{}, where.Nodes[module]...) sort.Strings(nodes) for _, n := range nodes { reach = append(reach, "mesh.mod."+module+".tool."+tool+"."+n) } m.Reaches[t] = reach } } return m } // PlacementsOf reads where everything runs from the records the bus's accounts are composed from. func PlacementsOf(r Records, interchangeable map[string]bool) Placements { p := Placements{Nodes: map[string][]string{}, Interchangeable: interchangeable} for node, declared := range r.Assigned { for _, d := range declared { p.Nodes[d.Module] = append(p.Nodes[d.Module], node) } } for _, nodes := range p.Nodes { sort.Strings(nodes) } // Where the router runs: a verified sender is believed only while its machine is root-free too. A router // placed nowhere, or on more than one machine, frees nothing. var routerNodes []string for node, declared := range r.Assigned { for _, d := range declared { for _, s := range d.Holds { if s.Name == routerSeat && !slices.Contains(routerNodes, node) { routerNodes = append(routerNodes, node) } } } } routerFree := len(routerNodes) == 1 && r.RootFree[routerNodes[0]] for node, declared := range r.Assigned { for _, d := range declared { for _, s := range d.Holds { if s.Kinded && s.Kind != "" { p.Kinds = append(p.Kinds, KindHeld{Seat: s.Name, Kind: s.Kind, Module: d.Module, Node: node, Capabilities: placedCapabilities(s.Capabilities, d.RunsAs, routerFree && r.RootFree[node])}) } } } } sort.Slice(p.Kinds, func(i, j int) bool { a, b := p.Kinds[i], p.Kinds[j] if a.Seat != b.Seat { return a.Seat < b.Seat } if a.Kind != b.Kind { return a.Kind < b.Kind } return a.Node < b.Node }) return p } // routerSeat is the seat the router of asks holds (novox/hq ADR 0259 §3). const routerSeat = "operator-channel" // placedCapabilities is what a kind's claim promises, as far as its placement lets the router believe it // (novox/hq ADR 0259 §8): `verified-sender` only from a holder that runs as an account of its own, on a bus // account of its own — never one the machine's runtime carries as the operator's account — and only while // its machine and the router's were root-free when composed (rootFree; the review of 2026-10-09, H3). The // membership carrying it is composed at a push, so it can outlive a pass that later fails: the router asks // the controller's root-free verb again before it honours an approval, and that is the check that holds. func placedCapabilities(declared []string, runsAs string, rootFree bool) []string { var out []string for _, c := range declared { if c == "verified-sender" && (runsAs == "" || !rootFree) { continue } out = append(out, c) } return out } func kindListed(list []KindHeld, k KindHeld) bool { for _, x := range list { if x.Seat == k.Seat && x.Kind == k.Kind && x.Module == k.Module && x.Node == k.Node { return true } } return false }