From 41a4405253a6ea57354a8868e47fb200a0e97838 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 30 Aug 2026 10:29:01 +0200 Subject: [PATCH] What a build machine may do, and what is kept MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two additions to the module-repository design, both from building it. A build machine has its own credential and it is not a node's: read the build queue, write the mesh exchange, nothing else. A node's queue carries that node's declarations. The answer goes through the exchange and never the default one, because permission there is per exchange rather than per queue — anything allowed to use it can publish into any node's queue. The price is that every asker sees every result and filters by correlation, which is cheap against a builder never needing that permission. And every result is kept, failures included, because one that leaves no trace is indistinguishable from a build nobody asked for. That is what a builds view reads; the board page is corrected to say so. --- 03-DESIGN/01-to-be/11-a-board.md | 2 +- 03-DESIGN/01-to-be/12-a-module-repository.md | 24 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/11-a-board.md b/03-DESIGN/01-to-be/11-a-board.md index bc4af04..44f60b3 100644 --- a/03-DESIGN/01-to-be/11-a-board.md +++ b/03-DESIGN/01-to-be/11-a-board.md @@ -21,7 +21,7 @@ the other four are about the mesh itself. | | what it shows | where it stands here | |---|---|---| | **the mesh** | every node, what each runs, what each takes from another, module versions | **everything behind it exists** — it is a reader, not a second source | -| **builds** | a build, its stages, its log | the builder exists; **what is missing is a record of past builds**, since a result is answered to whoever asked and kept nowhere | +| **builds** | a build, its stages, its log | **everything behind it exists** — every result is kept, failures included | | **sessions** | model sessions, their usage, and switching between accounts | [ADR 0024](../../02-DECISIONS/0024-model-access-is-a-provision.md) | | **channels** | nodes messaging each other | the agent layer | diff --git a/03-DESIGN/01-to-be/12-a-module-repository.md b/03-DESIGN/01-to-be/12-a-module-repository.md index 15cf989..f5a23a8 100644 --- a/03-DESIGN/01-to-be/12-a-module-repository.md +++ b/03-DESIGN/01-to-be/12-a-module-repository.md @@ -88,6 +88,16 @@ So it has its own queue, and the answer comes back correlated. **One queue**, so machines share the work and each request is done exactly once, which a routing key per machine would not give. +**A build machine has its own credential**, and it is not a node's. It may read the build queue +and write to the mesh exchange, and that is all — a node's queue carries that node's declarations, +and a build machine has no business reading them. + +**The answer goes through the exchange, never the default one.** Permission on the default +exchange is granted per *exchange*, not per queue, so anything allowed to use it can publish into +any node's queue. That is the privilege a build machine most obviously should not have. So an +asker binds its own reply queue to the same routing key and filters by correlation; every asker +sees every result, which is the price of the builder never needing that permission. + Three properties of the builder that are decisions: - **a request is acknowledged only once the answer is away.** A builder that dies mid-build then @@ -98,6 +108,20 @@ Three properties of the builder that are decisions: is not running, and those want completely different responses — the same rule the host follows about a service that does not exist +## What is kept + +**Every result, including the failures.** A failed build that leaves no trace is indistinguishable +from one nobody asked for, and the difference is the whole of whether somebody should be looking +at something. A build that failed before it knew what it was building keeps the repository, which +is what a person goes and looks at. + +Recording is idempotent on the correlation, because a result arrives twice — once as the answer to +whoever asked and once on the exchange, where the control plane is also listening. Two rows would +show one build as two, and which is real is not answerable afterwards. + +That is what a builds view reads, and until it existed there was nothing to read: a result was +answered to the asker and kept nowhere. + ## Three properties that are decisions - **A fresh clone every time.** A build reusing a working tree can succeed because of something a