Issue 123: the image registry is named after a role, and *artifact* is defined as one format #126

Merged
jschoubben merged 1 commits from issue/123-the-image-registry-is-named-after-a-role into main 2026-09-26 13:38:00 +00:00
@@ -0,0 +1,74 @@
---
status: located
opened: 2026-09-26
located-in: [hq 00-META/glossary.md, hq 02-DECISIONS/0075-two-stores-and-which-provides-what.md, mesh-controller internal/catalogue/seats.go, mesh-catalog modules/distribution]
fixed-by:
amended-design:
---
# 123 — The image registry is named after a role, and *artifact* is defined as one format
## What was observed
Reading the registry work back to the operator on 2026-09-26, three wordings turned out to disagree
with each other, and the disagreement was doing real damage: a reader — including whoever writes the
next module — cannot tell what the mesh's image registry is for from what it is called.
**One: the word for a delivered thing is defined as one format.** The glossary says *artifact* is
"what the mesh delivers to a machine to install and run: **an OCI image, by digest**", served by the
`artifact-store`. But a module definition's own build vocabulary already names four kinds of artifact,
all in use in the catalogue today — `image` (48 of them), `upstream` (3), `bundle` (1), `archive` (1) —
and the controller's manifest code documents the field as "image or archive". So the catalogue builds
artifacts that are not images, while the word for them means image, and the store named after the word
serves images only.
**Two: the seat is named after a role, and every other one is not.** [ADR 0079](../../02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md)
names the foundation seats after their servers — the store, the broker. [ADR 0109](../../02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md)
settled that a package registry seat is one **per ecosystem**, not one for all of them, which is why
there is now a seat for one language's packages and another for git. The image registry's seat is
`the-artifact-store`: named after neither its server nor what it serves. It is the last registry named
after the job it happens to be doing.
**Three: a module is not an image.** An image is one thing a module may install or build; a module may
also ship archives, files, directories, databases and a service it did not build at all. Prose that
calls a built image "the module's image" reads as though a module *were* an image, and the manifest's
own vocabulary does not: it says artifacts, each with a kind.
## Why it matters
The cost is confusion, in the place where the mesh explains itself. Two people reading
`artifact-store` will reasonably take it for two different things — "where OCI images live" and "where
everything a module delivers lives" — and those stop being the same thing the moment a module delivers
an archive, which one already does.
It also hides a question that ought to be asked plainly. Because the store is named after a role, a
reader assumes the role needs its own implementation. What the records actually say is narrower:
[ADR 0075](../../02-DECISIONS/0075-two-stores-and-which-provides-what.md) keeps two provisions because
packages and images are two protocols — a language's client cannot install from an OCI registry — and
it **already allows the forge to provide `artifact-store` too**, saying a mesh may choose it. The
reason the OCI registry is a second implementation is a bootstrap argument: something must serve images
before the mesh can build anything.
**That bootstrap argument is weaker than it reads.** The forge's server is an upstream public image;
only its runtime sidecar is built ([issue 121](../121-builders-real-package-registry-grant-deadlocks-genesis/01-diagnosis.md),
where the opposite was claimed and retracted). The store and the broker have the same shape, and
[ADR 0078](../../02-DECISIONS/0078-the-store-and-broker-are-modules.md) raises both at genesis as
plumbing and **adopts them in place** as ordinary modules. The forge can be raised that way too, which
would leave the question of a second registry implementation resting on the window before it is
adopted, rather than on protocols.
## Open questions
- Should the seat and the provision be named after what they serve — an OCI registry, images by digest
— leaving *artifact* free to mean what the build vocabulary already means by it: anything a module
produces, of any kind?
- Does the mesh need two registry implementations at all, or can the forge hold every registry seat
once it is adopted in place? The protocol argument keeps two **provisions**; it does not by itself
require two **servers**.
- If a window before adoption is the only reason for the second one, is that window a **seat**, or a
step in genesis that ends?
- Renaming touches the glossary, two records, the seat set, the builder's requirement and every image
reference in the catalogue. Which of those can be checked mechanically, so the rename is not a prose
exercise that leaves the code disagreeing?
- What check would keep the glossary honest — a definition tested against the kinds a definition may
actually declare, rather than restated by hand?