The runtime every module stands on is built from its own repository

It copied in a compiled directory that is not in source control and resolved
the toolkit to a sibling checkout, so only a workstation with two repositories
side by side could produce it — and its fingerprint was then typed into every
module by hand. Nothing could rebuild it, so nothing could check it, and the
rule that catches a base moving had no version on the far end of its edge.

The recipe now also says what the image in service actually is. It claimed
Alpine and has been serving Debian for as long as nobody could rebuild it.
This commit is contained in:
2026-09-13 02:39:11 +02:00
parent 991fb6faec
commit a174dfd404
3 changed files with 43 additions and 12 deletions
+30 -10
View File
@@ -1,15 +1,35 @@
# The tool runtime, as the container a node runs. It is handed the broker URL and the assigned
# modules' tool entrypoints at deploy time (MESH_BROKER_URL, MESH_TOOL_MODULES) and serves them.
FROM node:22-alpine AS build
# The tool runtime: the base every module written in this toolchain is compiled on top of, and the
# container a node runs to serve them. It is handed the broker credential and the assigned modules'
# entrypoints at deploy time and serves them.
#
# **Built from this repository alone.** It used to copy in a compiled output directory that is not
# in source control, and resolve the mesh's own toolkit to a sibling checkout on the same disk — so
# it could only be produced on a workstation with two repositories laid out side by side, and its
# fingerprint was then typed into every module's recipe by hand. That put the one artifact the whole
# toolchain stands on outside the toolchain: nothing could rebuild it, so nothing could check it,
# and the rule that catches a base moving had no version on the far end of its edge and could never
# fire (novox/hq issue 044).
#
# Debian rather than Alpine, and root rather than an unprivileged user, because that is what the
# image actually in service is — and modules have already been built against it, one of which
# installs a package with Debian's package manager. This recipe said Alpine while serving Debian for
# as long as nobody could rebuild it to notice. Changing the operating system under every module is
# a separate decision from making this buildable, and is not being taken here.
FROM node:22-bookworm-slim AS build
WORKDIR /app
COPY package.json ./
RUN npm install --omit=dev --no-audit --no-fund
COPY dist ./dist
COPY package.json package-lock.json ./
# Development dependencies included: the compiler is one of them, and so is the toolkit's own — it
# builds itself on install, which is what lets it be named by a git URL rather than fetched from a
# package registry this mesh does not yet run.
RUN npm install --no-audit --no-fund
COPY tsconfig.json ./
COPY src ./src
RUN npm run build
FROM node:22-alpine
# Everything the modules compile against and run on, and nothing that only the build needed.
FROM node:22-bookworm-slim
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY package.json package-lock.json ./
RUN npm install --omit=dev --no-audit --no-fund && npm cache clean --force
COPY --from=build /app/dist ./dist
COPY package.json ./
USER node
ENTRYPOINT ["node", "dist/main.js"]
+11
View File
@@ -0,0 +1,11 @@
{
"module": "mesh-tools",
"version": "1",
"slug": "tools",
"build": {
"artifacts": [
{ "name": "runtime", "kind": "image", "from": "Dockerfile" }
]
},
"resources": []
}
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@novox/mesh-tools",
"version": "0.1.0",
"description": "The Novox Mesh tool runtime — binds the mesh broker and serves the assigned modules' tools.",
"description": "The Novox Mesh tool runtime \u2014 binds the mesh broker and serves the assigned modules' tools.",
"type": "module",
"bin": {
"mesh-tools": "./dist/main.js"
@@ -11,7 +11,7 @@
"test": "node --test --experimental-strip-types 'test/*.test.ts'"
},
"dependencies": {
"@novox/mesh-sdk": "^0.1.0",
"@novox/mesh-sdk": "git+https://git.novox.be/novox/mesh-sdk.git#a1ed33b",
"amqplib": "^0.10.9"
},
"devDependencies": {