Merge pull request 'ADR 0156: an artifact is what a build produces, and the store's seat is named for its scope (group 4, step 3)' (#233) from feat/the-artifact-store-seat-is-named-for-its-scope into main
Reviewed-on: #233
This commit was merged in pull request #233.
This commit is contained in:
+5
-2
@@ -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
|
- **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.
|
**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
|
- **artifact** — anything a build produces and the mesh delivers to a machine by **digest**: an
|
||||||
**digest**. Served by the **artifact-store** (distribution). Every node pulls from it.
|
`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).
|
- 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
|
## How modules relate to the mesh
|
||||||
|
|||||||
+3
-1
@@ -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
|
- **`the-uplink` → `node-uplink`** ([ADR 0125](0117-a-machines-uplink-is-a-seat.md)). Unheld, so it
|
||||||
renames with no migration.
|
renames with no migration.
|
||||||
- **The registry seats — `the-artifact-store`, `npm-package-registry` (→ `mesh-artifact-store`,
|
- **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
|
*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
|
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.
|
the same pass as the node-* renames, so they keep their names until done deliberately.
|
||||||
|
|||||||
+83
@@ -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://<module>/<artifact>@sha256:…` for an image and
|
||||||
|
`artifact-store://<module>/<artifact>/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`
|
||||||
@@ -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)
|
- **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)
|
- **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)
|
- **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
|
### Its tiers, from the bottom up
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ convention, which later seats departed from.
|
|||||||
| `mesh-store` | — | mesh | — | the store the mesh's own records live in |
|
| `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-broker` | — | mesh | `mesh-bus` | the broker carrying the mesh's own bus |
|
||||||
| `mesh-vault` | — | mesh | `secret`, reserved | the vault |
|
| `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-catalog` | `the-catalogue` | mesh | — | the catalogue |
|
||||||
| `mesh-npm-package-registry` | `npm-package-registry` | mesh | `npm-package-registry` | the forge |
|
| `mesh-npm-package-registry` | `npm-package-registry` | mesh | `npm-package-registry` | the forge |
|
||||||
| `mesh-git` | `git` | mesh | `git` | the forge |
|
| `mesh-git` | `git` | mesh | `git` | the forge |
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
status: located
|
status: resolved
|
||||||
opened: 2026-09-26
|
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]
|
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:
|
fixed-by: ADR 0156; mesh-controller migration 0048 (feat/the-artifact-store-seat-is-named-for-its-scope); mesh-catalog modules/distribution
|
||||||
amended-design:
|
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
|
# 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?
|
exercise that leaves the code disagreeing?
|
||||||
- What check would keep the glossary honest — a definition tested against the kinds a definition may
|
- What check would keep the glossary honest — a definition tested against the kinds a definition may
|
||||||
actually declare, rather than restated by hand?
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user