ADR 0189: the store keeps what the records name, and a maintenance step holds its writers still

Issue 108: the artifact store has never collected anything. Fifty-three
repositories on the machine that serves everything else, and the only outcome
of leaving it is a full disk reported as somebody else's failure.

The mesh decides what may go — from its own build records, so it never names
a digest it did not put there — and the store reclaims the bytes in a nightly
window with its server held still. Deletion on the one door takes nothing a
push did not already have.

Designs 18 and 20 amended; issue 108 resolved.

Also issue 202, found running the controller's suite: a module whose required
setting nobody set is left out of the machine in silence, and dnsmasq became
that module this morning.
This commit is contained in:
2026-10-02 21:48:48 +02:00
parent 0b9fc90885
commit b69ae663bc
6 changed files with 298 additions and 6 deletions
+40 -1
View File
@@ -5,9 +5,10 @@ code:
- mesh-controller cmd/mesh-builder
- mesh-controller internal/builder
- mesh-catalog modules/builder
updated: 2026-10-01
updated: 2026-10-02
decisions:
- 02-DECISIONS/0157-a-build-says-what-it-does-on-the-bus-as-it-happens.md
- 02-DECISIONS/0189-the-store-keeps-what-the-records-name.md
- 02-DECISIONS/0150-a-modules-own-code-runs-as-supervised-processes-under-one-account.md
- 02-DECISIONS/0142-the-mesh-delivers-its-own-components-as-binaries.md
- 02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md
@@ -293,6 +294,44 @@ build's lines reach a reader of its subject in order and the stream holds them a
against a real server); the seat verb with an id reads the log (controller test); and, live, a build
after the roll-out read line by line through the console.
## The store keeps what the records name
*2026-10-02 — [ADR 0189](../../02-DECISIONS/0189-the-store-keeps-what-the-records-name.md),
[issue 108](../../04-ISSUES/108-the-registry-has-no-garbage-collection-once-it-has-two-doors/00-report.md).*
Every build pushes another layer set and, until this, nothing ever removed one. The registry's own
answer — collect what no tag names — is wrong for this mesh: each artifact is pushed under one
moving tag and machines are pinned by digest, so every build but the newest is untagged and some
machine may still be running it.
**The mesh decides and the store reclaims.** Deletion is enabled on the store's one door — that
door already accepts a push, and a writer who can push can replace any tag, so delete takes
nothing a push did not already have, and ADR 0082's bargain (a store every machine reaches with no
credential to distribute first) is kept. The mesh then removes what it put there and no longer
keeps, **naming it from its own build records** rather than enumerating the store: it has never
put anything there it did not record, so a digest it did not record making is never named, which
is what keeps the sweep away from the images genesis pushed before any record existed.
An artifact stays for one of two reasons and otherwise goes: a definition the mesh holds names it
(no age limit — this is the floor), or it belongs to one of the five most recent successful builds
of its module (somewhere for a wrong release to return to). The sweep runs after a build the mesh
recorded, which is the moment new bytes landed and the moment the keep set moved; it needs no
timer. Deleting a manifest frees no bytes, so the store's own collector runs nightly as a
scheduled step with the server held still — which is what `while-stopped` exists for
([design 20](20-writing-a-module.md)). Plain collection, not `--delete-untagged`: what the mesh
keeps is still a manifest and so still referenced, and the dangerous flag is not needed once the
mesh is the one deciding.
A machine behind by more than five builds of a module, recreating a container, cannot pull what it
was running. It is already a machine the mesh reports as behind, and the answer is the current
declaration.
*How it is checked:* the keep set, against records, holds what a manifest names and the five most
recent builds and nothing else; a reference the mesh never recorded is never in the delete set; an
image and an archive are asked for at their own endpoints; a store with deletion off names the
remedy rather than the status code; a store that does not have it is recorded collected rather
than retried for ever. Live: the store's size before and after the first nightly collection.
## The builder compiles the languages the mesh is written in
*2026-09-29 —