Register a module only from the repository the catalogue builds it from (hq ADR 0266 §7, route A) #174

Merged
mesh-admin merged 3 commits from fix/a-build-registers-only-from-its-modules-source into main 2026-10-09 10:56:08 +00:00
Contributor

Merge after #164 — this branch is built on feat/a-node-names-the-account-its-agents-run-as (it relies on #164's command verb being read-only, which closes module add through a verb, and uses its terminalRefusal). Until #164 merges, this diff also shows #164's seven commits; the two commits of this PR are the last two.

The route

An agent makes a repository of its own (or forks novox/mesh-catalog or novox/mesh-host), commits a module.json naming sudo (granting itself NOPASSWD) or mesh-host, and calls mesh-controller.build on it. The outcome was registered under that name from the agent's repository: RegisterModule upserts by name and overwrites source, and the trunk rule (ADR 0238) checked the trunk of the repository built — the agent's own. The next push made the agent root on every node.

The fix

  • Take-in (takeIn, which every outcome reaches whoever hears it and whichever verb asked it — build, rebuild, replay --register, assign with build, a plan, a merge): an outcome registers a module only from the module's registered repository; a module new to the catalogue only from a repository the catalogue already builds another module from (how a merge adds one, issue 300). Anything else only when the build request was kept as asked at the controller's terminal: new column build_request.at_terminal (migration 0084), set only when the asking process was started neither by a verb nor a seat call (MESH_VERB and MESH_CALLER both unset — runVerb sets both).
  • Ask (buildOneAsked, buildAndShow): through a verb, a build of a repository the catalogue builds no module from is not asked at all — the build node would run what the agent wrote.
  • Rollback (PreviousBuild): a failed gate puts back only a build of the failed build's repository. A refused build is still recorded, and a fork carries the commit the module was registered at.

Sources compare as one repository whether spelled as a seat path or as the URL composed from it (live sources are URLs, http://…:20000/novox/mesh-catalog.git).

Tests (each fails before, passes after)

  • TestABuildFromAnAgentsRepositoryIsNotRegisteredAsAModuleTheMeshHolds: own repo naming sudo, a fork of the catalogue, a fork of the node-engine — refused, catalogue unchanged, build recorded.
  • TestANewModuleFromARepositoryTheCatalogueDoesNotBuildFromIsNotRegistered (also an outcome no request was kept for).
  • TestAVerbAsksNoBuildOfARepositoryTheCatalogueDoesNotBuildFrom.
  • TestARollbackNeverPutsBackABuildFromAnotherRepository.
  • Still working: TestAtTheTerminalAnotherRepositoryIsRegistered (move, new external module), TestADeliveryFromTheRegisteredRepositoryIsRegistered (a plan's rebuild, a merge adding a module).

Nine existing tests registered a brand-new module into an empty catalogue from an outcome nobody asked for; they now keep that first build as the operator's at the terminal (asTheOperator), and the gate test's outcome echoes its seat as a real one does.

What changes for the operator

A build from a new repository, or a module moved to another repository, is done at the controller's terminal (mesh-controller build …). A rebuild, a delivery, build --behind/--on and a merge adding a module to the catalogue repository work as before.

merge-check.sh run on this head (which contains current main).

**Merge after #164** — this branch is built on `feat/a-node-names-the-account-its-agents-run-as` (it relies on #164's `command` verb being read-only, which closes `module add` through a verb, and uses its `terminalRefusal`). Until #164 merges, this diff also shows #164's seven commits; the two commits of this PR are the last two. ## The route An agent makes a repository of its own (or forks `novox/mesh-catalog` or `novox/mesh-host`), commits a `module.json` naming `sudo` (granting itself NOPASSWD) or `mesh-host`, and calls `mesh-controller.build` on it. The outcome was registered under that name from the agent's repository: `RegisterModule` upserts by name and overwrites `source`, and the trunk rule (ADR 0238) checked the trunk of *the repository built* — the agent's own. The next push made the agent root on every node. ## The fix - **Take-in** (`takeIn`, which every outcome reaches whoever hears it and whichever verb asked it — `build`, `rebuild`, `replay --register`, `assign` with build, a plan, a merge): an outcome registers a module only from the module's registered repository; a module new to the catalogue only from a repository the catalogue already builds another module from (how a merge adds one, issue 300). Anything else only when the build request was kept as **asked at the controller's terminal**: new column `build_request.at_terminal` (migration 0084), set only when the asking process was started neither by a verb nor a seat call (`MESH_VERB` and `MESH_CALLER` both unset — `runVerb` sets both). - **Ask** (`buildOneAsked`, `buildAndShow`): through a verb, a build of a repository the catalogue builds no module from is not asked at all — the build node would run what the agent wrote. - **Rollback** (`PreviousBuild`): a failed gate puts back only a build of the failed build's repository. A refused build is still recorded, and a fork carries the commit the module was registered at. Sources compare as one repository whether spelled as a seat path or as the URL composed from it (live sources are URLs, `http://…:20000/novox/mesh-catalog.git`). ## Tests (each fails before, passes after) - `TestABuildFromAnAgentsRepositoryIsNotRegisteredAsAModuleTheMeshHolds`: own repo naming `sudo`, a fork of the catalogue, a fork of the node-engine — refused, catalogue unchanged, build recorded. - `TestANewModuleFromARepositoryTheCatalogueDoesNotBuildFromIsNotRegistered` (also an outcome no request was kept for). - `TestAVerbAsksNoBuildOfARepositoryTheCatalogueDoesNotBuildFrom`. - `TestARollbackNeverPutsBackABuildFromAnotherRepository`. - Still working: `TestAtTheTerminalAnotherRepositoryIsRegistered` (move, new external module), `TestADeliveryFromTheRegisteredRepositoryIsRegistered` (a plan's rebuild, a merge adding a module). Nine existing tests registered a brand-new module into an empty catalogue from an outcome nobody asked for; they now keep that first build as the operator's at the terminal (`asTheOperator`), and the gate test's outcome echoes its seat as a real one does. ## What changes for the operator A build from a new repository, or a module moved to another repository, is done at the controller's terminal (`mesh-controller build …`). A rebuild, a delivery, `build --behind/--on` and a merge adding a module to the catalogue repository work as before. `merge-check.sh` run on this head (which contains current main).
mesh-admin added 9 commits 2026-10-09 09:48:34 +00:00
On the control node every agent ran as the operator's account, which has
passwordless sudo, so an agent could become root without a person (hq ADR
0266). A node now names an agent account at the controller's terminal only;
the agent's module declares it never to become root, the node-engine judges
that, and the self-check (DA) raises agent-can-become-root while it does not
hold, so ADR 0259's router can rest on it.
The generic command verb ran node account and node agent-account, so an agent
could name itself the operator account and have the next send grant it root
(hq ADR 0266 review). Refuse every node subcommand but list and show through
any verb; refuse the operator account as the agent account in both
directions and well-known service accounts as an agent account; and count a
verdict heard more than 15 minutes ago as not judged, so stopping the
node-engine cannot freeze a healthy one. Re-pin mesh-host to its review head.
The validator is unchanged; the pin follows the mesh-host pull request's head
so the two are judged together (hq ADR 0266).
Review found a chain through the command verb: set the operator's key to one
the caller holds, rotate secrets so they are sealed to it too, read the sealed
copies, open them. Whoever may call a verb includes agents (hq ADR 0266), so
command now runs an allow list of reading forms, and operator, identity,
token, broker, api, licence and every secret command but rotate are refused
through any verb.
Keeps the controller judged together with mesh-host's pull request (hq ADR
0266); the validator and the wire are unchanged.
A flag before the subcommand (plans --json go <id>) still acts, so the
generic command verb judges every word of a plans line, retry included
(hq ADR 0266). The rest of this change, places and accesses at the
terminal and one line per setting, is issue 339's on main (#168, #170,
#172), which now does it for every process a verb runs; this branch's
--through-verb flag and its copy of those rules go.
The validator and the wire are unchanged; the pin follows mesh-host's pull
request so the two are judged together (hq ADR 0266).
The engine's pull request now keeps main's placement guard (issue 339) and adds
only the agent-home rule; the pin follows it so the two are judged together
(hq ADR 0266). Move it to the engine's merged commit before this merges.
Fill machine facts in a user's home, so an agent account named with a home is made there
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
926dbd7a97
node agent-account <node> <account> [home] stored a home that nothing used: the
account was created at /home/<account> while its files went to the named home
(hq ADR 0266). The engine reads a user's home only when it creates the account,
so an existing one is never moved.
Author
Contributor

Delivery novox/mesh-controller@95e7a7120ab0 — covered since 2026-10-09T11:35:27Z

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Transitions

  • 2026-10-09 10:43 (new) → proposed (announced): novox/mesh-controller#174's head announced
  • 2026-10-09 10:48 proposed → checked (checked): the verdict names this commit
  • 2026-10-09 10:48 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
  • 2026-10-09 11:06 ready → held (hold): something holds it for a person: its group's composed check did not pass for the heads that merged, or it merged and no walk was opened for it
  • 2026-10-09 11:35 held → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-controller@eca6390d6f (merged as 33dc85d8 into main, walk plan-1791544480657912626): build-agent, mesh-controller, route-proxy

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@95e7a7120ab0` — **covered** since 2026-10-09T11:35:27Z **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves **Transitions** - 2026-10-09 10:43 (new) → proposed (announced): novox/mesh-controller#174's head announced - 2026-10-09 10:48 proposed → checked (checked): the verdict names this commit - 2026-10-09 10:48 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail - 2026-10-09 11:06 ready → held (hold): something holds it for a person: its group's composed check did not pass for the heads that merged, or it merged and no walk was opened for it - 2026-10-09 11:35 held → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-controller@eca6390d6fe4 (merged as 33dc85d8 into main, walk plan-1791544480657912626): build-agent, mesh-controller, route-proxy The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Author
Contributor

Merge check at c816da16

  • mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
  • mesh/repo-check: PASS — its merge-check.sh passed

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Run by the build seat on shanks as build-1791539342120430846 (builds --log build-1791539342120430846).

--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-09T08:07:39Z

machines:
  - a machine (f35): composes
  - holds mesh-dns-resolver (idt): composes
  - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
  - a machine (yvbpsm): composes

a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok  	github.com/novox/mesh-controller/cmd/mesh-builder	1.043s
ok  	github.com/novox/mesh-controller/cmd/mesh-controller	202.518s
ok  	github.com/novox/mesh-controller/examples/objectstore-provisioner	1.030s
ok  	github.com/novox/mesh-controller/examples/postgres-provisioner	1.037s
ok  	github.com/novox/mesh-controller/examples/redis-provisioner	1.021s
ok  	github.com/novox/mesh-controller/examples/route-proxy	1.188s
ok  	github.com/novox/mesh-controller/internal/artifacts	1.069s
ok  	github.com/novox/mesh-controller/internal/broker	2.769s
ok  	github.com/novox/mesh-controller/internal/builder	1.945s
ok  	github.com/novox/mesh-controller/internal/catalogue	5.013s
ok  	github.com/novox/mesh-controller/internal/conditions	2.507s
ok  	github.com/novox/mesh-controller/internal/envfile	1.041s
ok  	github.com/novox/mesh-controller/internal/facts	1.051s
ok  	github.com/novox/mesh-controller/internal/identity	4.738s
ok  	github.com/novox/mesh-controller/internal/inventory	86.348s
ok  	github.com/novox/mesh-controller/internal/lease	17.696s
ok  	github.com/novox/mesh-controller/internal/licences	4.309s
ok  	github.com/novox/mesh-controller/internal/licences/adapters	1.032s
ok  	github.com/novox/mesh-controller/internal/link	53.556s
ok  	github.com/novox/mesh-controller/internal/lint	2.152s
ok  	github.com/novox/mesh-controller/internal/outward	1.066s
ok  	github.com/novox/mesh-controller/internal/overlay	1.051s
ok  	github.com/novox/mesh-controller/internal/secrets	1.526s
ok  	github.com/novox/mesh-controller/internal/store	3.455s
ok  	github.com/novox/mesh-controller/internal/testbus	1.218s
ok  	github.com/novox/mesh-controller/internal/token	1.015s
**Merge check** at `c816da16` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves Run by the build seat on shanks as `build-1791539342120430846` (`builds --log build-1791539342120430846`). ``` --- the gate: build-agent, mesh-controller, route-proxy mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8) long-running resources without health: 1 files asking for a setting without saying whether it is trusted: 0 1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run composing every machine as the mesh is the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued composing every machine with the change the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose) judged by controller development build against the facts of 2026-10-09T08:07:39Z machines: - a machine (f35): composes - holds mesh-dns-resolver (idt): composes - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes - a machine (yvbpsm): composes a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy --- its merge-check.sh (go toolchain) ok github.com/novox/mesh-controller/cmd/mesh-builder 1.043s ok github.com/novox/mesh-controller/cmd/mesh-controller 202.518s ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.030s ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.037s ok github.com/novox/mesh-controller/examples/redis-provisioner 1.021s ok github.com/novox/mesh-controller/examples/route-proxy 1.188s ok github.com/novox/mesh-controller/internal/artifacts 1.069s ok github.com/novox/mesh-controller/internal/broker 2.769s ok github.com/novox/mesh-controller/internal/builder 1.945s ok github.com/novox/mesh-controller/internal/catalogue 5.013s ok github.com/novox/mesh-controller/internal/conditions 2.507s ok github.com/novox/mesh-controller/internal/envfile 1.041s ok github.com/novox/mesh-controller/internal/facts 1.051s ok github.com/novox/mesh-controller/internal/identity 4.738s ok github.com/novox/mesh-controller/internal/inventory 86.348s ok github.com/novox/mesh-controller/internal/lease 17.696s ok github.com/novox/mesh-controller/internal/licences 4.309s ok github.com/novox/mesh-controller/internal/licences/adapters 1.032s ok github.com/novox/mesh-controller/internal/link 53.556s ok github.com/novox/mesh-controller/internal/lint 2.152s ok github.com/novox/mesh-controller/internal/outward 1.066s ok github.com/novox/mesh-controller/internal/overlay 1.051s ok github.com/novox/mesh-controller/internal/secrets 1.526s ok github.com/novox/mesh-controller/internal/store 3.455s ok github.com/novox/mesh-controller/internal/testbus 1.218s ok github.com/novox/mesh-controller/internal/token 1.015s ```
jschoubben added 1 commit 2026-10-09 10:27:22 +00:00
Pin the node-engine at the head whose setuid search runs to its own bound
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
d951f22c04
mesh-host #61 dropped the two-minute limit inside the search's 15-minute
bound, asks pacman once, and calls a walk with errors incomplete; the pin
follows it so the two are judged together (hq ADR 0266). Move it to the
engine's merged commit before this merges.
jschoubben force-pushed fix/a-build-registers-only-from-its-modules-source from c816da16fa to 80ad37ec16 2026-10-09 10:27:22 +00:00 Compare
Author
Contributor

Follow-ups of the review (commit 80ad37e; branch rebased on #164's re-pin d951f22):

  • Protected trunk, refused not raised. Through any verb, a registration also needs the source on the mesh's forge with its trunk (the branch the module follows, else the default branch) covered by a rule that refuses direct pushes, requires at least one status, and lets no admin merge past one. Asked of gitea.gitea_branch_protection_get (glob rules included). Unreadable forge, or a source not on the forge, means refused. I chose refusing over a condition: a registered module is what the next push sends. I checked every repository built in the last 400 builds (13 repositories); all already pass this rule.
  • Repository identity. The forge's repository id (via gitea_api GET /repos/o/r) is recorded at registration (module.source_repo_id, in migration 0084). A different id under the same name (deleted and made again) is refused, also for a new module beside one registered from that repository. Existing modules record their id at their next registration; until then there is no id to compare (trust on first use).
  • Terminal is never the serving controller. serve sets MESH_SERVED_BY_THE_CONTROLLER=1 in its own environment, so it and everything it starts (verbs, children) never read as the terminal. A terminal request counts only when its repository and path match the outcome's.

Tests, each failing with its check removed: TestATrunkTheForgeDoesNotProtectRegistersNothing, TestARepositoryMadeAgainUnderItsNameIsNotTheModulesSource, TestATerminalRequestCoversOnlyWhatItAsked, TestTheServingControllerIsNeverTheTerminal. Merge order: #164, then this, then #175 (stacked: #175 adds migration 0085).

Follow-ups of the review (commit 80ad37e; branch rebased on #164's re-pin d951f22): - **Protected trunk, refused not raised.** Through any verb, a registration also needs the source on the mesh's forge with its trunk (the branch the module follows, else the default branch) covered by a rule that refuses direct pushes, requires at least one status, and lets no admin merge past one. Asked of `gitea.gitea_branch_protection_get` (glob rules included). Unreadable forge, or a source not on the forge, means refused. I chose refusing over a condition: a registered module is what the next push sends. I checked every repository built in the last 400 builds (13 repositories); all already pass this rule. - **Repository identity.** The forge's repository id (via `gitea_api GET /repos/o/r`) is recorded at registration (`module.source_repo_id`, in migration 0084). A different id under the same name (deleted and made again) is refused, also for a new module beside one registered from that repository. Existing modules record their id at their next registration; until then there is no id to compare (trust on first use). - **Terminal is never the serving controller.** `serve` sets `MESH_SERVED_BY_THE_CONTROLLER=1` in its own environment, so it and everything it starts (verbs, children) never read as the terminal. A terminal request counts only when its repository and path match the outcome's. Tests, each failing with its check removed: `TestATrunkTheForgeDoesNotProtectRegistersNothing`, `TestARepositoryMadeAgainUnderItsNameIsNotTheModulesSource`, `TestATerminalRequestCoversOnlyWhatItAsked`, `TestTheServingControllerIsNeverTheTerminal`. **Merge order: #164, then this, then #175** (stacked: #175 adds migration 0085).
Author
Contributor

Merge check at 80ad37ec

  • mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
  • mesh/repo-check: PASS — its merge-check.sh passed

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Run by the build seat on novox as build-1791541655866717096 (builds --log build-1791541655866717096).

--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-09T08:07:39Z

machines:
  - a machine (f35): composes
  - holds mesh-dns-resolver (idt): composes
  - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
  - a machine (yvbpsm): composes

a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok  	github.com/novox/mesh-controller/cmd/mesh-builder	1.044s
ok  	github.com/novox/mesh-controller/cmd/mesh-controller	228.974s
ok  	github.com/novox/mesh-controller/examples/objectstore-provisioner	1.020s
ok  	github.com/novox/mesh-controller/examples/postgres-provisioner	1.029s
ok  	github.com/novox/mesh-controller/examples/redis-provisioner	1.021s
ok  	github.com/novox/mesh-controller/examples/route-proxy	1.121s
ok  	github.com/novox/mesh-controller/internal/artifacts	1.059s
ok  	github.com/novox/mesh-controller/internal/broker	2.875s
ok  	github.com/novox/mesh-controller/internal/builder	2.833s
ok  	github.com/novox/mesh-controller/internal/catalogue	5.420s
ok  	github.com/novox/mesh-controller/internal/conditions	2.467s
ok  	github.com/novox/mesh-controller/internal/envfile	1.031s
ok  	github.com/novox/mesh-controller/internal/facts	1.029s
ok  	github.com/novox/mesh-controller/internal/identity	5.085s
ok  	github.com/novox/mesh-controller/internal/inventory	92.362s
ok  	github.com/novox/mesh-controller/internal/lease	17.671s
ok  	github.com/novox/mesh-controller/internal/licences	4.711s
ok  	github.com/novox/mesh-controller/internal/licences/adapters	1.012s
ok  	github.com/novox/mesh-controller/internal/link	54.418s
ok  	github.com/novox/mesh-controller/internal/lint	2.222s
ok  	github.com/novox/mesh-controller/internal/outward	1.037s
ok  	github.com/novox/mesh-controller/internal/overlay	1.023s
ok  	github.com/novox/mesh-controller/internal/secrets	1.500s
ok  	github.com/novox/mesh-controller/internal/store	3.401s
ok  	github.com/novox/mesh-controller/internal/testbus	1.207s
ok  	github.com/novox/mesh-controller/internal/token	1.015s
**Merge check** at `80ad37ec` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves Run by the build seat on novox as `build-1791541655866717096` (`builds --log build-1791541655866717096`). ``` --- the gate: build-agent, mesh-controller, route-proxy mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8) long-running resources without health: 1 files asking for a setting without saying whether it is trusted: 0 1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run composing every machine as the mesh is the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued composing every machine with the change the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose) judged by controller development build against the facts of 2026-10-09T08:07:39Z machines: - a machine (f35): composes - holds mesh-dns-resolver (idt): composes - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes - a machine (yvbpsm): composes a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy --- its merge-check.sh (go toolchain) ok github.com/novox/mesh-controller/cmd/mesh-builder 1.044s ok github.com/novox/mesh-controller/cmd/mesh-controller 228.974s ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.020s ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.029s ok github.com/novox/mesh-controller/examples/redis-provisioner 1.021s ok github.com/novox/mesh-controller/examples/route-proxy 1.121s ok github.com/novox/mesh-controller/internal/artifacts 1.059s ok github.com/novox/mesh-controller/internal/broker 2.875s ok github.com/novox/mesh-controller/internal/builder 2.833s ok github.com/novox/mesh-controller/internal/catalogue 5.420s ok github.com/novox/mesh-controller/internal/conditions 2.467s ok github.com/novox/mesh-controller/internal/envfile 1.031s ok github.com/novox/mesh-controller/internal/facts 1.029s ok github.com/novox/mesh-controller/internal/identity 5.085s ok github.com/novox/mesh-controller/internal/inventory 92.362s ok github.com/novox/mesh-controller/internal/lease 17.671s ok github.com/novox/mesh-controller/internal/licences 4.711s ok github.com/novox/mesh-controller/internal/licences/adapters 1.012s ok github.com/novox/mesh-controller/internal/link 54.418s ok github.com/novox/mesh-controller/internal/lint 2.222s ok github.com/novox/mesh-controller/internal/outward 1.037s ok github.com/novox/mesh-controller/internal/overlay 1.023s ok github.com/novox/mesh-controller/internal/secrets 1.500s ok github.com/novox/mesh-controller/internal/store 3.401s ok github.com/novox/mesh-controller/internal/testbus 1.207s ok github.com/novox/mesh-controller/internal/token 1.015s ```
jschoubben added 4 commits 2026-10-09 10:43:43 +00:00
Pin the node-engine at #61's head, which reads the homes in one order
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
e168b60159
Only the engine's own test changed; the pin follows the head so the two are
judged together (hq ADR 0266). Move it to the engine's merged commit before
this merges.
An agent could make a repository of its own, or fork one the mesh builds
from, commit a module.json naming sudo or mesh-host, and ask the build verb
for it: the outcome was registered under that name, and the next push made
whoever wrote it root on every node (novox/hq ADR 0266 §7, the review of
2026-10-09). The trunk rule checked the trunk of the repository built, which
was the agent's.

The take-in, which every outcome reaches whichever verb asked it, now
registers a module only from its registered repository, and a new module only
from a repository the catalogue already builds from (a merge adding one);
anything else only when the build request was kept as asked at the
controller's terminal (migration 0084). Through a verb, a build of a
repository the catalogue builds nothing from is not asked at all.
A build refused for its repository is still recorded, and a fork carries the
commit the module was registered at: the rollback's search for the previous
build would have found it and registered it by the back door.
Register only from a protected trunk of the same repository, and mark the serving controller never the terminal
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-controller@eca6390d6fe4 (merged as 33dc85d8 into main, walk plan-17915444…
95e7a7120a
A source repository's name is not its identity, and a trunk anyone may push
to makes the trunk rule mean nothing (the review of 2026-10-09). Through any
verb a module now registers only from a repository on the mesh's forge whose
trunk refuses direct pushes, requires a status and lets no administrator
merge past one, asked of the forge's own tools; and only from the repository
by the forge's id, recorded at registration (migration 0084), so one deleted
and made again under the name is refused. The serving controller marks its
environment, so nothing it runs or starts reads as the terminal, and a
terminal request covers only the repository and path it asked.
jschoubben force-pushed fix/a-build-registers-only-from-its-modules-source from 80ad37ec16 to 95e7a7120a 2026-10-09 10:43:43 +00:00 Compare
Author
Contributor

Merge check at 95e7a712

  • mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
  • mesh/repo-check: PASS — its merge-check.sh passed

Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-controller
  • tier 1: build-agent
  • tier 2: route-proxy
  • ace: receives build-agent, route-proxy
  • g14: receives build-agent
  • novox: receives mesh-controller, build-agent, route-proxy
  • shanks: receives build-agent
  • build-agent keeps data (ADR 0233): what it holds is backed up before it moves
  • route-proxy provides route: its consumers are sent again after it
  • route-proxy keeps data (ADR 0233): what it holds is backed up before it moves

Run by the build seat on ace as build-1791542632864709183 (builds --log build-1791542632864709183).

--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-09T08:07:39Z

machines:
  - a machine (f35): composes
  - holds mesh-dns-resolver (idt): composes
  - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
  - a machine (yvbpsm): composes

a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok  	github.com/novox/mesh-controller/cmd/mesh-builder	1.035s
ok  	github.com/novox/mesh-controller/cmd/mesh-controller	176.206s
ok  	github.com/novox/mesh-controller/examples/objectstore-provisioner	1.026s
ok  	github.com/novox/mesh-controller/examples/postgres-provisioner	1.030s
ok  	github.com/novox/mesh-controller/examples/redis-provisioner	1.021s
ok  	github.com/novox/mesh-controller/examples/route-proxy	1.131s
ok  	github.com/novox/mesh-controller/internal/artifacts	1.054s
ok  	github.com/novox/mesh-controller/internal/broker	2.545s
ok  	github.com/novox/mesh-controller/internal/builder	1.828s
ok  	github.com/novox/mesh-controller/internal/catalogue	4.370s
ok  	github.com/novox/mesh-controller/internal/conditions	2.402s
ok  	github.com/novox/mesh-controller/internal/envfile	1.031s
ok  	github.com/novox/mesh-controller/internal/facts	1.035s
ok  	github.com/novox/mesh-controller/internal/identity	4.099s
ok  	github.com/novox/mesh-controller/internal/inventory	72.311s
ok  	github.com/novox/mesh-controller/internal/lease	17.671s
ok  	github.com/novox/mesh-controller/internal/licences	3.740s
ok  	github.com/novox/mesh-controller/internal/licences/adapters	1.027s
ok  	github.com/novox/mesh-controller/internal/link	51.041s
ok  	github.com/novox/mesh-controller/internal/lint	2.015s
ok  	github.com/novox/mesh-controller/internal/outward	1.101s
ok  	github.com/novox/mesh-controller/internal/overlay	1.083s
ok  	github.com/novox/mesh-controller/internal/secrets	1.471s
ok  	github.com/novox/mesh-controller/internal/store	3.272s
ok  	github.com/novox/mesh-controller/internal/testbus	1.242s
ok  	github.com/novox/mesh-controller/internal/token	1.015s
**Merge check** at `95e7a712` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step - tier 0: mesh-controller - tier 1: build-agent - tier 2: route-proxy - ace: receives build-agent, route-proxy - g14: receives build-agent - novox: receives mesh-controller, build-agent, route-proxy - shanks: receives build-agent - build-agent keeps data (ADR 0233): what it holds is backed up before it moves - route-proxy provides route: its consumers are sent again after it - route-proxy keeps data (ADR 0233): what it holds is backed up before it moves Run by the build seat on ace as `build-1791542632864709183` (`builds --log build-1791542632864709183`). ``` --- the gate: build-agent, mesh-controller, route-proxy mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8) long-running resources without health: 1 files asking for a setting without saying whether it is trusted: 0 1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T08:07:39Z says they run composing every machine as the mesh is the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued composing every machine with the change the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose) judged by controller development build against the facts of 2026-10-09T08:07:39Z machines: - a machine (f35): composes - holds mesh-dns-resolver (idt): composes - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes - a machine (yvbpsm): composes a merge would rebuild 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy --- its merge-check.sh (go toolchain) ok github.com/novox/mesh-controller/cmd/mesh-builder 1.035s ok github.com/novox/mesh-controller/cmd/mesh-controller 176.206s ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.026s ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.030s ok github.com/novox/mesh-controller/examples/redis-provisioner 1.021s ok github.com/novox/mesh-controller/examples/route-proxy 1.131s ok github.com/novox/mesh-controller/internal/artifacts 1.054s ok github.com/novox/mesh-controller/internal/broker 2.545s ok github.com/novox/mesh-controller/internal/builder 1.828s ok github.com/novox/mesh-controller/internal/catalogue 4.370s ok github.com/novox/mesh-controller/internal/conditions 2.402s ok github.com/novox/mesh-controller/internal/envfile 1.031s ok github.com/novox/mesh-controller/internal/facts 1.035s ok github.com/novox/mesh-controller/internal/identity 4.099s ok github.com/novox/mesh-controller/internal/inventory 72.311s ok github.com/novox/mesh-controller/internal/lease 17.671s ok github.com/novox/mesh-controller/internal/licences 3.740s ok github.com/novox/mesh-controller/internal/licences/adapters 1.027s ok github.com/novox/mesh-controller/internal/link 51.041s ok github.com/novox/mesh-controller/internal/lint 2.015s ok github.com/novox/mesh-controller/internal/outward 1.101s ok github.com/novox/mesh-controller/internal/overlay 1.083s ok github.com/novox/mesh-controller/internal/secrets 1.471s ok github.com/novox/mesh-controller/internal/store 3.272s ok github.com/novox/mesh-controller/internal/testbus 1.242s ok github.com/novox/mesh-controller/internal/token 1.015s ```
mesh-admin merged commit eb7a158086 into main 2026-10-09 10:56:08 +00:00
mesh-admin deleted branch fix/a-build-registers-only-from-its-modules-source 2026-10-09 10:56:08 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
2 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#174