ADR 0076: the SDK is a published package the toolchain resolves by version

Records the decision the package-registry work turns on — the SDK is built on a
public base and published before the toolchain that consumes it, so nothing is
circular; mesh-tools stays the thin toolchain base but resolves the SDK by
version. Reconciles docs 12/17/22 and indexes the record.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-16 10:28:08 +02:00
parent 17c2e061df
commit b43b60b183
5 changed files with 118 additions and 0 deletions
@@ -408,6 +408,15 @@ being a builder rather than a result.
Everything outside those four is either upstream — a third-party image pulled by digest — or built
by the builder from a repository and a path, and published to the registry.
**One of those built things has an ordering constraint worth naming, because it looks like a fifth
member of the list and is not.** The SDK the toolchain compiles against is built by the ordinary
builder and published like anything else — but it cannot be compiled *in the mesh toolchain*, since
that toolchain is built from it, and it is published to the *package* registry rather than the
artifact store. So it is compiled on a public base image and published before the toolchain that
consumes it ([ADR 0076](../../02-DECISIONS/0076-the-sdk-is-a-published-package.md)). It is not
carried and it is not machinery; it is a dependency with a sequence, which is why it belongs here as
a footnote to the rule rather than a row in the table.
**A carried artifact is not a differently-pinned artifact.** Once published it is named by a digest
the mesh's registry assigned, exactly like everything the builder produces. A reader cannot tell
from a running mesh which of its images were carried, and that is the point: carrying is how the
+10
View File
@@ -178,6 +178,16 @@ credential for a database; it does not yet do so for the store its own images li
avoids the question by carrying the image it needs, which makes this a joining problem and a
pulling problem, not a genesis one.
**The SDK still comes from a git URL, and the ordering that fixes it is decided but not built.**
[ADR 0076](../../02-DECISIONS/0076-the-sdk-is-a-published-package.md) settles that the package
registry (gitea) comes up and the SDK is published into it *before* the base toolchain is built, so
the toolchain resolves the SDK by version rather than cloning it — closing
[issue 053](../../04-ISSUES/053-the-sdk-is-pinned-twice-and-the-two-disagree/00-report.md). The
builder already knows how to be handed a package-registry credential and inject it into a build; what
is not yet wired is the genesis step that raises gitea and publishes the SDK ahead of the base, and
the toolchain's own manifest still names the SDK by a git URL. Until both land, the base build clones
the SDK inside `docker build`, which is slow and names a branch head rather than a version.
## How these rules are checked
| Rule | Checked by |
+11
View File
@@ -63,6 +63,17 @@ registry. Nothing installs one, so the SDK comes from a git URL (issue 053). Nee
**Done when.** A module builds against the SDK resolved from the mesh's own registry, and issue 053
closes.
**Where it stands (2026-09-16).** The decision the bootstrap turned on is settled and recorded
([ADR 0076](../../02-DECISIONS/0076-the-sdk-is-a-published-package.md)): the SDK is a published
package, built on a public base image and published before the toolchain that consumes it; mesh-tools
stays the thin toolchain base but `npm ci`s the SDK by version. On the code, the builder now resolves
a package-registry credential — from a binding the mesh writes or from the environment for a hand-run
or bootstrap build — and injects it into an image build as a buildkit secret, never a layer, so a
token is not baked into the toolchain image. Unit-tested. Still ahead: gitea serving the registry in
full with a provisioner that mints tokens (2.1), the SDK built and published by the mesh (2.2), the
mesh-tools manifest flipped off the git URL to `npm ci` by version (2.3), and the genesis step that
raises gitea and publishes the SDK before the base build. Those close together in one lab run.
## Phase 3 — nothing is special after installation
**Why last.** The hardest and riskiest, and it needs everything above: an installer that completes,