From 41637befffa24ab6b29910b1577a3e3b81925e5f Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 16 Sep 2026 18:40:40 +0200 Subject: [PATCH] Rename mesh-control -> mesh-controller, substrate -> foundation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One name per thing, per the HQ glossary: the module/container/image/binary/repo becomes mesh-controller, the seat the-controller, and the store+broker pair the foundation (embedded base bundles, default template and example lock renamed with their go:embed directives). No behaviour change — a pure vocabulary rename. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx --- README.md | 8 +++--- modules/anthropic-manager/grantfile.ts | 6 ++--- modules/anthropic-manager/refresh/index.ts | 6 ++--- modules/anthropic-manager/sealedbox.ts | 8 +++--- .../anthropic-manager/test/sealedbox.test.ts | 2 +- .../module.json | 26 +++++++++---------- modules/model-usage/index.ts | 2 +- modules/route-proxy/Dockerfile | 6 ++--- modules/route-proxy/README.md | 4 +-- 9 files changed, 34 insertions(+), 34 deletions(-) rename modules/{mesh-control => mesh-controller}/module.json (57%) diff --git a/README.md b/README.md index 780aa49..2f88016 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ per module under [`modules/`](modules/). This is **data, not a control-plane concern**. The manifests describe *what a module is*: what it provides, what it requires, the seats it claims, the resources the host applies for it. The engine that reads them — parsing, eligibility resolution, sealing, declaration emission — lives -in the control plane (`novox/mesh-control`, `internal/catalogue`), which consumes this repository +in the control plane (`novox/mesh-controller`, `internal/catalogue`), which consumes this repository as a build source. The host (`novox/mesh-host`) applies the declarations the control plane emits. Neither is here. @@ -17,9 +17,9 @@ manifest names its image (pinned by digest), the resources the host owns for it files, the container, the private network it joins), what it `requires` from a provider and what it `provides` to consumers, and the sealed secrets it needs filled on the machine. -- **Core mesh components are not modules.** The node host, the substrate, the control-plane +- **Core mesh components are not modules.** The node host, the foundation, the control-plane contexts and the surfaces are the mesh itself; they ship as their own repositories - (`mesh-host`, `mesh-substrate`, `mesh-control`, `mesh-surfaces`, `mesh-sdk`), not from here. + (`mesh-host`, `mesh-foundation`, `mesh-controller`, `mesh-surfaces`, `mesh-sdk`), not from here. - **Standalone applications are not here either.** A larger application lives in its own repository with its manifest at the root, registered with the mesh as a build source (novox/hq [ADR 0010](https://git.novox.be/novox/hq)). This repository holds the modules the @@ -46,7 +46,7 @@ provider/consumer edge — is data inside the manifests, not a directory the tre The shape a manifest must satisfy is owned by the control plane's catalogue engine and is what validates a manifest before a machine ever sees it — a stray key, a consumer contributing the wrong provision field, an image that nothing builds. That validation belongs with this -repository and is being re-homed here from `mesh-control`; until it is, the pipeline is the +repository and is being re-homed here from `mesh-controller`; until it is, the pipeline is the gate — it builds each module and refuses a manifest it cannot resolve. ## Where the reasoning lives diff --git a/modules/anthropic-manager/grantfile.ts b/modules/anthropic-manager/grantfile.ts index 2b0ceda..1c5915d 100644 --- a/modules/anthropic-manager/grantfile.ts +++ b/modules/anthropic-manager/grantfile.ts @@ -1,9 +1,9 @@ // Reading the manager node's PUBLIC sealing key out of the bound facts the mesh delivers, and -// writing a sealed refresh token in the wire shape mesh-control reads. +// writing a sealed refresh token in the wire shape mesh-controller reads. // // **The public key is delivered, not derived.** The manager module holds no node key of its own // (novox/hq ADR 0050) — it is deliberately never given one. To seal a refresh token to this node it -// needs the node's PUBLIC sealing key, and mesh-control puts that in the manager holder's bound facts +// needs the node's PUBLIC sealing key, and mesh-controller puts that in the manager holder's bound facts // (`serves.manager_public_key`), safe to disclose because it is public. Both adoption and every // rotation read it from there. @@ -23,7 +23,7 @@ export function managerPublicKey(boundFile: string): string { return key; } -/** Write a sealed refresh token in the {sealed, manager_key} wire shape mesh-control reads. */ +/** Write a sealed refresh token in the {sealed, manager_key} wire shape mesh-controller reads. */ export function writeSealedGrant(path: string, sealed: string, managerKey: string): void { mkdirSync(dirname(path), { recursive: true }); const tmp = `${path}.tmp`; diff --git a/modules/anthropic-manager/refresh/index.ts b/modules/anthropic-manager/refresh/index.ts index e2f99de..6db3a94 100644 --- a/modules/anthropic-manager/refresh/index.ts +++ b/modules/anthropic-manager/refresh/index.ts @@ -12,13 +12,13 @@ // never the refresh token — which it seals per consumer holder and stores; // 5. poll usage with the fresh access token and record the licence-grain reading. // -// mesh-control receives the products of steps 3–4 through `licence submit-refresh` (access token + +// mesh-controller receives the products of steps 3–4 through `licence submit-refresh` (access token + // sealed box). The refresh token never leaves this process except as ciphertext, and it never had to // be opened here at all — the host did that. // // This runs as `mesh-tools run`, which connects no broker, so the outputs are written to files the -// host mounts; the submit itself (the transport to mesh-control) is done by the caller invoking -// `mesh-control licence submit-refresh`. In the lab that caller is the scenario; in production it is +// host mounts; the submit itself (the transport to mesh-controller) is done by the caller invoking +// `mesh-controller licence submit-refresh`. In the lab that caller is the scenario; in production it is // an authenticated call the manager node makes. The transport is the one part stubbed here — FLAGGED // — because a cross-node authenticated command surface is out of this module's scope. diff --git a/modules/anthropic-manager/sealedbox.ts b/modules/anthropic-manager/sealedbox.ts index a8cb1ae..ae4a19f 100644 --- a/modules/anthropic-manager/sealedbox.ts +++ b/modules/anthropic-manager/sealedbox.ts @@ -5,14 +5,14 @@ // carve-out delivers the refresh token to the manager module the way the mesh delivers every other // credential: sealed to the node's key, and unsealed by the *host* — never by the module. The host // unseals with Go's `golang.org/x/crypto/nacl/box.OpenAnonymous` (mesh-host -// internal/identity/sealing.go), and mesh-control seals with `box.SealAnonymous` -// (mesh-control internal/secrets/seal.go). Both are NaCl `crypto_box_seal`: +// internal/identity/sealing.go), and mesh-controller seals with `box.SealAnonymous` +// (mesh-controller internal/secrets/seal.go). Both are NaCl `crypto_box_seal`: // // sealed = ephemeralPub(32) ‖ crypto_box(msg, nonce, recipientPub, ephemeralSecret) // nonce = blake2b( ephemeralPub ‖ recipientPub , 24 bytes, unkeyed ) // // When the vendor rotates the refresh token, the manager module must store the new one back the -// same way — sealed to the manager node's own sealing key — so mesh-control keeps it without ever +// same way — sealed to the manager node's own sealing key — so mesh-controller keeps it without ever // reading it and the host can later unseal it to deliver the cleartext again. That reseal happens // here, on the manager node, in TypeScript. It therefore has to produce the *identical* byte format // Go's `Open` accepts, or the host would refuse the delivery. @@ -27,7 +27,7 @@ // (package.json dependencies; novox/hq ADR 0052). // // **How it is kept honest.** A cross-language test seals a fixture here and opens it in Go -// (mesh-control internal/secrets/sealedbox_xcheck_test.go); the fixture is regenerated from this +// (mesh-controller internal/secrets/sealedbox_xcheck_test.go); the fixture is regenerated from this // `seal()`. A drift between this seal and Go's box surfaces there as a seal Go cannot open, not as a // refresh token silently mangled in production. // diff --git a/modules/anthropic-manager/test/sealedbox.test.ts b/modules/anthropic-manager/test/sealedbox.test.ts index a30bb30..f7c11f8 100644 --- a/modules/anthropic-manager/test/sealedbox.test.ts +++ b/modules/anthropic-manager/test/sealedbox.test.ts @@ -5,7 +5,7 @@ import { generateKeyPairSync } from "node:crypto"; import { seal } from "../sealedbox.ts"; // The definitive proof that this seal interoperates with Go's box.OpenAnonymous (the host's Unseal -// and mesh-control's secrets.Seal/Open) is a cross-language test in mesh-control +// and mesh-controller's secrets.Seal/Open) is a cross-language test in mesh-controller // (internal/secrets/sealedbox_xcheck_test.go), which opens a fixture this module's seal() produced. // These tests hold the TypeScript side: the output has the crypto_box_seal shape, and it is // randomised so a rotation that changed nothing looks nothing like one that changed everything. diff --git a/modules/mesh-control/module.json b/modules/mesh-controller/module.json similarity index 57% rename from modules/mesh-control/module.json rename to modules/mesh-controller/module.json index e5e864b..b48c435 100644 --- a/modules/mesh-control/module.json +++ b/modules/mesh-controller/module.json @@ -1,5 +1,5 @@ { - "module": "mesh-control", + "module": "mesh-controller", "version": "1", "slug": "control", "capabilities": [ @@ -7,43 +7,43 @@ ], "claims": [ { - "name": "the-control-plane", + "name": "the-controller", "scope": "mesh" } ], "own-secrets": { - "inventory": "/var/lib/mesh/mesh-control/inventory", - "identity": "/var/lib/mesh/mesh-control/identity", - "licences": "/var/lib/mesh/mesh-control/licences", - "broker": "/var/lib/mesh/mesh-control/broker", - "broker-management": "/var/lib/mesh/mesh-control/broker-management", - "broker-address": "/var/lib/mesh/mesh-control/broker-address" + "inventory": "/var/lib/mesh/mesh-controller/inventory", + "identity": "/var/lib/mesh/mesh-controller/identity", + "licences": "/var/lib/mesh/mesh-controller/licences", + "broker": "/var/lib/mesh/mesh-controller/broker", + "broker-management": "/var/lib/mesh/mesh-controller/broker-management", + "broker-address": "/var/lib/mesh/mesh-controller/broker-address" }, "resources": [ { "id": "mesh-state", "type": "directory", - "path": "/var/lib/mesh/mesh-control", + "path": "/var/lib/mesh/mesh-controller", "mode": "0700" }, { "id": "control-env", "type": "file", - "path": "/var/lib/mesh/mesh-control/control.env", + "path": "/var/lib/mesh/mesh-controller/control.env", "mode": "0600", "content": "MESH_STORE_INVENTORY=${secret:inventory}\nMESH_STORE_IDENTITY=${secret:identity}\nMESH_STORE_LICENCES=${secret:licences}\nMESH_BROKER_AMQP=${secret:broker}\nMESH_BROKER_MANAGEMENT=${secret:broker-management}\nMESH_BROKER_ADDRESS=${secret:broker-address}\n" }, { "id": "server", "type": "container", - "name": "mesh-control", - "image": "mesh-control@sha256:0000000000000000000000000000000000000000000000000000000000000000", + "name": "mesh-controller", + "image": "mesh-controller@sha256:0000000000000000000000000000000000000000000000000000000000000000", "network": "host", "args": [ "serve" ], "env-file": [ - "/var/lib/mesh/mesh-control/control.env" + "/var/lib/mesh/mesh-controller/control.env" ], "env": { "MESH_BROKER_CERTIFICATE": "/broker-tls/tls.crt" diff --git a/modules/model-usage/index.ts b/modules/model-usage/index.ts index 18b5ec4..2bcf812 100644 --- a/modules/model-usage/index.ts +++ b/modules/model-usage/index.ts @@ -1,4 +1,4 @@ -// model-usage's entrypoint — the usage context store's consumer (novox/hq ADR 0054). mesh-control is +// model-usage's entrypoint — the usage context store's consumer (novox/hq ADR 0054). mesh-controller is // a CLI and cannot consume events, so the store that keeps the latest usage reading is a MODULE: it // subscribes to `module.*.usage.*` and upserts each row. Like the audit-logger, the on(...) IS the // whole handshake — the runtime imports this once the broker is bound, and every usage event any diff --git a/modules/route-proxy/Dockerfile b/modules/route-proxy/Dockerfile index f49d1c9..a22fa35 100644 --- a/modules/route-proxy/Dockerfile +++ b/modules/route-proxy/Dockerfile @@ -1,12 +1,12 @@ # The route-proxy module's runtime image: the reference reverse proxy compiled into a container. # # **The proxy source is not vendored here.** The canonical proxy — the contract written as something -# that runs — lives in the mesh-control repository at examples/route-proxy (novox/hq 08-connectivity +# that runs — lives in the mesh-controller repository at examples/route-proxy (novox/hq 08-connectivity # §3). This module ships the *packaging*, not a second copy of the contract, so the build context is -# the mesh-control repository root, and this Dockerfile compiles ./examples/route-proxy from it. +# the mesh-controller repository root, and this Dockerfile compiles ./examples/route-proxy from it. # # docker build -f mesh-catalog/modules/route-proxy/Dockerfile \ -# -t mesh-route-proxy:development /mesh-control +# -t mesh-route-proxy:development /mesh-controller # # The mesh pins the digest of what this produces; the committed module.json carries the placeholder # digest every mesh-built image does, replaced at publish. diff --git a/modules/route-proxy/README.md b/modules/route-proxy/README.md index 2075b86..639024b 100644 --- a/modules/route-proxy/README.md +++ b/modules/route-proxy/README.md @@ -30,9 +30,9 @@ an event. It only reads the file the mesh writes. (Contrast `redis`, which mints ## How it ships the Go proxy The proxy is a Go program, unlike the TypeScript tool-runtime modules. The canonical source is -**not vendored here** — it lives in the mesh-control repository at `examples/route-proxy`, the +**not vendored here** — it lives in the mesh-controller repository at `examples/route-proxy`, the contract written as something that runs. This module ships only the packaging: a multi-stage -[`Dockerfile`](Dockerfile) whose build context is the mesh-control repository root and which +[`Dockerfile`](Dockerfile) whose build context is the mesh-controller repository root and which compiles `./examples/route-proxy` into `mesh-route-proxy`. The committed `module.json` carries the placeholder digest every mesh-built image does (`@sha256:0000…`); the mesh pins the real digest at publish.