From 22a28ad54816485005025c8175c145d89ae5c695 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 30 Sep 2026 21:14:40 +0200 Subject: [PATCH] ADR 0156: an artifact is what a build produces, and the store's seat is named for its scope Issue 123 resolved; glossary corrected; design 26 and ADR 0121 point at the rename. --- 00-META/glossary.md | 7 +- ...-its-scope-and-modules-define-their-own.md | 4 +- ...es-and-the-store-is-named-for-its-scope.md | 83 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + 03-DESIGN/01-to-be/26-the-seats.md | 2 +- .../00-report.md | 18 +++- 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md diff --git a/00-META/glossary.md b/00-META/glossary.md index 34fa695..0befcf4 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -52,8 +52,11 @@ another — and a mesh you cannot name precisely is a mesh two people describe d - **package** — what code resolves when it is **compiled**: an npm/cargo/pypi dependency, by **version**. Served by the **package-registry** (gitea). Only a builder talks to it. -- **artifact** — what the mesh delivers to a machine to **install and run**: an OCI image, by - **digest**. Served by the **artifact-store** (distribution). Every node pulls from it. +- **artifact** — anything a build produces and the mesh delivers to a machine by **digest**: an + `image`, a mirrored `upstream` image, a `bundle` of the module's own code, an `archive`. Served by + the **artifact-store**, an OCI registry that holds every kind as content-addressed blobs + ([ADR 0156](../02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md)). + Every node pulls from it. An image is one kind of artifact, and a module is not an image. - These are two protocols, not one store being weak — see [ADR 0075](../02-DECISIONS/0075-two-stores-and-which-provides-what.md). ## How modules relate to the mesh diff --git a/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md b/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md index 046163d..7c6f927 100644 --- a/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md +++ b/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md @@ -81,7 +81,9 @@ closed set stays what its name says it is: the *system's* roles, not everyone's. - **`the-uplink` → `node-uplink`** ([ADR 0125](0117-a-machines-uplink-is-a-seat.md)). Unheld, so it renames with no migration. - **The registry seats — `the-artifact-store`, `npm-package-registry` (→ `mesh-artifact-store`, - `mesh-npm-package-registry`) — and `git` (→ `mesh-git`) — are decided but deferred.** They each + `mesh-npm-package-registry`) — and `git` (→ `mesh-git`) — are decided but deferred.** *(The + mechanism changed — 2026-09-30, by ADR 0156: `the-artifact-store` is renamed, one update and one + alias under ADR 0122; the other two stay deferred.)* They each *deliver* a provision, so renaming them is a delivering-seat migration: a holder that stops resolving mid-flight takes a provision away from every consumer. That risk is not worth carrying in the same pass as the node-* renames, so they keep their names until done deliberately. diff --git a/02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md b/02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md new file mode 100644 index 0000000..dfea386 --- /dev/null +++ b/02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md @@ -0,0 +1,83 @@ +--- +topic: the mesh +status: accepted +date: 2026-09-30 +deciders: jochen +reconstructed: false +extends: 02-DECISIONS/0075-two-stores-and-which-provides-what.md +--- + +# 156. An artifact is what a build produces, the artifact store serves every kind, and its seat is named for its scope + +## Context + +[Issue 123](../04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md) found three +wordings disagreeing about the mesh's registry. The glossary defined *artifact* as "an OCI image, by +digest"; the manifest's build vocabulary names four kinds — `image`, `upstream`, `bundle`, `archive` — +and the catalogue builds all four; the seat was `the-artifact-store`, the last of the mesh's own seats +named after the job it does rather than for the mesh +([ADR 0121](0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md) decided the +rename and deferred it). The issue asked whether the seat and provision should be renamed after +images, and whether the mesh needs two registry implementations at all. + +Reading what the store actually serves settles the first question the other way. A kept reference +has two shapes — `artifact-store:///@sha256:…` for an image and +`artifact-store:////blobs/sha256:…` for an archive — and both are served by the +same OCI registry, by digest. [ADR 0075](0075-two-stores-and-which-provides-what.md) already +defined the provision that way: *content-addressed blobs, pinned by digest, no versions, no ranges; +what the mesh delivers to machines*. The provision was never an image registry. Only the glossary said +so, and only the seat's name was odd. + +## Considered Options + +**1. Rename the seat and the provision after images.** Rejected. The store serves archives too, by the +same protocol; naming it for one kind would be the glossary's mistake made permanent, in the name +every manifest uses. + +**2. Fix the word, rename the seat for its scope, keep the provision.** Chosen. The rename ADR 0121 +deferred as a delivering-seat migration is, since [ADR 0122](0122-a-seat-is-data-a-rename-is-a-database-update.md), +one update and one alias: the former name resolves forever, a held record follows by cascade, a claim +written with the old name still holds. + +**On two implementations:** left as 0075 decided. Two provisions because two protocols; the OCI +registry the genesis installs because something must serve images before the mesh can build; the +forge may provide `artifact-store` too and a mesh may choose it. The bootstrap argument is weaker than +it reads, as 123 says, and the day the forge is raised at genesis and adopted in place is the day to +retire the second server — a migration a mesh performs, not a decision to take here. + +## Decision + +- **An artifact is anything a build produces** — an image, a mirrored upstream image, a bundle, an + archive — and the glossary says so. *Image* is one kind. A module is not an image; a module may + build several artifacts and install none. +- **The artifact store serves artifacts of every kind a machine fetches**, images and archives, by + digest, over the OCI registry protocol. The provision keeps its name. +- **The seat is `mesh-artifact-store`.** `the-artifact-store` is its alias. The catalogue's registry + module claims the new name; a definition elsewhere claiming the old one still holds. +- The two other deferred renames — `npm-package-registry` and `git` — stay deferred, and for the + same reason no longer. They are one migration each when wanted; nothing here needs them. + +## Consequences + +- The glossary stops contradicting the manifest vocabulary, and a reader of `artifact-store` reads + it as what it is: where the mesh's built things are kept. +- One migration on the seat table; no manifest but the registry's changes; no consumer of the + provision changes, because the provision did not. +- **What got harder:** nothing measurable. A record that says `the-artifact-store` is read through the + alias; design 26's table already carried the new name as intent. + +## How this is checked + +| Rule | Checked by | +|---|---| +| The former name resolves to the seat once the store's aliases are loaded | a catalogue test | +| The seat is in the compiled set under its new name, delivering `artifact-store` | the seat tests, updated | +| The registry module holds the seat under the new name on the live mesh | `seats` after the rollout | +| The glossary's *artifact* matches the build kinds a manifest may declare | design 18's table and the showcase module list the kinds; the glossary names the same four | + +## References + +- [issue 123](../04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md) +- [ADR 0075](0075-two-stores-and-which-provides-what.md) — extended: the provision as defined stands, the word is corrected +- [ADR 0121](0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md), [ADR 0122](0122-a-seat-is-data-a-rename-is-a-database-update.md) — the rename, decided and made cheap +- mesh-controller migration 0048; mesh-catalog `modules/distribution` diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index 737d7cc..6a3d436 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -169,6 +169,7 @@ python3 00-META/checks/index.py fail if stale - **0134** — [The mesh says what it applied](0134-the-mesh-says-what-it-applied.md) - **0142** — [The mesh delivers its own components as binaries, not as container images](0142-the-mesh-delivers-its-own-components-as-binaries.md) - **0154** — [The mesh's own verbs are the mesh-controller seat's tools, and which verbs those are](0154-the-meshs-own-verbs-are-the-controller-seats-tools.md) +- **0156** — [An artifact is what a build produces, the artifact store serves every kind, and its seat is named for its scope](0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md) ### Its tiers, from the bottom up diff --git a/03-DESIGN/01-to-be/26-the-seats.md b/03-DESIGN/01-to-be/26-the-seats.md index 5f8f8f5..115bce4 100644 --- a/03-DESIGN/01-to-be/26-the-seats.md +++ b/03-DESIGN/01-to-be/26-the-seats.md @@ -109,7 +109,7 @@ convention, which later seats departed from. | `mesh-store` | — | mesh | — | the store the mesh's own records live in | | `mesh-broker` | — | mesh | `mesh-bus` | the broker carrying the mesh's own bus | | `mesh-vault` | — | mesh | `secret`, reserved | the vault | -| `mesh-artifact-store` | `the-artifact-store` | mesh | `artifact-store` | the artifact registry | +| `mesh-artifact-store` | `the-artifact-store` (renamed 2026-09-30, [ADR 0156](../../02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md)) | mesh | `artifact-store` | the artifact registry | | `mesh-catalog` | `the-catalogue` | mesh | — | the catalogue | | `mesh-npm-package-registry` | `npm-package-registry` | mesh | `npm-package-registry` | the forge | | `mesh-git` | `git` | mesh | `git` | the forge | diff --git a/04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md b/04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md index 1829a9f..e94b96d 100644 --- a/04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md +++ b/04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md @@ -1,9 +1,9 @@ --- -status: located +status: resolved 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: +fixed-by: ADR 0156; mesh-controller migration 0048 (feat/the-artifact-store-seat-is-named-for-its-scope); mesh-catalog modules/distribution +amended-design: 03-DESIGN/01-to-be/26-the-seats.md --- # 123 — The image registry is named after a role, and *artifact* is defined as one format @@ -72,3 +72,15 @@ adopted, rather than on protocols. 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? + +## Resolved, 2026-09-30 + +Read from what the store serves rather than from what it was called: both shapes of a kept reference +— an image and an archive's blob — go to the same registry by digest, which is exactly the provision +ADR 0075 defined. So the word was wrong and the seat's name was odd, and the provision was right. +[ADR 0156](../../02-DECISIONS/0156-an-artifact-is-what-a-build-produces-and-the-store-is-named-for-its-scope.md): +*artifact* means what a build produces, of any of the four kinds; the seat is `mesh-artifact-store` +with the old name as its alias (one migration, ADR 0122's mechanism); the provision keeps its name. +The two-implementations question stays as 0075 answered it, with the day to retire the second server +named. The mechanical check the report asked for is the alias test and the glossary naming the same +four kinds as design 18's table. -- 2.54.0