Merge pull request 'Make dev-tools, lab and the build modules need the go and nodejs modules instead of declaring the toolchain packages, step B of issue 1573 (ADR 0477 §4)' (#409) from fix/1573b-toolchain-users into main

This commit was merged in pull request #409.
This commit is contained in:
2026-10-21 10:21:02 +00:00
17 changed files with 212 additions and 73 deletions
+3 -3
View File
@@ -5,16 +5,16 @@ machine: an agent working on a change builds it and runs its tests there, with t
pull request. The lab is the QA step after that: it tests the work in a sandbox, through its seat at the mesh
scope, and is not where development happens.
Assign it to every node.
Assign it to every node, with the `go` and `nodejs` modules: it requires their provisions `go-toolchain` and `node-toolchain` (novox/hq ADR 0477 clause 4).
## Owns
| what | package | class (ADR 0182) |
|---|---|---|
| the Go toolchain, for `go build` and `go test` in every Go module | `go` | package |
| the Go toolchain, for `go build` and `go test` in every Go module | the `go` module's package `go` | package |
| a C compiler, for `go test -race` and cgo | `gcc` | package |
| make | `make` | package |
| Node.js and npm, for the TypeScript modules' `npm ci` and `npm test` | `nodejs`, `npm` | package |
| Node.js and npm, for the TypeScript modules' `npm ci` and `npm test` | the `nodejs` module's packages `nodejs`, `npm` | package |
| Python, for the scripts some checks run | `python` | package |
| git and jq | `git`, `jq` | package |
+4 -15
View File
@@ -4,12 +4,11 @@
"capabilities": [
"package-manager"
],
"requires": [
"go-toolchain",
"node-toolchain"
],
"resources": [
{
"id": "go",
"type": "package",
"package": "go"
},
{
"id": "c-compiler",
"type": "package",
@@ -20,16 +19,6 @@
"type": "package",
"package": "make"
},
{
"id": "nodejs",
"type": "package",
"package": "nodejs"
},
{
"id": "npm",
"type": "package",
"package": "npm"
},
{
"id": "python",
"type": "package",
+6 -9
View File
@@ -1,14 +1,11 @@
# go
The Go toolchain as a module (novox/hq ADR 0477 §4, issue 1573).
The Go toolchain as a module (novox/hq ADR 0477 clause 4, issue 1573).
- **Declares the package `go`.** Today dev-tools, lab and mesh-build-go declare it too, which the resolver allows
(ADR 0303); once they require `go-toolchain` instead (issue 1573's second step), this is the only module that
declares it, and `checks/toolchains` refuses another.
- **Provides `go-toolchain` with the machine's reach**: a module that requires it composes only on a machine where
this module is assigned. It is never pulled in for whatever asked, so `go` is assigned to a node on purpose.
Nothing requires it yet; dev-tools, lab and mesh-build-go will, in the second step.
- **The only module that declares the package `go`.** `checks/toolchains` refuses any other that does.
- **Provides `go-toolchain` with the machine's reach**: dev-tools, lab and mesh-build-go require it, so each
composes only on a machine where this module is assigned. It is never pulled in for whatever asked, so `go` is
assigned to a node on purpose, and a node without it refuses those modules at resolution.
- Holds no long-running resource, so it adds nothing to `health-undeclared`.
The node-engine never uninstalls a package, so when the users stop declaring `go`, nothing leaves a node that has
this module.
The node-engine never uninstalls a package, so moving the declaration here removed nothing from a node.
+1 -1
View File
@@ -1,6 +1,6 @@
# lab
The `lab` module of the mesh catalogue: installs the package `git`; installs the package `make`; installs the package `python`; installs the package `file`; installs the package `iproute2`; installs the package `npm`; installs the package `go`; installs the package `incus`.
The `lab` module of the mesh catalogue: installs the package `git`; installs the package `make`; installs the package `python`; installs the package `file`; installs the package `iproute2`; installs the package `incus`; requires `go-toolchain` and `node-toolchain`, so the `go` module and the `nodejs` module are assigned to a machine running it (novox/hq ADR 0477 clause 4).
## Files it does not know
+3 -11
View File
@@ -6,7 +6,9 @@
"virtualisation"
],
"requires": [
"npm-package-registry"
"npm-package-registry",
"go-toolchain",
"node-toolchain"
],
"contributes": {
"npm-package-registry": {
@@ -84,16 +86,6 @@
"type": "package",
"package": "iproute2"
},
{
"id": "npm",
"type": "package",
"package": "npm"
},
{
"id": "go",
"type": "package",
"package": "go"
},
{
"id": "incus",
"type": "package",
+2 -2
View File
@@ -2,8 +2,8 @@
Design 47, release R4c-3 (novox/hq ADR 0405, ADR 0466 §1, ADR 0469, ADR 0470). The module that builds and checks Go
code on a build machine, as an account of its own (`runs-as`, no login shell, home at mode 0700), with the
toolchain installed as the packages it declares (`go`, `git`, `openssh`, `postgresql`) and the capability
`user-namespaces`. It claims no seat: it is assigned to the build machines (ADR 0469 §6) and runs dark until the
toolchain installed as the packages it declares (`git`, `openssh`, `postgresql`; `go` comes from the `go` module, which this module requires as `go-toolchain`) and the capability
`user-namespaces`. It claims no seat: it is assigned to the build machines (ADR 0469 clause 6) and runs dark until the
builder uses it.
## The recipe
@@ -143,8 +143,8 @@ func TestForgeFilesRenderFromTheBoundValuesInTheModulesOwnHome(t *testing.T) {
// template in the files/ archive (novox/hq ADR 0349 §2).
func TestManifestRequiresForgeAccountKeepsKeysAndTakesFilesFromTemplates(t *testing.T) {
m := readForgeManifest(t)
if len(m.Requires) != 1 || m.Requires[0] != "forge-account" {
t.Errorf("requires = %v, want [forge-account]", m.Requires)
if len(m.Requires) != 2 || m.Requires[0] != "forge-account" || m.Requires[1] != "go-toolchain" {
t.Errorf("requires = %v, want [forge-account go-toolchain]", m.Requires)
}
keeps := false
for _, s := range m.State {
@@ -64,7 +64,7 @@ func TestManifestIsValidAndDeclaresTheAccountTheCapabilityAndThePackages(t *test
}
}
slices.Sort(packages)
if want := []string{"git", "go", "openssh", "postgresql"}; !slices.Equal(packages, want) {
if want := []string{"git", "openssh", "postgresql"}; !slices.Equal(packages, want) {
t.Errorf("packages = %v, want %v", packages, want)
}
}
+2 -6
View File
@@ -27,7 +27,8 @@
}
],
"requires": [
"forge-account"
"forge-account",
"go-toolchain"
],
"own-secrets": {
"broker": "${dir:state}/broker"
@@ -105,11 +106,6 @@
"mode": "0644",
"template": "files/gitconfig"
},
{
"id": "go",
"type": "package",
"package": "go"
},
{
"id": "git",
"type": "package",
+2 -2
View File
@@ -2,8 +2,8 @@
Design 47, release R4c-3 (novox/hq ADR 0405, ADR 0466 §1, ADR 0469 §1 and §4). The module that builds and checks
TypeScript code on a build machine, as an account of its own (`runs-as`, no login shell, home at mode 0700), with the
packages it declares (`nodejs`, `npm`, `git`, `openssh`) and the capability `user-namespaces`. The bundle is Go
(`cmd/mesh-build-node`). It claims no seat: it is assigned to the build machines (ADR 0469 §6) and runs dark until the
packages it declares (`git`, `openssh`; `nodejs` and `npm` come from the `nodejs` module, which this module requires as `node-toolchain`) and the capability `user-namespaces`. The bundle is Go
(`cmd/mesh-build-node`). It claims no seat: it is assigned to the build machines (ADR 0469 clause 6) and runs dark until the
builder uses it. Its forge key and ssh files are the same as mesh-build-go's (issue 1484), filled on the node by the
provisioner's client (issue 1537).
@@ -66,7 +66,7 @@ func TestManifestIsValidAndDeclaresTheAccountTheCapabilityAndThePackages(t *test
}
}
slices.Sort(packages)
if want := []string{"git", "nodejs", "npm", "openssh"}; !slices.Equal(packages, want) {
if want := []string{"git", "openssh"}; !slices.Equal(packages, want) {
t.Errorf("packages = %v, want %v", packages, want)
}
}
@@ -134,6 +134,9 @@ func TestTheModuleCarriesItsToolchainLockAndTheManifestPlacesIt(t *testing.T) {
t.Errorf("the module carries no toolchain/%s: %v", name, err)
}
}
if !slices.Contains(m.Requires, "node-toolchain") {
t.Errorf("requires = %v lack node-toolchain, which provides the nodejs and npm packages (issue 1573)", m.Requires)
}
if !slices.Contains(m.Requires, "npm-package-registry") {
t.Errorf("requires = %v lack npm-package-registry, which the install resolves @novox from", m.Requires)
}
+2 -11
View File
@@ -29,7 +29,8 @@
],
"requires": [
"forge-account",
"npm-package-registry"
"npm-package-registry",
"node-toolchain"
],
"contributes": {
"npm-package-registry": {
@@ -126,16 +127,6 @@
"artifact": "toolchain",
"unknown": "program"
},
{
"id": "nodejs",
"type": "package",
"package": "nodejs"
},
{
"id": "npm",
"type": "package",
"package": "npm"
},
{
"id": "git",
"type": "package",
+7 -9
View File
@@ -1,14 +1,12 @@
# nodejs
Node.js and npm as a module (novox/hq ADR 0477 §4, issue 1573).
Node.js and npm as a module (novox/hq ADR 0477 clause 4, issue 1573).
- **Declares the packages `nodejs` and `npm`.** Today dev-tools, lab and mesh-build-node declare some of them too,
which the resolver allows (ADR 0303); once they require `node-toolchain` instead (issue 1573's second step), this
is the only module that declares them, and `checks/toolchains` refuses another.
- **Provides `node-toolchain` with the machine's reach**: a module that requires it composes only on a machine where
this module is assigned. It is never pulled in for whatever asked, so `nodejs` is assigned to a node on purpose.
Nothing requires it yet; dev-tools, lab and mesh-build-node will, in the second step.
- **The only module that declares the packages `nodejs` and `npm`.** `checks/toolchains` refuses any other that
does.
- **Provides `node-toolchain` with the machine's reach**: dev-tools, lab and mesh-build-node require it, so each
composes only on a machine where this module is assigned. It is never pulled in for whatever asked, so `nodejs`
is assigned to a node on purpose, and a node without it refuses those modules at resolution.
- Holds no long-running resource, so it adds nothing to `health-undeclared`.
The node-engine never uninstalls a package, so when the users stop declaring `nodejs` and `npm`, nothing leaves a
node that has this module.
The node-engine never uninstalls a package, so moving the declarations here removed nothing from a node.