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)
mesh/delivery-group group feat/r3e-the-gate checking: 2 of 3 member(s) ready
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate waits for its group's composed check
mesh/repo-check head 1f193f6d01d2 merged into trunk a3a9b8749d12 beside mesh-tools#37@06e6721e — fail: its merge-check.sh failed: --- FAIL: TestTheGateCarr…

This commit is contained in:
2026-10-20 06:43:17 +00:00
parent 41f18b2452
commit 1f193f6d01
2 changed files with 40 additions and 19 deletions
+6 -4
View File
@@ -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`).
@@ -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.<verb>`) 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.<verb>`)
// 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)