From d15c1bc8147c7f97bc735513a1907515a1669460 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 13:20:35 +0100 Subject: [PATCH] =?UTF-8?q?ADR=200625=20=C2=A73,=20ADR=200627=20=C2=A74:?= =?UTF-8?q?=20mesh-sdk=20imports=20the=20seat=20set=20in=20catalogue=20alo?= =?UTF-8?q?ne,=20and=20names=20no=20client=20seat=20outside=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit buscompose, delivery's builder and step asks, handacts, health and provisions take their seat names from catalogue. The package-list test refuses any other contracts import, the client seats' names outside catalogue, and the moved packages (asks, asker, publish) by name; what the group's join still moves (asks, asker, the vault module's name in delivery and provisions) is listed and only shrinks. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- go/buscompose/users.go | 6 ++-- go/catalogue/artifacts.go | 23 +++++++++++-- go/delivery/builder.go | 5 ++- go/delivery/stepasks.go | 5 ++- go/handacts/handacts.go | 4 +-- go/health/findings.go | 6 ++-- go/packages_list_test.go | 68 ++++++++++++++++++++++++++++++++++++- go/provisions/provisions.go | 3 +- go/testdata/seat-names.txt | 11 +++--- 9 files changed, 106 insertions(+), 25 deletions(-) diff --git a/go/buscompose/users.go b/go/buscompose/users.go index 990da3f..af9e75b 100644 --- a/go/buscompose/users.go +++ b/go/buscompose/users.go @@ -1,6 +1,6 @@ package buscompose -import contractseats "git.novox.be/novox/mesh-contracts/go/seats" +import "git.novox.be/novox/mesh-sdk/go/catalogue" // Declared is one module on one node, as composing its authority needs it. type Declared struct { @@ -104,6 +104,4 @@ type ProcessPrincipal struct { } // VaultSeat is the vault's seat: its holder alone asks the desks and the issuing providers in its own name. -// -// Deprecated: a whole seat's name is mesh-contracts' (seats.MeshVault); kept until its importers take it from there. -const VaultSeat = contractseats.MeshVault +const VaultSeat = catalogue.VaultSeat diff --git a/go/catalogue/artifacts.go b/go/catalogue/artifacts.go index 2a4c7d5..f23ce6b 100644 --- a/go/catalogue/artifacts.go +++ b/go/catalogue/artifacts.go @@ -47,7 +47,7 @@ func isRegistryHost(component string) bool { // through container-image-registry or oci-artifact-registry, whose blob it names the way the older form did. func InArtifactStore(reference string) (path string, kept bool) { if seat, rest, ok := InRegistrySeat(reference); ok { - if seat == contractseats.OciArtifactRegistry { + if seat == OciArtifactRegistrySeat { name, digest, _ := strings.Cut(rest, "@") return name + "/blobs/" + digest, true } @@ -58,7 +58,26 @@ func InArtifactStore(reference string) (path string, kept bool) { // RegistrySeats are the seats a reference of the registry form names first, the two that front the artifact store // (novox/hq ADR 0605 §1, §9). -var RegistrySeats = []string{contractseats.ContainerImageRegistry, contractseats.OciArtifactRegistry} +var RegistrySeats = []string{ContainerImageRegistrySeat, OciArtifactRegistrySeat} + +// The four registry seats (novox/hq ADR 0605 §1), named here so the rest of mesh-sdk takes them from the seat set +// through catalogue alone (ADR 0625 §3). +const ( + NpmPackageRegistrySeat = contractseats.NpmPackageRegistry + GoPackageRegistrySeat = contractseats.GoPackageRegistry + ContainerImageRegistrySeat = contractseats.ContainerImageRegistry + OciArtifactRegistrySeat = contractseats.OciArtifactRegistry +) + +// PublishSeats are the seats an artifact is published through (ADR 0605 §1). +var PublishSeats = []string{NpmPackageRegistrySeat, GoPackageRegistrySeat, ContainerImageRegistrySeat, OciArtifactRegistrySeat} + +// The seats of the vault, the provisioner, the hand acts' record and the conditions' keeper, as the seat set names them, +// for the rest of mesh-sdk (ADR 0625 §3). +const ( + VaultSeat = contractseats.MeshVault + ProvisionerSeat = contractseats.MeshProvisioner +) // InRegistrySeat reads a reference in the form a registry seat answers, `//@sha256:`: // the seat it came through and the rest. A seat's name holds no dot or port, so no image of an outside registry reads diff --git a/go/delivery/builder.go b/go/delivery/builder.go index 42bee50..98a35a0 100644 --- a/go/delivery/builder.go +++ b/go/delivery/builder.go @@ -6,7 +6,6 @@ import ( "reflect" "strings" - contractseats "git.novox.be/novox/mesh-contracts/go/seats" "git.novox.be/novox/mesh-sdk/go/catalogue" ) @@ -100,9 +99,9 @@ func (a BuiltArtifact) referenceProblem() string { return "" } if seat, path, ok := catalogue.InRegistrySeat(r); ok { - want := contractseats.ContainerImageRegistry + want := catalogue.ContainerImageRegistrySeat if a.Kind == "bundle" || a.Kind == "archive" { - want = contractseats.OciArtifactRegistry + want = catalogue.OciArtifactRegistrySeat } module, rest, _ := strings.Cut(path, "/") if a.Kind == "package" || seat != want || module == "" || rest != a.Name+"@"+a.Digest { diff --git a/go/delivery/stepasks.go b/go/delivery/stepasks.go index 327e87d..85da720 100644 --- a/go/delivery/stepasks.go +++ b/go/delivery/stepasks.go @@ -12,7 +12,7 @@ import ( "strings" "time" - contractseats "git.novox.be/novox/mesh-contracts/go/seats" + "git.novox.be/novox/mesh-sdk/go/catalogue" ) // **Asks: a build or a check step is a message a build node pulls when it has a free slot** (novox/hq ADR 0525, as @@ -466,8 +466,7 @@ func (c ComposeJob) check(id string) error { } // registrySeats are the seats an artifact is published through (ADR 0605 §1). -var registrySeats = []string{contractseats.NpmPackageRegistry, contractseats.GoPackageRegistry, - contractseats.ContainerImageRegistry, contractseats.OciArtifactRegistry} +var registrySeats = catalogue.PublishSeats func (b BuildJob) check(id string) error { if err := checkName("module", b.Module); err != nil { diff --git a/go/handacts/handacts.go b/go/handacts/handacts.go index 2cc4336..36bc835 100644 --- a/go/handacts/handacts.go +++ b/go/handacts/handacts.go @@ -11,12 +11,12 @@ import ( "strings" "time" - contractseats "git.novox.be/novox/mesh-contracts/go/seats" + "git.novox.be/novox/mesh-sdk/go/catalogue" ) // The seat, its holder and what it keeps (ADR 0565 clause 10). const ( - Seat = contractseats.MeshHandActs + Seat = catalogue.HandActsSeat Module = "mesh-hand-acts" // ActsLog is the log of every act, kept 400 days; WarrantsState one key `.` per warrant, made once. ActsLog = "acts" diff --git a/go/health/findings.go b/go/health/findings.go index e237636..edafe11 100644 --- a/go/health/findings.go +++ b/go/health/findings.go @@ -11,7 +11,7 @@ import ( "strings" "time" - contractseats "git.novox.be/novox/mesh-contracts/go/seats" + "git.novox.be/novox/mesh-sdk/go/catalogue" ) // The modules holding the four health seats, and the states between them, as `_` buckets. @@ -274,6 +274,6 @@ type Would struct { // KeeperSeat and the self-check's run as `checked` on SelfCheckSeat: the controller's events and the take-over key that // chose between the two sources ended with it (novox/hq ADR 0590 clause 3). const ( - KeeperSeat = contractseats.MeshConditions - SelfCheckSeat = contractseats.MeshSelfCheck + KeeperSeat = catalogue.ConditionsSeat + SelfCheckSeat = catalogue.SelfCheckSeat ) diff --git a/go/packages_list_test.go b/go/packages_list_test.go index 633ea39..be88d7d 100644 --- a/go/packages_list_test.go +++ b/go/packages_list_test.go @@ -29,6 +29,28 @@ var meshSDKPackages = []string{ "sdkversion", "seal", "seatdef", "testbus", "views", } +// clientSeats are the seats whose logic is their client's in mesh-contracts (novox/hq ADR 0627 §1, §4): mesh-sdk names +// none of them outside catalogue, and holds no package over them. +var clientSeats = []string{contractseats.OperatorChannel, contractseats.MeshVault, "node-engine", + contractseats.NpmPackageRegistry, contractseats.GoPackageRegistry, contractseats.ContainerImageRegistry, + contractseats.OciArtifactRegistry} + +// notInSDK are the packages that moved to a seat's client or contract (ADR 0627 §1, §4) and may not come back. +var notInSDK = []string{"asks", "asker", "publish"} + +// untilTheJoin is what ADR 0627 still moves at the group's join, each `: `, naming what the checks below +// would refuse; it only shrinks, and is empty when the group is pinned: asks and asker are operator-channel's client +// (mesh-contracts go/clients/operatorchannelclient) once delivery's gate and assigner asks no longer hold the +// router's ask as asks.Ask; the vault module's name in delivery and provisions goes with the vault's client. +var untilTheJoin = []string{ + "asks/asks.go: imports git.novox.be/novox/mesh-contracts/go/seats", + "asks/asks.go: Seat", + "asks: a package that moved", + "asker: a package that moved", + "delivery/signers.go: mesh-vault", + "provisions/provisions.go: mesh-vault", +} + // computesNot are the functions whose computation is one owner's alone (ADR 0593 §2, §7): the indexer computes a // fingerprint, its named tree and a package's version; the node-engine composes. var computesNot = []string{"SourceFingerprint", "SourceFingerprint2", "NamedTree", "MeshPackagesOf", "PackageVersionsOf", @@ -55,7 +77,15 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { } return false } - var seatNames []string + var seatNames, pending []string + clientNamed := func(v string) bool { + for _, seat := range clientSeats { + if v == seat || strings.HasPrefix(v, "mesh.seat."+seat+".") { + return true + } + } + return false + } err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { if err != nil { return err @@ -78,11 +108,22 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { return err } where := filepath.ToSlash(path) + ": " + inCatalogue := dir == "catalogue" + // ADR 0625 §3: mesh-sdk's only import of a contracts module is catalogue's of the seat set. + for _, imp := range file.Imports { + p, _ := strconv.Unquote(imp.Path.Value) + if strings.HasPrefix(p, "git.novox.be/novox/mesh-contracts/") && (!inCatalogue || p != contractsSeatSet) { + pending = append(pending, where+"imports "+p) + } + } ast.Inspect(file, func(n ast.Node) bool { switch n := n.(type) { case *ast.BasicLit: if v, err := strconv.Unquote(n.Value); err == nil && n.Kind == token.STRING && namesSeat(v) { seatNames = append(seatNames, where+v) + if !inCatalogue && clientNamed(v) { + pending = append(pending, where+v) + } } case *ast.ValueSpec: for i, name := range n.Names { @@ -90,6 +131,10 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { if sel, ok := n.Values[i].(*ast.SelectorExpr); ok { if x, ok := sel.X.(*ast.Ident); ok && x.Name == "contractseats" { seatNames = append(seatNames, where+name.Name) + if !inCatalogue && slices.Contains([]string{"OperatorChannel", "MeshVault", "NodeEngine", + "NpmPackageRegistry", "GoPackageRegistry", "ContainerImageRegistry", "OciArtifactRegistry"}, sel.Sel.Name) { + pending = append(pending, where+name.Name) + } } } } @@ -146,6 +191,24 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { } } slices.Sort(found) + for _, dir := range found { + if slices.Contains(notInSDK, dir) { + pending = append(pending, dir+": a package that moved") + } + } + // ADR 0627 §4, ADR 0625 §3: no package over a client's seat, no client seat's name outside catalogue, no contracts + // import but the seat set's in catalogue; what the join still moves is untilTheJoin's. + for _, p := range pending { + if !slices.Contains(untilTheJoin, p) { + t.Errorf("%s: mesh-sdk holds no logic over a seat whose client is in mesh-contracts, names none of them outside "+ + "catalogue, and imports no contracts module but the seat set in catalogue (ADR 0627, ADR 0625 §3)", p) + } + } + for _, k := range untilTheJoin { + if !slices.Contains(pending, k) { + t.Errorf("untilTheJoin keeps %q, which is gone: take it off the list", k) + } + } for _, dir := range found { if !slices.Contains(meshSDKPackages, dir) { t.Errorf("mesh-sdk holds the package %s, which it does not keep (ADR 0593 §1): it is its owner module's package", dir) @@ -230,5 +293,8 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { } } +// contractsSeatSet is the seat-set package of mesh-contracts, catalogue's one import of a contracts module. +const contractsSeatSet = "git.novox.be/novox/mesh-contracts/go/seats" + // sdkModule is mesh-sdk's Go module path. const sdkModule = "git.novox.be/novox/mesh-sdk/go" diff --git a/go/provisions/provisions.go b/go/provisions/provisions.go index c4b4690..e42b024 100644 --- a/go/provisions/provisions.go +++ b/go/provisions/provisions.go @@ -13,13 +13,12 @@ import ( "strings" "time" - contractseats "git.novox.be/novox/mesh-contracts/go/seats" "git.novox.be/novox/mesh-sdk/go/catalogue" ) // The seat, its holder and its two states, and the names a reader declares in its `reads`. const ( - Seat = contractseats.MeshProvisioner + Seat = catalogue.ProvisionerSeat Module = "mesh-provisioner" ProvisionsState = "provisions" PlansState = "plans" diff --git a/go/testdata/seat-names.txt b/go/testdata/seat-names.txt index 3002238..2f9e3b4 100644 --- a/go/testdata/seat-names.txt +++ b/go/testdata/seat-names.txt @@ -1,7 +1,12 @@ asks/asks.go: Seat buscompose/health_grants.go: mesh.seat.mesh-self-check.event. -buscompose/users.go: VaultSeat catalogue/artifact_sweep_seat.go: ArtifactSweepSeat +catalogue/artifacts.go: ContainerImageRegistrySeat +catalogue/artifacts.go: GoPackageRegistrySeat +catalogue/artifacts.go: NpmPackageRegistrySeat +catalogue/artifacts.go: OciArtifactRegistrySeat +catalogue/artifacts.go: ProvisionerSeat +catalogue/artifacts.go: VaultSeat catalogue/catalog_seat.go: CatalogSeat catalogue/checker_seat.go: CheckerSeat catalogue/control_records_seats.go: HandActsSeat @@ -48,14 +53,10 @@ delivery/provided.go: the-private-network delivery/signers.go: mesh-vault delivery/stepasks.go: node-build-node handacts/handacts.go: mesh-hand-acts -handacts/handacts.go: Seat -health/findings.go: KeeperSeat health/findings.go: mesh-conditions health/findings.go: mesh-healers health/findings.go: mesh-self-check -health/findings.go: SelfCheckSeat internal/beside/beside.go: mesh-catalog overlay/overlay.go: the-private-network provisions/provisions.go: mesh-provisioner provisions/provisions.go: mesh-vault -provisions/provisions.go: Seat