2536 reads of mesh-controller.lease were refused on 2026-10-30 (mesh-vault, mesh-grants, the assigner, artifact-store-tools, the watchman, mesh-config). The controller composed the bus's users with its own copy of a reader-less judgement (internal/broker ReadsAnnounced), which knows no named readers: the lease is announced readable by nobody and read by the parts named for it (ADR 0547 clause 9, ADR 0561 §3). The copy is deleted; BusRecords judges each read for its module with buscompose.ReadsAnnouncedBy. Each refusal was also printed on every composition, about 420 times a read; it is now said once per process. mesh-config's read of the lease stays refused: it reads the lease for its take-over (hand-back ends at the lease write, ADR 0561 §3) and is not among the named readers. That is mesh-sdk's NamedReaders, routed to the lead. Quick fix: mark the lease readable in the controller's announcement (tried and reverted: it would open the lease to every module and contradict ADR 0561 §3). Thorough fix: one judgement, the SDK's, for every composer. Chose thorough. Research 072 piece: 03-domains, mesh-grants (bus membership and grants leave the controller): the controller composes reads with the same SDK function the grants part uses.
76 lines
2.7 KiB
Go
76 lines
2.7 KiB
Go
package broker
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
|
)
|
|
|
|
// D1 (ADR 0495 clause 2): the controller announces every bucket of its own, and readable exactly the record mirrors (the
|
|
// declared packages the pacman module reads among them, ADR 0507 §5), the chain's buckets, the checks running and the
|
|
// plans building.
|
|
func TestTheControllerAnnouncesWhatItKeeps(t *testing.T) {
|
|
s := ControllerAnnouncement("novox")
|
|
if _, err := announce.Encode(s); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var readable []string
|
|
for _, k := range s.States {
|
|
if k.Readable {
|
|
readable = append(readable, k.Name)
|
|
}
|
|
}
|
|
want := []string{ChainBuilds, MirrorDeclaredConfig, MirrorPredefined, ChainRollouts,
|
|
MirrorAssignments, MirrorDeclaredPackages, ControllerGrants, ControllerComposed}
|
|
slices.Sort(want)
|
|
if !slices.Equal(readable, want) {
|
|
t.Fatalf("readable %v, want %v", readable, want)
|
|
}
|
|
for _, name := range []string{"lease", "calls", "states-announced"} {
|
|
if !s.Keeps(name) || s.Readable(name) {
|
|
t.Errorf("%s: kept %v, readable %v", name, s.Keeps(name), s.Readable(name))
|
|
}
|
|
}
|
|
// The buckets of plan state release 6 deleted are no longer kept (ADR 0539 clause 13).
|
|
for _, name := range []string{"merge-window", "rollout-silent", "plans-building"} {
|
|
if s.Keeps(name) {
|
|
t.Errorf("%s is still kept", name)
|
|
}
|
|
}
|
|
perms, err := PermissionsFor(Principal{Kind: KindController})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(perms.Publish, announce.Subject(ControllerSeat)) {
|
|
t.Fatal("the controller may not say what it keeps")
|
|
}
|
|
}
|
|
|
|
// D2: every account that keeps state may say so on its own subject, a process account included, and no other's.
|
|
func TestAnAccountKeepingStateMaySayWhatItKeeps(t *testing.T) {
|
|
keeper, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "keeper", PasswordHash: "x",
|
|
State: []string{"things"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(keeper.Publish, announce.Subject("keeper")) || slices.Contains(keeper.Publish, announce.Subject("other")) {
|
|
t.Fatalf("the keeper's announcement grants: %v", keeper.Publish)
|
|
}
|
|
process, err := PermissionsFor(Principal{Kind: KindProcess, Node: "one", Module: "keeper", Process: "send",
|
|
PasswordHash: "x", State: []string{"sends"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(process.Publish, announce.Subject("keeper")) {
|
|
t.Fatal("a process keeping state may not say what it keeps")
|
|
}
|
|
none, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "stateless", PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if slices.Contains(none.Publish, announce.Subject("stateless")) {
|
|
t.Fatal("a module keeping nothing may say it keeps something")
|
|
}
|
|
}
|