A module names the module its build stands on, not a copy of it

A fingerprint written into a recipe names one particular copy of the base — the
copy on whichever machine the person typing it was using. On any other mesh that
copy has never existed, so the build stops on its first line with a message
about an image nobody can look up. Three modules in the catalogue were in
exactly that state, and the line each of them replaced was equally dead.

A module now names the module and artifact instead, and the mesh answers with
what it holds. The builder is still a thing that clones, builds and answers: the
answer travels with the question, because only the mesh knows what it has.

A base the mesh has not built is refused before anything is built, naming which
module has to exist first.
This commit is contained in:
2026-09-13 23:53:22 +02:00
parent cb5108a864
commit cfe2816495
9 changed files with 269 additions and 16 deletions
+25
View File
@@ -344,6 +344,31 @@ type Build struct {
// Artifacts are what the source produces, each named so a resource can refer to it before
// anybody knows its digest.
Artifacts []Artifact `json:"artifacts,omitempty"`
// On is what this module's own build stands on: another module's artifact, named rather than
// pinned.
//
// **A module may not write down which copy of its base to use** (novox/hq issue 044). Every
// module in a scripted toolchain is compiled inside one shared image, and a fingerprint typed
// into a recipe names one particular copy of it — the copy on whichever machine the person
// typing was using. On any other mesh that copy has never existed, so the build stops on its
// first line. Naming the module instead lets the mesh answer with the copy *this* mesh has,
// which is the only one it can fetch.
//
// It does not make the build edge declared. What this says is where to start; what the build
// was actually built against is still read back out of the build itself (ADR 0009), and the
// two can disagree — a recipe that names a base and then bakes in a second one is exactly the
// drift that reading it back catches.
On []BuildsOn `json:"on,omitempty"`
}
// BuildsOn is one base a build needs, and the name the recipe knows it by.
type BuildsOn struct {
// Arg is the build argument the recipe reads it from.
Arg string `json:"arg"`
// Module is whose artifact it is.
Module string `json:"module"`
// Artifact is which of that module's artifacts, by its own name for it.
Artifact string `json:"artifact"`
}
// Artifact is one thing built from a module's source.