From 1f193f6d01d2589852a843fe4b138e82e99b0d63 Mon Sep 17 00:00:00 2001 From: mesh-tools Date: Tue, 20 Oct 2026 06:43:17 +0000 Subject: [PATCH] Let the catalogue hold the gate and today's module as the two claimants of the seat, and say the removal follows the handover (issue 1351) --- modules/mesh-delivery-gate/README.md | 10 ++-- .../cmd/mesh-delivery-gate/catalogue_test.go | 49 +++++++++++++------ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/modules/mesh-delivery-gate/README.md b/modules/mesh-delivery-gate/README.md index 0da8df86..23bcd87a 100644 --- a/modules/mesh-delivery-gate/README.md +++ b/modules/mesh-delivery-gate/README.md @@ -22,9 +22,9 @@ ends as covered or delivered when a later merge covers it. ## Taking the seat over from today's module -The gate claims the seat `mesh-delivery` beside the module `mesh-delivery`, which the catalogue no longer holds. The controller -keeps a module that is assigned (it refuses to forget it), so the running module goes by a handover of verbs after the merge, -never by hand on a machine (novox/hq ADR 0449 §4, ADR 0450 §6): +The gate claims the seat `mesh-delivery` beside the module `mesh-delivery`, which the catalogue still holds, unchanged. The +controller refuses a merge that removes a module that is assigned, so today's module stays in the catalogue until it is +unassigned, and goes by a handover of verbs after the merge, never by hand on a machine (novox/hq ADR 0449 §4, ADR 0450 §6): 1. assign `mesh-delivery-gate` to the machine that holds the seat (`mesh-controller.assign`); 2. check that `mesh-controller.seats` still names `mesh-delivery`, held by the running module; @@ -36,5 +36,7 @@ never by hand on a machine (novox/hq ADR 0449 §4, ADR 0450 §6): Until then the gate is silent: it takes no event, writes no key, asks nothing and answers no verb but `delivery_status`, which says why (`holds-the-seat`, `seat-waits`). -The catalogue holds the names of the old module that the handover needs, and no others: the three buckets the gate carries +After the handover, the removal of `modules/mesh-delivery` follows as a pull request of its own, merged by the gate; the catalogue +then has one claimant of the seat. Until then the catalogue holds exactly these two, and the names of the old module that +the handover needs, and no others: the three buckets the gate carries over, and the event the issue tracker and the tool runner hear until the module is forgotten (`catalogue_test.go`). diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/catalogue_test.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/catalogue_test.go index af564adc..75dff68d 100644 --- a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/catalogue_test.go +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/catalogue_test.go @@ -9,41 +9,56 @@ import ( "testing" ) -// **Today's module is gone from the catalogue** (novox/hq ADR 0437 §1, issue 1351; how it is checked): no `modules/mesh-delivery` -// is held, no manifest declares the module `mesh-delivery`, and no manifest names the module in what it reads, hears or -// calls but through the seat's name (`mesh-delivery` as a seat or a repository, `seat:mesh-delivery.`) and through -// the names below, each of which stays until today's module is forgotten by the controller, because it is the only way to -// reach what that module left: the three buckets the gate carries over (ADR 0450 §6) and the event the trackers hear -// (issue 1350). Removing the module from the catalogue does not stop the running module: the controller keeps it until it is -// unassigned (mesh-controller upgrades.go retireDeleted), and the handover follows the merge by verbs. +// **The gate and today's module are the two claimants of the seat in the catalogue** (novox/hq ADR 0437 §1, ADR 0449 §4, issue +// 1351; how it is checked). R3e keeps `modules/mesh-delivery` unchanged: the controller refuses a merge that removes a module +// still assigned, and today's module is assigned until the handover, which follows the merge. Its removal is a pull request of +// its own after the handover, which makes the claimants exactly one. Until then exactly these two claim the seat `mesh-delivery` +// and no third does (the seat's pass counts only assigned claimants, mesh-controller internal/catalogue/seat_pass.go +// SeatsToPassOn, so the unassigned one does not block it). And no manifest but the gate's and mesh-issues' names today's module +// in what it reads or hears, but through the seat's name (`mesh-delivery` as a seat or a repository, `seat:mesh-delivery.`) +// and the names below, which stay until today's module is forgotten: the three buckets the gate carries over (ADR 0450 §6) and +// the event the trackers hear (issue 1350). Today's module itself is left out: it is unchanged. var oldModuleNames = map[string][]string{ "mesh-delivery-gate": {"mesh-delivery.deliveries", "mesh-delivery.groups", "mesh-delivery.pulls"}, "mesh-issues": {"mesh-delivery.transition"}, } -func TestTheCatalogueHoldsNoModuleMeshDeliveryButThroughTheNamesItsHandoverNeeds(t *testing.T) { +// seatClaimants are the modules that claim the seat: the gate, and today's module until its removal. +var seatClaimants = []string{"mesh-delivery", "mesh-delivery-gate"} + +func TestTheCatalogueHoldsTheGateAndTodaysModuleAsTheOnlyClaimantsOfTheSeat(t *testing.T) { modules := filepath.Join("..", "..", "..") - if _, err := os.Stat(filepath.Join(modules, "mesh-delivery")); err == nil { - t.Fatal("modules/mesh-delivery is still in the catalogue: its code is the gate's now") - } dirs, err := os.ReadDir(modules) if err != nil { t.Fatal(err) } read := 0 + var claimants []string for _, dir := range dirs { raw, err := os.ReadFile(filepath.Join(modules, dir.Name(), "module.json")) if err != nil { continue } read++ - var manifest any + var manifest struct { + Module string `json:"module"` + Claims []struct { + Name string `json:"name"` + } `json:"claims"` + } if err := json.Unmarshal(raw, &manifest); err != nil { t.Fatalf("%s: %v", dir.Name(), err) } - if m, _ := manifest.(map[string]any); m["module"] == "mesh-delivery" { - t.Errorf("%s declares the module mesh-delivery", dir.Name()) + for _, claim := range manifest.Claims { + if claim.Name == "mesh-delivery" { + claimants = append(claimants, manifest.Module) + } } + if dir.Name() == "mesh-delivery" { + continue // today's module, unchanged: it names itself + } + var generic any + _ = json.Unmarshal(raw, &generic) var walk func(v any) walk = func(v any) { switch x := v.(type) { @@ -61,7 +76,11 @@ func TestTheCatalogueHoldsNoModuleMeshDeliveryButThroughTheNamesItsHandoverNeeds } } } - walk(manifest) + walk(generic) + } + slices.Sort(claimants) + if !slices.Equal(claimants, seatClaimants) { + t.Errorf("the seat mesh-delivery is claimed by %v; wanted exactly %v (the removal of today's module makes it one)", claimants, seatClaimants) } if read < 20 { t.Fatalf("only %d manifests were read: the catalogue is not where the test looks", read)